Python编程从入门到实践习题12-5

12-5  侧面射击:编写一个游戏,将一艘飞船放置在屏幕左边,并允许玩家上下移动飞船。在玩家按空格键时,让飞船发射一颗在屏幕中央向右穿行的子弹,并在子弹离开屏幕而消失后将其删除。

这个题和书上的程序类似,但自己写的时候还是遇到了许多问题,磕磕碰碰实现了。

主程序:game

import pygame

from settings import Settings

import func as f

from ship import Ship

from bullet import Bullet

from pygame.sprite import Group

def run_game():
	pygame.init()
	
	settings = Settings()
	                
	screen = pygame.display.set_mode((settings.screen_width, settings.screen_height))
	pygame.display.set_caption("Side Shoot")
	
	ship = Ship(screen)
	
	bullets = Group()
	
	while True:
		
		f.check_keys(settings, screen, ship, bullets)
		ship.update()
		bullets.update()
		
		#删除已消失的子弹
		for bullet in bullets.copy():
			if bullet.rect.left > screen.get_rect().right:
				bullets.remove(bullet)
				
		f.update_screen(settings, screen, ship, bullets)
	
run_game()

Settings类:

import pygame

class Settings():
	"""所有设置的类"""
	
	def __init__(self):
		
		#设置屏幕的属性
		self.screen_width = 1200
		self.screen_height = 600
		self.bg_color = (230, 230, 230)

		#设置子弹属性
		self.bullet_speed_factor = 1
		self.bullet_width = 5
		self.bullet_height = 5
		self.bullet_color = 0, 0, 0

Ship类:

import pygame

class Ship():
	
	def __init__(self, screen):
		"""设置飞船的属性"""
		self.screen = screen#EEEE:忘记写
		
		self.image = pygame.image.load('ship.bmp')#读取飞船图片
		self.image = pygame.transform.rotate(self.image, -90)#将飞船顺时针旋转90°
		self.rect = self.image.get_rect()#获取飞船图片外接矩形
		self.screen_rect = screen.get_rect()#获取屏幕的外接矩形
		
		#设置飞船的位置,将飞船放置在屏幕左侧中间
		self.rect.centery = self.screen_rect.centery
		self.rect.left = self.screen_rect.left
		
		#初始化飞船上下移动属性
		self.moving_up = False
		self.moving_down = False
	
	def update(self):
		"""更新飞船位置"""
		if self.moving_up and self.rect.top > 0:
			self.rect.centery -= 1
		elif self.moving_down and self.rect.bottom < self.screen_rect.bottom:
			self.rect.centery += 1	
	
	def blitme(self):
		"""绘制飞船"""
		self.screen.blit(self.image, self.rect)
		
		
		

Bullet类:

import pygame

from pygame.sprite import Sprite

class Bullet(Sprite):
	"""一个对子弹进行管理的类"""
	
	def __init__(self, settings, screen, ship):
		"""在飞船出创建一个子弹对象"""
		
		#继承父类的属性
		super().__init__()
		
		self.screen = screen
		
		#在(0, 0)处创建一个子弹的矩形,再设置其准确位置
		self.rect = pygame.Rect(0, 0, settings.bullet_width, settings.bullet_height)
		self.rect.centery = ship.rect.centery
		self.rect.right = ship.rect.right
		
		#存储用小数表示的子弹位置
		self.x = float(self.rect.x)
		
		self.color = settings.bullet_color
		self.speed_factor = settings.bullet_speed_factor
		
	def update(self):
		"""更新子弹位置"""
		self.x += self.speed_factor
		self.rect.x = self.x
		
	def draw_bullet(self):
		"""在屏幕上绘制子弹"""
		pygame.draw.rect(self.screen, self.color, self.rect)

函数模块func:

import pygame

import sys

from ship import Ship

from bullet import Bullet

def check_keys(settings, screen, ship, bullets):
	for event in pygame.event.get():
		if event.type == pygame.QUIT:
			sys.exit()
		elif event.type == pygame.KEYDOWN:
			check_keys_down(event, settings, screen, ship, bullets)
		elif event.type == pygame.KEYUP:
			check_keys_up(event, ship)
		
def check_keys_down(event,settings, screen, ship, bullets):
	if event.key == pygame.K_UP:
		ship.moving_up = True
	if event.key == pygame.K_DOWN:
		ship.moving_down = True
	elif event.key == pygame.K_SPACE:
		#创建一颗子弹,并加入到Group编组中
		new_bullet = Bullet(settings, screen, ship)
		bullets.add(new_bullet)
	
def check_keys_up(event,ship):
	if event.key == pygame.K_UP:
		ship.moving_up = False
	if event.key == pygame.K_DOWN:
		ship.moving_down = False
		
def update_screen(settings, screen, ship, bullets):
	screen.fill(settings.bg_color)
	ship.blitme()
	for bullet in bullets.sprites():
		bullet.draw_bullet()
	pygame.display.flip()

效果图:


这子弹模型让我想起了小时候掌机上一个像弹乒乓球的游戏,呵呵!

问题与总结:

1.初始化Ship类时,忘记写self.screen = screen

2.当按住↑键时,飞船直接到了屏幕顶部,经检查是在check_keys_down()中,moving_up拼写出错

3.对编组bullets中的bullet使用for循环时,应写成for bullet in bullet.sprites():

4.各处形参传递顺序应一致,本次因为没注意一直出现 AttributeError,值得注意

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
### 回答1: 很好的问题!《Python编程入门实践》是一本非常好的Python编程入门书籍,它提供了许多有趣的习题,可以帮助读者巩固所学的知识并提高编程能力。 这些习题涵盖了Python编程的各个方面,包括基本语法、函数、类、文件操作、Web开发等等。通过完成这些习题,读者可以逐步掌握Python编程的核心概念和技能,并且能够应用这些知识来解决实际问题。 如果你正在学习《Python编程入门实践》,我建议你认真完成每个章节的习题,并且尝试自己编写一些类似的程序。此外,你还可以参考一些其他的Python编程练习题,例如LeetCode、Codewars等网站上的题目,来进一步提高自己的编程能力。 ### 回答2: 《Python编程入门实践》是一本非常优秀的Python入门教材,其习题设计也是非常合理和有挑战性的。这些习题不仅具备良好的逻辑链条和难度递进,而且还让我们真正理解了Python编程的精髓,加深了对Python语言的理解和运用。 针对《Python编程入门实践》的习题,在学习过程中,我们可以从以下几个方面进行思考和总结: 首先,我们需要认真阅读题目,并按照题目要求进行分析和思考。在解决问题的过程中,我们应该养成良好的习惯,将问题分解为多个小问题,并一步一步的解决它们,而不是一次性的解决大问题。 其次,我们需要运用所学知识进行编程。我们应该熟练掌握Python的语法和各种库函数的使用,并能够独立设计和编写Python程序。 除此之外,我们还需要注重细节和思考的深度,通过自己的思考和探索,深入理解Python编程的本质和特点,并能够灵活运用到实际问题中。 最后,我们还需要进行代码的优化和重构,使其更加简洁高效。同时,我们也要注重代码的可读性和重用性,尽量使用函数封装和模块化的方式来进行编程。 在学习过程中,我们也可以参考一些其他优秀的 Python 教材和相关网站,不断学习和探索,提高自己的学习效率和编程水平。 总之,通过对《Python编程入门实践》的习题的认真学习和练习,我们可以不断巩固和提高自己的 Python 编程能力,并为将来的工作和学习打下坚实的基础。 ### 回答3: 《Python编程入门实践》是一本非常好的Python入门教程。针对各个章节后面的习题,这些习题都很典型,旨在让读者将章节中所学到的内容应用到实践中,并进一步加深对Python编程语言的理解。 这些习题既有简单的,也有较为困难的。比如,在第二章后面的习题中,有一个要求用Python输出自己的名字、年龄和所在城市的程序,这个练习是比较简单的,可以通过以下代码来实现: name = "张三" age = 20 city = "北京" print("我的名字是%s,今年%d岁,我来自%s。" % (name, age, city)) 再比如,在第六章的练习中,要求编写一个Python程序,让用户输入一些数字,然后计算它们的和。这个练习稍微有点难度,可用如下程序实现: nums = input("请输入一些数字,用逗号隔开:") # 读入输入的数字 num_list = nums.split(",") # 将输入的数字按逗号分隔开,并存储到列表中 sum = 0 # 定义变量sum,用于计算输入数字的总和 for i in num_list: # 遍历列表中的每个元素 sum += int(i) # 将每个元素转换为整型并累加到sum中 print("输入数字的总和是:%d" % sum) 当然,这些习题还有很多其他的变式,具体要看读者的深度理解和编程能力。总结来说,Python编程入门实践的课后习题是非常有价值的,读者可以通过完成这些练习来巩固所学到的知识点,同时也可以提升自己的编程能力和思维能力。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值