1

I am making a pygame game for a school project, and I have been doing a lot of debugging. I just finished fixing the classes by giving it two positional arguments instead of 1, after that when I tried to run the game it gave me errors on lines 454 and 441, however my code is only around 180 lines long. (My aim with all of this was making another sort of player that the player could move called an enemy) It could all be a problem with my library and not the code itself. I will include the error code below and the code itself.

Error code: 
Traceback (most recent call last):
  File "C:\Users\(Myname)\PycharmProjects\LearningPython3\venv\lib\site-packages\pygame\sprite.py", line 441, in add
    self.add(*sprite)
TypeError: pygame.sprite.AbstractGroup.add() argument after * must be an iterable, not pygame.Surface

During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "C:\Users\(myname)\PycharmProjects\LearningPython3\App.py", line 147, in <module>
    enemy_group.add(enemy_image)
  File "C:\Users\(myname)\PycharmProjects\LearningPython3\venv\lib\site-packages\pygame\sprite.py", line 454, in add
    sprite.add_internal(self)
AttributeError: 'pygame.Surface' object has no attribute 'add_internal'

The code in parts (Some parts are not included):

# bullet class
class Bullet (pygame.sprite.Sprite):
    def __init__(self,pos_x,pos_y):
        super().__init__()
        self.image = pygame.Surface((50,10))
        self.image.fill((255,255,0))
        self.rect = self.image.get_rect(center = (pos_x,pos_y))

    def update(self):
        self.rect.x += 5
#Making the enemy work
enemy_speed_factor = 1.5
class Enemy:
    def __init__(self, enemy_image):
        """Initialize the enemy and set its starting position"""
        self.screen = screen


        #Load the enemy image and get its rect
        self.image = pygame.image.load("Enemy4.png")
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()

        #start each new enemy at the bottom of the screen
        self.rect.centerx = self.screen_rect.centerx
        self.rect.bottom = self.screen_rect.bottom

        #store a decimal value for the enemys x and y center
        self.centerx = float(self.rect.centerx)
        self.centery = float(self.rect.centery)

        #Movement flag
        self.moving_right = False
        self.moving_left = False
        self.moving_down = False
        self.moving_up = False

    def update(self):
        """Update the enemys position based on the movement flag"""
        #Upade the enemy's center value, not the rect.
        if self.moving_right and self.rect.right < self.screen_rect.right:
            self.centerx += self.ai_settings.enemy_speed_factor
        if self.mobing_left and self.rect.left >0:
            self.centerx -= self.ai_settings.enemy_speed_factor
        if self.moving_down and self.rect.bottom < self.screen_rect.bottom:
            self.centery =+ self.ai_settings.enemy_speed_factor
        if self.moving_down and self.rect.top > self.screen_rect.top:
            self.centery -= self.ai_settings.enemy_speed_factor

        #Update rect object from self.center
        if self.moving_up or self.moving_down:
            self.rect.centery = self.centery
        if self.moving_left or self.moving_right:
            self.rect.centerx = self.centerx
    def blitme(selfself, self):
        """draw the enemy at its current location"""
        self.screen.blit(self.image, self.rect)

#making the movements for the enemy
def check_keydown_events(events, enemy):
    """responds to keypresses"""
    if event.key == pygame.K_RIGHT:
        enemy.moving_right = True
    elif event.key == pygame.K_LEFT:
        enemy.moving_left = True
    elif event.key == pygame.K_DOWN:
        enemy.moving_down = True
    elif event.key == pygame.K_UP:
        enemy.moving_up = True

def check_keyup_evets(event, enemy):
    """responds to key releases"""
    if event.key == pygame.K_RIGHT:
        enemy.moving_right = False
    elif event.key == pygame.K_LEFT:
        enemy.moving_left = False
    elif event.key == pygame.K_DOWN:
        enemy.moving_down = False
    elif event.key == pygame.K_UP:
        enemy.moving_up = False


def check_keyup_events(event, enemy):
    pass


def check_events(enemy):
    """Respond to keypresses and mouse events"""
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
        elif event.type == pygame.KEYDOWN:
            check_keydown_events(event, enemy)
        elif event.type == pygame.KEYUP:
            check_keyup_events(event, enemy)

def update_screen(ai_settings, screen, enemy):
    """Update images on the screen and flip to the new screen"""
    #Redeaw the screen during each pass through the loop
    screen.fill(ai_settings.bg_color)
    enemy.blitme()

    #Make the most recently drawn screeen visible
    pygame.display.flip()


def blitme(self):
    self.screen.blit(self)


# enemy
enemy_image = pygame.image.load("Enemy4.png")
enemy = Enemy(enemy_image)
enemy_group = pygame.sprite.Group()
enemy_group.add(enemy)

sourvad
  • 320
  • 1
  • 6
Karma
  • 55
  • 5
  • Can you also put the code where you have the following call: `self.add(*sprite)` – sourvad Mar 23 '21 at 16:39
  • I dont have that line of code – Karma Mar 23 '21 at 16:40
  • Can you put the code where you call the following: `enemy_group.add(enemy_image)`? It seems like pygame is expecting a `Sprite` object but it is receiving a `Surface` object. – sourvad Mar 23 '21 at 16:46
  • I dont have that I was debating to put that or enemy_group.add(enemy) instead of enemy_image, its on the second part – Karma Mar 23 '21 at 16:48
  • According to [the documentation for `pygame.sprite.Group().add()`](https://www.pygame.org/docs/ref/sprite.html#pygame.sprite.Group.add), you can only add a [pygame `Sprite`](https://www.pygame.org/docs/ref/sprite.html#pygame.sprite.Sprite) object to a sprite group. But you're trying to add a `pygame.image` in your error example, and in the code you've shown, you're trying to add an `Enemy` object. None of those are sprites. So why are you expecting that to work? Do you not understand what `pygame.sprite.Group()` is for? – Random Davis Mar 23 '21 at 16:56
  • 2
    Try inheriting the Sprite class in the Enemy class like so: `class Enemy (pygame.sprite.Sprite):` and pass the object of the Enemy class to the group like so: `enemy = Enemy() enemy_group.add(enemy)` Of course, initialize using the image like you normally do. – sourvad Mar 23 '21 at 16:57
  • @sourvad you put enemy = Enemy() enemy_group.add(enemy) should I type it in all at once or was that a typo? – Karma Mar 23 '21 at 17:06
  • It wasn't a type but keep them in separate line, I cannot format properly in comments as I can do in an answer. – sourvad Mar 23 '21 at 17:07
  • Ok thank you very much – Karma Mar 23 '21 at 17:18
  • @sourvad it gives me this error msg enemy = Enemy() TypeError: __init__() missing 1 required positional argument: 'enemy_image' after i did what you told me to do, however isnt the positonal argument given and enemy_image is defined in the first line as enemy_image = pygame.image.load("Enemy4.png") – Karma Mar 23 '21 at 17:29
  • The reason the error occurs at line 400 is because your code imports a module (`pygame`). You pass a wrong argument and the error occurs in another file (`pygame\sprite.py`), which is more than 400 lines of code long. – D_00 Mar 23 '21 at 18:02
  • @D_00 oh ok thank you for clarifying, that still confused me till now, thank you – Karma Mar 23 '21 at 18:09

0 Answers0