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

一 添加Play按钮

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

  1. import pygame.font
  2.  
  3. class Button() :
  4. def __init__(self,ai_settings,screen,msg):
  5. #初始化按钮的属性
  6. self.screen=screen
  7. self.screen_rect=screen.get_rect()
  8.  
  9. #设置按钮的尺寸和其他属性
  10. self.width,self.height=200,50
  11. self.button_color=(0,255,0)
  12. self.text_color = (255,255,255)
  13. self.font = pygame.font.SysFont(None,48)
  14.  
  15. #创建按钮的rect对象,并使其居中
  16. self.rect = pygame.Rect(0,0,self.width,self.height)
  17. self.rect.center = self.screen_rect.center
  18.  
  19. #按钮的标签只需要创建一次
  20. self.prep_msg(msg)
  21.  
  22. def prep_msg(self,msg):
  23. #讲msg渲染为图像,并使其在按钮上居中
  24. self.msg_image = self.font.render(msg,True,self.text_color,self.button_color)
  25. self.msg_image_rect = self.msg_image.get_rect()
  26. self.msg_image_rect.center = self.rect.center
  27.  
  28. def draw_button(self):
  29. #绘制一个用颜色填充的按钮,再绘制文本
  30. self.screen.fill(self.button_color,self.rect)
  31. 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中添加标亮的代码:

  1. import pygame
  2. from pygame.sprite import Group
  3.  
  4. from settings import Settings
  5. from game_stats import GameStats
  6. from ship import Ship
  7. import game_functions as gf
  8. from button import Button
  9. def run_game():
  10. # Initialize pygame, settings, and screen object.
  11. pygame.init()
  12. ai_settings = Settings()
  13. screen = pygame.display.set_mode(
  14. (ai_settings.screen_width, ai_settings.screen_height))
  15. pygame.display.set_caption("Alien Invasion")
  16.  
  17. #创建play按钮
  18. play_button = Button(ai_settings,screen,"Play")
  19.  
  20. # Create an instance to store game statistics.
  21. stats = GameStats(ai_settings)
  22.  
  23. # Set the background color.
  24. bg_color = (230, 230, 230)
  25.  
  26. # Make a ship, a group of bullets, and a group of aliens.
  27. ship = Ship(ai_settings, screen)
  28. bullets = Group()
  29. aliens = Group()
  30.  
  31. # Create the fleet of aliens.
  32. gf.create_fleet(ai_settings, screen, ship, aliens)
  33.  
  34. # Start the main loop for the game.
  35. while True:
  36. gf.check_events(ai_settings, screen, ship, bullets)
  37.  
  38. if stats.game_active:
  39. ship.update()
  40. gf.update_bullets(ai_settings, screen, ship, aliens, bullets)
  41. gf.update_aliens(ai_settings, stats, screen, ship, aliens, bullets)
  42.  
  43. gf.update_screen(ai_settings, screen, stats, ship, aliens, bullets,play_button)
  44.  
  45. run_game()

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

  1. def update_screen(ai_settings, screen,stats, ship, aliens, bullets,play_button):
  2. """Update images on the screen, and flip to the new screen."""
  3. # Redraw the screen, each pass through the loop.
  4. screen.fill(ai_settings.bg_color)
  5.  
  6. # Redraw all bullets, behind ship and aliens.
  7. for bullet in bullets.sprites():
  8. bullet.draw_bullet()
  9. ship.blitme()
  10. aliens.draw(screen)
  11. if not stats.game_active :
  12. play_button.draw_button()
  13.  
  14. # Make the most recently drawn screen visible.
  15. pygame.display.flip()

运行效果如下:

三 开始游戏

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

  1. def check_events(ai_settings, screen, stats,play_button,ship, bullets):
  2. """Respond to keypresses and mouse events."""
  3. for event in pygame.event.get():
  4. if event.type == pygame.QUIT:
  5. sys.exit()
  6. elif event.type == pygame.KEYDOWN:
  7. check_keydown_events(event, ai_settings, screen, ship, bullets)
  8. elif event.type == pygame.KEYUP:
  9. check_keyup_events(event, ship)
  10. elif event.type == pygame.MOUSEBUTTONDOWN :
  11. mouse_x,mouse_y = pygame.mouse.get_pos()
  12. check_play_button(stats,play_button,mouse_x,mouse_y)
  13.  
  14. def check_play_button(stats,play_button,mouse_x,mouse_y) :
  15. #在玩家点击play按钮时开始游戏
  16. if play_button.rect.collidepoint(mouse_x,mouse_y) :
  17. stats.game_active = True

注意一下几点:

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

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

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

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

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

  1. def check_events(ai_settings, screen, stats,play_button,ship,aliens, bullets):
  2. """Respond to keypresses and mouse events."""
  3. for event in pygame.event.get():
  4. if event.type == pygame.QUIT:
  5. sys.exit()
  6. elif event.type == pygame.KEYDOWN:
  7. check_keydown_events(event, ai_settings, screen, ship, bullets)
  8. elif event.type == pygame.KEYUP:
  9. check_keyup_events(event, ship)
  10. elif event.type == pygame.MOUSEBUTTONDOWN :
  11. mouse_x,mouse_y = pygame.mouse.get_pos()
  12. check_play_button(ai_settings,screen,stats,play_button,ship,aliens,bullets,mouse_x,mouse_y)
  13.  
  14. def check_play_button(ai_settings,screen,stats,play_button,ship,aliens,bullets,mouse_x,mouse_y) :
  15. #在玩家点击play按钮时开始游戏
  16. button_clicked=play_button.rect.collidepoint(mouse_x,mouse_y)
  17. if button_clicked and not stats.game_active :
  18. #隐藏光标
  19. pygame.mouse.set_visible(False)
  20. #重置游戏信息
  21. stats.reset_stats()
  22. stats.game_active = True
  23.  
  24. #清空外星人列表和子弹列表
  25. aliens.empty()
  26. bullets.empty()
  27.  
  28. #创建一群新的外星人,并让飞船居中
  29. create_fleet(ai_settings,screen,ship,aliens)
  30. ship.center_ship()

注意一下几点:

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

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

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

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

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

  

Python 项目实践一(外星人入侵小游戏)第五篇的更多相关文章

  1. Python 项目实践二(生成数据)第一篇

    上面那个小游戏教程写不下去了,以后再写吧,今天学点新东西,了解的越多,发现python越强大啊! 数据可视化指的是通过可视化表示来探索数据,它与数据挖掘紧密相关,而数据挖掘指的是使用代码来探索数据集的 ...

  2. Python 项目实践一(外星人入侵小游戏)第二篇

    接着上次的继续学习. 一 创建一个设置类 每次给游戏添加新功能时,通常也将引入一些新设置.下面来编写一个名为settings的模块,其中包含一个名为Settings的类,用于将所有设置存储在一个地方, ...

  3. Python 项目实践二(生成数据)第二篇之随机漫步

    接着上节继续学习,在本节中,我们将使用Python来生成随机漫步数据,再使用matplotlib以引人瞩目的方式将这些数据呈现出来.随机漫步是这样行走得到的路径:每次行走都完全是随机的,没有明确的方向 ...

  4. Python 项目实践二(生成数据)第二篇

    接着上节继续学习,在本节中,我们将使用Python来生成随机漫步数据,再使用matplotlib以引人瞩目的方式将这些数据呈现出来.随机漫步是这样行走得到的路径:每次行走都完全是随机的,没有明确的方向 ...

  5. Pygame小游戏练习五

    @Python编程从入门到实践 Python项目练习 十一.显示游戏得分及最高分 创建新类Scoreboard,用以显示得分和最高分. # scoreboard.py import pygame.fo ...

  6. Python 项目实践一(外星人入侵)第一篇

    python断断续续的学了一段实践,基础课程终于看完了,现在跟着做三个小项目,第一个是外星人入侵的小游戏: 一 Pygame pygame 是一组功能强大而有趣的模块,可用于管理图形,动画乃至声音,让 ...

  7. 用python+pygame写贪吃蛇小游戏

    因为python语法简单好上手,前两天在想能不能用python写个小游戏出来,就上网搜了一下发现了pygame这个写2D游戏的库.了解了两天再参考了一些资料就开始写贪吃蛇这个小游戏. 毕竟最开始的练手 ...

  8. python写的battle ship小游戏 - 1.0

    最近学python,这是今天写的一个小游戏. from random import randint class Board(object): board = [] def __init__(self, ...

  9. 从Python小白到第一个小游戏发布

    1.安装必要的环境(附图两张) 直接下载安装程序,本人win10系统,根据电脑系统下载并安装对应的python.exe,安装路径可以选择D盘的,具体安装细节这里就不说了,不知道的可以留言或者找度娘 2 ...

  10. docker项目——搭建飞机大战小游戏

    项目2:搭建打飞机小游戏,验证数据持久化(最底下有链接) 第一步:拉取镜像 [root@localhost docker-image]# docker load < httpd_img.tar. ...

随机推荐

  1. 《Linux命令行与shell脚本编程大全》第十二章 使用结构化命令

    许多程序要就对shell脚本中的命令施加一些逻辑控制流程. 结构化命令允许你改变程序执行的顺序.不一定是依次进行的 12.1 使用if-then语句 如下格式: if command then     ...

  2. 转贴---Linux服务器性能评估

    http://fuliang.iteye.com/blog/1024360 http://unixhelp.ed.ac.uk/CGI/man-cgi?vmstat ------------------ ...

  3. js实际工作中的技能点

    1.基础知识 a.原型,原型链 b.作用域,闭包 c.异步,单线程 2.JS API a.DOM操作 b.Ajax c.事件绑定 3.开发环境 a.版本管理(git) b.模块化(require.js ...

  4. 电子笔记本的思考(1)(ver0.3)

    章节:电子笔记本的思考(1)   陶哲轩在<解题·成长·快乐——陶哲轩教你学数学>中着重强调,用纸笔来“缓存”思维对于数学解题的重要性: 用选定的符号表达你所知道的信息,并画一个示意图.把 ...

  5. 【转】使用nvm快速搭建 Node.js 开发环境

    原文链接:http://www.cnblogs.com/shuoer/p/7802891.html 快速搭建 Node.js 开发环境 如果你想长期做 node 开发, 或者想快速更新 node 版本 ...

  6. KVM克隆 快照

    原创博文安装配置KVM http://www.cnblogs.com/elvi/p/7718574.htmlweb管理kvm http://www.cnblogs.com/elvi/p/7718582 ...

  7. 高可用的Spring FTP上传下载工具类(已解决上传过程常见问题)

    前言 最近在项目中需要和ftp服务器进行交互,在网上找了一下关于ftp上传下载的工具类,大致有两种. 第一种是单例模式的类. 第二种是另外定义一个Service,直接通过Service来实现ftp的上 ...

  8. CCF-201604-1-折点计数

    问题描述 试题编号: 201604-1 试题名称: 折点计数 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 给定n个整数表示一个商店连续n天的销售量.如果某天之前销售量在增长 ...

  9. Linux多线程编程详细解析----条件变量 pthread_cond_t

    Linux操作系统下的多线程编程详细解析----条件变量 1.初始化条件变量pthread_cond_init #include <pthread.h> int pthread_cond_ ...

  10. 修复mysql表

    1>用"repair table"方式修复语法:repair table 表名 [选项]选项如下:QUICK 用在数据表还没被修改的情况下,速度最快EXTENDED 试图去恢 ...