python外星人入侵游戏 报错invalid destination position for blit

import sys import pygame from pygame.sprite import Group from setting import Setting from ship import Ship from bullet import Bullet from allien import Allien class AlienInvasion: #管理游戏资源和行为的类 def __init__(self): pygame.init() self.setting = Setting() self.screen = pygame.display.set_mode((self.setting.screen_width,self.setting.screen_height)) #设置背景色 # 创建飞3 self.ship = Ship(self) # 创建子弹的编组 self.bullets =pygame.sprite.Group() self.bulelts_allowed = 5 # 创建外星人的编组 self.alliens = pygame.sprite.Group() pygame.display.set_caption("Alien Invasion") #开始游戏的主循环 def run_game(self): while True: #监视键盘和鼠标的辅助方法 self._check_event() # 创建外星人 self.ship.update() # 控制子弹移动方法检查子弹是否达到最上面 self.update_bullet() self.creat_fleet() #让最近绘制的屏幕可见的方法 self.update_alliens() #让最近绘制的屏幕可见的方 self._update_screen() def update_alliens(self): self._check_fleet_edges() self.alliens.update() def update_bullet(self): self.bullets.update( ) for bullet in self.bullets.copy(): if bullet.rect.bottom < 0: self.bullets.remove(bullet) # 创建外星人组 def creat_fleet(self): # 创造一个外星人并计算一行可以容纳多少外星人 # 外星人间距等于外星人宽度 allien = Allien(self) allien_width = allien.rect.width available_space_x = self.setting.screen_width - (2 * allien_width) number_allien_x = available_space_x // (2 * allien_width) # 计算屏幕可以容纳多少行外星人 allien_hegiht = allien.rect.height available_space_y = self.setting.screen_height - (3 * allien_hegiht) row_number = available_space_y // (2 * allien_hegiht) self.creat_allien(row_number,number_allien_x) def creat_allien(self,row_number,number_allien_x): for number_row in range(row_number - 1): for number_x in range(number_allien_x): allien = Allien(self) allien_width = allien.rect.width allien_height = allien.rect.height allien_width, allien_hegiht = allien.rect.size allien.x = allien_width + (2 * allien_width * number_x) allien.y = allien_height + (2 * allien_height * number_row) allien.rect.x = allien.x allien.rect.y = allien.y self.alliens.add(allien) def _check_fleet_edges(self): for alien in self.alliens.sprites(): if alien.check_edges(): self._change_fleet_direction() break def _change_fleet_direction(self): for alien in self.aliens.sprites(): allien.rect.y += self.setting.fleet_drop_speed self.setting.fleet_direction *= -1 def _fire_bullet(self): if len(self.bullets) <= self.bulelts_allowed: new_bullet = Bullet(self) self.bullets.add(new_bullet) # 响应事件的辅助方法 def _check_event(self): for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() # 按下按键的操作 elif event.type == pygame.KEYDOWN: self._check_event_keydown(event) # 松开按键的操作 elif event.type == pygame.KEYUP: self._check_event_keyup(event) # 按下按键的操作 elif event.type == pygame.KEYDOWN: self._check_event_keydown(event) def _check_event_keydown(self,event): if event.key == pygame.K_RIGHT: self.ship.moving_right = True elif event.key == pygame.K_LEFT: self.ship.moving_left = True elif event.key == pygame.K_SPACE: self._fire_bullet() elif event.key == pygame.K_q: sys.exit() def _check_event_keyup(self,event): if event.key == pygame.K_RIGHT: self.ship.moving_right = False elif event.key == pygame.K_LEFT: self.ship.moving_left = False # 屏幕刷新的辅助方法 def _update_screen(self): self.screen.fill(self.setting.bg_color) self.ship.blitme() for bullet in self.bullets.sprites(): bullet.draw_bullet() self.alliens.draw(self.screen) pygame.display.flip() #创建游戏实例并开始游戏 if __name__ == '__main__': ai_game = AlienInvasion() ai_game.run_game() import pygame from pygame.sprite import Sprite class Allien(Sprite): def __init__(self,ai_game): super().__init__() self.screen = ai_game.screen self.setting = ai_game.setting # 创建图像和其矩形 self.image = pygame.image.load("image/alien.bmp") self.rect = self.image.get_rect() # 每个外星人都在左上角附件 self.rect.x = self.rect.width self.rect.y = self.rect.height # 储存x的精确位置 self.x = float(self.rect.x) def update(self): self.x += (self.setting.allien_speed * self.setting.fleet_direction) self.rect = self.x def check_edges(self): screen_rect = self.screen.get_rect() if self.rect.right >= screen_rect.right or self.rect.left <= screen_rect.left: return True #储存游戏中所有设置的类 class Setting: def __init__(self): #屏幕设置 self.screen_width = 1200 self.screen_height = 800 self.bg_color = (230,230,230) # 飞船速度设置 self.ship_speed = 1.5 # 子弹设置 self.bullet_speed = 1 self.bullet_width = 3 self.bullet_height = 15 self.bullet_color = (60,60,60) # 外星人设置 self.allien_speed = 1.0 self.fleet_drop_speed = 10 # fleet_direction = 1 为1 表示右移,为-1表示左移 self.fleet_direction = 1 import pygame from pygame.sprite import Sprite class Bullet(Sprite): # 子弹的类 def __init__(self,ai_game): super().__init__() self.screen = ai_game.screen # 在(0,0)处先创建一个矩形,再移动到飞船 self.rect = pygame.Rect(0,0,ai_game.setting.bullet_width,ai_game.setting.bullet_height) self.rect.centerx = ai_game.ship.rect.centerx self.rect.top = ai_game.ship.rect.top # 储存用小数表达的子弹的y self.y = float(self.rect.y) self.color = ai_game.setting.bullet_color self.speed = ai_game.setting.bullet_speed # 子弹的移动 def update(self): #更新表示子弹位置的小数值 self.y -= self.speed # 更新表示矩形y位置??? self.rect.y = self.y def draw_bullet(self): # 在屏幕上绘制子弹 pygame.draw.rect(self.screen,self.color,self.rect)