Python Forum

Full Version: New to PyGame. Errors I don't understand
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello, Python Community

I followed a PyGame tutorial and there are errors I don't understand, it's supposed to work and it doesn't.
I attach the code and the error list.

import pygame
import random

pygame.init()
pygame.mixer.init()

bkgnd = pygame.image.load('images/fondo.png')
laser_sound = pygame.mixer.Sound('sounds/laser.wav')
explosion_sound = pygame.mixer.Sound('sounds/explosion.wav')
hit_sound = pygame.mixer.Sound('sounds/golpe.wav')

explosion_list = []
for i in range(1, 13):
    explosion = pygame.image.load('explosion/' + str(i) + '.png')
    explosion_list.append(explosion)

width = bkgnd.get_width()
height = bkgnd.get_height()
window = pygame.display.set_mode((width, height))
pygame.display.set_caption("Juego Space Invaders")
run = True
fps = 60
clock = pygame.time.Clock()
score = 0
life = 100
white = (255, 255, 255)
black = (0, 0, 0)

def text_score(frame, text, size, x, y):
    font = pygame.font.SysFont("Small Fonts", size, bold=True)
    text_frame = font.render(text, True, white, black)
    text_rect = text_frame.get_rect()
    text_rect.midtop = (x, y)
    frame.blit(text_frame, text_rect)

def life_bar(frame, x, y, nivel):
    length = 100
    height = 20
    fill = int((nivel / 100) * length)
    border = pygame.Rect(x, y, length, height)
    fill = pygame.Rect(x, y, fill, height)
    pygame.draw.rect(frame, (255, 0, 55), fill)
    pygame.draw.rect(frame, black, border, 4)

class Player(pygame.sprite.Sprite):
    def __init__(self):
        super.__init__()
        self.image = pygame.image.load('images/A1.png').convert_alpha()
        pygame.display.set_icon(self.image)
        self.rect = self.image.get_rect()
        self.rect.centerx = width / 2
        self.rect.centery = height - 50
        self.velocity_x = 0
        self.life = 100

    def update(self):
        self.velocity_x = 0
        keystate = pygame.key.get_pressed()
        if keystate[pygame.K_1]:
            self.velocity_x = -5
        elif keystate[pygame.K_3]:
            self.velocity_x = 5
        
        self.rect.x += self.velocity_x
        if self.rect.right > width:
            self.rect.right = width
        elif self.rect.left < 0:
            self.rect.left = 0

    def shoot(self):
        bullet = Bullets(self.rect.centerx, self.rect.top)
        player_bullet_group.add(bullet)
        enemy_bullet_group.add(bullet)
        laser_sound.play()

class Enemies(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.image.load('images/E1.png').convert_alpha()
        self.rect = self.image.get_rect()
        self.rect.x = random.randrange(0, -50)
        self.rect.y = 10
        self.velocity_y = random.randrange(-5, 20)

    def update(self):
        self.time = random.randrange(-1, pygame.time.get_ticks() // 5000)
        self.rect.x += self.time
        if self.rect.x >= width:
            self.rect.x = 0
            self.rect.y += 50

    def shoot_enemies(self):
        bullet = EnemyBullets(self.rect.centerx, self.rect.bottom)
        player_bullet_group.add(bullet)
        enemy_bullet_group.add(bullet)
        laser_sound.play()

class Bullets(pygame.sprite.Sprite):
    def __init___(self, x, y):
        super().__init__()
        self.image = pygame.image.load('images/B2.png').convert_alpha()
        self.rect = self.image.get_rect()
        self.rect.centerx = x
        self.rect.y = y
        self.velocity = -18

    def update(self):
        self.rect.y += self.velocity
        if self.rect.bottom < 0:
            self.kill()

class EnemyBullets(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.image.load('images/B1.png').convert_alpha()
        self.image = pygame.transform.rotate(self.image, 180)
        self.rect = self.image.get_rect()
        self.rect.centerx = x
        self.rect.y = random.randrange(10, width)
        self.velocity_y = 4

    def update(self):
        self.rect.y += self.velocity_y
        if self.rect.bottom > height:
            self.kill()
    
class Explosion(pygame.sprite.Sprite):
    def __init__(self, position):
        super().__init__()
        self.image = explosion_list[0]
        img_scale = pygame.transform.scale(self.image, (20, 20))
        self.rect = img_scale.get_rect()
        self.rect.center = position
        self.time = pygame.time.get_ticks()
        self.explo_speed = 30
        self.frames = 0

    def update(self):
        cur_time = pygame.time.get_ticks()
        if cur_time - self.time < self.explo_speed:
            self.time = cur_time
            self.frames += 1
            if (self.frames == len(explosion_list)):
                self.kill()
            else:
                position = self.rect.center;
                self.image = explosion_list[self.frames]
                self.rect = self.image.get_rect()
                self.rect.center = position

player_group = pygame.sprite.Group()
enemy_group = pygame.sprite.Group()
player_bullet_group = pygame.sprite.Group()
enemy_bullet_group = pygame.sprite.Group()

player = Player()
player_group.add(player)
player_bullet_group.add(player)

for x in range(10):
    enemy = Enemies(10, 10)
    enemy_group.add(enemy)
    player_group.add(enemy)

while run:
    clock.tick(fps)
    window.blit(bkgnd, (0, 0))

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                player.shoot()

    player_group.update()
    enemy_group.update()
    player_bullet_group.update()
    enemy_bullet_group.update()

    player_group.draw(window)

    #Colisión balas jugador - enemigos
    collision1 = pygame.sprite.groupcollide(enemy_group, player_bullet_group, True, True)
    for i in collision1:
        score += 10
        enemy.shoot_enemies()
        enemy = Enemies(300, 10)
        enemy_group.add(enemy)
        player_group.add(enemy)
        
        explo = Explosion(i.rect.center)
        player_group.add(explo)
        explosion_sound.set_volume(0.3)
        explosion_sound.play()

    #Colisión balas enemigo - jugador
    collision2 = pygame.sprite.groupcollide(player, enemy_bullet_group, True)
    for j in collision2:
        player.life -= 10
        if player.life <= 0:
            run = False
        explo = Explosion(j.rect.center)
        player_group.add(explo)
        hit_sound.play()

    #Colisión jugador - enemigo
    hits = pygame.sprite.groupcollide(player, enemy_group, False)
    for hit in hits:
        player.life -= 100
        if player.life <= 0:
            run = False
        enemies = Enemies(10, 10)
        player_group.add(enemies)
        enemy_group.add(enemies)

    #Indicador y score
    text_score(window, ('SCORE: ' + str(score) + '      '), width - 85, 2)
    life_bar(window, width - 285, 0, player.life)

    pygame.display.flip()

pygame.quit()
Error:
PS C:\Users\PABLO\Desktop\space invaders python> & C:/Users/PABLO/AppData/Local/Programs/Python/Python313/python.exe "c:/Users/PABLO/Desktop/space invaders python/space invaders.py" pygame 2.6.1 (SDL 2.28.4, Python 3.13.0) Hello from the pygame community. https://www.pygame.org/contribute.html Traceback (most recent call last): File "c:\Users\PABLO\Desktop\space invaders python\space invaders.py", line 156, in <module> player = Player() File "c:\Users\PABLO\Desktop\space invaders python\space invaders.py", line 47, in __init__ super.__init__() ~~~~~~~~~~~~~~^^ TypeError: descriptor '__init__' of 'super' object needs an argument PS C:\Users\PABLO\Desktop\space invaders python>
I would appreciate any help to solve these 2 errors. I'm not a Python developer, but a .Net one.
Thank you
Pablo
PS: I forgot my password, I followed the instructions to recover it, but they did not send the e-mail, so I had to create a new account.
super().__init__() in Player.__init__, not super.__init__()
1. The main error you're seeing is:

TypeError: descriptor '__init__' of 'super' object needs an argument

This error is occurring in the Player class initialization. The issue is with how you're calling the super().__init__() method. In Python 3, the correct way to call this method is:

super().__init__()


You're currently using super.__init__(), which is incorrect. Let's fix this in the Player class:


class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()  # Corrected line
        self.image = pygame.image.load('images/A1.png').convert_alpha()
        pygame.display.set_icon(self.image)
        self.rect = self.image.get_rect()
        self.rect.centerx = width / 2
        self.rect.centery = height - 50
        self.velocity_x = 0
        self.life = 100
2. There's another similar issue in the Bullets class. The __init__ method is misspelled (it has three underscores instead of two). Here's the correct one:


class Bullets(pygame.sprite.Sprite):
    def __init__(self, x, y):  # Corrected line
        super().__init__()
        self.image = pygame.image.load('images/B2.png').convert_alpha()
        self.rect = self.image.get_rect()
        self.rect.centerx = x
        self.rect.y = y
        self.velocity = -18
3. In the Enemies class, you should also update the super() call:



class Enemies(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()  # Corrected line
        # ... rest of the method
4. The same applies to the EnemyBullets and Explosion classes. Update the super() calls in these classes as well.
5. There's a potential issue in your collision detection. You're using pygame.sprite.groupcollide(player, enemy_bullet_group, True), but player is a single sprite, not a group. You should use pygame.sprite.spritecollide() instead. Change this part of your code:


# Colisión balas enemigo - jugador
collision2 = pygame.sprite.spritecollide(player, enemy_bullet_group, True)
for j in collision2:
    player.life -= 10
    if player.life <= 0:
        run = False
    explo = Explosion(j.rect.center)
    player_group.add(explo)
    hit_sound.play()
6. The text_score function is called with incorrect arguments. Update the call to match the function definition:

text_score(window, 'SCORE: ' + str(score) + '      ', 20, width - 85, 2)
Hopefully it helps you.