zoukankan      html  css  js  c++  java
  • Python 项目实践一(外星人入侵小游戏)第五篇

    接着上节的继续学习,在本章中,我们将结束游戏《外星人入侵》的开发。我们将添加一个Play按钮,用于根据需要启动游戏以及在游戏结束后重启游戏。我们还将修改这个游戏,使其在玩家的等级提高时加快节奏,并实现一个记分系统。

    一 添加Play按钮

    由于Pygame没有内置创建按钮的方法,我们创建一个Button类,用于创建带标签的实心矩形。你可以在游戏中使用这些代码来创建任何按钮。下面是Button类的第一部分,请将这个类保存为button.py代码如下:

    import pygame.font
    
    class Button() :
        def __init__(self,ai_settings,screen,msg):
            #初始化按钮的属性
            self.screen=screen
            self.screen_rect=screen.get_rect()
    
            #设置按钮的尺寸和其他属性
            self.width,self.height=200,50
            self.button_color=(0,255,0)
            self.text_color = (255,255,255)
            self.font = pygame.font.SysFont(None,48)
    
            #创建按钮的rect对象,并使其居中
            self.rect = pygame.Rect(0,0,self.width,self.height)
            self.rect.center = self.screen_rect.center
    
            #按钮的标签只需要创建一次
            self.prep_msg(msg)
    
        def prep_msg(self,msg):
            #讲msg渲染为图像,并使其在按钮上居中
            self.msg_image = self.font.render(msg,True,self.text_color,self.button_color)
            self.msg_image_rect = self.msg_image.get_rect()
            self.msg_image_rect.center = self.rect.center
    
        def draw_button(self):
            #绘制一个用颜色填充的按钮,再绘制文本
            self.screen.fill(self.button_color,self.rect)
            self.screen.blit(self.msg_image,self.msg_image_rect)
    

    代码中已经注释的很清楚了,不再做过多的介绍,这里重点说一下几个点:

    (1)导入了模块pygame.font,它让Pygame能够将文本渲染到屏幕上。

    (2)pygame.font.SysFont(None,48)指定使用什么字体来渲染文本。实参None让Pygame使用默认字体,而48指定了文本的字号。

    (3)方法prep_msg()接受实参self以及要渲染为图像的文本(msg)。调用font.render()将存储在msg中的文本转换为图像,然后将该图像存储在msg_image中。

    (4)方法font.render()还接受一个布尔实参,该实参指定开启还是关闭反锯齿功能(反锯齿让文本的边缘更平滑)

    (5)screen.fill()来绘制表示按钮的矩形,再调用screen.blit(),并向它传递一幅图像以及与该图像相关联的rect对象,从而在屏幕上绘制文本图像。

    二 在屏幕绘制按钮

    在alien_invasion.py中添加标亮的代码:

    import pygame
    from pygame.sprite import Group
    
    from settings import Settings
    from game_stats import GameStats
    from ship import Ship
    import game_functions as gf
    from button import Button
    def run_game():
        # Initialize pygame, settings, and screen object.
        pygame.init()
        ai_settings = Settings()
        screen = pygame.display.set_mode(
            (ai_settings.screen_width, ai_settings.screen_height))
        pygame.display.set_caption("Alien Invasion")
    
        #创建play按钮
        play_button = Button(ai_settings,screen,"Play")
        
        # Create an instance to store game statistics.
        stats = GameStats(ai_settings)
        
        # Set the background color.
        bg_color = (230, 230, 230)
        
        # Make a ship, a group of bullets, and a group of aliens.
        ship = Ship(ai_settings, screen)
        bullets = Group()
        aliens = Group()
        
        # Create the fleet of aliens.
        gf.create_fleet(ai_settings, screen, ship, aliens)
    
        # Start the main loop for the game.
        while True:
            gf.check_events(ai_settings, screen, ship, bullets)
            
            if stats.game_active:
                ship.update()
                gf.update_bullets(ai_settings, screen, ship, aliens, bullets)
                gf.update_aliens(ai_settings, stats, screen, ship, aliens, bullets)
            
            gf.update_screen(ai_settings, screen, stats, ship, aliens, bullets,play_button)
    
    run_game()
    

    修改update_screen(),以便在游戏处于非活动状态时显示Play按钮:

    def update_screen(ai_settings, screen,stats, ship, aliens, bullets,play_button):
        """Update images on the screen, and flip to the new screen."""
        # Redraw the screen, each pass through the loop.
        screen.fill(ai_settings.bg_color)
        
        # Redraw all bullets, behind ship and aliens.
        for bullet in bullets.sprites():
            bullet.draw_bullet()
        ship.blitme()
        aliens.draw(screen)
        if not stats.game_active :
            play_button.draw_button()
        
        # Make the most recently drawn screen visible.
        pygame.display.flip()
    

    运行效果如下:

    三 开始游戏

    为在玩家单击Play按钮时开始新游戏,需在game_functions.py中添加如下代码,以监视与这个按钮相关的鼠标事件:

    def check_events(ai_settings, screen, stats,play_button,ship, bullets):
        """Respond to keypresses and mouse events."""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                check_keydown_events(event, ai_settings, screen, ship, bullets)
            elif event.type == pygame.KEYUP:
                check_keyup_events(event, ship)
            elif event.type == pygame.MOUSEBUTTONDOWN :
                mouse_x,mouse_y = pygame.mouse.get_pos()
                check_play_button(stats,play_button,mouse_x,mouse_y)
    
    def check_play_button(stats,play_button,mouse_x,mouse_y) :
        #在玩家点击play按钮时开始游戏
        if play_button.rect.collidepoint(mouse_x,mouse_y) :
            stats.game_active = True
    

    注意一下几点:

    (1)无论玩家单击屏幕的什么地方,Pygame都将检测到一个MOUSEBUTTONDOWN事件,但我们只关心这个游戏在玩家用鼠标单击Play按钮时作出响应。

    (2)使用了pygame.mouse.get_pos(),它返回一个元组,其中包含玩家单击时鼠标的x和y坐标。

    (3)使用collidepoint()检查鼠标单击位置是否在Play按钮的rect内,如果是这样的,我们就将game_active设置为True,让游戏就此开始!

    四 重置游戏,将按钮切换到非活动状态以及隐藏光标

    前面编写的代码只处理了玩家第一次单击Play按钮的情况,而没有处理游戏结束的情况,因为没有重置导致游戏结束的条件。为在玩家每次单击Play按钮时都重置游戏,需要重置统计信息、删除现有的外星人和子弹、创建一群新的外星人,并让飞船居中。

    def check_events(ai_settings, screen, stats,play_button,ship,aliens, bullets):
        """Respond to keypresses and mouse events."""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                check_keydown_events(event, ai_settings, screen, ship, bullets)
            elif event.type == pygame.KEYUP:
                check_keyup_events(event, ship)
            elif event.type == pygame.MOUSEBUTTONDOWN :
                mouse_x,mouse_y = pygame.mouse.get_pos()
                check_play_button(ai_settings,screen,stats,play_button,ship,aliens,bullets,mouse_x,mouse_y)
    
    def check_play_button(ai_settings,screen,stats,play_button,ship,aliens,bullets,mouse_x,mouse_y) :
        #在玩家点击play按钮时开始游戏
        button_clicked=play_button.rect.collidepoint(mouse_x,mouse_y)
        if  button_clicked and not stats.game_active :
            #隐藏光标
            pygame.mouse.set_visible(False)
            #重置游戏信息
            stats.reset_stats()
            stats.game_active = True
    
            #清空外星人列表和子弹列表
            aliens.empty()
            bullets.empty()
    
            #创建一群新的外星人,并让飞船居中
            create_fleet(ai_settings,screen,ship,aliens)
            ship.center_ship()
    

    注意一下几点:

    (1),Play按钮存在一个问题,那就是即便Play按钮不可见,玩家单击其原来所在的区域时,游戏依然会作出响应。游戏开始后,如果玩家不小心单击了Play按钮原来所处的区域,游戏将重新开始!为修复这个问题,可让游戏仅在game_active为False时才开始

    button_clicked = play_button.rect.collidepoint(mouse_x, mouse_y)
    if button_clicked and not stats.game_active:
    

    (2)为让玩家能够开始游戏,我们要让光标可见,但游戏开始后,光标只会添乱。在游戏处于活动状态时让光标不可见,游戏结束后,我们将重新显示光标,让玩家能够单击Play按钮来开始新游戏。

    def check_play_button(ai_settings, screen, stats, play_button, ship, aliens,bullets, mouse_x, mouse_y):
        """在玩家单击Play按钮时开始新游戏"""
        button_clicked = play_button.rect.collidepoint(mouse_x, mouse_y)
        if button_clicked and not stats.game_active:
            # 隐藏光标
            pygame.mouse.set_visible(False)
    

    还有好多要写,但实在写不下去了,明天再写吧!休息休息!

      

  • 相关阅读:
    【Java EE 学习 81】【CXF框架】【CXF整合Spring】
    【Java EE 学习 80 下】【调用WebService服务的四种方式】【WebService中的注解】
    【Java EE 学习 80 上】【WebService】
    【Java EE 学习 79 下】【动态SQL】【mybatis和spring的整合】
    【Java EE 学习 79 上】【mybatis 基本使用方法】
    【Java EE 学习 78 下】【数据采集系统第十天】【数据采集系统完成】
    【Java EE 学习 78 中】【数据采集系统第十天】【Spring远程调用】
    【Java EE 学习 78 上】【数据采集系统第十天】【Service使用Spring缓存模块】
    【Java EE 学习 77 下】【数据采集系统第九天】【使用spring实现答案水平分库】【未解决问题:分库查询问题】
    【Java EE 学习 77 上】【数据采集系统第九天】【通过AOP实现日志管理】【通过Spring石英调度动态生成日志表】【日志分表和查询】
  • 原文地址:https://www.cnblogs.com/ChinacloudTech/p/8126356.html
Copyright © 2011-2022 走看看