游戏类模版框架_鼠标操控收集型.py

"""游戏类模版框架_鼠标操控收集型.py,
本程序设计了一个Game类,展示如何组织一个游戏的逻辑。
好处是当游戏结束的条件满足时,可以非常方便的重新开始游戏。
"""
 
import pygame
import random
 
# --- 定义全局颜色常量 ---
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
 
SCREEN_WIDTH = 700
SCREEN_HEIGHT = 500 
 
class Block(pygame.sprite.Sprite):
    """这个类代表玩家收集的方块"""
 
    def __init__(self):
        """ 调用父类的初始化方法 """
        super().__init__()
        self.image = pygame.Surface([20, 20])
        self.image.fill(BLACK)
        self.rect = self.image.get_rect()
 
    def reset_pos(self):
        """ 重新设置坐标. """
        self.rect.y = random.randrange(-300, -20)
        self.rect.x = random.randrange(SCREEN_WIDTH)
 
    def update(self):
        """ 更新坐标 """
        self.rect.y += 1
 
        if self.rect.y > SCREEN_HEIGHT + self.rect.height:
            self.reset_pos()
 
 
class Player(pygame.sprite.Sprite):
    """ 玩家类 """
    def __init__(self):
        super().__init__()
        self.image = pygame.Surface([20, 20])
        self.image.fill(RED)
        self.rect = self.image.get_rect()
 
    def update(self):
        """更新玩家坐标. """
        pos = pygame.mouse.get_pos()
        self.rect.x = pos[0]
        self.rect.y = pos[1]
 
 
class Game:
    """ Game类. """
 
    def __init__(self):
        """ 游戏的初始化方法,游戏中有得分,游戏是否结束等. """
 
        self.score = 0
        self.game_over = False
        self.font = pygame.font.SysFont("serif", 25)
 
        # 游戏的方块列表和所有角色列表
        self.block_list = pygame.sprite.Group()
        self.all_sprites_list = pygame.sprite.Group()
 
        # 创建方块
        for i in range(50):
            block = Block() 
            block.rect.x = random.randrange(SCREEN_WIDTH)
            block.rect.y = random.randrange(-300, SCREEN_HEIGHT)
 
            self.block_list.add(block)
            self.all_sprites_list.add(block)
 
        # 创建玩家,并加入到所有角色列表,方便统一update与draw
        self.player = Player()
        self.all_sprites_list.add(self.player)
 
    def process_events(self):
        """ 处理所有事件,如果按了关闭按钮会返回真。 """ 
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return True
            if event.type == pygame.MOUSEBUTTONDOWN:
                if self.game_over:   # 游戏结束了,单击鼠标再次初始化游戏
                    self.__init__()
 
        return False
 
    def run_logic(self):
        """
        这个方法每帧运行一次,主要是更新坐标与碰撞检测。
        """
        if not self.game_over:
            # 更新所有角色坐标
            self.all_sprites_list.update()
 
            # 检查玩家方块是否和方块们碰到
            blocks_hit_list = pygame.sprite.spritecollide(self.player, self.block_list, True)
 
            # 检测碰撞列表中的每个方块
            for block in blocks_hit_list:
                self.score += 1
                print(self.score)              
 
            if len(self.block_list) == 0:
                self.game_over = True
 
    def display_frame(self, screen):
        """ 重画所有角色. """
        screen.fill(WHITE)   # 清背景为白色
 
        if self.game_over:   # 如果游戏结束 了,显示单击重启动游戏的字        
            text = self.font.render("Game Over, click to restart", True, BLACK)
            center_x = (SCREEN_WIDTH // 2) - (text.get_width() // 2)
            center_y = (SCREEN_HEIGHT // 2) - (text.get_height() // 2)
            screen.blit(text, [center_x, center_y])
 
        if not self.game_over:# 如果游戏没有结束         
            self.all_sprites_list.draw(screen)
 
        pygame.display.flip()
 
 
def main():
    """ 主要流程函数. """
    # 初始化派gei引擎
    pygame.init()
 
    size = [SCREEN_WIDTH, SCREEN_HEIGHT]
    screen = pygame.display.set_mode(size)
 
    pygame.display.set_caption("游戏类模版框架_鼠标操控收集型")
    pygame.mouse.set_visible(False)
 
    # 创建done用来结束while循环
    done = False
    clock = pygame.time.Clock()
 
    # 创建一个游戏实例
    game = Game()
 
    # 游戏主要循环
    while not done:
 
        # 处理所有事件
        done = game.process_events()
 
        # 游戏运行逻辑,更新坐标与检测碰撞,得分等
        game.run_logic()
 
        # 重画所有对象
        game.display_frame(screen)
 
        # 每秒显示60次(到了1/60秒就继续下一次循环
        clock.tick(60)
 
    # 关闭窗口结束
    pygame.quit()
 
if __name__ == "__main__":
    main()