Beispiel #1
0
class levelLoader(object):
	""" 
	This class actually handles a lot of things; while also handling the level loading, it also must be used to call from another class in the game
	class itself.  For example, to use anything from the Player class, the user must have levelLoader.getPlayer().functionHere.
	In all honesty, this class handles pretty much everything that has anything to do with levels.
	"""
	def __init__(self):
		self.level = 0
		self.platforms = []

		self.doorsClosed = True

		self.entities = pygame.sprite.Group()
		self.coin = pygame.sprite.Group()
		self.spikes = pygame.sprite.Group()
		self.trophies = pygame.sprite.Group()
		self.x = 0
		self.y = 0

		self.levelCoins = 0
		self.loadedCoins = False

		self.showDebug = False

	def buildLevel(self):
		"""
		KEY FOR LEVELS
        P = Platform
        C = player starting position
        A = Spike (Up)    - 1
        V = Spike (Down)  - 2
        > = Spike (Right) - 3
        < = Spike (Left)  - 4
        K = Key
        X = Trophy
        T = Door Top
        B = Door Bottom
        O = Coin
        """
		level = open(Directory.getDirectory() + '/levels/level' + str(self.level) + '.txt', 'r')
		for row in level:
		    for col in row:
		    	if col.isdigit() and self.loadedCoins == False:
		    		if int(col) > 0:
		    			self.loadedCoins = True
		    			self.levelCoins = int(col)
		    		else:
		    			self.loadedCoins = True
		    			self.levelCoins = 1
		        if col == "P":
		            p = Platform(self.x, self.y) # Place a platform at the given x,y
		            self.platforms.insert(0, p) # Insert it into the platforms list
		            self.entities.add(p) # Add to entities so it appears on screen
		        if col == "C":
					self.charX = self.x # The character x found from file loading
					self.charY = self.y # The character y found from file loading
					self.player = Player(self.charX, self.charY) # Set the player along with the x,y of the starting position
		        if col == "A":
		            spike = Spike(self.x, self.y, 1) # Load a spike at the x,y found 
		            self.entities.add(spike) # Add the spike to the entities
		            self.spikes.add(spike) # Add the spike to the spike sprite group for collison purposes
		        if col == "V":
		            spike = Spike(self.x, self.y, 2) # Load a spike at the x,y found 
		            self.entities.add(spike) # Add the spike to the entities
		            self.spikes.add(spike) # Add the spike to the spike sprite group for collison purposes
		        if col == ">":
		            spike = Spike(self.x, self.y, 3) # Load a spike at the x,y found 
		            self.entities.add(spike) # Add the spike to the entities
		            self.spikes.add(spike) # Add the spike to the spike sprite group for collison purposes
		        if col == "<":
		            spike = Spike(self.x, self.y, 4) # Load a spike at the x,y found 
		            self.entities.add(spike) # Add the spike to the entities
		            self.spikes.add(spike) # Add the spike to the spike sprite group for collison purposes
		        if col == "O":
					coin = Coins(self.x, self.y) # Load a coin image at the given x,y
					self.entities.add(coin) # Coin 1 to the entities
					self.coin.add(coin) # add coin 1 to the coinA sprite group
		        if col == "X":
					try:
						win_object = Trophy(self.x, self.y, self.level) # Load the proper trophy by passing the level to the trophy class and load at the given x,y from file loading
						self.entities.add(win_object) # Add the trophy to the entities so it appears
						self.trophies.add(win_object) # Also make it a trophy sprite for collision detection purposes
					except:
						win_object = Trophy(self.x, self.y, 0)
						self.entities.add(win_object) # Add the trophy to the entities so it appears
						self.trophies.add(win_object) # Also make it a trophy sprite for collision detection purposes
		        if col == "T":
		            self.doorA = Door(self.x, self.y)
		            self.platforms.append(self.doorA) # Make the door top a platform so the player cannot walk through it
		            self.entities.add(self.doorA) # Add the door bottom to the entities
		        if col == "B":
		            self.doorB = Door(self.x, self.y)
		            self.platforms.append(self.doorB) # Make the door bottom a platform so the player cannot walk through it
		            self.entities.add(self.doorB) # Add the door bottom to entities
		        self.x += 32
		    self.y += 32
		    self.x = 0

		# Try loading in the level image and theme; if it fails, use level 0 theme and background
		try:
		    self.background = pygame.image.load(Directory.getDirectory() + '/images/backgrounds/background' + str(self.level) + '.png').convert_alpha()
		    self.background_rect = self.background.get_rect()
		except:
		    self.background = pygame.image.load(Directory.getDirectory() + '/images/backgrounds/background0.png').convert_alpha()
		    self.background_rect = self.background.get_rect()

	def getPlayer(self):
		return self.player

	def getPlatforms(self):
		return self.platforms

	def getEntities(self):
		return self.entities

	def getCoins(self):
		return self.coin

	def getTrophy(self):
		return self.trophies

	def getSpikes(self):
		return self.spikes

	def getBGWidth(self):
		return self.background_rect.w

	def getBGHeight(self):
		return self.background_rect.h

	def getBackground(self):
		return self.background

	def delPlatforms(self):
		del self.platforms[-1]

	def delDoors(self):
		self.doorsClosed = False
		self.doorA.kill()
		self.doorB.kill()

	def rebuildDoors(self):
		self.doorsClosed = True

	def doorStatus(self):
		return self.doorsClosed

	def clearScreen(self):
		self.player.onGround = True
		self.x = 0
		self.y = 0
		self.loadedCoins = False
		level = self.level
		self.platforms = None
		self.doorA.kill()
		self.doorB.kill()
		self.entities.empty()
		self.trophies.empty()
		self.spikes.empty()
		self.coin.empty()

	def rebuildObjects(self):
		self.level = self.level
		self.platforms = []
		self.doorsClosed = True
		self.player = Player(self.charX, self.charY)
		self.entities = pygame.sprite.Group()
		self.coin = pygame.sprite.Group()
		self.spikes = pygame.sprite.Group()
		self.trophies = pygame.sprite.Group()
		self.x = 0
		self.y = 0
		self.player.dead = False
		self.player.up = False
		self.player.right = False
		self.player.left = False
		self.player.running = False

	def addLevel(self):
		self.level += 1

	def resetLevel(self):
		self.level = 0

	def getLevel(self):
		return self.level

	def loadingBar(self):
		return self.loadingBar

	def getLevelCoins(self):
		return self.levelCoins

	def infoScreen(self):
		self.debug = Display.font.render("Information Window", True, (255,255,255))
		self.death_status = Display.font.render("player.canDie: " + str(self.getPlayer().canDie), True, (255,255,255))
		self.door_status = Display.font.render("door_closed: " + str(self.doorsClosed), True, (255,255,255))
		self.coin_debug = Display.font.render("coin_count: " + str(self.getPlayer().getCoins()), True, (255,255,255))
		Display.screen.blit(self.debug, (0,0))
		Display.screen.blit(self.death_status, (0,25))
		Display.screen.blit(self.door_status, (0,50))
		Display.screen.blit(self.coin_debug, (0,75))
Beispiel #2
0
def main():
    """The main loop of the game.  It handles loading the levels, key strokes, playing music and sounds; relies heavily on multiple other classes to function correctly.
        These include the camera, coins, door, entities, platform, player, sounds, spike, themes, and trophies classes."""
    gc.enable() # Garbage collector
    global cameraX, cameraY, key_count, delete_door, current_level, deaths, deaths_total, volume # Load in the global variables
    pygame.mixer.pre_init(44100, -16, 2, 2048) # Initilize the music
    screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH) # Set the screen information
    screen_rect = screen.get_rect()
    timer = pygame.time.Clock()

    # We don't want to see the normal mouse cursor while playing.
    pygame.mouse.set_visible(False)

    sounds = Sounds() # Allows us to call sounds by doing sounds.name

    font = pygame.font.SysFont("arial", 25) # Font for the game

    loading_bar = pygame.transform.scale(pygame.image.load("images/button.png"), (WIN_WIDTH, 35)) # Loading bar image (so that the "Loading Level (level)..." text is visible)

    up = down = left = right = running = False # Set all key strokes (directions) to False


    # Load in the first level by assigning sprites into groups and into the platforms and coin_list lists
    # Read about what each thing does in the respective class
    # !!! WARNING !!! The game will break if the level does not contain the player ("C") within; the game may break if the door Top and Bottom is not found as well.
    """KEY FOR LEVELS
        P = Platform
        C = player starting position
        A = Spike (Up)
        V = Spike (Down)
        > = Spike (Right)
        < = Spike (Left)
        K = Key
        X = Trophy
        T = Door Top
        B = Door Bottom"""

    platforms = []
    coin_list = []

    entities = pygame.sprite.Group()
    coinA = pygame.sprite.Group()
    spikes = pygame.sprite.Group()
    trophies = pygame.sprite.Group()
    monsters = pygame.sprite.Group()
    x = 0
    y = 0
    level = open('levels/level' + str(current_level) + '.txt', 'r')
    for row in level:
        for col in row:
            if col == "P":
                p = Platform(x, y) # Place a platform at the given x,y
                platforms.insert(0, p) # Insert it into the platforms list
                entities.add(p) # Add to entities so it appears on screen
            if col == "C":
                charX = x # The character x found from file loading
                charY = y # The character y found from file loading
                player = Player(charX, charY) # Set the player along with the x,y of the starting position
            if col == "A":
                spike = Spike(x, y, 1) # Load a spike at the x,y found 
                entities.add(spike) # Add the spike to the entities
                spikes.add(spike) # Add the spike to the spike sprite group for collison purposes
            if col == "V":
                spike = Spike(x, y, 2) # Load a spike at the x,y found 
                entities.add(spike) # Add the spike to the entities
                spikes.add(spike) # Add the spike to the spike sprite group for collison purposes
            if col == ">":
                spike = Spike(x, y, 3) # Load a spike at the x,y found 
                entities.add(spike) # Add the spike to the entities
                spikes.add(spike) # Add the spike to the spike sprite group for collison purposes
            if col == "<":
                spike = Spike(x, y, 4) # Load a spike at the x,y found 
                entities.add(spike) # Add the spike to the entities
                spikes.add(spike) # Add the spike to the spike sprite group for collison purposes
            
            if col == "M":
                monster = Monster(x, y) # Load a spike at the x,y found 
                entities.add(monster) # Add the spike to the entities
                monsters.add(monster) # Add the spike to the spike sprite group for collison purposes
            
            if col == "K":
                c1 = Coins(x, y) # Load a coin image at the given x,y
                entities.add(c1) # Coin 1 to the entities
                coinA.add(c1) # add coin 1 to the coinA sprite group
            if col == "X":
                win_object = Trophy(x, y) # Load the proper trophy by passing the current_level to the trophy class and load at the given x,y from file loading
                entities.add(win_object) # Add the trophy to the entities so it appears
                trophies.add(win_object) # Also make it a trophy sprite for collision detection purposes
            if col == "T":
                doorA = Door(x, y, pygame.transform.scale(pygame.image.load("images/door_locked1.png"), (60,100)))
                platforms.append(doorA) # Make the door top a platform so the player cannot walk through it
                entities.add(doorA) # Add the door bottom to the entities
            if col == "B":
                doorB = Door(x, y, pygame.transform.scale(pygame.image.load("images/door_locked2.png"), (60,32)))
                platforms.append(doorB) # Make the door bottom a platform so the player cannot walk through it
                entities.add(doorB) # Add the door bottom to entities
            x += 32
        y += 32
        x = 0

    # Try loading in the level image and theme; if it fails, use level 0 theme and background
    background = pygame.image.load('images/backgrounds/background.png').convert_alpha()
    background_rect = background.get_rect()

    total_level_width  = len('level'[0])*32
    total_level_height = len('level')*32
    camera = Camera(complex_camera, total_level_width, total_level_height)
    entities.add(player) # Finally, add player to entities so it appears
    missiles = pygame.sprite.RenderUpdates()

        
    # The main loop of the game which runs it until we're done.    
    while 1:
        pygame.display.set_caption("Asylum | Deaths (level): " + str(deaths) + " | Deaths (Total): " + str(deaths_total) + " | FPS: " + str(int(timer.get_fps())))
        asize = ((screen_rect.w // background_rect.w + 1) * background_rect.w, (screen_rect.h // background_rect.h + 1) * background_rect.h)
        bg = pygame.Surface(asize)

        # Create the background
        for x in range(0, asize[0], background_rect.w):
            for y in range(0, asize[1], background_rect.h):
                screen.blit(background, (x, y))

        timer.tick(38) # The maximum framerate; the game is designed to run at an FPS of 30-40 (38 being best)

        # All the keystroke events; the game can run using the UP-RIGHT-LEFT arrow keys, Space Bar, and the AWD keys (down is never needed)
        #   ENTER will kill the player (used if the player glitch spawns outside the level or glitch out (reloads the level as if they died))
        for e in pygame.event.get():
            if e.type == QUIT: 
                exit()
            if e.type == KEYDOWN and e.key == K_ESCAPE:
                exit()
            if e.type == KEYDOWN and e.key == K_UP:
                player.direction = 'up'
                up = True
                down = left = right = False
            if e.type == KEYDOWN and e.key == K_DOWN:
                player.direction = 'down'
                down = True
                up = left = right = False
            if e.type == KEYDOWN and e.key == K_LEFT:
                player.direction = 'left'
                left = True
                right = up = down = False
            if e.type == KEYDOWN and e.key == K_RIGHT:
                player.direction = 'right'
                right = True
                left = up = down = False
            if e.type == KEYDOWN and e.key == K_w:
                player.direction = 'up'
                up = True
                down = left = right = False
            if e.type == KEYDOWN and e.key == K_s:
                player.direction = 'down'
                down = True
                up = left = right = False
            if e.type == KEYDOWN and e.key == K_a:
                player.direction = 'left'
                left = True
                right = up = down = False
            if e.type == KEYDOWN and e.key == K_d:
                player.direction = 'right'
                right = True
                left = up = down = False
            """
            if e.type == KEYDOWN and e.key == K_RSHIFT and player.attacking == False and pygame.sprite.spritecollide(player, monster, True):
                print "Space bar clicked, attacking!"
                player.attacking = True
                sounds.shot.play()
                sounds.shot.set_volume(volume)
                if player.direction == 'down':
                    player.image = pygame.transform.scale(player.attackList[0], (50, 50))
                if player.direction == 'left':
                    player.image = pygame.transform.scale(player.attackList[1], (50, 50))
                if player.direction == 'up':
                    player.image = pygame.transform.scale(player.attackList[2], (50, 50))
                if player.direction == 'right':
                    player.image = pygame.transform.scale(player.attackList[3], (50, 50))
            """

            if e.type == KEYUP and e.key == K_UP:
                player.direction = 'up'
                up = False
            if e.type == KEYUP and e.key == K_DOWN:
                player.direction = 'down'
                down = False
            if e.type == KEYUP and e.key == K_RIGHT:
                player.direction = 'right'
                right = False
            if e.type == KEYUP and e.key == K_LEFT:
                player.direction = 'left'
                left = False
            if e.type == KEYUP and e.key == K_w:
                player.direction = 'up'
                up = False
            if e.type == KEYUP and e.key == K_s:
                player.direction = 'down'
                down = False
            if e.type == KEYUP and e.key == K_d:
                player.direction = 'right'
                right = False
            if e.type == KEYUP and e.key == K_a:
                player.direction = 'left'
                left = False
            """
            if e.type == KEYUP and e.key == K_RSHIFT:
                player.attacking = False
                print "reset attack"
            """

        # All of the coin collision detection; when it occurs, the coin is removed and a sound plays while adding one to the coin_count (4 opens the door)
        # the True in each IF statement means that when the collision occurs the coin is removed from it's group, thus removing it from appearing on screen
        if pygame.sprite.spritecollide(player, coinA, True, pygame.sprite.collide_mask):
            sounds.coin_sound.play()
            sounds.coin_sound.set_volume(volume)
            key_count += 1

        # If the player manages to reach the trophy, reset the level deaths, add one to the current_level, kill the theme (music), add the loading bar, print out loading level
        #       kill all key-presses (directions) empty all sprites and lists and load in the next level
        if pygame.sprite.spritecollide(player, trophies, True, pygame.sprite.collide_mask):
            sounds.footsteps.play()
            deaths = 0
            current_level += 1
            platforms = None
            level = None
            up = False
            right = False
            left = False
            key_count = 0
            doorA.kill()
            doorB.kill()
            entities.empty()
            trophies.empty()
            spikes.empty()
            coinA.empty()
            monsters.empty()
            screen.blit(loading_bar, (0,0)) # Blit the loading bar image to the screen (so text shows up on all background colors)
            load_text = font.render("Loading Level " + str(current_level) + "...", True, (255, 255, 255)) # Blit loading text to the loading_bar
            screen.blit(load_text, (1,0))
            pygame.display.update()
            gc.collect()
            x = 0
            y = 0
            platforms = []
            pause.sleep(3) # Sleep for 5 seconds ('loading'...might have an effect on lag by allowing it to pause for a few seconds)
            try:
                level = open('levels/level' + str(current_level) + '.txt', 'r') # Try loading the next level; if it fails, we assume they finished the game and reload the title screen
            except:
                screen.blit(loading_bar, (0,0))
                congrats = font.render("Congratulations! You've conquered your fears and escaped Asylum!", True, (255, 255, 255))
                screen.blit(congrats, (0,0))
                print "blitted congrats"
                pygame.display.update()
                pause.sleep(5)
                False
                current_level = 0 # Reset the level counter so clicking play again doesn't crash the game
                coin_count = 0 # Reset coin count
                delete_door = True # Reset the door deletion status (True means the door can be removed)
                # Since we're heading back to the title menu, let's bring back the title screen music.
                pygame.mixer.pre_init(44100, -16, 2, 2048)
                sounds = Sounds()
                titleScreen()
            for row in level:
                for col in row:
                    if col == "P":
                        p = Platform(x, y)
                        platforms.insert(0, p)
                        entities.add(p)
                    if col == "C":
                        charX = x
                        charY = y
                        player = Player(charX, charY)
                    if col == "A":
                        spike = Spike(x, y, 1)
                        entities.add(spike)
                        spikes.add(spike)
                    if col == "V":
                        spike = Spike(x, y, 2) # Load a spike at the x,y found 
                        entities.add(spike) # Add the spike to the entities
                        spikes.add(spike) # Add the spike to the spike sprite group for collison purposes
                    if col == ">":
                        spike = Spike(x, y, 3) # Load a spike at the x,y found 
                        entities.add(spike) # Add the spike to the entities
                        spikes.add(spike) # Add the spike to the spike sprite group for collison purposes
                    if col == "<":
                        spike = Spike(x, y, 4) # Load a spike at the x,y found 
                        entities.add(spike) # Add the spike to the entities
                        spikes.add(spike) # Add the spike to the spike sprite group for collison purposes
                    if col == "M":
                        monster = Monster(x, y) # Load a spike at the x,y found 
                        entities.add(monster) # Add the spike to the entities
                        monsters.add(monster) # Add the spike to the spike sprite group for collison purposes
                    if col == "K":
                        c1 = Coins(x, y)
                        entities.add(c1)
                        coin_list.append(c1)
                        coinA.add(c1)
                    if col == "X":
                        win_object = Trophy(x, y)
                        entities.add(win_object)
                        trophies.add(win_object)
                    if col == "T":
                        doorA = Door(x, y, pygame.transform.scale(pygame.image.load("images/door_locked1.png"), (60,100)))
                        platforms.append(doorA) # Make the door top a platform so the player cannot walk through it
                        entities.add(doorA) # Add the door bottom to the entities
                    if col == "B":
                        doorB = Door(x, y, pygame.transform.scale(pygame.image.load("images/door_locked2.png"), (60,32)))
                        platforms.append(doorB) # Make the door bottom a platform so the player cannot walk through it
                        entities.add(doorB) # Add the door bottom to entities
                    x += 32
                y += 32
                x = 0
            """
            player.update(up, down, left, right, running, platforms)
            for e in entities:
                screen.blit(e.image, camera.apply(e))
            """
            pygame.display.update()
            delete_door = True # reset door status
            player.dead = False # ensure the player isn't dead
            entities.add(player)

        # Player collision with spike; if true, kill the player
        if pygame.sprite.spritecollide(player, spikes, False, pygame.sprite.collide_mask):
            player.dead = True
        if pygame.sprite.spritecollide(player, monsters, False, pygame.sprite.collide_mask):
            player.dead = True

        for m in monsters:
            m.sensePlayers(player, platforms)

        # If the player is dead, reset all key strokes to False, play the death sound, empty all groups and lists and reload the level, add one to both total and level deaths
        if player.dead == True:
            up = False
            right = False
            left = False
            sounds.death_sound.play()
            sounds.death_sound.set_volume(volume)
            player = Player(charX, charY)
            platforms = None
            level = None
            x = 0
            y = 0
            doorA.kill()
            doorB.kill()
            entities.empty()
            trophies.empty()
            spikes.empty()
            coinA.empty()
            monsters.empty()
            gc.collect()
            pause.sleep(1)
            key_count = 0
            platforms = []
            level = open('levels/level' + str(current_level) + '.txt', 'r')
            deaths += 1
            deaths_total += 1
            for row in level:
                for col in row:
                    if col == "P":
                        p = Platform(x, y)
                        platforms.insert(0, p)
                        entities.add(p)
                    if col == "C":
                        charX = x
                        charY = y
                        player = Player(charX, charY)
                    if col == "A":
                        spike = Spike(x, y, 1)
                        entities.add(spike)
                        spikes.add(spike)
                    if col == "V":
                        spike = Spike(x, y, 2) # Load a spike at the x,y found 
                        entities.add(spike) # Add the spike to the entities
                        spikes.add(spike) # Add the spike to the spike sprite group for collison purposes
                    if col == ">":
                        spike = Spike(x, y, 3) # Load a spike at the x,y found 
                        entities.add(spike) # Add the spike to the entities
                        spikes.add(spike) # Add the spike to the spike sprite group for collison purposes
                    if col == "<":
                        spike = Spike(x, y, 4) # Load a spike at the x,y found 
                        entities.add(spike) # Add the spike to the entities
                        spikes.add(spike) # Add the spike to the spike sprite group for collison purposes
                    if col == "M":
                        monster = Monster(x, y) # Load a spike at the x,y found 
                        entities.add(monster) # Add the spike to the entities
                        monsters.add(monster) # Add the spike to the spike sprite group for collison purposes
                    if col == "K":
                        c1 = Coins(x, y)
                        entities.add(c1)
                        coin_list.append(c1)
                        coinA.add(c1)
                    if col == "X":
                        win_object = Trophy(x, y)
                        entities.add(win_object)
                        trophies.add(win_object)
                    if col == "T":
                        doorA = Door(x, y, pygame.transform.scale(pygame.image.load("images/door_locked1.png"), (60,100)))
                        platforms.append(doorA) # Make the door top a platform so the player cannot walk through it
                        entities.add(doorA) # Add the door bottom to the entities
                    if col == "B":
                        doorB = Door(x, y, pygame.transform.scale(pygame.image.load("images/door_locked2.png"), (60,32)))
                        platforms.append(doorB) # Make the door bottom a platform so the player cannot walk through it
                        entities.add(doorB) # Add the door bottom to entities
                    x += 32
                y += 32
                x = 0
                delete_door = True
                player.dead = False
            entities.add(player) # Readd the player to the entities

        # If the coin count is four, then set the door status to False, kill the door sprites and remove from the platforms list
        # When delete_door is True it means the door can be removed when the coins are all collected; False means it's been opened. This check was added to prevent it from continually playing the sounds.
        if key_count >= 1 and delete_door == True:
            sounds.door.play()
            sounds.door.set_volume(volume)
            for x in xrange(2): # Since we ensure doors are added to the end of the list, we can just remove the last two items in the platforms list safely
                del platforms[-1]
            delete_door = False # now the door status is False
            doorA.kill() # Kill doorA and doorB (makes it disappear (the door has "opened"))
            doorB.kill()

        camera.update(player)

        # Update the player and everything else
        missiles.update()
        pygame.sprite.groupcollide(missiles, platforms, True, False)
        missiles.draw(screen)
        player.update(up, down, left, right, running, platforms)
        for e in entities:
            screen.blit(e.image, camera.apply(e))

        pygame.display.update() # Update the display