Python编程从入门到实践 12-3 火箭

12-3 火箭:编写一个游戏,开始屏幕中央有一个火箭,而玩家可使用四个方向键上下左右移动火箭。请务必确保火箭不会移动到屏幕外面。

过程:首先创建一个文件夹命名为rocket,以便将所有文件集中,便于运行时系统找到对应的文件。在文件夹里创建一个新的文件夹images便于存放火箭的图片,在网上百度一下火箭的照片,保存下来改成为bmp格式(具体方法百度,或自己摸索)。

创建主文件crazy_rocket.py,确保放在刚才创建的rocket文件夹中,代码如下

#文件名字为crazy_rocket.py
"""第一步导入sys和pygame模块"""
import sys# 模块提供了许多函数和变量来处理 Python 运行时环境的不同部分.
import pygame#pygame包含游戏开发所需要的功能
from c_r_settings import Settings#从模块中导入Settings类
from rocket import Rocket#导入对象Rocket
import cr_game_functions as gf#使用as给模块指定别名,节省打字时间
def run_game():#游戏运行时的总函数
	pygame.init()#初始化游戏并创建一个屏幕对象
	cr_settings = Settings()#创建设置类 
	screen = pygame.display.set_mode((cr_settings.screen_width,cr_settings.screen_height))#设置屏幕分辨率
	pygame.display.set_caption("Crazy Rocket")#设置标题栏名称
	crazy_rocket = Rocket(cr_settings,screen)#创建一架火箭
	#开始游戏主循环
	while True:
		gf.check_events(crazy_rocket)#检测键盘和鼠标的响应事件
		crazy_rocket.update()#根据移动标志调整火箭的位置
		gf.update_screen(cr_settings,screen,crazy_rocket)#更新屏幕上的图像,并切换到新屏幕
run_game()#调用run_game函数来运行游戏

文件设置的模块,在rocket文件夹里创建一名称为c_r_settings.py的文件代码如下

#文件名字为c_r_settings
'''创建设置类'''
class Settings():
	def __init__(self):#方法__init__()特殊方法,每个与类相关的方法的调用都自动传入实参self,它是一个指向实例本身的引用
		self.screen_width = 800#屏幕宽度
		self.screen_height = 600#屏幕高度
		#因为我的屏幕分辨率较低仅为720p即1280*720,所以将游戏窗口设置为800*600
		self.bg_color=(222,222,222)#RGB(Red Green Blue)每种色的取值范围为0-255,通过组合不同的值最多可创建256*256*256=16777216中颜色
		self.rocket_speed_factor = 1.5#火箭的移动距离1.5像素

 

游戏功能实现的函数模块,在rocket文件夹里创建一名称为cr_game_functions.py的文件

#文件名称为cr_game_functions.py
import sys#导入sys模块 
import pygame#导入pygame模块 
def check_events(crazy_rocket):#定义监控响应按键和鼠标事件的函数
	"""响应按键和鼠标事件"""
	for event in pygame.event.get():#从队列里获取事件,即键盘响应中是按顺序的响应的属于队列
		if event.type == pygame.QUIT:#如果事件的类型为
			print("Quit")
			sys.exit()
		elif event.type == pygame.KEYDOWN:#如果事件的类型为键盘被按下去
			check_keydown_events(event,crazy_rocket)#调用键盘被按下的函数
		elif event.type == pygame.KEYUP:#如果事件的类型为键盘没被按下
			check_keyup_events(event,crazy_rocket)#调用键盘没被按下的函数
def check_keydown_events(event,crazy_rocket):#键盘被按下的函数
	if event.key == pygame.K_RIGHT:#如果按键为右方向键
		crazy_rocket.moving_right = True#将标志设置为真,即True
	elif event.key == pygame.K_LEFT:#如果按键为左方向键
		crazy_rocket.moving_left = True#将标志设置为真,即True
	elif event.key == pygame.K_UP:#原理同上
		crazy_rocket.moving_up = True
	elif event.key ==pygame.K_DOWN:#原理同上
		crazy_rocket.moving_down = True
def check_keyup_events(event,crazy_rocket):#键盘没被按下的函数
	if event.key == pygame.K_RIGHT:#如果按键为右方向键
		crazy_rocket.moving_right = False#将标志设置为假,即False
	elif event.key == pygame.K_LEFT:#原理同上
		crazy_rocket.moving_left = False
	elif event.key == pygame.K_UP:#原理同上
		crazy_rocket.moving_up = False
	elif event.key == pygame.K_DOWN:#原理同上
		crazy_rocket.moving_down = False
def update_screen(cr_settings,screen,crazy_rocket):#更新屏幕上的图像,并切换到新屏幕
	screen.fill(cr_settings.bg_color)#每次循环都重绘屏幕(此处背景颜色填充)
	crazy_rocket.blitme()#在指定的位置绘制火箭
	pygame.display.flip()#更新整个待显示的Surface对象到屏幕上

 

被控制的游戏对象类模块,包含很多属性,在rocket文件夹里创建一个名称为rocket.py的文件

#文件名称为rocket.py
#创建rocket类
import pygame
class Rocket():
	def __init__(self,cr_settings,screen):
		self.screen = screen
		self.image = pygame.image.load('images/rocket.bmp')#加载飞船图像
		self.rect = self.image.get_rect()#获取外接矩形
		self.screen_rect = screen.get_rect()#窗口矩形化
		self.cr_settings = cr_settings
		self.rect.centerx = self.screen_rect.centerx#使对象横坐标居中
		#self.rect.bottom = self.screen_rect.bottom#使对象靠近底边,同理left,top,right
		self.rect.centery = self.screen_rect.centery#使对象的纵坐标居中
		self.center = float(self.rect.centerx)#横坐标存储小数的变量,因为rect只存储整数部分,因此用float()处理下
		self.centery = float(self.rect.centery)#原理同上,只是纵坐标而已
		self.moving_right = False#标志初始时为假
		self.moving_left = False
		self.moving_up = False
		self.moving_down = False
	def blitme(self):#在指定位置画火箭
		self.screen.blit(self.image,self.rect)#传入参数为图像,对应图像所在的矩形
	def update(self):#根据移动标志调整火箭的位置
		if self.moving_right and self.rect.right <self.screen_rect.right:#如果条件为真且满足不离开边界的条件
			self.center += self.cr_settings.rocket_speed_factor#横坐标右移动self.cr_settings.rocket_speed_factor个像素
		if self.moving_left and self.rect.left > 0:#原理同上,边界条件为横坐标大于0
			self.center -= self.cr_settings.rocket_speed_factor
		if self.moving_up and self.rect.top >0:#原理同上,边界条件为纵坐标大于0。最上边的边界纵坐标值为0,最下边的纵坐标为最大值。(很奇怪的坐标系)
			self.centery -= self.cr_settings.rocket_speed_factor
		if self.moving_down and self.rect.bottom <self.screen_rect.bottom:#原理同上,边界条件为纵坐标值<底边的纵坐标
			self.centery += self.cr_settings.rocket_speed_factor
		self.rect.centerx = self.center#横坐标赋值
		self.rect.centery = self.centery#纵坐标赋值

运行即可满足题目条件 。

————————————————————————————————————————————————————

在调试代码时,有一疑问想问问大家,如能解答,万分感谢。————————————————————————

#出现错误:当移动到边界操作对象就不能动了,且开始移动时只有两个键可用(四个键的任意一个)
def check_keydown_events(event,crazy_rocket):
	if event.key == pygame.K_RIGHT:
		crazy_rocket.moving_right = True
	elif event.key == pygame.K_LEFT:
		crazy_rocket.moving_left = True
	elif event.key == pygame.K_UP:
		crazy_rocket.moving_up = True
	elif event.key == pygame.K_DOWN:
		crazy_rocket.moving_down = True
def check_keyup_events(event,crazy_rocket):
	if event.key == pygame.K_RIGHT:
		crazy_rocket.moving_right = False
	elif event.key == pygame.K_LEFT:
		crazy_rocket.moving_left == False
	elif event.key == pygame.K_UP:
		crazy_rocket.moving_up == False
	elif event.key == pygame.K_DOWN:
		crazy_rocket.moving_down == False  	
#可以满足条件
def check_keydown_events(event,crazy_rocket):
	if event.key == pygame.K_RIGHT:
		crazy_rocket.moving_right = True
	elif event.key == pygame.K_LEFT:
		crazy_rocket.moving_left = True
	elif event.key == pygame.K_UP:
		crazy_rocket.moving_up = True
	elif event.key ==pygame.K_DOWN:
		crazy_rocket.moving_down = True
def check_keyup_events(event,crazy_rocket):
	if event.key == pygame.K_RIGHT:
		crazy_rocket.moving_right = False
	elif event.key == pygame.K_LEFT:
		crazy_rocket.moving_left = False
	elif event.key == pygame.K_UP:
		crazy_rocket.moving_up = False
	elif event.key == pygame.K_DOWN:
		crazy_rocket.moving_down = False

上面两个函数我感觉是一样的,但运行时却是不同的结果。我检查了几遍,没有发现异常。但是出现了 错误,如上面的代码所示。如能解答留下评论或联系方式。加,共同学习也行,共享资源。

 

©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值