13.外星人

1.回顾项目:重构代码(添加一个结束游戏的快捷键Q),本章涉及游戏功能如下。

1.屏幕左上角添加一个外星人,指定合适的边距;
2.根据第一个外星人和屏幕尺寸计算屏幕需要容纳多少个外星人,循环创建外星人填满屏幕;
3.让外星人群想两边和下方移动,直到外星人被全部击落,若整群外星人被击落则再创建一群外星人,若外星人撞到飞船或抵达屏幕底端,则销毁飞船并再创建一群外星人;
4.限制玩家可用飞船数量,配给的飞船用完后,游戏结束。

2.创建第一个外星人:与放置飞船类似,将外星人的位图文件保存在文件夹images中。创建alien.py文件,定义Alien类,该类继承pygame.sprite导入的Sprite类,其他设置与Ship类相似。game_function模块中update_screen()函数中添加绘制外星人的代码。
alien.bmp 图像文件如下:
在这里插入图片描述
alien.py 代码如下:

# -*- coding: GBK -*- 
import pygame
from pygame.sprite import Sprite

class Alien(Sprite):
	'''表示单个外星人的类'''
	
	def __init__(self, ai_settings, screen):
		'''初始化外星人并设置其起始位置'''
		super().__init__()
		self.screen = screen 
		self.ai_settings = ai_settings
		
		# 加载外星人图像,并设置其rect属性
		self.image = pygame.image.load('images/alien.bmp')
		self.rect = self.image.get_rect()
		
		# 每个外星人最初都在屏幕左上角附近
		self.rect.x = self.rect.width
		self.rect.y = self.rect.height
		
		# 存储外星人的准确位置
		self.x = float(self.rect.x)
		
	def blitme(self):
		'''在指定位置绘制外星人'''
		self.screen.blit(self.image, self.rect)

game_functions.py 代码如下:

# -*- coding: GBK -*- 
import sys		# 使用模块sys来退出游戏。
import pygame
from bullet import Bullet

def check_keydown_events(event, ai_settings, screen, ship, bullets):
	'''响应按键'''
	if event.key == pygame.K_RIGHT:
		ship.moving_right = True
	elif event.key == pygame.K_LEFT:
		ship.moving_left = True
	elif event.key == pygame.K_SPACE:	# 空白键
		fire_bullet(ai_settings, screen, ship, bullets)
	elif event.key == pygame.K_q:	# 字母Q键
		sys.exit()

def fire_bullet(ai_settings, screen, ship, bullets):
	'''如果还没有到达限制,就发射一颗子弹'''
	# 创建一颗新子弹,并将其加入到编组bullets中
	if len(bullets) < ai_settings.bullets_allowed:	# 限制子弹数量
		new_bullet = Bullet(ai_settings, screen, ship)
		bullets.add(new_bullet)	

		
def check_keyup_events(event, ship):
	'''响应松开'''
	if event.key == pygame.K_RIGHT:
		ship.moving_right = False
	elif event.key == pygame.K_LEFT:
		ship.moving_left = False

def check_events(ai_settings, screen, ship, bullets):
	'''响应按键和鼠标事件'''
	# 监视键盘和鼠标事件
	for event in pygame.event.get():	#Pygame检测到的时间
		if event.type == pygame.QUIT:	#玩家单击窗口关闭按钮,则检测到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)

def update_screen(ai_settings, screen, ship, alien, bullets):
	'''更新屏幕上的图像,并切换到新屏幕'''
	# 每次循环时都重绘屏幕
	screen.fill(ai_settings.bg_color)	#screen.fill()只接受一个实参:一种颜色
	# 在飞船和外星人后面重绘所有子弹
	for bullet in bullets.sprites():	#方法bullets.sprites()返回一个列表,其中包含编组bullets中的所有精灵
		bullet.draw_bullet()
	ship.blitme()	#在指定位置绘制飞船
	alien.blitme()	#在指定位置绘制外星人
	
	# 让最近绘制的屏幕可见
	pygame.display.flip()	#不断更新屏幕,以显示元素的新位置	

def update_bullets(bullets):
	'''更新子弹的位置,并删除已消失子弹'''
	# 更新每一粒子弹的位置
	bullets.update()	#对编组调用update(),编组自动对其中每个精灵调用update(),即为每一粒子弹调用bullet.update()
	
	# 删除已消失子弹
	for bullet in bullets.copy():	# 遍历编组的副本
		if bullet.rect.bottom <= 0:
			bullets.remove(bullet)
	# print(len(bullets))	# 核实已消失子弹确实删除了	

alien_invasion.py 执行代码如下:

# -*- coding: GBK -*- 
import pygame		# 模块pygame包含开发游戏所需的功能。
from settings import Settings	# 导入设置模块的Setting类
from ship import Ship	# 导入ship模块的Ship类,它负责管理飞船的大部分行为。
import game_functions as gf	# 导入game_functions模块
from pygame.sprite import Group	#用于创建子弹编组
from alien import Alien		# 导入alien模块Alien类,控制每个外星人的行为

def run_game():
	# 初始化游戏并创建一个屏幕对象
	pygame.init()	#初始化背景设置,让Pygame能够正确地工作。
	ai_settings = Settings()	#创建Settings实例,并使用它来访问设置
	screen = pygame.display.set_mode((ai_settings.screen_width, ai_settings.screen_height))	#调用pygame.display.set_mode()来创建一个窗口,实参是一个元祖,指定游戏窗口尺寸。
	pygame.display.set_caption("Alien Invasion")	#设置窗口的标题
	
	# 创建一艘飞船
	ship = Ship(ai_settings, screen)
	# 创建一个用于存储子弹的编组
	bullets = Group()
	# 创建一个外星人
	alien = Alien(ai_settings, screen)
	
	# 开始游戏的主循环
	while True:
		# 响应按键和鼠标事件
		gf.check_events(ai_settings, screen, ship, bullets)
		# 更新飞船的位置
		ship.update()
		
		# 更新子弹的位置,并删除已消失子弹
		gf.update_bullets(bullets)
		
		# 新屏幕上的图像,并切换到新屏幕
		gf.update_screen(ai_settings, screen, ship, alien, bullets)  
		
run_game()

在这里插入图片描述
3.创建一群外星人:需要确定一行可以容纳多少外星人(屏幕宽度减去两个外星人宽度alien_width得到可用宽度,因外星人之间间隔一个宽度,故可用宽度除以2个alien_width得到每行的外星人数量);外星人行数计算:屏幕高度减去飞船高度减去3个alien_height(1个上边缘间距,2个是飞船和外星人间隔距离)得到可用高度,故可用高度除以2个alien_height得到可容纳外星人行数。因Alien类继承了Sprite类,故也可创建外星人的编组。每创建一个外星人在计算属性rect值后添加至编组,对编组调用draw()时,Pygame自动绘制编组的每个元素,由元素的属性rect决定绘制位置。alien.draw(screen)表示在屏幕上绘制编组中的每个外星人。
game.functions.py 代码如下:

# -*- coding: GBK -*- 
import sys		# 使用模块sys来退出游戏。
import pygame
from bullet import Bullet
from alien import Alien		# 导入alien模块Alien类,控制每个外星人的行为

def check_keydown_events(event, ai_settings, screen, ship, bullets):
	'''响应按键'''
	if event.key == pygame.K_RIGHT:
		ship.moving_right = True
	elif event.key == pygame.K_LEFT:
		ship.moving_left = True
	elif event.key == pygame.K_SPACE:	# 空白键
		fire_bullet(ai_settings, screen, ship, bullets)
	elif event.key == pygame.K_q:	# 字母Q键
		sys.exit()

def fire_bullet(ai_settings, screen, ship, bullets):
	'''如果还没有到达限制,就发射一颗子弹'''
	# 创建一颗新子弹,并将其加入到编组bullets中
	if len(bullets) < ai_settings.bullets_allowed:	# 限制子弹数量
		new_bullet = Bullet(ai_settings, screen, ship)
		bullets.add(new_bullet)	

		
def check_keyup_events(event, ship):
	'''响应松开'''
	if event.key == pygame.K_RIGHT:
		ship.moving_right = False
	elif event.key == pygame.K_LEFT:
		ship.moving_left = False

def check_events(ai_settings, screen, ship, bullets):
	'''响应按键和鼠标事件'''
	# 监视键盘和鼠标事件
	for event in pygame.event.get():	#Pygame检测到的时间
		if event.type == pygame.QUIT:	#玩家单击窗口关闭按钮,则检测到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)

def update_screen(ai_settings, screen, ship, aliens, bullets):
	'''更新屏幕上的图像,并切换到新屏幕'''
	# 每次循环时都重绘屏幕
	screen.fill(ai_settings.bg_color)	#screen.fill()只接受一个实参:一种颜色
	# 在飞船和外星人后面重绘所有子弹
	for bullet in bullets.sprites():	#方法bullets.sprites()返回一个列表,其中包含编组bullets中的所有精灵
		bullet.draw_bullet()
	ship.blitme()	#在指定位置绘制飞船
	aliens.draw(screen)		#对编组调用draw(),Pygame自动绘制编组的每个元素,绘制的位置由元素的属性rect决定。此处在屏幕上绘制编组中每个外星人。
	
	# 让最近绘制的屏幕可见
	pygame.display.flip()	#不断更新屏幕,以显示元素的新位置	

def update_bullets(bullets):
	'''更新子弹的位置,并删除已消失子弹'''
	# 更新每一粒子弹的位置
	bullets.update()	#对编组调用update(),编组自动对其中每个精灵调用update(),即为每一粒子弹调用bullet.update()
	
	# 删除已消失子弹
	for bullet in bullets.copy():	# 遍历编组的副本
		if bullet.rect.bottom 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值