用python写游戏:《外星人入侵》给游戏添加记分功能

news2025/1/4 16:49:47

项目需求:

在游戏《外星人入侵》中,玩家控制着一艘最初出现在屏幕底部中央的飞船。玩家可以使用箭头键左右移动飞船,还可使用空格键进行射击。游戏开始时,一群外星人出现在天空中,他们在屏幕中向下移动。玩家的任务是射杀这些外星人。玩家将所有外星人都消灭干净后,将出现一群新的外星人,他们移动的速度。只要有外星人撞到了玩家的飞船或到达了屏幕底部,玩家就损失一艘飞船。玩家损失三艘飞船后,游戏结束。

文章目录

        • 闲 谈
        • 记 分:
          • 添加按钮
          • 提高等级
            • 重置速度
          • 记分
            • 显示得分
            • 创建记分牌
            • 在外星人被消灭时显示得分
            • 将消灭的每个外星人的点数都计入得分
            • 提高点数
            • 美化积分
            • 给游戏设置高分记录
            • 显示等级
            • 显示余下的飞船数量

往期博客
关于: 设置飞船的博客

关于:给飞船添加射击功能的博客

关于:设置外星人群的博客

关于:添加游戏结束功能的博客


闲 谈

今天是 2023.4.11,星期二.
用 python 写《外星人入侵》游戏的最后一章内容。

我们每个喜欢编程的人都是持续学习的人,每个人的学习方式都不一样,学习本身没有方法可言。
只是方式不同,我的学习方式是读书,然后搬运到博客里。发出去,
自己一直觉得,这样就代表学过了,有不明白的地方,搬运过去就想通了。
有遗忘的点,自己随手可查,因为都是亲手搬运,所以知道答案在哪。。

在文章里,我可能废话较多,这是我的难言之隐。因为这样,我就觉得自己还在理想的地方。


记 分:

现在我们需要给游戏添加一个按钮,一个用于开始游戏的按钮。
然后还需要修改这个游戏,因为需要随着玩家等级的提高来提高游戏节奏速度。
最后是一个记分系统,记录玩家游戏时所得分数。

添加按钮

为什么要添加按钮?
我们现在游戏的状态是只要启动程序,外星人群不会等玩家做好准备就开始入侵。
所以我们要添加一个启动游戏的按钮,当程序启动时,玩家点击按钮后,外星人群才可以开始移动。

通过这点,我们可以分析添加按钮的需求应该是:

按钮出现在游戏开始前,并在游戏结束后重新出现,因为玩家游戏失败后,可再次点击按钮重新开始游戏。而不是从新启动应用。

如何添加按钮?
先让游戏处于非活动状态,然后提示玩家点击按钮后开始游戏。

game_stats.py:

将 game_sactive 状态改为 未激活状态

		self.game_active = False

现在即便程序启动,游戏也会处于非活动状态。

等我们创建按钮后,玩家才可以开始游戏。

由于python没有内置创建按钮的方法,所以我们需要自己去创建一个Button类,用于创建带标签的实心矩形,也就是我们要创建的 play按钮。

有了Button类 之后,我们可以在游戏的任何地方创建按钮。

button.py:

"""pygame.font 用于将本文渲染到屏幕上"""
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)
		
				#None 参数用于指定使用什么字体来进行渲染。
				#None为pygame默认字体,48为字体字号
		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)

在屏幕上绘制按钮

现在我们可以开始通过 Button类来创建按钮了。
这个游戏只需要一个按钮,所以我们直接在

alien_invasion.py 中创建:

from button import Button

	#创建按钮
	play_button = Button(ai_settings,screen,"Play")

	# while 循环来控制游戏
	while True:
		gf.update_screen(ai_settings,screen,stats,ship,aliens,bullets,play_button)

将 按钮变量传递给更新绘制屏幕的方法是为了希望在屏幕更新时显示按钮。

下面是对 update_screen 方法的更改:

def update_screen(ai_settings,screen,ship,aliens,bullets,play_button):
		#每次循环时都重绘屏幕
		screen.fill(ai_settings.bg_color)
		#在飞船和外星人后面重绘所有子弹
		for bullet in bullets.sprites():
			bullet.draw_bullet()
		ship.blitme()
		aliens.draw(screen)
		
		#如果游戏处于非活动状态,就绘制play按钮
		if not stats.game_active:
			play_button.draw_button()
		
		#让最近绘制的屏幕可见
		pygame.display.flip()

现在我们运行游戏,看一下按钮添加后的效果。

在这里插入图片描述

为了让玩家点击按钮开始游戏,我们需要添加监视该按钮的鼠标事件:

game_functions.py:

#管理被隔离的监听循环事件	
def check_events(ai_settings,screen,stats,play_button,ship,bullets):
	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		

alien_invasion.py:

while True:
		gf.check_events(ai_settings,screen,stats,play_button,ship,bullets)

重置游戏

前面写的代码只处理了玩家第一次单击按钮的情况,而没有处理游戏结束的情况,
因为没有重置导致游戏结束的条件。

为了在玩家每次单击按钮时都重置游戏,需要重置统计信息,删除现有的外星人和子弹,创建一群新的外星人,并让飞船居中。

game_functions.py:

def check_play_button(ai_settings,screen,stats,play_button,ship,aliens,bullets,mouse_x,mouse_y):
	#在玩家单机play按钮时开始游戏
	if play_button.rect.collidepoint(mouse_x,mouse_y):
		stats.reset_stats()
		stats.game_active = True
		
		#清空外星人列表和子弹列表
		aliens.empty()
		bullets.empty()
		
		#创建一群新的外星人
		create_fleet(ai_settings,screen,ship,aliens)
		ship.center_ship()	

继续修改调用处:
game_functions.py:

#管理被隔离的监听循环事件	
def check_events(ai_settings,screen,stats,play_button,ship,aliens,bullets):
	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)
			

aliens.invasion.py:

# while 循环来控制游戏
	while True:
		gf.check_events(ai_settings,screen,stats,play_button,ship,aliens,bullets)

将 play 按钮切换到非活动状态

当前的 play 按钮存在一个问题,那就是即便按钮不可见,用户点击按钮的位置游戏依然会做出响应。

为了修复这个问题,我们可以让游戏尽在 game_active为False时才开始:
game_functions.py

def check_play_button(ai_settings,screen,stats,play_button,ship,aliens,bullets,mouse_x,mouse_y):
	button_clicked = play_button.rect.collidepoint(mouse_x,mouse_y)
	#在玩家单机play按钮时开始游戏
	if button_clicked and not stats.game_active:
		stats.reset_stats()
		stats.game_active = True
		
		#清空外星人列表和子弹列表
		aliens.empty()
		bullets.empty()
		
		#创建一群新的外星人
		create_fleet(ai_settings,screen,ship,aliens)
		ship.center_ship()			
			

隐藏光标

为让玩家在游戏时看不到光标。

game_functions.py:

def check_play_button(ai_settings,screen,stats,play_button,ship,aliens,bullets,mouse_x,mouse_y):

	if button_clicked and not stats.game_active:
		#隐藏光标
		pygame.mouse.set_visible(False)


def ship_hit(ai_settings,stats,screen,ship,aliens,bullets):
	else:
		stats.game_active = False
		pygame.mouse.set_visible(True)
提高等级

当前游戏里的外星人被玩家消灭后,玩家会提高一个等级,可游戏的难度并没有改变。
下面我们就着手去改动游戏的节奏。

修改速度设置

我们首先组织 aisettings类,
将游戏设置划分为静态和动态的两组。对于随着游戏进行而变化的设置,我们还确保它们在开始新游戏时被重置。

settings.py __ init __():

class Settings():
	#存储《外星人入侵》的所有设置的类
	
	def __init__(self):
		self.screen_width = 1200
		self.screen_height = 800
		self.bg_color = (230,230,230)
		
		self.bullet_speed_factor = 1
		self.bullet_width = 3
		self.bullet_height = 15
		self.bullet_color = 60,60,60
		self.bullets_allowed = 3
		#外星人设置
		self.fleet_drop_speed =10		
		#初始化岁游戏进行而变化的设置
		self.speedup_scale = 1.1
		self.initialize_dynamic_settings()
		
	def initialize_dynamic_settings(self):
		#飞船的设置
		self.ship_speed_factor = 1.5
		#飞船的生命值
		self.ship_limit = 3
		#外星人的设置
		self.alien_speed_factor = 1
		
		#fleet_direction为1表示向右移动,为-1表示向左移动
		self.fleet_direction =1
		
	def increase_speed(self):
		self.ship_speed_factor *= self.speedup_scale
		self.bullet_speed_factor *= self.speedup_scale
		self.alien_speed_factor *= self.speedup_scale
重置速度

我们刚才提高了游戏等级,但是没有重置速度,这样会导致什么问题呢?

玩家在第一次游戏时,游戏进度随着玩家操作的提升而提升,而当玩家失去所有飞船生命值重新开始游戏后,游戏的速度还是提升之后的速度,我们需要将速度重置一下,以便于在新游戏时,速度也是游戏开始时该有的初始速度。

game_functions.py:

def check_play_button(ai_settings,screen,stats,play_button,ship,aliens,bullets,mouse_x,mouse_y):
	button_clicked = play_button.rect.collidepoint(mouse_x,mouse_y)
	#在玩家单机play按钮时开始游戏
	if button_clicked and not stats.game_active:
		#重置游戏设置
		ai_settings.initialize_dynamic_settings()
		
		#隐藏光标
		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()
记分

下面我们来给游戏添加一个记分系统,以实时跟踪玩家的得分,并显示最高得分、当前等级和余下的飞船数。

得分是游戏的一项统计信息。
在GameStats中添加一个 score属性:

	def reset_stats(self):
		#初始化在游戏运行期间可能变化的统计信息
		self.ships_left = self.ai_settings.ship_limit
		self.score =0

我们将记分的属性写在 reset_stats()方法中是因为在每次开始游戏时都重置得分。

显示得分

如果想让得分显示在游戏中,我们还需要创建一个新类:Scoreboard。
目前这个类,我们只让其显示玩家得分。之后在考虑添加显示最高得分,等级,飞船余下的生命数值。

scoreboard.py:

import pygame.font

class Scoreboard():
	#显示得分信息的类
	def __init__(self,ai_settings,screen,stats):
		#初始化现实得分涉及的属性
		self.screen = screen
		self.screen_rect = screen.get_rect()
		self.ai_settings = ai_settings
		self.stats = stats
		
		#显示得分信息时使用的字体设置
		self.text_color = (30,30,30)
		self.font = pygame.font.SysFont(None,48)
		
		#准备初始得分图像
		self.prep_score()

	def prep_score(self):
		#将得分转换为一副渲染的图像
		score_str = str(self.stats.score)
		self.score_image = self.font.render(score_str,True,self.text_color,self.ai_settings.bg_color)
		
		#将得分放到屏幕上
		self.score_rect = self.score_image.get_rect()
		self.score_rect.right = self.screen_rect.right - 20
		self.score_rect.top = 20
	
	def show_score(self):
		#在屏幕上显示得分
		self.screen.blit(self.score_image,self.score_rect)
创建记分牌

为显示得分,我们在 alien_invasion,py中创建一个Scoreboard 实例:

from scoreboard import Scoreboard


	#创建存储游戏统计信息的实例,并创建记分牌
	#创建一个用于存储游戏统计信息的实例
	stats = GameStats(ai_settings)
	# 记分牌
	sb = Scoreboard(ai_settings,screen,stats)

# while 循环来控制游戏
	while True:
		gf.update_screen(ai_settings,screen,stats,sb,ship,aliens,bullets,play_button)

创建了记分牌的实例,又改动了 update_screen 的传递参数,所以在update_screen方法的定义处,我们也需要修改:

game_functions.py:

def update_screen(ai_settings,screen,stats,sb,ship,aliens,bullets,play_button):
		#每次循环时都重绘屏幕
		screen.fill(ai_settings.bg_color)
		#在飞船和外星人后面重绘所有子弹
		for bullet in bullets.sprites():
			bullet.draw_bullet()
		ship.blitme()
		aliens.draw(screen)
		
		#显示得分
		sb.show_score()
		
		#如果游戏处于非活动状态,就绘制play按钮
		if not stats.game_active:
			play_button.draw_button()
		
		#让最近绘制的屏幕可见
		pygame.display.flip()

来开一下 记分牌的设置效果:
在这里插入图片描述

在外星人被消灭时显示得分

现在我们已经成功把记分牌设置到游戏中了,下一步要做的就是实时计算得分,
每当有外星人被击中时,我们都更新stats.score 的值,再调用 prep_score更新得分图像。

但是在此之前,我们需要指定玩家每击落一个外星人都将得到多少个点:

settings.py:

def initialize_dynamic_settings(self):
	#记分
	self.alien_points  = 50

随着游戏的进行,我们将提高每个外星人值的点数。

为了确保每次开始新游戏时这个值都会被重置:

game_functions.py:

def check_bullet_alien_collisions(ai_settings,screen,stats,sb,ship,aliens,bullets):	
	#检查是否有子弹击中外星人,如果是,删除相应子弹和外星人。
	collisions = pygame.sprite.groupcollide(bullets,aliens,True,True)
	
	if len(aliens) ==0:
		bullets.empty()
		ai_settings.increase_speed()
		create_fleet(ai_settings,screen,ship,aliens)
	if collisions:
		stats.score +=ai_settings.alien_points
		sb.prep_score()

修改调用处:
game_functions.py:

def update_bullets(ai_settings,screen,stats,sb,ship,aliens,bullets):
	#更新子弹的位置,并删除已消失的子弹
	#更新子弹的位置
	bullets.update()
	
	#删除已消失的子弹
	for bullet in bullets.copy():
		if bullet.rect.bottom <= 0:
			bullets.remove(bullet)
			
	check_bullet_alien_collisions(ai_settings,screen,stats,sb,ship,aliens,bullets)

alien_invasion.py:

	while True:
		gf.update_bullets(ai_settings,screen,stats,sb,ship,aliens,bullets)

现在可以测试一下记分功能了。

在这里插入图片描述

将消灭的每个外星人的点数都计入得分

目前,如果有在同一次循环里的两颗子弹射中了外星人,或是因为子弹过宽射中了多多个外星人,玩家都只能得到击杀了一个外星人的分数值,为修复这种问题,我们来调整检测子弹和外星人的碰撞方式。

在方法check_bullet_alien_collisions()中,与外星人碰撞的子弹都是字典 collisions中的一个键;而与每颗子弹相关的值都是一个列表,其中包含该子弹撞到的外星人。我们遍历字典 collisions,确保将消灭的每个外星人的点数都记入得分:

game_functions.py:

def check_bullet_alien_collisions(ai_settings,screen,stats,sb,ship,aliens,bullets):	
	#检查是否有子弹击中外星人,如果是,删除相应子弹和外星人。
	collisions = pygame.sprite.groupcollide(bullets,aliens,True,True)
	
	if len(aliens) ==0:
		bullets.empty()
		ai_settings.increase_speed()
		create_fleet(ai_settings,screen,ship,aliens)
		
	if collisions:
		for aliens in collisions.values():
			stats.score += ai_settings.alien_points *len(aliens)
			sb.prep_score()
		stats.score +=ai_settings.alien_points
		sb.prep_score()
提高点数

在游戏中,玩家的等级会不对提高,游戏也会随之增加难度,因此处于较高的等级时,外星人的点数应更高。
settings.py:

	def __init__(self):
		#外星人点数的提高速度
		self.score_scale = 1.5
		
	def increase_speed(self):
		self.alien_points = int(self.alien_points * self.score_scale)
美化积分

在大多数街机风格游戏中,得分都显示为 10 的倍数,下面也让我们的得分系统遵循这个原则。

设置得分的格式,使用逗号表示千位分隔符。

scoreboard.py:

def prep_score(self):
		#将得分转换为一副渲染的图像
		score_str = str(self.stats.score)
		rounded_score = int(round(self.stats.score,-1))
		score_str = "{:,}".format(rounded_score)

为将得分进行美化,我们使用了 round 函数,该函数接收两个参数,它可以实现让小数精确到小数点后多少位。而实现小数位数也是由第二个参数实现的。如果将其置定为负数,该函数就会将其进行处理的参数圆整到 10、100、1000等整数倍。
round()总是返回一个小数值,所以我们使用int()让其转换为整数值。

现在我们来看一下游戏积分的美化效果:
在这里插入图片描述

给游戏设置高分记录

每个游戏都有类似最高得分的排行,现在我们来给《外星人入侵》添加一个最高分的榜单。

先将最高得分存储在 GameStats 中。
game_stats.py:

def __init__(self,ai_settings):
	self.high_score = 0

为了放置最高得分值进行重置,所以将其设置在 初始化方法当中。

设置好了存储最高得分的变量后,我们需要将其显示到屏幕当中,开始修改 scoreboard.py:

修改 __ init __()方法:

def __init__(self,ai_settings,screen,stats):
	self.prep_high_score()

#为将最高得分显示在屏幕上而定义的新方法
def prep_high_score(self):
		#将最高得分转换为渲染的图像
		high_score = int(round(self.stats.high_score,-1))
		high_score_str = "{:,}".format(high_score)
		
		self.high_score_image = self.font.render(high_score_str,True,self.text_color,self.ai_settings.bg_color)
		
		#将最高得分显示在屏幕顶部
		self.high_score_rect = self.high_score_image.get_rect()
		self.high_score_rect.centerx = self.screen_rect.centerx
		self.high_score_rect.top = self.score_rect.top

我们来运行游戏,来看一下最高得分设置效果:
在这里插入图片描述

接着,为了检查是否诞生了新的最高分,
在game_functions.py 中添加一个新函数checck_high_score():

def check_high_score(stats,sb):
	#检查是否诞生了新的最高分
	if stats.score > stats.high_score:
		stats.high_score = stats.score
		sb.prep_high_score()

函数 check_high_score() 包含两个参数:
stats 和 sb ,它使用 stats 来比较当前得分和最高得分。并在必要使用使用sb来修改最高得分图像。

在 函数 check_bulleet_alien_collisions()中,每当有外星人被消灭,
都需要在更新得分后调用 check_high_score():

def check_bullet_alien_collisions(ai_settings,screen,stats,sb,ship,aliens,bullets):
	check_high_score(stats,sb)

现在我们来看一下设置最高分记录的效果:
在这里插入图片描述

显示等级

为了能够在游戏中显示玩家的等级,我们现在 GameStats中添加一个表示当前等级的属性。

def reset_stats(self):
	self.level = 1

为了在每次开始新游戏时初始化等级,我们将其定义在 rest_stats 函数中。
因为该函数的调用处就是 init 方法中。

为了让 Scoreboard 能够在当前得分下方显示当前等级,我们在 init方法中调用一个新方法:

scoreboard.py:

def __init__(self,ai_settings,screen,stats):
	self.prep_level()

新调用方法定义如下:

	def prep_level(self):
		#将等级转换为渲染的图像
		self.level_image = self.font.render(str(self.stats.level),True,self.text_color,self.ai_settings.bg_color)
		
		#将等级放在得分下方
		self.level_rect = self.level_image.get_rect()
		self.level_rect.right = self.score_rect.right
		self.level_rect.top = self.score_rect.bottom +10

在这里我们让 prep_level 创建一幅图像,并将其 reght 属性设置为得分的right属性。然后top属性设置为比得分图像的bottom属性大10像素,以便得分和等级之间留出一定的空间。

为了让其显示到屏幕上,我们还需要更新一下 show_score() 方法

def show_score(self):
		#在屏幕上显示得分
		self.screen.blit(self.score_image,self.score_rect)
		self.screen.blit(self.high_score_image,self.high_score_rect)
		self.screen.blit(self.level_image,self.level_rect)

我们来看一下等级是否能成功显示到屏幕当中:
在这里插入图片描述

现在虽然成功将等级显示到游戏屏幕中了,可是编辑提高等级的逻辑。

提高等级逻辑如下:

game_functions.py:

def check_bullet_alien_collisions(ai_settings,screen,stats,sb,ship,aliens,bullets):	
	#检查是否有子弹击中外星人,如果是,删除相应子弹和外星人。
	collisions = pygame.sprite.groupcollide(bullets,aliens,True,True)
	
	if len(aliens) ==0:
		bullets.empty()
		ai_settings.increase_speed()
		create_fleet(ai_settings,screen,ship,aliens)
		
		stats.level += 1
		sb.prep_level()

如果一整群的外星人都被成功消灭之后,我们就将 stats.level 的值加1,并调用 prep_level() ,以确保正确地显示新等级。

为了确保点击 play 按钮再次开始游戏时 记分和等级图像能够重置:

game_functions.py

def check_play_button(ai_settings,screen,stats,sb,play_button,ship,aliens,bullets,mouse_x,mouse_y):
		#在玩家单机play按钮时开始游戏
	if button_clicked and not stats.game_active:
		#重置游戏设置
		ai_settings.initialize_dynamic_settings()
		
		#隐藏光标
		pygame.mouse.set_visible(False)
		stats.reset_stats()
		stats.game_active = True
		
		#重置记分牌图像
		sb.prep_score()
		sb.prep_high_score()
		sb.prep_level()

修改调用处:

def check_events(ai_settings,screen,stats,sb,play_button,ship,aliens,bullets):
	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,sb,play_button,ship,aliens,bullets,mouse_x,mouse_y)
		
			

修改 check_events() 的调用处:
alien_invasion.py:

while True:
		gf.check_events(ai_settings,screen,stats,sb,play_button,ship,aliens,bullets)

测试:
在这里插入图片描述

显示余下的飞船数量

这是《外星人入侵》小项目的最后一个功能点。
显示玩家剩余飞船的数量使用图像而不是数字。为此,我们在屏幕左上角绘制飞船图像来指出还余下多少艘飞船。

让 ship 基础 Sprite ,以便能够创建飞船编组:
ship.py:

from pygame.sprite import Sprite

class Ship(Sprite):
		def __init__(self,ai_settings,screen):
		super(Ship,self).__init__()

修改 Scoreboard,在其中创建一个可供显示的飞船编组。

from pygame.sprite import Group
from ship import Ship

def __init__(self,ai_settings,screen,stats):
	self.prep_ships()

prep_ships 定义如下:

scoreboard.py:

	def prep_ships(self):
		#显示还余下多少艘飞船
		self.ships = Group()
		for ship_number in range(self.stats.ships_left):
			ship = Ship(self.ai_settings,self.screen)
			ship.rect.x = 10 +ship_number * ship.rect.width
			ship.rect.y = 10
			self.ships.add(ship)

将飞船绘制到屏幕上:
scoreboard.py:

	def show_score(self):
		#在屏幕上显示得分
		self.screen.blit(self.score_image,self.score_rect)
		self.screen.blit(self.high_score_image,self.high_score_rect)
		self.screen.blit(self.level_image,self.level_rect)
		self.screen.draw(self.screen)
		

为让玩家知晓游戏开始时自己拥有多少生命值,
在 game_functions.py 的 check_play_button() 中进行调用:

sb.prep_ships()

然后在将玩家控制的飞船与外星人碰撞后的显示进行更新:
game_functions.py:

def update_aliens(ai_settings,screen,stats,sb,ship,aliens,bullets):
	#检查是否有外星人位于屏幕边缘,并更新整群外星人的位置
	check_fleet_edges(ai_settings,aliens)
	
	#更新外新人群中所有外星人的位置
	aliens.update()
	
	
	if pygame.sprite.spritecollideany(ship,aliens):
		#print("Ship hit!!!")
		ship_hit(ai_settings,screen,stats,sb,ship,aliens,bullets)
	
	check_aliens_bottom(ai_settings,screen,stats,sb,ship,aliens,bullets)

def ship_hit(ai_settings,screen,stats,sb,ship,aliens,bullets):
	if stats.ships_left > 0:
		#响应外星人撞到的飞船
		stats.ships_left -= 1
	
		sb.prep_ships()
		
		#清空外星人列表和子弹列表
		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)

更新调用处:
game_functions.py

def check_aliens_bottom(ai_settings,screen,stats,sb,ship,aliens,bullets):
	#检查是否有外星人到达底部
	screen_rect = screen.get_rect()
	
	for alien in aliens.sprites():
		if alien.rect.bottom >= ship.rect.bottom:
			ship_hit(ai_settings,screen,stats,sb,ship,aliens,bullets)
			break

alien_invasion.py:

# while 循环来控制游戏
	while True:
		gf.check_events(ai_settings,screen,stats,sb,play_button,ship,aliens,bullets)
		if stats.game_active:
			ship.update()
			gf.update_bullets(ai_settings,screen,stats,sb,ship,aliens,bullets)
			gf.update_aliens(ai_settings,screen,stats,sb,ship,aliens,bullets)
		
		bullets.update()
		gf.update_screen(ai_settings,screen,stats,sb,ship,aliens,bullets,play_button)

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/454814.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

骨传导耳机的原理是什么,推荐几款热门的骨传导耳机

骨传导耳机的出现&#xff0c;彻底改变了传统耳机的音质、佩戴方式、听音体验&#xff0c;让我们能在享受音乐的同时&#xff0c;还能听到外界环境的声音&#xff0c;在开车、骑行、跑步时佩戴也非常安全。骨传导耳机作为新兴产品&#xff0c;已经进入了快速发展的阶段。今天我…

nodejs+vue 文旅旅游公司智能管理OA系统

通过本次设计&#xff0c;让我学到了更多的知识&#xff0c;而且在设计中会有一些问题出现&#xff0c;最后通过查阅资料和在老师和同学的帮助下完成了系统的设计和开发&#xff0c;使得这次系统的开发非常的有意义。同时通过这次系统的设计也让我明白了自己在哪方面有不足&…

把ChatGPT训练成你的得力助手

在调教chatgpt时&#xff0c;我们大部分的时候都需要一个好的学术翻译官&#xff0c;但是在他成为学术翻译官之前我们有很多规定要说明&#xff0c;比如不用回答我的问题&#xff0c;不用计算公式等。我将以下命令要求集成&#xff0c;在使用的时候只需要你发给它这段话&#x…

FL Studio有中文版吗?如何下载最新V21版本

FL Studio是一款功能强大的数字音频工作站&#xff08;DAW&#xff09;&#xff0c;它广泛应用于音乐创作和音乐制作领域。在使用FL Studio时本文将详细探讨FL Studio的功能特点的重要性。 一、FL Studio是什么软件 FL Studio是由比利时软件公司Image-Line开发的音…

电脑系统错误怎么办?您可以看看这5个方法!

案例&#xff1a;电脑出现系统错误该如何解决&#xff1f; 【这几天长时间使用我的电脑&#xff0c;导致它的系统出现了错误。有没有小伙伴知道如何解决电脑系统出错的问题&#xff1f;求一个能快速解决的方法。】 电脑系统出现错误是使用电脑时难免会遇到的问题之一&#xf…

性能测试(LoadRunner)

文章目录 1. 性能测试概述2. 常见的性能指标3. 性能测试的分类4. loadRunner 工具的介绍5. 使用 VUG4.1 打开 LR 自带的 web 系统4.2 编写性能测试脚本 6. 性能测试脚本的增强6.1 事务&#xff08;lr_start/end_transaction&#xff09;6.2 集合点&#xff08;lr_rendzvous&…

SpringCloudAlibaba服务注册与配置中心——Nacos

Nacos 本专栏学习内容来自尚硅谷周阳老师的视频 有兴趣的小伙伴可以点击视频地址观看 简介 Nacos是阿里巴巴推出的服务注册和配置中心。等价于EurekaConfigBus&#xff0c;可以替代Eureka做服务注册中心&#xff0c;替代Config做服务配置中心。官方文档 安装 关于Nacos的安装…

HBase进阶——文件的合并、 MemStore Flush、StoreFile Compaction、 Region Split、高可用与预分区介绍

系列文章目录 centos7虚拟机下hbase的使用案例讲解 hbase进阶操作——读流程与写流程介绍 centos7虚拟机在集群zookeeper上面配置hbase的具体操作步骤 文章目录 系列文章目录 一、HBase的架构原理 1、StoreFile 2、MemStore 3、WAL 二、HBase的shell操作 2.1、创建表…

pytest使用 一(安装、简单的测试用例、运行)

Pytest框架 — 1.Pytest测试框架介绍 - 知乎 2023最新pytest接口自动化测试框架&#xff0c;三天带你精通pytest&#xff0c;带你写出最好的代码&#xff01;&#xff08;已更新2023新版&#xff09;_哔哩哔哩_bilibili 一、pytest安装 pip3 install pytest # 查看pytest版本…

前端学习--Ajax(1) get/post

一、客户端和服务器 上网的目的&#xff1a;借助互联网获取和消费资源 1.1 服务器 负责存放和对外提供资源的计算机 1.2 客户端 负责获取和消费资源的计算机 二、URL地址 2.1 概念 Uniform Resource Locator 中文叫统一资源定位符&#xff0c;标识互联网上每一个资源的存…

(3)相关概念和索引的CURD

核心概念 https://www.elastic.co/guide/en/elasticsearch/reference/7.10/index.html 什么是搜索引擎&#xff1f; 全文搜索引擎 自然语言处理&#xff08;NLP&#xff09;、爬虫、网页处理、大数据处理。如谷歌、百度、搜狗、必应等等。 垂直搜索引擎 有明确搜索目的的…

脉诊在现代医学中的应用与局限性

目录 一、脉诊在疾病诊断中的作用及局限性 二、现代脉诊仪的可靠性 三、中医在现代医学中的地位 四、中西医结合的发展趋势 结论 一、脉诊在疾病诊断中的作用及局限性 脉诊作为中医诊断的重要方法之一&#xff0c;通过检测脉搏波的特征来了解患者的身体状况&#xff0c;进…

学习笔记:《Foundation models for generalist medical artificial intelligence》

目录 一、GMAI模型的概念与优势 二、GMAI模型面临的挑战 1.验证 2.社会偏见 3.隐私 4.规模 5.技术挑战 三、结论&#xff1a; 参考文献 最近在《Nature》杂志上发表的一篇名为《Foundation models for generalist medical artificial intelligence》的文章&#xff0c…

品牌如何借助江湖老大“音乐记忆”做宣传?

去年有个卖咖啡的小姐姐火了&#xff0c;“咖啡你冲不冲&#xff0c;冲冲冲冲冲”节奏分明、及其洗脑&#xff0c;引发众多网友模仿和音频采用。 其实这种借用音乐记忆扩大品牌知名度和传播范围的品宣手段十分常见&#xff0c;仔细回想一下&#xff0c;我们平时听到较为魔性的…

05-Node.js—http模块

目录 1、HTTP 协议1.1 概念1.2 请求报文的组成1.3 HTTP 的请求行1.4 HTTP 请求头1.5 HTTP 的请求体1.6 响应报文的组成 2、创建 HTTP 服务2.1 操作步骤2.2 测试2.3 注意事项 3、获取 HTTP 请求报文3.1 请求方法 request.method3.2 请求版本 request.httpVersion3.3 请求路径 re…

基本绘图函数

基本绘图函数 cv2.line()函数------用于绘制直线. 算子解释&#xff1a; cv2.line(img1, (20, 80), (120, 80), (0, 255, 255))cv2.line(img, pt1, pt2, color, thicknessNone, lineTypeNone, shiftNone) img&#xff1a;背景图。 pt1&#xff1a;直线起点坐标。 pt2&#x…

实战详解docker安装步骤——Linux操作系统(CentOS7.9)下安装容器技术docker引擎

一、安装docker依赖环境 yum install -y yum-utils device-mapper-persistent-data lvm2二、配置国内docker-ce的yum源 &#xff08;这里采用的是阿里云镜像配置文件&#xff09; yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-c…

基于java Springboot+Vue+shiro前后端分离疫情防疫管理系统设计和实现2.0

基于java SpringbootVueshiro前后端分离疫情防疫管理系统设计和实现2.0 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获…

老板们搞怪营业,品牌好感度upup真有梗

老板下场营业最经典的莫过于“老乡鸡”了。在手撕联名信事件出圈后&#xff0c;老乡鸡围绕束从轩创始人IP&#xff0c;开展了一系列社交传播宣传&#xff0c;比如“咯咯哒糊弄学”等。 50多岁的老乡鸡董事长束从轩&#xff0c;一改传统企业家严肃正经的形象&#xff0c;跟着老乡…

Pytorch深度学习笔记(九)加载数据集

目录 1.名词解释 2. 数据集加载器Dataloader 3.完整代码 推荐课程&#xff1a;08.加载数据集_哔哩哔哩_bilibili 1.名词解释 名词解释&#xff1a;Epoch&#xff0c;Batch&#xff0c;Batch-Size&#xff0c;Iterations Epoch&#xff08;周期&#xff09;&#xff1a;指所…