Esempio n. 1
0
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)))	
Esempio n. 2
0
class Layers:
    globalPanel = None
    stats = None
    walls = []
    objects = []
    backgrounds = []
    bullets = []
    tanks = None

    main_scene = None

    def __init__(self, main_scene):
        self.bullets = BatchNode()
        self.walls = BatchNode()
        self.objects = BatchNode()
        self.backgrounds = BatchNode()
        self.tanks = BatchNode()
        # self.decorations = BatchNode()

        #main_scene = get_main_scene_layer()
        self.main_scene = main_scene
        self.main_scene.add(self.backgrounds, z=0)
        self.main_scene.add(self.bullets, z=1)
        # self.main_scene.add(self.decorations)
        self.main_scene.add(self.walls)
        self.main_scene.add(self.objects)
        self.main_scene.add(self.tanks)

        self.globalPanel = cocos.layer.Layer()
        self.main_scene.add(self.globalPanel, z=1)

        # self.stats = StatsLayer()

    def init_panel_with_stats(self):
        self.main_scene.init_panel_with_stats()

    def setHealth(self, health):
        self.main_scene.setHealth(health)

    def damage(self, damage, position):
        self.main_scene.damage(damage, position)

    def addElement(self, item, time=0):
        self.globalPanel.add(item)

        if time:
            t = Timer(time, lambda: self.globalPanel.remove(item))
            t.start()

    tankz = 3

    def addTank(self, tank):
        self.tankz += 1
        print(tank.position)
        self.tanks.add(tank, z=2)
        self.tanks.add(tank.Gun, z=3)
        self.tanks.add(tank.healthHelper, z=4)

    def removeTank(self, tank):
        self.tanks.remove(tank)
        self.tanks.remove(tank.Gun)
        self.tanks.remove(tank.healthHelper)

    def addAnimation(self, anim):
        self.globalPanel.add(anim)

    def addObject(self, obj, z=0):
        self.objects.add(obj, z=z)

        if obj.healthHelper:
            self.objects.add(obj.healthHelper, z=2)

    def removeObject(self, obj):
        self.objects.remove(obj)

        if obj.healthHelper:
            self.objects.remove(obj.healthHelper)

    def addWall(self, wall, z=0):
        self.walls.add(wall, z=z)

    def removeWall(self, wall):
        self.walls.remove(wall)

    def removeAnimation(self, anim):
        self.globalPanel.remove(anim)
        # try:
        #     if anim in self.globalPanel: self.globalPanel.remove(anim)
        # except Exception:
        #     pass

    def addBullet(self, bullet):
        self.bullets.add(bullet)

    def removeBullet(self, bullet):
        if bullet in self.bullets: self.bullets.remove(bullet)
Esempio n. 3
0
class GameLayer(ScrollableLayer):
    def __init__(self, *args):
        super().__init__()

        self.hud = args[0]
        self.obstacle_map = args[1]
        self.objects_map = args[2]
        self.tileset = args[3]

        self.create_mario()
        self.create_cliff()
        self.create_flag()

        self.enemies = BatchNode()
        self.add(self.enemies)
        self.enemy_objs = self.objects_map.match(label="enemy")
        self.exist_enemy_index = []

        width, height = director.get_window_size()
        self.cm = CollisionManagerGrid(0, width, 0, height, 20, 20)

        stats.reset_current_game()

        Sound.play("mario")

    def on_enter(self):
        super().on_enter()
        self.schedule(self.update)

    def on_exit(self):
        super().on_exit()
        self.unschedule(self.update)

    def create_mario(self):
        obj = self.objects_map.match(label="start point")[0]
        self.mario = Mario(obj.position, self.obstacle_map)
        self.add(self.mario, z=50)

    def create_cliff(self):
        self.cliffs = BatchNode()
        self.add(self.cliffs)

        for i, _ in enumerate(self.obstacle_map.cells):
            if not self.obstacle_map.cells[i][0].tile:
                self.cliffs.add(
                    Cliff(self.obstacle_map.cells[i][0].center,
                          self.obstacle_map))

    def create_flag(self):
        obj = self.objects_map.match(label="flag")[0]
        self.flag = Flag(obj.position)
        self.add(self.flag)

    def find_new_enemies(self):
        for obj in self.enemy_objs:
            if self.obstacle_map.is_visible(obj) and \
                    obj["index"] not in self.exist_enemy_index:
                yield obj

    def create_enemies(self):
        for obj in self.find_new_enemies():
            if obj.name == "Goomba":
                self.enemies.add(Goomba(obj.position, self.obstacle_map))
            elif obj.name == "Koopa":
                self.enemies.add(Koopa(obj.position, self.obstacle_map))

            self.exist_enemy_index.append(obj["index"])

    def update(self, dt):
        self.mario.update_(dt)
        self.create_enemies()
        self.handle_collide()
        self.update_timer(dt)

    def handle_collide(self):
        self.collide_with_obstacle()
        self.collide_with_objects()

    def collide_with_obstacle(self):
        if not self.mario.collide_cells:
            return

        cell = self.mario.collide_cells.popleft()
        label = cell.get("label")

        if label == "normal brick":
            if self.mario.state == Mario.SMALL:
                Sound.play("bump")
                self.popup_brick("normal", cell)
            else:
                Sound.play("brick_smash")
                self.smash_brick(cell)
        elif label == "unknown brick":
            self.popup_brick("unknown", cell)

            objs = self.objects_map.get_in_region(cell.left, cell.bottom,
                                                  cell.right, cell.top)
            if objs:
                Sound.play("powerup_appears")
                # normally, only 1 object collide with cell
                self.collide_unknown_brick_with_obj(objs[0])
            else:
                Sound.play("coin")
                self.collide_unknown_brick_without_obj(cell)
        elif label == "flagpole":
            self.world_complete()

    def popup_brick(self, name, cell):
        self.obstacle_map.set_cell_opacity(cell.i, cell.j, 0)
        self.add(PopupBrick(name, cell.center))

        def recover_opacity():
            self.obstacle_map.set_cell_opacity(cell.i, cell.j, 255)
            self.obstacle_map.set_cell_color(cell.i, cell.j, (255, 255, 255))

        self.do(Delay(0.2) + CallFunc(recover_opacity))

        if name == "unknown":
            # change cell image to "bumped brick"
            cell.tile = self.tileset[1]
            self.obstacle_map.set_dirty()

    def smash_brick(self, cell):
        cell.tile = None
        self.obstacle_map.set_dirty()

        self.add(BrokenBrick(cell.midtop))

    def collide_unknown_brick_with_obj(self, obj):
        if obj.name == "Normal mushroom":
            self.add(NormalMushroom(obj.position, self.obstacle_map))
        elif obj.name == "Life mushroom":
            self.add(LifeMushroom(obj.position, self.obstacle_map))
        elif obj.name == "Reward":
            if self.mario.state == Mario.SMALL:
                self.add(NormalMushroom(obj.position, self.obstacle_map))
            elif self.mario.state == Mario.BIG:
                self.add(FireFlower(obj.position, self.obstacle_map))
            elif self.mario.state == Mario.FIRE:
                self.add(FireFlower(obj.position, self.obstacle_map))

    def collide_unknown_brick_without_obj(self, cell):
        self.add(Coin(cell.midtop))
        stats.coins += 1
        stats.score += 200

    def collide_with_objects(self):
        self.cm.xmin = self.obstacle_map.view_x
        self.cm.xmax = self.obstacle_map.view_x + self.obstacle_map.view_w

        self.cm.clear()

        for _, enemy in self.enemies.children:
            if enemy.active:
                self.cm.add(enemy)

        for _, cliff in self.cliffs.children:
            self.cm.add(cliff)

        for _, node in self.children:
            if isinstance(node, Mushroom) or isinstance(node, FireFlower):
                self.cm.add(node)

        for obj in self.cm.iter_colliding(self.mario):
            if isinstance(obj, Enemy):
                self.collide_enemy(obj)
            elif isinstance(obj, Cliff):
                self.collide_cliff()
                break
            else:
                self.collide_prop(obj)

    def collide_enemy(self, obj):
        if self.mario.collide_bottom_obj(obj):
            Sound.play("stomp")
            stats.score += 100
            obj.die()
            self.mario.do(JumpBy((0, 0), 16, 1, 0.3))
        else:
            if self.mario.state == Mario.SMALL:
                self.game_over("enemy")
            elif self.mario.state == Mario.BIG:
                self.mario.state = Mario.SMALL
            elif self.mario.state == Mario.FIRE:
                self.mario.state = Mario.BIG

            self.enemies.remove(obj)

    def collide_cliff(self):
        self.game_over("cliff")

    def collide_prop(self, obj):
        Sound.play("powerup")

        if isinstance(obj, NormalMushroom):
            stats.score += 1000
            if self.mario.state == Mario.SMALL:
                self.mario.state = Mario.BIG
        elif isinstance(obj, LifeMushroom):
            stats.life += 1
        elif isinstance(obj, FireFlower):
            stats.score += 1000
            if self.mario.state == Mario.BIG:
                self.mario.state = Mario.FIRE
            elif self.mario.state == Mario.FIRE:
                # do something else
                pass

        self.remove(obj)

    def enter_info_scene(self, world_complete=False):
        from info_scene.info_scene import InfoScene
        director.replace(InfoScene(self.hud, world_complete))

    def game_over(self, reason):
        stats.life -= 1

        Sound.stop("mario")
        if stats.life > 0:
            Sound.play("death")
        else:
            Sound.play("game_over")

        # change current layer z-order, make it the top
        self.parent.remove(self)
        self.parent.add(self, z=3)

        self.unschedule(self.update)

        if reason == "enemy" or reason == "timeout":
            self.mario.die()
            self.do(Delay(1) + CallFunc(self.enter_info_scene))
        elif reason == "cliff":
            self.enter_info_scene()
        else:
            pass

    def world_complete(self):
        stats.update_score_flagpole_height(self.mario.y)

        Sound.stop("mario")
        Sound.play("flagpole")

        self.unschedule(self.update)

        end_point_pos_x = 0
        castle_flag_pos = 0, 0

        for obj in self.objects_map.objects:
            if obj.name == "End point":
                end_point_pos_x = obj.x
            elif obj.name == "Castle flag":
                castle_flag_pos = obj.position

        self.flag.lower()
        self.mario.raise_flag(end_point_pos_x)

        self.do(
            Delay(5) +
            CallFunc(lambda: self.add(CastleFlag(castle_flag_pos))) +
            Delay(5) + CallFunc(self.enter_info_scene, True))

    def update_timer(self, dt):
        stats.update_timer(dt)

        if stats.time == 100:
            Sound.stop("mario")
            Sound.play("out_of_time")
            self.do(Delay(2) + CallFunc(Sound.play, "mario"))

        if stats.time <= 0:
            self.game_over("timeout")