记录学习项目的过程,这是一个简单的飞船游戏,通过学习这个项目来了解pygame是如何处理在屏幕上绘制图像等任务,重点是学习程序的高级逻辑是如何设计的。
在游戏《外星人入侵》中,玩家控制一艘最初出现在屏幕底部中央的飞船,玩家可以使用箭头键左右移动飞船,还可使用空格扯射击。 游戏开始时,一群外早人出现在天空中,并向屏幕下方移动。玩家的任务是射杀这些外星人 。玩家将所有外星人都消灭干净后,将出现一群新的外星人,其移动速度更快。只要有外星人撞到玩家的飞船或到达屏幕底部,玩家就损失一艘飞船。玩家损失三艘飞船后,游戏结束。
安装命令: $ python -m pip install --user pygame
#alien_invasion.py
import sys
import pygame
class AlienInvasion:
'''管理游戏资源和行为的类'''
def __init__(self):
'''初始化游戏并创建游戏资源'''
pygame.init() # 初始化背景设置
self.screen = pygame.display.set_mode((1200, 800)) #长高的像素
pygame.display.set_caption("Alien Invasion") # 添加窗口名称
def run_game(self):
"""开始游戏的主循环"""
while True:
# 监视键盘和鼠标事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# 让最近绘制的屏幕可见
pygame.display.flip()
if __name__ == '__main__':
# 创建游戏实例并运行游戏
ai = AlienInvasion()
ai.run_game()
ps: while循环包含一个事件循环以及管理屏幕更新的代码。事件是用户玩游戏时执行的操作,如按键或移动鼠标。为程序响应事件,可编写一个事件循环,以侦听事件并根据发生的事件类型执行合适的任务。
#alien_invasion.py
def __init__(self):
--snip--
pygame.display.set_caption("Alien Invasion")
#设置背景色
self.bg_color = (230, 230, 230)
def run_game(self):
--snip--
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# 每次循环时都重绘屏幕。
self.screen.fill(self.bg_color)
# 让最近绘制的屏幕可见
pygame.display.flip()
ps: 颜色是以RGB值指定的。这种颜色由红色、绿色和蓝色值组成,其中每个值的可取值范围为0~255,豆沙绿:199, 237, 204
#setting.py
class Settings:
'''存储游戏《外星人入侵》中所有设置的类'''
def __init__(self):
'''初始化游戏的设置'''
# 屏幕设置
self.screen_width = 1200
self.screen_hight = 750
self.bg_color = (230, 230, 230)
#alien_invasion.py
--snip--
import pygame
from settings import Settings
class AlienInvasion:
'''管理游戏资源和行为的类'''
def __init__(self):
'''初始化游戏并创建游戏资源'''
pygame.init() # 初始化背景设置
self.settings = Settings()
self.screen = pygame.display.set_mode(
(self.settings.screen_width, self.settings.screen_hight)
)
pygame.display.set_caption("Alien Invasion") # 添加窗口名称
def run_game(self):
--snip--
# 每次循环时都重绘屏幕
self.screen.fill(self.settings.bg_color)
# 让最近绘制的屏幕可见
pygame.display.flip()
--snip--
在游戏中几乎可以使用任何类型的图像文件,但使用位图(.bmp)文件最为简单,因为pygame默认加载位图
#ship.py
import pygame
class Ship:
'''管理飞船的类'''
def __init__(self, ai_game):
'''初始化飞船并设置其初始位置。'''
self.screen = ai_game.screen
self.screen_rect = ai_game.screen.get_rect()
# 加载飞船图像并获取其外接矩形
self.image = pygame.image.load('image/ship.bmp')
self.rect = self.image.get_rect()
# 对于每艘新飞船,都将其放在屏幕底部的中央。
self.rect.midbottom = self.screen_rect.midbottom
def blitme(self):
''' 在指定位置绘制飞船 '''
self.screen.blit(self.image, self.rect)
# alien_incasion.py
--snip--
from settings import Settings
from ship import Ship
class AlienInvasion:
'''管理游戏资源和行为的类'''
def __init__(self):
--snip--
pygame.display.set_caption("Alien Invasion") # 添加窗口名称
self.ship = Ship(self) # 添加图像属性
def run_game(self):
--snip--
# 每次循环时都重绘屏幕
self.screen.fill(self.settings.bg_color)
self.ship.blitme()
# 让最近绘制的屏幕可见
pygame.display.flip()
--snip--
方法_check_events()和_update_screen()
ps:将越来越长的方法run_game()拆分成两个辅助方法。辅助方法在类中执行任务,但并非是通过实例调用的。在python中,辅助方法的名称以单个下划线打头。
#alien_invasion.py
def run_game(self):
'''开始游戏的主循环'''
while True:
self._check_events()
--snip--
def _check_events(self):
''' 响应按键和鼠标事件 '''
for even in pygame.event.get(): # 事件获取
if even.type == pygame.QUIT:
sys.exit()
#alien_invasion,py
def run_game(self):
'''开始游戏的主循环'''
while True:
self._check_events()
self._update_events()
def _check_events(self):
--snip--
def _update_screen(self):
'''更新屏幕上的图像,并切换到新屏幕。'''
self.screen.fill(self.settings.bg_color)
self.ship.blitme()
pygame.display.flip()