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()

pygame 2.1.0 (SDL 2.0.16, Python 3.9.9)
Hello from the pygame community. https://www.pygame.org/contribute.html
Traceback (most recent call last):
File "D:\allien_work\allien_invasion.py", line 140, in
ai_game.run_game()
File "D:\allien_work\allien_invasion.py", line 41, in run_game
self._update_screen()
File "D:\allien_work\allien_invasion.py", line 134, in _update_screen
self.alliens.draw(self.screen)
File "C:\Users\Lenovo\AppData\Roaming\Python\Python39\site-packages\pygame\sprite.py", line 546, in draw
surface.blits((spr.image, spr.rect) for spr in sprites)
TypeError: invalid destination position for blit
[Finished in 918ms]

你好,可以将Setting和Allien类粘贴出来吗?