def __init__(self, position, speed, image, bounce_sound): super(Ball, self).__init__() self.position = Vec2d(position) self.speed = Vec2d(speed) self.image = image self.bounce_sound = bounce_sound self.age = 0.0
def set_position(self, x_or_pair, y=None): diff = Vec2d(self.pos) super(UIGroup, self).set_position(x_or_pair, y) diff = Vec2d(self.pos) - diff for element in self.elements: element.set_position(Vec2d(element.pos) + diff)
def __init__(self, entity): self.entity = entity self._velocity = Vec2d(0, 0) self._movement_velocity = Vec2d(0, 0) self._acceleration = Vec2d(0, 0) self.mass = 1 self.forces = {}
def test_contains_point(self): polygon = Polygon([Vec2d(1, 0), Vec2d(0, 0), Vec2d(0, 1), Vec2d(1, 1)]) self.assertTrue(polygon.contains_point(Vec2d(0.5, 0.5))) self.assertFalse(polygon.contains_point(Vec2d(2, 0))) self.assertFalse(polygon.contains_point(Vec2d(1, 0))) self.assertFalse(polygon.contains_point(Vec2d(0, 0))) self.assertFalse(polygon.contains_point(Vec2d(0, 1))) self.assertFalse(polygon.contains_point(Vec2d(1, 1)))
def update_terminals(self): term_iter = self.level_manager.active_terminal_groups.iteritems() for group, terminals in term_iter: term1_vec = Vec2d(terminals[0].x, terminals[0].y) term2_vec = Vec2d(terminals[1].x, terminals[1].y) colour = terminals[0].colour self.add_terminals(group, term1_vec, term2_vec, colour) self.level_manager.set_terminals(self.terminals)
def __init__(self, world, name, image): self.world = world self.name = name self.image = image self.location = Vec2d(0, 0) self.destination = Vec2d(0, 0) self.speed = 0. self.brain = StateMachine() self.id = 0
def get_vec_grid_coords(self, screen_x_or_pair, screen_y=None): coords = None if screen_y is not None: row = screen_y / self.block_size column = screen_x_or_pair / self.block_size coords = Vec2d(column, row) else: coords = Vec2d(screen_x_or_pair / self.block_size) return self.clamp_to_grid(coords)
def render(self, grid, cur_line): mouse_pos = Vec2d(pygame.mouse.get_pos()) m_grid_pos = grid.get_vec_grid_coords(mouse_pos.x, mouse_pos.y) screen = pygame.display.get_surface() black = Color('Black') white = Color('White') screen.fill(black) # START DRAW grid size = grid.block_size for y in xrange(grid.rows): for x in xrange(grid.columns): cur_square = Rect(x * size, y * size, size, size) # grid_val = GRID.get_grid_value(x, y) # COLOURS[grid_val] # Change colour based on grid value if m_grid_pos.x == x and m_grid_pos.y == y: # Semi-transparent Hover inner_sq = get_inner_square(cur_square) sur = screen.convert_alpha() pygame.draw.rect(sur, alpha(white, 75), inner_sq) screen.blit(sur, (0, 0)) pygame.draw.rect(screen, white, cur_square, 2) grid.level_manager.render_level() for line in grid.finished_lines: line_label = line.start_terminal.label for point in line.draw_points: screen.blit(line_label, point) # END DRAW GRID # DRAW CUR_LINE if cur_line: points = cur_line.draw_points label = cur_line.start_terminal.label for point in points: screen.blit(label, point) sur = screen.convert_alpha() for point in cur_line.get_grid_possible_moves(): # Semi-transparent Hover inner_sq = get_inner_square_from_point(Vec2d(point), size) pygame.draw.rect(sur, alpha(white, 50), inner_sq) screen.blit(sur, (0, 0)) # END DRAW CUR_LINE # DRAW UI for element in self.elements: if not element.hidden: if type(element) == UIGroup: for el in element.elements: screen.blit(el.rendered_text, el.pos) else: screen.blit(element.rendered_text, element.pos)
def test_border_non_intersect(self): polygon = Polygon() polygon.add_point(0, 0) polygon.add_point(0, 1) polygon.add_point(1, 1) polygon.add_point(1, 0) line1 = [Vec2d(0, 0), Vec2d(1, 0)] self.assertFalse(intersect_polygon(line1, polygon))
def run(): pygame.init() screen = pygame.display.set_mode((640, 480)) # , FULLSCREEN) stars = [] star_pos = Vec2d(0, 0) white = (255, 255, 255) CENTER = (320.0, 240.0) clock = pygame.time.Clock() # 第一帧, 画一些星星 for n in range(200): x = float(randint(0, 639)) y = float(randint(0, 479)) speed = float(randint(10, 300)) stars.append(Star(x, y, speed)) while True: for event in pygame.event.get(): if event.type == QUIT: return if event.type == KEYDOWN: return # 增加一颗新的星星 x = float(randint(0, 639)) y = float(randint(0, 479)) speed = float(randint(10, 300)) star = Star(x, y, speed) stars.append(star) time_passed = clock.tick() time_passed_seconds = time_passed / 1000.0 screen.fill((0, 0, 0)) # 绘制所有星星 for star in stars: star_pos = (Vec2d(star.x, star.y) - Vec2d(CENTER)).normalized() new_x = star.x + star_pos.x * time_passed_seconds * star.speed new_y = star.y + star_pos.y * time_passed_seconds * star.speed pygame.draw.aaline(screen, white, (new_x, new_y), (star.x, star.y)) star.x = new_x star.y = new_y def on_screen(star): return star.x > 0 and star.y > 0 and star.x < 640.0 and star.y < 480.0 # 星星跑出画面 删除 stars = list(filter(on_screen, stars)) print(len(stars)) pygame.display.update()
def get_points(self): min_x, max_x, min_y, max_y = self.get_min_max() points = [ Vec2d(max_x, min_y), Vec2d(min_x, min_y), Vec2d(min_x, max_y), Vec2d(max_x, max_y), ] return points
def test_basic_polygon_intersect(self): poly = Polygon() poly.add_point(0, 0) poly.add_point(0, 1) poly.add_point(1, 1) poly.add_point(1, 0) line = [Vec2d(-0.5, -0.5), Vec2d(0.5, 0.5)] self.assertTrue(intersect_polygon(line, poly)) line = [Vec2d(1, -1), Vec2d(1, 0)] self.assertFalse(intersect_polygon(line, poly))
def test_non_overlapping(self): points_0 = [Vec2d(1, 0), Vec2d(0, 0), Vec2d(0, 1), Vec2d(1, 1)] points_1 = [Vec2d(3, 0), Vec2d(2, 0), Vec2d(2, 1), Vec2d(3, 1)] separating_vectors, overlaps = calculate_separating_vectors( points_0, points_1) self.assertFalse(overlaps) self.assertSameElements(separating_vectors, [])
def test_broken_hull_history3(self): points = [ Vec2d(579, 518), Vec2d(500, 512), Vec2d(528, 501), Vec2d(573, 477), Vec2d(510, 541), Vec2d(533, 565), Vec2d(542, 578), Vec2d(516, 437), Vec2d(575, 401), Vec2d(519, 470) ] hull_points = generate_convex_hull(points) self.assertEqual(len(hull_points), 6)
def test_convex_hull(self): points = [ Vec2d(1, 0), Vec2d(0, 0), Vec2d(0.5, 0.5), Vec2d(0, 1), Vec2d(1, 1) ] self.assertEqual( generate_convex_hull(points), [Vec2d(1, 1), Vec2d(1, 0), Vec2d(0, 0), Vec2d(0, 1)])
def test_broken_hull_history2(self): points = [ Vec2d(105, 150), Vec2d(113, 134), Vec2d(84, 111), Vec2d(143, 137), Vec2d(136, 97), Vec2d(138, 60) ] hull_points = generate_convex_hull(points) self.assertEqual( hull_points, [Vec2d(105, 150), Vec2d(143, 137), Vec2d(138, 60), Vec2d(84, 111)])
def generate_convex_hull(points, screen=None): # Note, this algorithm requires that we select the bottom most point. # Otherwise, we could potentially get negative angles from `get_angle_between()` # which throws off the angle sorting if len(points) < 3: raise Exception( 'Cannot generate convex hull for fewer than three points') pivot_point = get_bottom_right_most_point(points) point_to_angle_map = {} for point in points: if point == pivot_point: continue angle = Vec2d(pivot_point.x + 1, pivot_point.y).get_angle_between(point - pivot_point) if angle < 0: angle += 360 point_to_angle_map[point] = angle sorted_points = sorted(point_to_angle_map.iteritems(), key=lambda tuple: (tuple[1], tuple[0].get_distance(pivot_point)), reverse=True) sorted_points = [x[0] for x in sorted_points] sorted_points.append(pivot_point) hull_points = [pivot_point, sorted_points[0], sorted_points[1]] for point in sorted_points[2:]: next_hull_point_found = False while not next_hull_point_found: previous, current, next = hull_points[-3:] vec2 = next - current vec1 = current - previous if vec2.cross(vec1) > 0: hull_points.append(point) next_hull_point_found = True elif vec2.cross(vec1) < 0: hull_points.pop(-2) else: next_dist = (next - previous).get_length() current_dist = (current - previous).get_length() # Keep the point that's further away for our convex hull if next_dist > current_dist: hull_points.pop(-2) else: hull_points.pop() hull_points.append(point) next_hull_point_found = True hull_points.pop() return hull_points
def check_conditions(self): if Vec2d(*NEST_POSITION).get_distance(self.ant.location) \ < NEST_SIZE: if (randint(1, 10) == 1): self.ant.drop(self.ant.world.background) return 'exploring' return None
def grid_point_to_draw_point(self, point): label = self.start_terminal.label screen_point = self.grid.get_pos_from_grid_coords(point) # Only for labels screen_point += self.grid.block_size / 2 screen_point = (screen_point.x - label.get_width() / 2, screen_point.y - label.get_height() / 2) return Vec2d(screen_point)
def get_net_force(self, exclude_forces=None): if exclude_forces is None: exclude_forces = [] return (sum([ force.vector for force_name, force in self.forces.iteritems() if force_name not in exclude_forces ] or [Vec2d(0, 0)]))
def get_grid_possible_moves(self): point = self.grid_points[-1] potential_moves = [] if point.y >= 1: potential_moves.append(Vec2d(point.x, point.y - 1)) if point.y + 1 < self.grid.rows: potential_moves.append(Vec2d(point.x, point.y + 1)) if point.x >= 1: potential_moves.append(Vec2d(point.x - 1, point.y)) if point.x + 1 < self.grid.columns: potential_moves.append(Vec2d(point.x + 1, point.y)) adjacent_points = [] for move in potential_moves: if not self.grid.is_grid_collision(move, self.group): adjacent_points.append(move) return adjacent_points
def generate_random_polygon(x_max, y_max, max_points): from lib.geometry.polygon import Polygon points = [] i = 0 while i < max_points: x = random.randint(0, x_max) y = random.randint(0, y_max) if Vec2d(x, y) in points: continue else: points.append(Vec2d(x, y)) i += 1 hull_points = generate_convex_hull(points) return Polygon(hull_points)
def get_close_entity(self, name, location, range=100.0): # 通过一个范围寻找之内的所有实体 location = Vec2d(*location) for entity in self.entities.values(): if entity.name == name: distance = location.get_distance_to(entity.location) if distance < range: return entity return None
def test_broken_hull_history1(self): points = [ Vec2d(60, 130), Vec2d(65, 83), Vec2d(105, 74), Vec2d(141, 136), Vec2d(79, 123) ] hull_points = generate_convex_hull(points) self.assertEqual( hull_points, [Vec2d(141, 136), Vec2d(105, 74), Vec2d(65, 83), Vec2d(60, 130)])
def run(): pygame.init() screen = pygame.display.set_mode(SCREEN_SIZE, 0, 32) world = World() w, h = SCREEN_SIZE clock = pygame.time.Clock() ant_image = pygame.image.load('../image/ant.png').convert_alpha() leaf_image = pygame.image.load('../image/leaf.png').convert_alpha() spider_image = pygame.image.load('../image/spider.png').convert_alpha() for ant_no in range(ANT_COUNT): ant = Ant(world, ant_image) ant.location = Vec2d(randint(0, w), randint(0, h)) ant.brain.set_state('exploring') world.add_entity(ant) while True: for event in pygame.event.get(): if event.type == QUIT: return # 还是读取帧间隔时间, 但是限制最高30fps time_passed = clock.tick(30) if randint(1, 10) == 1: leaf = Leaf(world, leaf_image) leaf.location = Vec2d(randint(0, w), randint(0, h)) world.add_entity(leaf) if randint(1, 100) == 1: spider = Spider(world, spider_image) spider.location = Vec2d(-50, randint(0, h)) spider.destination = Vec2d(w + 50, randint(0, h)) world.add_entity(spider) world.process(time_passed) world.render(screen) pygame.display.update()
def __init__(self): super(Queen, self).__init__([ ReproductionComponent(), MovementComponent(speed=150), SpriteRenderComponent(self, 'mite.png', 64, 64), ]) self.position = Vec2d(0, 0) Queen.system_manager.send_message({ 'message_type': MESSAGE_TYPE.CREATE_ENTITY, 'entity_type': 'queen', 'entity': self })
def _compute_t_value(intersector, intersectee): intersectee_dir = intersectee[1] - intersectee[0] normal = Vec2d(intersectee_dir[1], -intersectee_dir[0]) A = intersector[0] B = intersector[1] P = intersectee[0] denominator = (A - B).dot(normal) if denominator == 0: return None return (A - P).dot(normal) / denominator
def __init__(self, x, y, radius, colour, group): self.x = x self.y = y # for colours # self.pos = Vec2d(x, y) self.radius = radius self._active_colour = (255, 255, 255) self._inactive_colour = (150, 150, 150) self.colour = self._inactive_colour # only for text colour self.group = group self._font = font.SysFont('Arial', 40, bold=True) self.label = self._font.render(str(int(group) + 1), 0, self.colour) # for text version self.pos = Vec2d(x - self.label.get_width() / 2, y - self.label.get_height() / 2) self.used = False
def test_line_intersect_epsilon(self): polygon = Polygon([ Vec2d(540, 591), Vec2d(600, 571), Vec2d(590, 440), Vec2d(542, 471), Vec2d(533, 576) ]) planner = AStarPlanner() planner.add_polygon(polygon) planner.init() path = planner.find_path(596, 526, 462, 516) self.assertEquals(path, [Vec2d(600, 571), Vec2d(540, 591), Vec2d(462, 516)])
def run(): resource_manager = ResourceManager.get_instance() resource_manager.setup(settings.SPRITES_FOLDER) system_manager = set_up_systems() obstacle1 = Obstacle(Vec2d(250, 50), 100, 100, 10) obstacle2 = Obstacle(Vec2d(250, 250), 100, 100, 10) obstacle3 = Obstacle(Vec2d(250, 450), 100, 100, 10) # obstacle3 = Obstacle(Vec2d(300, 50), 100, 100, 10) # obstacle3 = Obstacle(Vec2d(300, 250), 100, 100, 10) # obstacle3 = Obstacle(Vec2d(300, 450), 100, 100, 10) obstacle3 = Obstacle(Vec2d(400, 50), 100, 100, 10) obstacle3 = Obstacle(Vec2d(400, 250), 100, 100, 10) obstacle3 = Obstacle(Vec2d(400, 450), 100, 100, 10) system_manager.send_message( {'message_type': MESSAGE_TYPE.INIT_MOVEMENT_PLANNER}) queen = Queen() clock = pygame.time.Clock() quit = False while True: system_manager.update(1 / float(30)) for event in pygame.event.get(): if event.type == pygame.QUIT: quit = True elif event.type == pygame.MOUSEBUTTONDOWN: mouse_pos = pygame.mouse.get_pos() system_manager.send_message({ 'message_type': MESSAGE_TYPE.MOVE_ENTITY, 'entity': queen, 'goal': mouse_pos, }) keys = pygame.key.get_pressed() if keys[pygame.K_ESCAPE]: quit = True if quit: sys.exit() clock.tick(30)