signed

QiShunwang

“诚信为本、客户至上”

Python编程:从入门到实践 第十三章 错误反思

2021/4/26 15:17:48   来源:

在学习这这章的时候,遇到一个棘手的难题,就是我造出来的外星人群只有三个(哎呀,我是按代码抄的,真不知道哪儿抄错了)(文章结尾附代码)我写的代码
上面的外星人和飞船都是我自己动手画的,飞船是以前学PS时画的,外星人用win10自带的画板画的。

但是书上的代码运行结果:
书里的源代码
我反复查找,反复确认,排查了一整天,发现我的代码
(我加了两个print来排查问题)

class Alien(Sprite):

	def update(self):
			"""移动外星人"""
			#self.x=self.rect.x
			self.x+=(self.ai_settings.alien_speed_factor*self.ai_settings.fleet_direction)
			print("%%%%%("+str(self.rect.x)+","+str(self.rect.y)+")%%%%")
			self.rect.x=self.x
			print("问题所在("+str(self.rect.x)+","+str(self.rect.y)+")%%%%")

输出结果在这里插入图片描述
也就是在下面这部分出现了问题

self.x+=(self.ai_settings.alien_speed_factor*self.ai_settings.fleet_direction)

对比书上附带的代码

class Alien(Sprite):
    """A class to represent a single alien in the fleet."""
    --snip--
    
    def update(self):
        """Move the alien right or left."""
        print("-----------%%%%%("+str(self.rect.x)+","+str(self.rect.y)+")%%%%----------")
        self.x += (self.ai_settings.alien_speed_factor *
                        self.ai_settings.fleet_direction)
        print("问题所在("+str(self.rect.x)+","+str(self.rect.y)+")%%%%")
        self.rect.x = self.x

显然,我写的部分的self.x并没有使用aliens组下一个外星人的x,而是继续使用第一个的x

不过不大明白这背后的原理是啥,最后强制修改了这个值,修改如下:

class Alien(Sprite):

	def update(self):
			"""移动外星人"""
			self.x=self.rect.x
			self.x+=(self.ai_settings.alien_speed_factor*self.ai_settings.fleet_direction)
			print("%%%%%("+str(self.rect.x)+","+str(self.rect.y)+")%%%%")
			self.rect.x=self.x
			print("问题所在("+str(self.rect.x)+","+str(self.rect.y)+")%%%%")

输出结果如下:
在这里插入图片描述
可算正常了,继续看书在这里插入图片描述
恳请爸爸们指正!!真的难死我了(哭)
——————————————————源码分界线——————————————————

#alien_invasion.py
import pygame
from pygame.sprite import Group

from settings import Settings
from game_stats import GameStats
from ship import Ship
import game_functions as gf

def run_game():
	pygame.init()
	ai_settings=Settings()
	screen = pygame.display.set_mode(
		(ai_settings.screen_width, ai_settings.screen_height)) 
	pygame.display.set_caption("Alien Invasion")
	
	#创建一个用于统计信息的实例
	stats=GameStats(ai_settings)
	
	#创建飞船,子弹组,外星人编组
	ship=Ship(ai_settings,screen)
	bullets=Group()#Group组类似列表
	aliens=Group()
	gf.create_fleet(ai_settings,screen,ship,aliens)

	#开始游戏主循环
	while True:
		gf.check_events(ai_settings,screen,ship,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,ship,bullets,aliens)

run_game()
#alien.py
import pygame
from pygame.sprite import Sprite

class Alien(Sprite):
	def __init__(self,ai_settings,screen):
		super().__init__()
		self.ai_settings=ai_settings
		self.screen=screen
		
		#加载外星人,矩形化
		self.image=pygame.image.load('images/laowai.png')
		self.image=pygame.transform.scale(self.image,(80,80))
		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 check_edges(self):
		screen_rect=self.screen.get_rect()
		if self.rect.right>=screen_rect.right:
			return True
		elif self.rect.left<=0:
			return True
	
	def update(self):
		"""移动外星人"""
		self.x=self.rect.x
		self.x+=(self.ai_settings.alien_speed_factor*self.ai_settings.fleet_direction)
		self.rect.x=self.x
	
	def blitme(self):
		"""绘制外星人"""
		self.screen.blit(self.image,self.rect)
#game_functions.py
def update_aliens(ai_settings,stats,screen,ship,aliens,bullets):
	check_fleet_edges(ai_settings,aliens)
	aliens.update()
	#检测外星人与飞船的碰撞
	if pygame.sprite.spritecollideany(ship,aliens):
		ship_hit(ai_settings,stats,screen,ship,aliens,bullets)
	#检测外星人是否到达底部
	check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets)