def add_things(): for i in range(amount): z = random.random() * 6.28 r = 0.001 + random.random() * 0.01 pos = r * math.cos(z), r * math.sin(z) vel = tuple( Vec2d(pos).normalized() * (1 + 4 * random.random()) * 3) offset = 0, 0 texcoords = 0, 0 texsize = 1, 1 angle = random.random() * 6.28 avel = (-1 if random.random() > 0.5 else 1) * ( random.random() * 0.1 + 0.9) * 10 * Vec2d(vel).get_length() size = (0.1, 0.1) rgba = [random.random() for i in range(3)] + [1.0] name = "polygon_normals.{}.generated".format( random.choice((3, 4, 5, 6, 8))) rv = psys.add(size=size, texture_coordinates=atlas.texcoords(name), texture_size=atlas.texsize(name), position=pos, offset=offset, angle=angle, colour=rgba) things[rv] = (pos, angle, vel, avel)
def test_point_components_random_pure_rotational_velocity(): for i in range(1000): a = rnd() r = rnd() ang = rnd() c, _, _ = create_and_check_point_component(rnd2(), ang, (0, 0), a, Vec2d(r, 0), rnd()) assert vectors_almost_equal( c.velocity, Vec2d(0, pi * r * a / 180.0).rotated_degrees(ang))
def test_point_components_random_combined_velocities(): for i in range(1000): a = rnd() r = rnd() ang = rnd() v = rnd2() c, block, thing = create_and_check_point_component( rnd2(), ang, v, a, Vec2d(r, 0), rnd()) print thing.velocity, v, c.velocity assert vectors_almost_equal( c.velocity - thing.velocity, Vec2d(0, pi * r * a / 180.0).rotated_degrees(ang))
def test_point_components_random_pure_rotational_velocity_at_zero_angle(): for i in range(1000): a = rnd() r = rnd() c, _, _ = create_and_check_point_component(rnd2(), 0.0, (0, 0), a, Vec2d(r, 0), rnd()) assert vectors_almost_equal(c.velocity, (0, pi * r * a / 180.0))
def create_and_check_point_component(thing_xy, thing_angle, vel, angvel, comp_xy, comp_angle): comp_xy = Vec2d(comp_xy) thing_xy = Vec2d(thing_xy) vel = Vec2d(vel) block, thing = setup_world() thing.position = thing_xy thing.angle_degrees = thing_angle thing.velocity = vel thing.angular_velocity_degrees = angvel component = PointComponent(block, comp_xy, comp_angle) assert almost_equal(component.position.get_distance(thing.position), comp_xy.get_length()) assert degrees_almost_equal(component.angle_degrees, thing.angle_degrees + comp_angle) return component, block, thing
def test_point_component_at_origin(): block, thing = setup_world() component = PointComponent(block, (0, 0), 0.0) assert component.position == block.position assert component.position == Vec2d(0, 0) assert component.angle_degrees == block.angle_degrees assert component.angle_degrees == 0.0
def with_engine(block, edge_index=3): try: rv = block for index in edge_index: rv = with_engine(rv, index) return rv except TypeError: pass angle = block.edge(edge_index).angle_degrees pos = Vec2d(polar_degrees(angle, 16.0)) pos = Vec2d(0, 0) pos = block.edge(edge_index).midpoint() context = {"block": block} engine = create_component("engine", context, position=pos, angle_degrees=angle, required_edge=edge_index, power=500, cost=50) return block
def update(self, dt): super(Ship, self).update() if self.minimap_symbol_sprite: self.minimap_symbol_sprite.position = self.position if self._shooting: self.world.shoot_volley(self) self.body.reset_forces() spin = self._spin rotation_distance = 100 rotation_force_size = self.turn_power if spin == 0: delta_angular_momentum = rotation_force_size * rotation_distance * dt angular_momentum = self.body.angular_velocity * self.body.moment if angular_momentum > 0 and abs( angular_momentum) > delta_angular_momentum: spin = 1 elif angular_momentum < 0 and abs( angular_momentum) > delta_angular_momentum: spin = -1 else: self.body.angular_velocity = 0 rotation_force = Vec2d(self.turn_power, 0) * spin rotation_offset = Vec2d(0, rotation_distance) self.body.apply_force(rotation_force, rotation_offset) self.body.apply_force(-rotation_force, -rotation_offset) forces = [] if self._thrusting: force = (self._turbo_multiplier if self._turbo else 1) * self.thrust_power dx, dy = polar_degrees(self.angle_degrees, force) forces.append(Vec2d(dx, dy)) if self._braking: stopforce = self.body.velocity.normalized() * -1 * self.brake_power if self.velocity.get_length() < stopforce.get_length() * 0.01: forces = [] self.body.velocity = Vec2d(0, 0) else: forces.append(stopforce) self.body.apply_force(reduce(lambda x, y: x + y, forces, Vec2d(0, 0)))
def with_gun(block, edge_index=1): try: rv = block for index in edge_index: rv = with_gun(rv, index) return rv except TypeError: pass angle = block.edge(edge_index).angle_degrees pos = Vec2d(polar_degrees(angle, 16.0)) pos = Vec2d(0, 0) pos = block.edge(edge_index).midpoint() context = {"block": block} cooldown = 0.2 # .cooldown = 0.1 # a LOT more powerful with lower cooldown cost = (750 * cooldown) * 2.0 / 3.0 # more reasonable power usage gun = create_component("gun", context, position=pos, angle_degrees=angle, required_edge=edge_index, cooldown=cooldown, cost=cost) return block
def create_dumb_missile(world, shooter, gun): points = [(0,0),(9,0),(9,33),(0,33)] shape = ConvexPolygonShape(*points) shape.translate( shape.centroid() * -1) layer = None rv = Debris( world, layer, (0,0), shape, None, mass = 1.0, moment = physics.infinity, collision_type = physics.CollisionTypes["bullet"], group = physics.CollisionGroups["bullets"] ) speed = 10 acceleration = Vec2d(gun.direction) * 1500 base_velocity = gun.velocity base_velocity = shooter.velocity # unrealistic but possibly better rv.velocity = base_velocity + gun.direction * speed rv.position = gun.position rv.angle_radians = degrees_to_radians( gun.angle_degrees + 90.0 ) # realistic rv.inert = False rv.grace = 0.5 rv.shooter = shooter rv.lifetime = 0.0 kw = {} kw[ "size" ] = 9.0,33.0 kw[ "texture_size" ] = world.atlas.texsize( "laserGreen" ) kw[ "texture_coordinates" ] = world.atlas.texcoords( "laserGreen" ) kw[ "position" ] = rv.position kw[ "angle" ] = rv.angle_radians kw[ "colour" ] = (0.4,0.4,1.0,1.0) rv.index = world.object_psys.add( **kw ) world.psys_managed_things.append( (rv, rv.index) ) def update_bullet( bullet, dt ): if not bullet.alive: return bullet.lifetime += dt bullet.grace -= dt if bullet.lifetime > 0.2: bullet.velocity += acceleration * dt if bullet.ttl <= bullet.lifetime: bullet.kill() def kill_bullet( rv ): world.psys_managed_things.remove( (rv,rv.index) ) world.object_psys.remove( rv.index ) def my_impact( thing, block, block_index ): basic_impact( hp = 5, thing = thing, block = block, block_index = block_index ) rv.ttl = 1.5 rv.kill_hooks.append( kill_bullet ) rv.impact = my_impact world.pre_physics.add_hook( rv, partial(update_bullet,rv) )
def setup_game(self, player_ship_data=None): self.sim = physics.PhysicsSimulator(timestep=None) # self.player = create_ship_thing( self, self.main_layer, (500,500), shape = "small", hp = 5 ) if not player_ship_data: self.player = Ship.load_file("current_garage_ship.yaml", self) else: self.player = Ship.load_data(player_ship_data, self) self.player.position = (300, 300) self.player.invulnerable = False self.enemy = create_ship_thing(self, (500, 500), shape="small", hp=10) self.enemy.invulnerable = False self.enemy.body.angular_velocity_limit = degrees_to_radians(144 * 2) self.enemy2 = create_ship_thing(self, (0, 500), shape="small", hp=10) self.enemy2.invulnerable = False self.enemy2.body.angular_velocity_limit = degrees_to_radians(144 * 2) self.enemy.angle_degrees = random.random() * 360.0 self.enemy2.angle_degrees = random.random() * 360.0 self.batch = cocos.batch.BatchNode() self.main_layer.cocos_layer.add(self.batch) self.physics_objects = [] self.things = [] self.psys_managed_things = [] for i in range(200): cols = "red", "purple", "grey", "blue", "green", "yellow" sq = create_square_thing(self, None, (100, 0), None) sq.position = (random.random() - 0.5) * 4000, (random.random() - 0.5) * 4000 sq.angle_radians = random.random() * math.pi * 2 sq.mylabel = sq.position sq.velocity = (300, 10) kw = {} name = "polygon_normals.4.generated" kw["size"] = Vec2d(106.6666666, 106.6666666) kw["texture_coordinates"] = self.atlas.texcoords(name) kw["texture_size"] = self.atlas.texsize(name) z = random.random() * 6.28 r = 0.1 + random.random() * 10.0 pos = r * math.cos(z), r * math.sin(z) # need to translate from pixel space # [0,self. # to # [-1.3333,1.3333] x [-1,1] p = sq.position p = p + self.main_layer.cocos_layer.position p = Vec2d(p) / Vec2d(self.window.width, self.window.height) p = (p * 2) - Vec2d(1, 1) p = p * Vec2d(self.window.width / float(self.window.height), 1) kw["position"] = p kw["angle"] = sq.angle_radians kw["colour"] = 1.0, 0.5, 0.5, 1.0 index = self.object_psys.add(**kw) self.psys_managed_things.append((sq, index)) self.things.append(sq) def draw_psys(): # CMSDTv # T = translate by self.main_layer.cocos_layer.position # # M = v -> v - (1,1) # C = v -> v * (w/h, 1) w = float(self.window.width) h = float(self.window.height) x, y = self.main_layer.cocos_layer.position mat = (2.0 / w, 0.0, 0.0, (2 * x / w - 1), 0.0, 2.0 / h, 0.0, (2 * y / h - 1), 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0) self.object_psys.set_transformation_matrix(mat) glEnable(GL_SCISSOR_TEST) glScissor(0, 0, self.window.width + 1 - self.hud_width, self.window.height) self.object_psys.draw() glDisable(GL_SCISSOR_TEST) s = 0.3 sx, sy = 500 + self.sim._t * 100, 200 sx, sy = self.window.width - self.hud_width * 0.5, self.window.height - self.hud_width * 0.5 mat = (0.0, s * 2.0 / w, 0.0, (2 * sx / w - 1), s * 2.0 / h, 0, 0.0, (2 * sy / h - 1), 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0) self.hud_psys.set_transformation_matrix(mat) self.hud_psys.draw() graphics.Layer(self.scene, cocos_layer=graphics.FunctionCocosLayer(draw_psys)) self.sim.space.add_collision_handler(physics.CollisionTypes["main"], physics.CollisionTypes["bullet"], self.collide_general_with_bullet)