def main(): regs = Registry() for i in range(15): sphere = Sphere(mass=1.0, radius=4.0, pos=Vector2d(random.random() * 100.0, random.random() * 100.0), vel=Vector2d(20.0, 0.0), damping=0.0, elasticity=0.97) regs.add_entity(RigidBody(sphere), Drawable(), Movable()) for e1, [r1] in regs.get_components(RigidBody): for e2, [r2] in regs.get_components(RigidBody): if e1 == e2: continue regs.add_entity( Link( SpringDamperLink(r1.sphere, r2.sphere, damping=0.1, spring=1.0, length=100.0)), Drawable()) regs.add_system(InputSystem()) regs.add_system(GravitationalSystem()) regs.add_system(ScreenBounceSystem()) regs.add_system(SimulationSystem()) regs.add_system(RenderSystem()) regs.add_system(GameLoopSystem()) while True: regs.process()
def __init__(self): super(Ball, self).__init__(radius=3, mass=1.0, pos=Vector2d(425.0, 425.0), vel=Vector2d(0.0, -10.0), damping=0.00, elasticity=0.97)
def startup(self, persistent): self.persist = persistent self.persist['success'] = False self.persist['score'] = 0 self.entities = [] self.started = False self.paused = False self.starfield = Starfield(self.screen_rect) self.show_cursor = False self.time = 0.0 # Load level for line in open(self.persist['level']).readlines(): mass, size, pos, vel, mutable, color = line.split(":") pos = pos.split(",") vel = vel.split(",") mutable = mutable.startswith('1') entity = Planet( float(size), mass=float(mass), pos=Vector2d(float(pos[0]), float(pos[1])), vel=Vector2d(float(vel[0]), float(vel[1])), elasticity=0.97, ) entity.mutable = mutable c = map(int, color.split(",")) entity.color = pg.Color(*c) self.entities.append(entity)
def __init__(self, world=None, mass=10.0, inertia=10.0, damping=0.0, elasticity=0.8, vel=Vector2d(0, 0), pos=Vector2d(0, 0), theta=0, dtheta=0): self._world = world self._mass = mass self._inertia = inertia self._damping = damping self._elasticity = elasticity self._state = Vector( 0, # dx 0, # dy 0, # dtheta 0, # x 0, # y 0, # theta ) self.pos = pos self.vel = vel self.dtheta = dtheta self.theta = theta self._applied_force = Vector2d(0, 0) self._applied_torque = 0 self._gravity = Vector(0, 0, 0)
def test_min_dist_point_line(self): point = Vector2d(0.0, 1.0) line1 = Vector2d(1.0, 0.0) line2 = Vector2d(1.0, 2.0) (cp, u) = min_distance_point_line(point, line1, line2) self.assertEqual(u, 0.5) self.assertEqual(cp, Vector2d(1.0, 1.0))
def test_multiplication(self): a = Vector2d(3,1) b = Vector2d(1,2) c = a * b self.assertEqual(c, [3,2]) a *= b self.assertEqual(a,c) d = -1 * a self.assertEqual(d, [-1 * a.x, -1 * a.y])
def test_intersect_circle_line(self): circle_center = Vector2d(25.0, 0.0) circle_radius = 10.0 line_start = Vector2d(0.0, 0.0) line_end = Vector2d(50.0, 0.0) xsect = intersect_circle_line(circle_center, circle_radius, line_start, line_end) self.assertTrue(xsect)
def test_subtraction(self): a = Vector2d(3,0) b = Vector2d(0,2) c = a - b self.assertEqual(c, [3,-2]) a -= b self.assertEqual(a,c) d = 1 - a self.assertEqual(d, [1 - a.x, 1 - a.y])
def test_addition(self): a = Vector2d(3,0) b = Vector2d(0,2) c = a + b self.assertEqual(c, [3,2]) a += b self.assertEqual(a,c) d = 1 + a self.assertEqual(d, [a.x+1, a.y+1])
def test_division(self): a = Vector2d(3.0,1.0) b = Vector2d(1.0,2.0) c = a / b self.assertEqual(c, [3, 0.5]) a /= b self.assertEqual(a,c) d = 1 / a self.assertEqual(d, [1 / a.x, 1 / a.y])
def calc_wall_force(ship): wall_force = 50 distance = 30 if ship.x < distance: ship.apply_force_to_com(Vector2d(wall_force, 0.0)) elif ship.x > (screen_mode.x - distance): ship.apply_force_to_com(Vector2d(-wall_force, 0.0)) if ship.y < distance: ship.apply_force_to_com(Vector2d(0.0, wall_force)) elif ship.y > (screen_mode.y - distance): ship.apply_force_to_com(Vector2d(.0, -wall_force))
def test_cross(self): a = Vector3d(-0, 10, 0) b = Vector3d(10, 0, 0) c = b.cross(a) self.assertEqual(c, [0, 0, 100]) d = a.cross(b) self.assertEqual(d, [0, 0, -100]) a = Vector2d(-0, 10) b = Vector2d(10, 0) c = b.cross(a) self.assertEqual(c, 100)
def test_intersection_line_line_parallel(self): line11 = Vector2d(0.0, 0.0) line12 = Vector2d(0.0, 4.0) line21 = Vector2d(0.0, 0.0) line22 = Vector2d(0.0, 4.0) (cp, u1, u2) = intersection_line_line(line11, line12, line21, line22) self.assertEqual(cp, Vector2d(0.0, 0.0)) self.assertEqual(u1, 0.0) self.assertEqual(u2, 0.0)
def tick(self, _): for er, (r, m) in self.registry.get_components(RigidBody, Movable): if r.sphere.y > 650: counter_force = Vector2d(0.0, 100 * (650 - r.sphere.y)) r.sphere.apply_force_to_com(counter_force) if r.sphere.x < 10: counter_force = Vector2d(100.0 * (10.0 - r.sphere.x), 0.0) r.sphere.apply_force_to_com(counter_force) elif r.sphere.x > 790: counter_force = Vector2d(100.0 * (790 - r.sphere.x), 0.0) r.sphere.apply_force_to_com(counter_force)
def do_flock(this_ship, ships): if not ships: return avg_vel = Vector2d(0.0, 0.0) avg_pos = Vector2d(0.0, 0.0) for ship in ships: avg_vel += ship.vel avg_pos += ship.pos l = len(ships) avg_vel /= l avg_pos /= l this_ship.apply_force_to_com(avg_vel) this_ship.apply_force_to_com(avg_pos - this_ship.pos)
def test_angle(self): a = Vector2d(4,4) b = Vector2d(4,-4) c = b.angle_diff(a) self.assertAlmostEqual(c, math.pi/2) d = b.angle_diff(b) self.assertAlmostEqual(d, 0) e = Vector2d(-4, -4) f = e.angle_diff(a) self.assertAlmostEqual(f, math.pi) g = a.angle_diff(e) self.assertAlmostEqual(g, -math.pi) h = a.angle() self.assertAlmostEqual(h, math.pi/4)
def tick(self, _): for er, (r, m, p) in self.registry.get_components(RigidBody, Movable, Seeking): if p.target is None: continue (rt, ) = self.registry.get_entity(p.target, RigidBody) m.force += pursuit(r.sphere.pos, r.sphere.vel, rt.sphere.pos, rt.sphere.vel) for er, (r, m, e) in self.registry.get_components(RigidBody, Movable, Evading): if e.target is None: continue (rt, ) = self.registry.get_entity(e.target, RigidBody) m.force += evade_within(r.sphere.pos, r.sphere.vel, rt.sphere.pos, rt.sphere.vel, 50.0) for er, (r, m, w) in self.registry.get_components(RigidBody, Movable, Wandering): m.force += wander(r.sphere.pos, r.sphere.vel, w.displacement, w.dist) e, [c] = next(self.registry.get_components(Centroid)) for er, (r, m) in self.registry.get_components(RigidBody, Movable): m.force += arrive(r.sphere.pos, r.sphere.vel, c.center, 50.0) for er, (r, m) in self.registry.get_components(RigidBody, Movable): m.force = truncate(m.force, m.max_force) r.sphere.apply_force_to_com(m.force / r.sphere.mass) m.force = Vector2d(0.0, 0.0)
def apply_torque(screen, sphere1, sphere2, link, dt): target = Vector2d(10.0, -10.0) link_vector = sphere2.pos - sphere1.pos vec = link_vector.perp().normalize() deviation = target.angle_diff(link_vector) Kc = 80.0 # P force = Kc * 2.9 * deviation # I if hasattr(sphere2, "sum_deviation"): sphere2.sum_deviation += deviation * dt iforce = sphere2.sum_deviation * 0.1 * Kc force += iforce else: sphere2.sum_deviation = 0.0 # D if hasattr(sphere2, "prev_deviation"): dforce = (sphere2.prev_deviation - deviation) / dt force += dforce * -8.4 * Kc sphere2.prev_deviation = deviation sphere2.apply_force_to_com(vec * -1.0 * force)
def main(): regs = Registry() for i in range(30): m = float(random.randrange(10, 30)) sphere = Sphere(mass=m, radius=int(m), pos=Vector2d(random.randrange(800.0), random.randrange(800.0)), damping=0.01, elasticity=0.97) regs.add_entity(RigidBody(sphere), Drawable(), Movable()) regs.add_entity(Centroid(), Drawable()) regs.add_system(InputSystem()) regs.add_system(CollisionCheckSystem()) regs.add_system(CollisionSystem()) regs.add_system(SeekCentroidSystem()) regs.add_system(SimulationSystem()) regs.add_system(RenderSystem()) regs.add_system(GameLoopSystem()) while True: regs.process()
def _test_rect_slight_hit(self): rect1 = Rectangle(mass=1, dimensions=Vector2d(100, 20), pos=Vector2d(50, 10), vel=Vector2d(0, 0), theta=0) sphere1 = Sphere( mass=1, radius=10, pos=Vector2d(10, 30), vel=Vector2d(0, 0), ) collides = rect1.collides_with(sphere1) self.assertTrue(collides) rect1.resolve_collision(sphere1)
def __init__(self, pos, vel=Vector2d(.01, 0.0)): super(Triangle, self).__init__(mass=1.0, radius=30, pos=pos, vel=vel, damping=0.0, elasticity=1.0) self.direction = vel self.color = (155, 50, 50)
def __init__(self): pos = Vector2d(400.0, 400.0) vel = Vector2d(.0, .0) self.radius = 20.0 super(Ship, self).__init__( mass=1.0, pos=pos, vel=vel, dtheta=0., #05 * 180 / math.pi, damping=0.00, elasticity=0.97, dimensions=Vector2d(100, 40)) self.surface = pygame.Surface(self.dimensions.tuple()) dim = self.dimensions rect_tuple = (5, 5, dim.x - 10, dim.y - 10) self.surface.fill((0, 100, 0)) pygame.draw.rect(self.surface, (255, 0, 0), rect_tuple, 0)
def update(self, dt): dt /= 100.0 if not self.started: p = pg.mouse.get_pos() self.cursor = Vector2d([float(i) for i in p]) player = self.entities[0].pos diff = self.cursor - player if diff.length() < 1000: self.show_cursor = True diff /= 50 self.initial_velocity = diff self.entities[0].vel = Vector2d(float(diff[0]), float(diff[1])) else: self.show_cursor = False elif not self.paused: self.time += dt entity_set = list(self.entities) # Success condition if self.entities[0].collides_with(self.entities[-1]): self.persist['init_vel'] = self.initial_velocity self.persist['success'] = True self.persist['score'] = self.time self.done = True return for entity in entity_set: entity_set.remove(entity) for other in entity_set: if entity.collides_with(other): entity.resolve_collision(other) force = entity.calc_gravity(other) entity.apply_force(entity.pos, force) other.apply_force(other.pos, -force) for entity in self.entities: if entity.mutable == True: entity.update(0, dt) self.starfield.update() else: pass
def test_sphere_gracing_hit(self): sphere1 = Sphere(mass=1, radius=10, pos=Vector2d(10, 10), vel=Vector2d(10, 0), damping=0., elasticity=1.0) sphere2 = Sphere(mass=1, radius=10, pos=Vector2d(10, 30), vel=Vector2d(0, 0), damping=0., elasticity=1.0) collides = sphere1.collides_with(sphere2) self.assertEqual(sphere1.pos, (10, 10), "First check") self.assertTrue(collides) sphere1.resolve_collision(sphere2) self.assertEqual(sphere1.dtheta, 0) self.assertEqual(sphere2.dtheta, 0) self.assertEqual(sphere1.pos, (10, 10)) self.assertEqual(sphere1.vel, (10, 0))
def collides_with(self, other): if hasattr(other, 'radius'): center = Vector2d(1,0).rotate(self.theta).normalize() center_perp = center.perp() relative_pos = other.pos - self.pos dist = relative_pos.dot(center) lateral_dist = relative_pos.dot(center_perp) if (abs(dist) <= self.dimensions.x/2 + other.radius and abs(lateral_dist) <= self.dimensions.y/2+other.radius): return True return False
def main(): polygon = [] polygon.append(Vector2d(0.0, 0.0)) polygon.append(Vector2d(10.0, 0.0)) polygon.append(Vector2d(20.0, 10.0)) polygon.append(Vector2d(10.0, 10.0)) polygon.append(Vector2d(0.0, 10.0)) point_inside = Vector2d(10.0, 10.0) point_outside = Vector2d(30.0, 10.0) assert not point_outside_box(point_inside, bounding_box(polygon)) assert point_outside_box(point_outside, bounding_box(polygon))
def test_inside_polygon(self): polygon = [] polygon.append(Vector2d(0.0, 0.0)) polygon.append(Vector2d(10.0, 0.0)) polygon.append(Vector2d(10.0, 10.0)) polygon.append(Vector2d(0.0, 10.0)) point_inside = Vector2d(5.0, 5.0) point_outside = Vector2d(15.0, 15.0) point_on_edge = Vector2d(10.0, 10.0) self.assertTrue(inside_polygon(point_inside, polygon)) self.assertFalse(inside_polygon(point_outside, polygon)) self.assertTrue(inside_polygon(point_on_edge, polygon))
def min_distance_point_line(p, l1, l2): """Calculates shortest distance from a point p to a line given by the points l1 and l2. """ u_nom = ((p.x - l1.x) * (l2.x - l1.x) + (p.y - l1.y) * (l2.y - l1.y)) u_den = (l2 - l1).length_sq() if u_den == 0: return (l1, 0.0) u = u_nom / u_den x = l1.x + u * (l2.x - l1.x) y = l1.y + u * (l2.y - l1.y) closest_point = Vector2d(x, y) return (closest_point, u)
def test_outside_box(self): polygon = [] polygon.append(Vector2d(0.0, 0.0)) polygon.append(Vector2d(10.0, 0.0)) polygon.append(Vector2d(20.0, 10.0)) polygon.append(Vector2d(10.0, 10.0)) polygon.append(Vector2d(0.0, 10.0)) point_inside = Vector2d(10.0, 10.0) point_outside = Vector2d(30.0, 10.0) self.assertFalse( point_outside_box(point_inside, bounding_box(polygon))) self.assertTrue( point_outside_box(point_outside, bounding_box(polygon)))
def main(): regs = Registry() for i in range(10): m = float(random.randrange(10.0, 20.0)) sphere = Sphere( mass = m/10.0, radius = int(m), pos = Vector2d(random.randrange(800.0), random.randrange(800.0)), damping = 0.30, elasticity = 0.90 ) regs.add_entity( RigidBody(sphere), Drawable(), Movable(), Seeking(target=4)) #, # Evading(target=3)) # Wandering()) regs.add_component(4, Wandering()) regs.add_component(3, Wandering()) regs.remove_component(4, Seeking()) regs.remove_component(3, Seeking()) # regs.remove_component(4, Evading()) # regs.remove_component(3, Evading()) regs.add_entity( Centroid(), Drawable()) regs.add_system(InputSystem()) regs.add_system(CollisionCheckSystem()) regs.add_system(CollisionSystem()) regs.add_system(ForceSystem()) regs.add_system(SimulationSystem()) regs.add_system(RenderSystem()) regs.add_system(GameLoopSystem()) while True: regs.process()