Beispiel #1
0
class GS_Game(GameState):
	def __init__(self, kernel, gsm):
		GameState.__init__(self, "Game", kernel, gsm)

		self.mLevelName = ""
		self.mLevel = None

		self.mGroundLevel = 570

		self.mHighScores = {}

		self.mScrollSpeed = 2

		self.mPaused = 0

		self.mHouse = None

		self.mCurrentLevel = 1
		self.mLevelComplete = False
		self.mSoundState = 1

		self.mMusic = self.mKernel.SoundManager().LoadSound("BGmusic_flyaway.wav")

		self.mGameOverImage, self.mGameOverRect = self.mKernel.ImageManager().LoadImage("gameover.bmp")
		self.mLevelCompleteImage, self.mLevelCompleteRect = self.mKernel.ImageManager().LoadImage("levelcomplete.bmp")
		self.mMainMenuImage, self.mMainMenuRect = self.mKernel.ImageManager().LoadImage("mainmenu_small.bmp")
		self.mNextLevelImage, self.mNextLevelRect = self.mKernel.ImageManager().LoadImage("nextlevel.bmp")
		self.mHighScoreImage, self.mHighScoreRect = self.mKernel.ImageManager().LoadImage("highscore_alert.bmp")

		self.mGameOverRect.topleft = (400 - self.mGameOverRect.width / 2, 150)
		self.mLevelCompleteRect.topleft = (400 - self.mLevelCompleteRect.width / 2, 50)
		self.mHighScoreRect.topleft = (400 - self.mHighScoreRect.width / 2, 225)
		self.mNextLevelRect.topleft = (600 - self.mMainMenuRect.width / 2, 350)
		self.mMainMenuRect.topleft = (400 - self.mMainMenuRect.width / 2, 350)

		self.mFont = pygame.font.SysFont("Helvetica", 16, True)

		self.mPreviousPop = False
		self.mPreviousDead = 0
		self.mCurrentLevel = 1

		self.mNextLevelName = ""

	def Initialize(self, levelName = ""):
		self.mHighScores = {}
		self.mScore = 0
		self.mPaused = 0

		if (levelName):
			self.LoadLevel(levelName)

			if (levelName[5].isdigit()):
				self.mCurrentLevel = int(levelName[5])
			else:
				self.mCurrentLevel = -1

		elif (self.mNextLevelName):
			self.LoadLevel(self.mNextLevelName)
		else:
			self.LoadLevel("Level1")

		self.LoadScores()

		self.mLevelComplete = False

		for entity in self.mLevel.mEntities:
			entity.mSoundState = self.mSoundState

		self.mBalloon.mSoundState = self.mSoundState
		self.mPerson.mSoundState = self.mSoundState

		self.mMusic.set_volume(.3 * self.mSoundState)
		self.mMusic.stop()
		self.mMusic.play(-1)


		fullLevelName = os.path.join("data", "levels", "Level" + str(self.mCurrentLevel + 1) + ".lvl")
		if os.path.isfile(fullLevelName):
			self.mNextLevelName = "Level" + str(self.mCurrentLevel + 1)
			self.mMainMenuRect.topleft = (200 - self.mMainMenuRect.width / 2, 350)
		else:
			self.mNextLevelName = ""
			self.mMainMenuRect.topleft = (400 - self.mMainMenuRect.width / 2, 350)

		return GameState.Initialize(self)

	def LoadLevel(self, levelName):
		self.mLevelName = levelName + ".lvl"
		self.mLevel = Level(self.mKernel, 800)

		self.mLevel.LoadLevel(self.mLevelName)
		self.mLevel.mScrollSpeed = self.mScrollSpeed

		self.mCordImage, self.mCordRect = self.mKernel.ImageManager().LoadImage("cord.bmp")
		self.mCordRect.bottomleft = (0, self.mGroundLevel)

		self.mPerson = Person(self.mKernel, self.mLevel)
		self.mPerson.SetPosition([128, self.mGroundLevel])
		self.mPerson.mScreenOffset = 128
		self.mPerson.SetGroundLevel(self.mGroundLevel)
		self.mPerson.SyncCollisionRect()

		self.mHouse = House(self.mKernel, self.mLevel)
		self.mHouse.SetPosition([ self.mLevel.mLevelLength - 512, self.mGroundLevel - 480 ])
		self.mHouse.SyncCollisionRect()

		self.SpawnBalloon()

	def SpawnBalloon(self):
		self.mBalloon = Balloon(self.mKernel, self.mLevel)
		self.mBalloon.SetPosition([ self.mLevel.mCameraX + self.mPerson.mScreenOffset + 128, self.mGroundLevel - self.mBalloon.Rect().height - 128 ])
		self.mBalloon.mGroundLevel = 500

	def Destroy(self):
		self.mMusic.stop()
		self.mNextLevelName = ""
		self.mCurrentLevel = 1
		return GameState.Destroy(self)

	def Pause(self):
		self.mMusic.stop()
		return GameState.Pause(self)

	def Unpause(self):
		self.mMusic.play(-1)
		return GameState.Unpause(self)


	def HandleEvent(self, event):
		if (event.type == QUIT):
			pygame.quit()
			sys.exit()
		elif (event.type == KEYDOWN):
			if (event.key == K_UP):
				self.mPerson.Jump()
			elif (event.key == K_DOWN):
				self.mPerson.Duck()
			elif (event.key == K_SPACE):
				self.mBalloon.mBlown = 1
			elif (event.key == K_p):
				self.mPaused = (self.mPaused + 1) % 2
			elif (event.key == K_ESCAPE):	
				self.mGameStateManager.SwitchState('MainMenu')
			elif (event.key == K_m):
				for entity in self.mLevel.mEntities:
					entity.mSoundState = (entity.mSoundState +1) % 2
				self.mBalloon.mSoundState = (self.mBalloon.mSoundState +1) % 2
				self.mPerson.mSoundState = (self.mBalloon.mSoundState + 1) % 2
				self.mSoundState = (self.mSoundState +1) % 2
				self.mMusic.set_volume(.3*self.mSoundState)


		elif(event.type == KEYUP):
			if (event.key == K_SPACE):
				self.mBalloon.mBlown = 0  
			elif (event.key == K_DOWN):
				self.mPerson.Run()

		elif (event.type == MOUSEBUTTONDOWN):
			if (self.mMainMenuRect.collidepoint(event.pos)):
				self.Destroy()
				self.mGameStateManager.SwitchState("MainMenu")
			elif (self.mNextLevelRect.collidepoint(event.pos)):
				self.mCurrentLevel += 1
				self.Initialize()

		return GameState.HandleEvent(self, event)

	def Update(self, delta):
		if (not self.mLevelComplete):
			if self.mPerson.CheckCollision(self.mHouse):
				self.mLevelComplete = True
				self.SaveScore()
				self.mPerson.Done()

		if self.mLevel.mCameraX > (self.mLevel.mLevelLength - 1500):
			self.mBalloon.mBlown = 0

		if not self.mLevelComplete and self.mPaused == 0:
			if (self.mPerson.mDead == 0 and self.mPerson.mLives > 0):
				self.mLevel.Scroll(self.mScrollSpeed)

			self.mLevel.Update(delta)

			if (self.mPerson.mLives > 0):
				self.mPerson.Update(delta)

			if (self.mPerson.mDead == 0):# and self.mPerson.mLives > 0):
				self.mBalloon.Update(delta)

			if (self.mPerson.CheckCollision(self.mBalloon) and self.mBalloon.CheckCollision(self.mPerson)):
				self.mPerson.OnCollision(self.mBalloon)
				self.mBalloon.OnCollision(self.mPerson)

			self.mLevel.CheckCollisions(self.mPerson)
			self.mLevel.CheckCollisions(self.mBalloon)
					

			if (self.mBalloon.mPopped):
				if (not self.mPreviousPop):
					self.mPerson.mLives -= 1

				if (self.mBalloon.mPosition[0] < self.mLevel.mCameraX):
					if (self.mPerson.mLives > 0):
						self.SpawnBalloon()

			if (self.mPerson.mResetting):
				self.SpawnBalloon()
				self.mPerson.mResetting = False
			
		self.mLevel.Draw()

		self.mHouse.DrawBack()

		self.mCordRect.bottomright = self.mPerson.Rect().bottomleft
		self.mLevel.DisplaySurface().blit(self.mCordImage, self.mCordRect)
		self.mPerson.Draw()
		self.mHouse.Draw()
		self.mBalloon.Draw()

		self.mLevel.Blit()

		textSurface = self.mFont.render( str(self.mLevelName)[0:-4], True, Colors.WHITE)
		self.mKernel.DisplaySurface().blit(textSurface, (30, 580, textSurface.get_rect().width, textSurface.get_rect().height))
		
		textSurface = self.mFont.render("Score: " + str(self.mPerson.mScore), True, Colors.WHITE)
		self.mKernel.DisplaySurface().blit(textSurface, (150, 580, textSurface.get_rect().width, textSurface.get_rect().height))
		
		textSurface = self.mFont.render("Lives: " + str(self.mPerson.mLives), True, Colors.WHITE)
		self.mKernel.DisplaySurface().blit(textSurface, (270, 580, textSurface.get_rect().width, textSurface.get_rect().height))

		textSurface = self.mFont.render("In Basket: " + str(self.mBalloon.mValue), True, Colors.WHITE)
		self.mKernel.DisplaySurface().blit(textSurface, (390, 580, textSurface.get_rect().width, textSurface.get_rect().height))

		textSurface = self.mFont.render("Points Possible: " + str(self.mLevel.mMaxScore), True, Colors.WHITE)
		self.mKernel.DisplaySurface().blit(textSurface, (540, 580, textSurface.get_rect().width, textSurface.get_rect().height))
		
		if (self.mPerson.mLives == 0):
			self.mKernel.DisplaySurface().blit(self.mGameOverImage, self.mGameOverRect)
			
			self.mMainMenuRect.topleft = (400 - self.mMainMenuRect.width / 2, 350)
			self.mKernel.DisplaySurface().blit(self.mMainMenuImage, self.mMainMenuRect)

		if (self.mLevelComplete):
			self.mKernel.DisplaySurface().blit(self.mLevelCompleteImage, self.mLevelCompleteRect)
			self.mKernel.DisplaySurface().blit(self.mMainMenuImage, self.mMainMenuRect)

			if (self.mHighScores[self.mLevelName]  == self.mPerson.mScore):
				self.mKernel.DisplaySurface().blit(self.mHighScoreImage, self.mHighScoreRect)

			if (self.mNextLevelName != ""):
				self.mKernel.DisplaySurface().blit(self.mNextLevelImage, self.mNextLevelRect)

		self.mPreviousDead = self.mPerson.mDead
		self.mPreviousPop = self.mBalloon.mPopped
		
		return GameState.Update(self, delta)

	def SaveScore(self):
		if self.mLevelName in self.mHighScores:
			if self.mPerson.mScore > self.mHighScores[self.mLevelName]:
				self.mHighScores[self.mLevelName] = self.mPerson.mScore
		else:
			self.mHighScores[self.mLevelName] = self.mPerson.mScore

		with open(os.path.join("data", "highscores.txt"), 'w') as file:
			for level in self.mHighScores:
				file.write(level + " " + str(self.mHighScores[level]) + "\n")

	def LoadScores(self):
		HighScoreFile = os.path.join("data", "highscores.txt")
		if (os.path.isfile(HighScoreFile)):
			with open(HighScoreFile) as highscores:
					scoreList = highscores.read().splitlines() 

					for i in range(0, len(scoreList)):
						parts = scoreList[i].split()

						self.mHighScores[parts[0]] = int(parts[1])
Beispiel #2
0
class MainGameState(GameState):

    def __init__(self):
        GameState.__init__(self)
        self.resetGame()

    def resetGame(self):
        self.player = Player((Globals.window.screen_size[0] / 2, Globals.window.screen_size[1]))
        self.level = Level(self)

        self.score = 0
        self.smooth_score = 0

        self.all_sprites = pygame.sprite.Group()
        self.all_sprites.add(self.player)

        self.enemies = pygame.sprite.Group()
        self.background = pygame.sprite.Group()
        self.foreground = pygame.sprite.Group()
        self.effects = pygame.sprite.Group()
        self.powerups = pygame.sprite.Group()
        self.enemy_bullets = pygame.sprite.Group()
        self.player_bullets = pygame.sprite.Group()



        # GUI
        self.gui = pygame.sprite.Group()
        self.hp_bar = GuiBar(pygame.Rect(5, 5, 128, 16))
        self.score_text = GuiText(position=(5, 16+5+5), font_size=16)
        self.gui.add(self.hp_bar)
        self.gui.add(self.score_text)

        self.level.Start()

    def addEnemy(self, new_enemy):
        self.enemies.add(new_enemy)
        self.all_sprites.add(new_enemy)

    def spawnExplosion(self, position):
        new_explosion = Animation(Globals.resourceManager.get_sprite_sheet("explosion.png"), center=position,
                                  loop=False, frames_per_frame=5)
        self.effects.add(new_explosion)

    def addBackground(self, image) -> Background:
        new_background = Background(image)
        self.background.add(new_background)
        return new_background

    def addForeground(self, image) -> Background:
        new_foreground = Background(image)
        self.foreground.add(new_foreground)
        return new_foreground

    def addBullet(self, bullet, player=True):
        if player:
            self.player_bullets.add(bullet)
        else:
            self.enemy_bullets.add(bullet)
        self.all_sprites.add(bullet)

    @staticmethod
    def pixel_perfect_collision(s1, s2):
        # First check rect collision then check mask collision
        return s1.rect.colliderect(s2) and pygame.sprite.collide_mask(s1, s2)

    def check_collisions(self):

        for powerup in self.powerups:
            # Check if player picked up a powerup
            if self.player.rect.colliderect(powerup.rect):
                powerup.on_pickup(self.player)
                powerup.kill()
                Globals.resourceManager.get_sound("powerup.wav").play()

        for enemy in self.enemies:
            # Check if enemy is hit by a bullet
            for bullet in self.player_bullets:
                if self.pixel_perfect_collision(bullet, enemy):
                    enemy.damage(bullet.get_dmg())
                    bullet.kill()
                    Globals.resourceManager.get_sound("hit.wav").play()
                    Globals.window.shakeCamera(1)
            # Check if enemy is hit by the player
            if self.player.is_alive() and not self.player.is_invincible() and self.pixel_perfect_collision(self.player, enemy):
                self.player.damage(50)
                enemy.damage(50)
                Globals.resourceManager.get_sound("hit.wav").play()
                Globals.window.shakeCamera(5)

        if self.player.is_alive() and not self.player.is_invincible():
            for enemy_bullet in self.enemy_bullets:
                if self.pixel_perfect_collision(self.player, enemy_bullet):
                    self.player.damage(enemy_bullet.get_dmg())
                    enemy_bullet.kill()
                    Globals.resourceManager.get_sound("hit.wav").play()
                    Globals.window.shakeCamera(5)

    def start(self):
        self.level.Start()

    def end(self):
        pass

    def update(self):
        screen_rect = Globals.window.fake_screen.get_rect()

        if Globals.window.game_state is self:
            move = self.level.Update()
            # update player
            pressed_keys = pygame.key.get_pressed()
            self.player.update(screen_rect, pressed_keys)
        else:
            move = self.level.Update(game_not_paused=False)

        # and his bullets
        self.player_bullets.update(screen_rect)

        # update enemies and their bullets
        self.enemies.update(screen_rect)
        self.enemy_bullets.update(screen_rect)

        # move backgrounds
        self.background.update(move, screen_rect)

        # move foreground
        self.foreground.update(move * 2, screen_rect)
        self.effects.update(move * 2, screen_rect)
        self.powerups.update(move * 2, screen_rect)

        self.check_collisions()

    def draw(self, screen):
        # draw background
        for entity in self.background:
            entity.draw(screen)
        # draw foreground clouds etc.
        for entity in self.foreground:
            entity.draw(screen)
        # draw effects explosions etc.
        for entity in self.effects:
            entity.draw(screen)
        # draw powerups
        for entity in self.powerups:
            entity.draw(screen)
        # draw all generic sprites enemies, player, etc.
        for entity in self.all_sprites:
            entity.draw(screen)
        # sync and draw gui

        if self.smooth_score < self.score:
            diff = self.score - self.smooth_score
            if diff > 60:
                self.smooth_score += int(diff/3)
            else:
                self.smooth_score += 1

        self.score_text.set_text("SCORE: " + str(self.smooth_score))
        self.hp_bar.set_progress(self.player.hp / self.player.max_hp)
        for entity in self.gui:
            entity.draw(screen)