def __init__(self): super(Game, self).__init__() # Set map dimensions self.px_width = 7680 self.px_height = 4320 # Set player score self.score = 0 self.destroy_flag = False self.trail_list = [Sprite('ships/trail.png'), Sprite('ships/trail2.png')] self.trail_choice = random.choice (self.trail_list) # Set physics space self.space = pm.Space(iterations = 500) self.space.gravity = 0, 0 self.space.add_collision_handler(0, 1, post_solve=self.player_asteroid_collision) self.space.add_collision_handler(1, 2, post_solve=self.asteroid_planet_collision) # Set batches and add them to the layer self.star_batch = BatchNode() self.planet_batch = BatchNode() self.weapon_batch = BatchNode() self.asteroid_batch = BatchNode() self.trail_batch = BatchNode() self.add(self.star_batch) self.add(self.planet_batch) self.add(self.weapon_batch) self.add(self.asteroid_batch) self.add(self.trail_batch) # Generate star map and add stars, planets, and suns self.world = CreateWorld() self.world.make_map(self.star_batch, self.planet_batch, self, self.space) self.asteroids = Asteroids(self.asteroid_batch, self.space) # Track keys, lasers to move self.keys_being_pressed = set() self.laser_count = set() # Create a player, add to space and layer self.player = create_player() self.player.name = "player" self.space.add(self.player.body, self.player.poly) self.player2 = create_player() self.player2.name = "player2" self.space.add(self.player2.body, self.player2.poly) self.players = [self.player, self.player2] self.player.cooldown = 0 self.player2.cooldown = 0 self.add(self.player) self.add(self.player2) # Schedule update and debug self.schedule(self.update) self.schedule_interval(self.debug, 1)
class Game(ScrollableLayer): is_event_handler = True def __init__(self): super(Game, self).__init__() # Set map dimensions self.px_width = 7680 self.px_height = 4320 # Set player score self.score = 0 self.destroy_flag = False self.trail_list = [Sprite('ships/trail.png'), Sprite('ships/trail2.png')] self.trail_choice = random.choice (self.trail_list) # Set physics space self.space = pm.Space(iterations = 500) self.space.gravity = 0, 0 self.space.add_collision_handler(0, 1, post_solve=self.player_asteroid_collision) self.space.add_collision_handler(1, 2, post_solve=self.asteroid_planet_collision) # Set batches and add them to the layer self.star_batch = BatchNode() self.planet_batch = BatchNode() self.weapon_batch = BatchNode() self.asteroid_batch = BatchNode() self.trail_batch = BatchNode() self.add(self.star_batch) self.add(self.planet_batch) self.add(self.weapon_batch) self.add(self.asteroid_batch) self.add(self.trail_batch) # Generate star map and add stars, planets, and suns self.world = CreateWorld() self.world.make_map(self.star_batch, self.planet_batch, self, self.space) self.asteroids = Asteroids(self.asteroid_batch, self.space) # Track keys, lasers to move self.keys_being_pressed = set() self.laser_count = set() # Create a player, add to space and layer self.player = create_player() self.player.name = "player" self.space.add(self.player.body, self.player.poly) self.player2 = create_player() self.player2.name = "player2" self.space.add(self.player2.body, self.player2.poly) self.players = [self.player, self.player2] self.player.cooldown = 0 self.player2.cooldown = 0 self.add(self.player) self.add(self.player2) # Schedule update and debug self.schedule(self.update) self.schedule_interval(self.debug, 1) def on_key_press(self, key, mod): try: self.keys_being_pressed.add( key ) except KeyError: pass def on_key_release(self, key, mod): try: self.keys_being_pressed.remove(key) except KeyError: pass def remove_from_set(self, item, container): new_set = container.copy() try: new_set.remove(item) except KeyError: new_set.remove(item) finally: return new_set def player_asteroid_collision(self, space, arbiter): for asteroid in self.asteroids.asteroid_count: # This for loop checks the identity of the arbiter-asteroid with every asteroid until it finds a match # Then it calculates the damage to the player if asteroid.body is arbiter.shapes[1].body: if self.player.body is arbiter.shapes[0].body: player = self.player player.speed = sqrt(pow(player.body.velocity[0], 2) + pow(player.body.velocity[1], 2) ) elif self.player2.body is arbiter.shapes[0].body: player = self.player2 player.speed = sqrt(pow(player.body.velocity[0], 2) + pow(player.body.velocity[1], 2) ) else: print "error did not find player" # Get the speed of an asteroid from it's velocity using the pythagoras theorem asteroid.speed = sqrt(pow(asteroid.body.velocity[0], 2) + pow(asteroid.body.velocity[1], 2) ) # The damage is just the asteroid speed minus the player speed plus an arbitary number if asteroid.morph == 'large': damage = abs(5 + asteroid.speed - player.speed) player.health -= damage elif asteroid.morph == 'medium': damage = abs(10 + asteroid.speed - player.speed ) player.health -= damage elif asteroid.morph == 'small': damage = abs(15 + asteroid.speed - player.speed ) player.health -= damage def asteroid_planet_collision(self, space, arbiter): for asteroid in self.asteroids.asteroid_count: # This for loop checks the identity of the arbiter with the asteroid for every asteroid until it finds a match if asteroid.body is arbiter.shapes[0].body: self.explode(asteroid) # Remove asteroids from world self.space.remove(asteroid.body, asteroid.poly) self.asteroids.asteroid_count = self.remove_from_set(asteroid, self.asteroids.asteroid_count) self.asteroid_batch.remove(asteroid) self.destroy_flag = True # Regenerate asteroids and adjust score if asteroid.morph == 'large': self.asteroids.create_asteroid(asteroid.position, asteroid.morph) self.asteroids.create_asteroid(asteroid.position, asteroid.morph) elif asteroid.morph == 'medium': self.asteroids.create_asteroid(asteroid.position, asteroid.morph) self.asteroids.create_asteroid(asteroid.position, asteroid.morph) def update_asteroids(self,dt): for player in self.players: if player.cooldown < 20: player.cooldown += 1 # Move asteroids and collide them with lasers for asteroid in self.asteroids.asteroid_count: self.planetoid_gravity(asteroid.body, 5000000, 1.0, dt) asteroid.position = asteroid.body.position asteroid.rotation = asteroid.body.angle for laser in self.laser_count: collide = asteroid.get_rect().contains(laser.position[0], laser.position[1]) if collide: # Remove laser from world laser.do(FadeOut(0.09) + CallFunc (self.weapon_batch.remove, laser) ) self.laser_count = self.remove_from_set(laser, self.laser_count) # Create an explosion self.explode(asteroid) try: self.asteroids.asteroid_count = self.remove_from_set(asteroid, self.asteroids.asteroid_count) self.space.remove(asteroid.body, asteroid.poly) self.asteroid_batch.remove(asteroid) except: print "WARNING: could not remove asteroid" continue self.destroy_flag = True # Regenerate asteroids and adjust score if asteroid.morph == 'large': self.asteroids.create_asteroid(asteroid.position, asteroid.morph) self.asteroids.create_asteroid(asteroid.position, asteroid.morph) player = laser.owner player.score += 10 elif asteroid.morph == 'medium': self.asteroids.create_asteroid(asteroid.position, asteroid.morph) self.asteroids.create_asteroid(asteroid.position, asteroid.morph) player = laser.owner player.score += 25 elif asteroid.morph == "small": player = laser.owner player.score += 50 def planetoid_gravity(self, body, gravity, damping, dt): # for every planet created adjust a body's velocity to imitate gravity for planet in self.world.planet_count: p = pm.Vec2d(body.position) - pm.Vec2d(planet.position) sqdist = p.get_length_sqrd() g = (p * -gravity)/(sqdist * sqrt(sqdist)) pm.Body.update_velocity(body, g, damping, dt) def update_trail(self, trail_choice, player): if trail_choice == self.trail_list[0]: # Red trail trail = Sprite('ships/trail.png') elif trail_choice == self.trail_list[1]: # Blue trail trail = Sprite('ships/trail2.png') trail.position = player.position self.trail_batch.add(trail) trail.do(FadeOut(1) + CallFunc (self.trail_batch.remove, trail ) ) def explode(self, asteroid): explode = Explosion() ''' if asteroid.morph == "large": explode.size = 25 elif asteroid.morph == 'medium': explode.size = 15 elif asteroid.morph == 'small': explode.size = 5 ''' explode.size = 5 explode.start_color = Color( 255, 0, 0, 255 ) explode.end_color = Color(255,0,0,255) explode.total_particles = 10 explode.position = asteroid.position explode.auto_remove_on_finish = True self.add(explode) def debug(self, dt): ''' print "#########################" print "Asteroid count" print len(self.asteroids.asteroid_count) print "asteroid_batch children" print len(self.asteroid_batch.get_children()) print "Laser count" print len(self.laser_count) print "weapon_batch children" print len(self.weapon_batch.get_children()) print "number of bodies" print len(self.space.bodies) print "#########################" ''' pass def player_player_damage(self): for player in self.players: for laser in self.laser_count: collide = player.get_rect().contains(laser.position[0], laser.position[1]) if collide: if laser.owner is not player: player.health -= laser.damage player.score -= 50 laser.owner.score += 50 laser.do(FadeOut(0.09) + CallFunc (self.weapon_batch.remove, laser) ) self.laser_count = self.remove_from_set(laser, self.laser_count) self.explode(player) def update(self, dt): # Create a list of pressed keys key_names = [symbol_string(k) for k in self.keys_being_pressed] # Turn player angle to radians # Get the vector angle of the player player2_radians = self.player2.rotation * (pi/180) player_radians = self.player.rotation * (pi/180) self.player.vector_angle = xAngle, yAngle = sin(player_radians), cos(player_radians) self.player2.vector_angle = xAngle, yAngle = sin(player2_radians), cos(player2_radians) for key in key_names: # Handle player input if key == "LEFT": self.player2.rotation -= 1 elif key == "RIGHT": self.player2.rotation += 1 elif key == "UP": self.player2.body.apply_impulse ( (self.player2.vector_angle[0] * 20, self.player2.vector_angle[1] * 20) ) elif key == "DOWN": self.player2.body.apply_impulse( (-self.player2.vector_angle[0] * 20, -self.player2.vector_angle[1] * 20) ) if key == "BACKSPACE": if self.player2.cooldown >= 20: laser = Sprite('weapons/LaserMKI.png') laser.rotation = self.player2.rotation laser.position = self.player2.get_rect().center laser.vector = self.player2.vector_angle laser.owner = self.player2 laser.damage = 100 self.weapon_batch.add(laser) self.laser_count.add(laser) self.player2.cooldown = 0 if key == "A": self.player.rotation -= 1 elif key == "D": self.player.rotation += 1 elif key == "W": self.player.body.apply_impulse ( (self.player.vector_angle[0] * 20, self.player.vector_angle[1] * 20) ) elif key == "S": self.player.body.apply_impulse( (-self.player.vector_angle[0] * 20, -self.player.vector_angle[1] * 20) ) if key == "SPACE": if self.player.cooldown >= 20: laser = Sprite('weapons/LaserMKI.png') laser.rotation = self.player.rotation laser.position = self.player.get_rect().center laser.vector = self.player.vector_angle laser.owner = self.player laser.damage = 100 self.weapon_batch.add(laser) self.laser_count.add(laser) self.player.cooldown = 0 for laser in self.laser_count: laser.position = laser.position[0] + laser.vector[0] * dt * 2000, laser.position[1] + laser.vector[1] * dt * 2000 # Update asteroids and planetary gravity self.planetoid_gravity(self.player.body, 5000000, 1.0, dt) self.planetoid_gravity(self.player2.body, 5000000, 1.0, dt) self.update_asteroids(dt) if self.destroy_flag == True: if len(self.asteroids.asteroid_count) <= 5: #print "There are %s asteroids in the scene" % (str(len(self.asteroids.asteroid_count))) self.asteroids.create_asteroid("garbage input", 'new') self.destroy_flag = False # Step the simulation self.space.step(0.05) self.player_player_damage() # Update player position self.player.position = self.player.body.position self.player2.position = self.player2.body.position # Update player tails self.update_trail(self.trail_list[0], self.player) self.update_trail(self.trail_list[1], self.player2) if self.player.health <= 0 or self.player2.health <= 0: director.replace(SplitColsTransition(GameOver(self.player.score, self.player2.score)))