简体   繁体   English

Pygame:游戏结束屏幕

[英]Pygame: Game Over Screen

Hello I am making a game in pygame and I am wondering how and what the best way is to add a game over screen.您好,我正在pygame制作游戏,我想知道如何以及最好的方法是在屏幕上添加游戏。 Here is the code up to where the players health is smaller or equal to 0:以下是玩家生命值小于或等于 0 的代码:

import pygame
import random
import pygame.mixer
import Funk
from player import *
from zombie import *
from level import *
from bullet import *
from constants import *
from time import *
import menu as dm

class Game():

    def __init__(self):
        pygame.init()
        pygame.mixer.init()

        #pygame.mixer.music.load('sounds/menugame.ogg')
        #pygame.mixer.music.play(-1)

        # A few variables
        self.gravity = .50
        self.ground = pygame.Rect(0, 640, 1280, 80)
        self.red = (255, 0, 0)
        self.darkred = (200, 0, 0)
        self.darkblue = (0, 0, 200)
        self.darkgreen = (0, 200, 0)
        self.clock = pygame.time.Clock() #to track FPS
        self.fps = 0

        # Bullets
        self.bullets = []

        # Screen
        size = (1280, 720)
        self.screen = pygame.display.set_mode(size)
        pygame.display.set_caption("Moon Survival")
        self.clock.tick(self.fps)

        # Moon / Background
        self.moon = Background()

        # Zombies
        self.zombies = []
        for i in range(10):
            self.zombies.append( Zombie(random.randint(0,1280), random.randint(0,720)) )

        # Player
        self.player = Player(25, 320, self.gravity)

        # Font for text
        self.font = pygame.font.SysFont(None, 72)

        # Pause - center on screen
        self.pause_text = self.font.render("PAUSE", -1, (255,0,0))
        self.pause_rect = self.pause_text.get_rect(center = self.screen.get_rect().center)

    def run(self):

        clock = pygame.time.Clock()

        # "state machine" 
        RUNNING   = True
        PAUSED    = False 
        GAME_OVER = False

        # Game loop
        while RUNNING:

            # (all) Events

            for event in pygame.event.get():

                if event.type == pygame.QUIT:
                    RUNNING = False

                elif event.type == pygame.KEYDOWN:

                    if event.key == pygame.K_s:
                        self.bullets.append(Bullet(self.player.rect.x + 30, self.player.rect.y + 30, self.player.direction))

                    if event.key == pygame.K_ESCAPE:
                        RUNNING = False

                    elif event.key == pygame.K_p:
                        choose = dm.dumbmenu(self.screen, [
                        'Resume Game',

                        'Menu',

                        'Quit Game'], 200, 200,'orecrusherexpanded',100,0.75,self.darkred,self.red)

                        if choose == 0:
                            print "You choose 'Start Game'."
                            break
                        elif choose == 1:
                            execfile('run_game.py')
                            print "You choose 'Controls'."
                        if choose == 2:
                            print "You choose 'Quit Game'."
                            pygame.quit()
                            sys.exit()

                # Player/Zomies events  

                if not PAUSED and not GAME_OVER:
                    self.player.handle_events(event)

            # (all) Movements / Updates

            if not PAUSED and not GAME_OVER:
                self.player_move()
                self.player.update()

                for z in self.zombies:
                    self.zombie_move(z)
                    z.update(self.screen.get_rect())

                for b in self.bullets:
                    b.update()
                    for tile in self.moon.get_surrounding_blocks(b):
                        if tile is not None:
                            if pygame.sprite.collide_rect(b, tile):
                                # Destroy block
                                x = tile.rect.x / tile.rect.width
                                y = tile.rect.y / tile.rect.height
                                self.moon.levelStructure[x][y] = None
                                try:
                                    self.bullets.remove(b)
                                except:
                                    continue

            # (all) Display updating

            self.moon.render(self.screen)

            for z in self.zombies:
                z.render(self.screen)

            for b in self.bullets:
                b.render(self.screen)

            self.player.render(self.screen)

            if PAUSED:
                self.screen.blit(self.pause_text, self.pause_rect)

            Funk.text_to_screen(self.screen, 'Level 1', 5, 675)
            Funk.text_to_screen(self.screen, 'Health: {0}'.format(self.player.health), 5, 0)
            Funk.text_to_screen(self.screen, 'Score: {0}'.format(self.player.score), 400, 0)
            Funk.text_to_screen(self.screen, 'Time: {0}'.format(self.player.alivetime), 750, 0)

            pygame.display.update()

            # FTP

            clock.tick(100)

        # --- the end ---
        pygame.quit()

    def player_move(self):
        # add gravity
        self.player.do_jump()

        # simulate gravity
        self.player.on_ground = False
        if not self.player.on_ground and not self.player.jumping:
            self.player.velY = 4

        # Health
        for zombie in self.zombies:
            if pygame.sprite.collide_rect(self.player, zombie):
                self.player.health -= 5
                if self.player.health <= 0:


        # move player and check for collision at the same time
        self.player.rect.x += self.player.velX
        self.check_collision(self.player, self.player.velX, 0)
        self.player.rect.y += self.player.velY
        self.check_collision(self.player, 0, self.player.velY)

    def zombie_move(self, zombie_sprite):
        # add gravity
        zombie_sprite.do_jump()

        # simualte gravity
        zombie_sprite.on_ground = False
        if not zombie_sprite.on_ground and not zombie_sprite.jumping:
            zombie_sprite.velY = 4

        # Zombie damage
        for zombie in self.zombies:
            for b in self.bullets:
                if pygame.sprite.collide_rect(b, zombie):
                    #The same bullet cannot be used to kill
                    #multiple zombies and as the bullet was 
                    #no longer in Bullet.List error was raised
                    zombie.health -= 10                
                    self.bullets.remove(b)
                    if zombie.health <= 0:
                        self.player.score += random.randint(10, 20)
                        self.zombies.remove(zombie)
                    break

        # move zombie and check for collision
        zombie_sprite.rect.x += zombie_sprite.velX
        self.check_collision(zombie_sprite, zombie_sprite.velX, 0)
        zombie_sprite.rect.y += zombie_sprite.velY
        self.check_collision(zombie_sprite, 0, zombie_sprite.velY)

    def check_collision(self, sprite, x_vel, y_vel):
        # for every tile in Background.levelStructure, check for collision
        for block in self.moon.get_surrounding_blocks(sprite):
            if block is not None:
                if pygame.sprite.collide_rect(sprite, block):
                    # we've collided! now we must move the collided sprite a step back
                    if x_vel < 0:
                        sprite.rect.x = block.rect.x + block.rect.w

                        if sprite is Zombie:
                            print "wohoo"

                    if type(sprite) is Zombie:
                            # the sprite is a zombie, let's make it jump
                            if not sprite.jumping:
                                sprite.jumping = True
                                sprite.on_ground = False

                    if x_vel > 0:
                        sprite.rect.x = block.rect.x - sprite.rect.w

                    if y_vel < 0:
                        sprite.rect.y = block.rect.y + block.rect.h

                    if y_vel > 0 and not sprite.on_ground:
                        sprite.on_ground = True
                        sprite.rect.y = block.rect.y - sprite.rect.h

#---------------------------------------------------------------------

Game().run()

I am not exactly sure how to do it, because I tried to use another py call game over but the time of which the player died was then reset to 0 and went back up, so is it possible for anything to happen where the player dies?我不太确定该怎么做,因为我尝试使用另一个 py 调用游戏结束,但是玩家死亡的时间随后被重置为 0 并返回,所以玩家死亡的地方是否有可能发生任何事情?

Use states in your engine.在引擎中使用状态。

Some pseudo code:一些伪代码:

while game_running:
    if STATE == STATE_MENU:
        Menu_ProcessInput()
        Menu_Update()
        Menu_Draw()
    elif STATE == STATE_INGAME:
        INGAME_ProcessInput()
        INGAME_Update()
        INGAME_Draw()
    elif STATE == STATE_GAMEOVER:
        GAMEOVER_ProcessInput()
        GAMEOVER_Update()
        GAMEOVER_Draw()

This is an easy solution that does not require messing around with multiple loops for menus etc.这是一个简单的解决方案,不需要搞乱菜单等的多个循环。

You should use states as Marcus wrote.你应该使用马库斯写的状态。 I will elaborate on this a bit.我将详细说明这一点。 You should have a class that will be your Game class.你应该有一个类作为你的游戏类。

This will include all the screens.这将包括所有屏幕。 A draft would look like this:草稿看起来像这样:

class GameEngine:
    def __init__(self):
        #initialize pygame
        #load resources
        #etc...
        states = [PlayGameState(),OptionsState(),GameOverState()]
    def run(self):
        while(True):
            states[current_state].draw()
            states[current_state].update()
            for event in pygame.event.get():
                states[current_state].input(event)

Then you can have the logic for all the states separate, and adding a new screen is just a matter of adding to the states list.然后您可以将所有状态的逻辑分开,添加新屏幕只是添加到状态列表的问题。

Pausing the game in this example would be really easy, it would simply see if the event_key was ESC and state was PlayGame, it would change it to PauseState.在这个例子中暂停游戏真的很容易,它会简单地查看 event_key 是否为 ESC,状态是否为 PlayGame,它会将其更改为 PauseState。

The GameEngine could also poll the state, to see if it ended so that yu could change to the GameOverState, and after that back to MainState. GameEngine 还可以轮询状态,查看它是否结束,以便您可以更改为 GameOverState,然后再返回 MainState。

Raise an exception, and catch it at a point where you're outside the running of the game but with the data you need to handle a game over.引发异常,并在您处于游戏运行之外但拥有处理游戏所需的数据时捕获它。

try:
    stuff()
except GameOver:
    game_over_screen()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM