ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

14.计分_1(添加Play按钮)

2021-04-27 15:59:44  阅读:218  来源: 互联网

标签:Play 14 settings ai screen 计分 bullets ship self


1.添加Play按钮:Play按钮在开始游戏前出现,结束游戏后再次出现。需要使游戏一开始处于非活动状态,在game_stats.py中修改game_active为False。
新建button模块,创建Button类,用于创建带标签的实心矩形。该模块导入了pygame.font模块将文本渲染到屏幕上,Button类中pygame.font.SysFont()可指定文本的字体和字号,font.render()方法可以使文本渲染成图像,该方法传递四个实参:字符串文本信息,布尔实参,文本颜色和背景色。布尔实参指定开启或关闭反锯齿功能(反锯齿让文本的边缘更光滑),若不指定背景颜色,Pygame将以透明背景的方式渲染文本。screen.fill()绘制按钮矩形,screen.blit()绘制文本图像。
game.functions模块中新建函数start_game()和check_play_button(),并修改了check_keydown_events()、check_events()、update_screen()和ship_hit()。上述修改是为了实现Play按钮显示在屏幕上,游戏未开始时鼠标点击Play按钮或者按下P键可以开始游戏,并重置游戏。游戏结束后Play按钮重新出现。游戏为活跃状态时隐藏光标。
alien_invasion模块创建Button实例,并增加check_events()和update_screen()的实参。
game_stats.py 代码如下:

# -*- coding: GBK -*- 
class GameStats():
	'''跟踪游戏的统计信息'''
	
	def __init__(self, ai_settings):
		'''初始化统计信息'''
		self.ai_settings = ai_settings
		self.reset_stats()
		
		# 让游戏一开始处于非活动状态
		self.game_active = False
		
	def reset_stats(self):
		'''初始化在游戏运行期间可能变化的统计信息'''
		self.ship_left = self.ai_settings.ship_limit

button.py 代码如下:

# -*- coding: GBK -*- 
import pygame.font	#用于将文本渲染到屏幕上

class Button():
	
	def __init__(self, ai_settings, screen, msg):
		'''初始化按钮的属性'''
		self.screen = screen
		self.screen_rect = self.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)	#选择字体渲染文本,实参None表示使用默认字体,后一个实参表示字号
		
		# 创建按钮的rect对象,并使其居中
		self.rect = pygame.Rect(0, 0, self.width, self.height)
		self.rect.center = self.screen_rect.center
		
		# 按钮的标签只需创建一次
		self.prep_msg(msg)		#调用prep_msg()方法使字符串信息渲染为图像
		
	def prep_msg(self, msg):
		'''将msg渲染为图像,并使其在按钮上居中'''
		self.msg_image = self.font.render(msg, True, self.text_color, 
			self.button_color)	#调用font.render()将msg中的文本转换为图像,布尔实参指定开启或关闭反锯齿功能(反锯齿让文本的边缘更平滑),后两个实参分别为文本颜色和背景色
		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)	#screen.fill()绘制按钮
		self.screen.blit(self.msg_image, self.msg_image_rect)	#绘制文本图像

game_functions.py 代码如下:

# -*- coding: GBK -*- 
import sys		# 使用模块sys来退出游戏。
import pygame
from bullet import Bullet
from alien import Alien		# 导入alien模块Alien类,控制每个外星人的行为
from time import sleep		# sleep()函数可用来让游戏暂停

def check_keydown_events(event, ai_settings, screen, stats, ship, aliens, 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()
	elif event.key == pygame.K_p:	# 游戏处于非活跃状态时按P键可以开始游戏
		if not stats.game_active:
			start_game(ai_settings, screen, stats, ship, aliens, bullets)

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, stats, play_button, ship, aliens, 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, stats, ship, aliens, bullets)
		elif event.type == pygame.KEYUP:		#根据松开键修改移动标志的值
			check_keyup_events(event, ship)
		elif event.type == pygame.MOUSEBUTTONDOWN:
			mouse_x, mouse_y = pygame.mouse.get_pos()	#get_pos()返回一个元祖,包含点击时鼠标的x和y坐标
			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)	#cllidepoint()检查鼠标单击位置是否在Play按钮的rect内
	if button_clicked and not stats.game_active:		#仅在游戏非活跃状态时点击Play按钮区域才可以重新开始游戏,防止游戏时误点Play按钮区域导致重新开始
		start_game(ai_settings, screen, stats, ship, aliens, bullets)


def start_game(ai_settings, screen, stats, ship, aliens, bullets):
	'''在按Q键或者鼠标点击Play按钮时开始游戏'''
	# 隐藏光标
	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()	

def update_screen(ai_settings, screen, stats, ship, aliens, bullets, play_button):
	'''更新屏幕上的图像,并切换到新屏幕'''
	# 每次循环时都重绘屏幕
	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决定。此处在屏幕上绘制编组中每个外星人。
	
	#如果游戏处于非活跃状态,就绘制Play按钮
	if not stats.game_active:
		play_button.draw_button()
	
	# 让最近绘制的屏幕可见
	pygame.display.flip()	#不断更新屏幕,以显示元素的新位置	

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

def check_bullet_alien_collisions(ai_settings, screen, ship, aliens, bullets):
	'''响应子弹和外星人的碰撞'''
	# 删除发生碰撞的子弹和外星人	
	collisions = pygame.sprite.groupcollide(bullets, aliens, True, True)	#每当子弹和外星人的rect重叠时,Pygame删除发生碰撞的子弹和外星人
	
	if len(aliens) == 0:
		# 若外星人群被消灭干净,删除现有的子弹并新建一群外星人
		bullets.empty()		#方法empty()可删除编组中剩余所有精灵
		create_fleet(ai_settings, screen, ship, aliens)

def get_number_aliens_x(ai_settings, alien_width):
	'''计算每行可容纳多少个外星人'''
	available_space_x = ai_settings.screen_width - 2 * alien_width	#计算放置外星人的空间
	number_aliens_x = int(available_space_x / (2 * alien_width))	#计算放置外星人数量,确保为整数
	return number_aliens_x

def get_number_rows(ai_settings, ship_height, alien_height):
	available_space_y = (ai_settings.screen_height - 
							(3 * alien_height) - ship_height)	#此处减去的2个alien_height是为了在飞船与外星人之间间隔一定空白,给玩家留出射杀外星人的时间
	number_rows = int(available_space_y / (2 * alien_height))
	return number_rows

def create_alien(ai_settings, screen, aliens, alien_number, row_number):
	'''创建一个外星人并将其放在当前行'''
	# 外星人间距为外星人宽度
	alien = Alien(ai_settings, screen)
	alien_width = alien.rect.width
	alien.x = alien_width + 2 * alien_width * alien_number	#确定生成外星人的x坐标
	alien.rect.x = alien.x
	alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number	#确定生成外星人的y坐标
	aliens.add(alien)	#将生成的外星人添加至编组	

def create_fleet(ai_settings, screen, ship, aliens):
	'''创建外星人群'''
	# 创建一个外星人,并计算一行可容纳多少个外星人	
	alien = Alien(ai_settings, screen)
	number_aliens_x = get_number_aliens_x(ai_settings, alien.rect.width)
	number_rows = get_number_rows(ai_settings, ship.rect.height, alien.rect.height)

	#创建外星人群
	for row_number in range(number_rows):
		for alien_number in range(number_aliens_x):		#此处alien_number从0开始数起,range()也需要整数
			create_alien(ai_settings, screen, aliens, alien_number, row_number)		

def check_fleet_edges(ai_settings, aliens):
	'''外星人到达边缘时采取相应的措施'''
	for alien in aliens.sprites():
		if alien.check_edges():
			change_fleet_direction(ai_settings, aliens)
			break

def change_fleet_direction(ai_settings, aliens):
	'''将整群外星人下移,并改变他们的方向'''
	for alien in aliens.sprites():
		alien.rect.y += ai_settings.fleet_drop_speed
	ai_settings.fleet_direction *= -1

def ship_hit(ai_settings, stats, screen, ship, aliens, bullets):
	'''响应被外星人撞到的飞船'''
	if stats.ship_left > 0:
		# 讲ships_left减1
		stats.ship_left -= 1

		# 清空外星人列表和子弹列表
		aliens.empty()
		bullets.empty()

		# 创建一群新的外星人,并将飞船放到屏幕底部中央
		create_fleet(ai_settings, screen, ship, aliens)
		ship.center_ship()

		# 暂停
		sleep(0.5)
	else:
		stats.game_active = False
		pygame.mouse.set_visible(True)	# 游戏不活跃状态后会显示Play按钮,并显示光标

def check_aliens_bottom(ai_settings, stats, screen, ship, aliens, bullets):
	'''检查是否有外星人到达了屏幕底端'''
	screen_rect = screen.get_rect()
	for alien in aliens.sprites():
		if alien.rect.bottom >= screen_rect.bottom:
			# 像飞船被撞到一样进行处理
			ship_hit(ai_settings, stats, screen, ship, aliens, bullets)
			break

def update_aliens(ai_settings, stats, screen, ship, aliens, bullets):
	'''检查是否有外星人位于屏幕边缘,并更新整群外星人的位置'''
	check_fleet_edges(ai_settings, aliens)
	aliens.update()		#对编组调用update(),自动对每个外星人调用方法update()
	
	# 检测外星人和飞船之间的碰撞
	if pygame.sprite.spritecollideany(ship, aliens):	#接受两个实参,检查编组是否有成员与精灵发生了碰撞,若有停止遍历编组,返回发生碰撞的那个外星人,否则返回None
		ship_hit(ai_settings, stats, screen, ship, aliens, bullets)
	
	# 检查是否有外星人到达屏幕底端
	check_aliens_bottom(ai_settings, stats, screen, ship, aliens, 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 game_stats import GameStats	#导入跟踪游戏统计信息的类GameStats
from button import Button	#导入Button类,用于创建带标签的实心矩形

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")	#设置窗口的标题
	
	
	# 创建Play按钮,创建Button实例
	play_button = Button(ai_settings, screen, "Play")
	
	# 创建一个用于存储游戏统计信息的实例
	stats = GameStats(ai_settings)
	
	# 创建一艘飞船
	ship = Ship(ai_settings, screen)
	# 创建一个用于存储子弹的编组
	bullets = Group()
	# 创建一个外星人编组
	aliens = Group()
	
	# 创建外星人群
	gf.create_fleet(ai_settings, screen, ship, aliens)
	
	# 开始游戏的主循环
	while True:
		# 响应按键和鼠标事件
		gf.check_events(ai_settings, screen, stats, play_button, ship, aliens, 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()

在这里插入图片描述

标签:Play,14,settings,ai,screen,计分,bullets,ship,self
来源: https://blog.csdn.net/MUJINGXI_LH/article/details/116164950

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有