Apr-06-2024, 06:39 PM
Hi,
I'm trying to add mouse control for the character in a Space Invaders clone whose code I found online.
Determining the X position of the mouse pointer (event.pos[0]) works, in line 278 I pass this to the function
"spaceship.update(event.pos[0])".
The error occurs in line 242, see error message.
I don't understand the error message, because I specified "pos" on line 75...
When I move the mouse, the program crahses...
I tried very long and don't know the reason for the error.
Thank you very much for your support!
Traceback (most recent call last):
File "D:\Daten\aktuell\sinvaders\main.py", line 242, in <module>
game_over = spaceship.update()
TypeError: Spaceship.update() missing 1 required positional argument: 'pos'
I'm trying to add mouse control for the character in a Space Invaders clone whose code I found online.
Determining the X position of the mouse pointer (event.pos[0]) works, in line 278 I pass this to the function
"spaceship.update(event.pos[0])".
The error occurs in line 242, see error message.
I don't understand the error message, because I specified "pos" on line 75...
When I move the mouse, the program crahses...
I tried very long and don't know the reason for the error.
Thank you very much for your support!
Traceback (most recent call last):
File "D:\Daten\aktuell\sinvaders\main.py", line 242, in <module>
game_over = spaceship.update()
TypeError: Spaceship.update() missing 1 required positional argument: 'pos'
import pygame from pygame import mixer from pygame.locals import * import random pygame.mixer.pre_init(44100, -16, 2, 512) mixer.init() pygame.init() #define fps clock = pygame.time.Clock() fps = 60 screen_width = 1280 screen_height = 720 screen = pygame.display.set_mode((screen_width, screen_height)) pygame.display.set_caption('Space Invanders') #define fonts font30 = pygame.font.SysFont('Constantia', 30) font40 = pygame.font.SysFont('Constantia', 40) #load sounds #explosion_fx = pygame.mixer.Sound("img/explosion.wav") #explosion_fx.set_volume(0.25) #explosion2_fx = pygame.mixer.Sound("img/explosion2.wav") #explosion2_fx.set_volume(0.25) #laser_fx = pygame.mixer.Sound("img/laser.wav") #laser_fx.set_volume(0.25) #define game variables rows = 4 cols = 10 alien_cooldown = 1000#bullet cooldown in milliseconds last_alien_shot = pygame.time.get_ticks() countdown = 3 last_count = pygame.time.get_ticks() game_over = 0#0 is no game over, 1 means player has won, -1 means player has lost #define colours red = (255, 0, 0) green = (0, 255, 0) white = (255, 255, 255) #load image bg = pygame.image.load("images/bg.png") screen_rect = bg.get_rect() def draw_bg(): screen.blit(bg, (0, 0)) #define function for creating text def draw_text(text, font, text_col, x, y): img = font.render(text, True, text_col) screen.blit(img, (x, y)) #create spaceship class class Spaceship(pygame.sprite.Sprite): def __init__(self, x, y, health): pygame.sprite.Sprite.__init__(self) self.image = pygame.image.load("images/ship.png") self.rect = self.image.get_rect() self.rect.center = [x, y] self.health_start = health self.health_remaining = health self.last_shot = pygame.time.get_ticks() self.xmin = self.rect.width // 2 # Compute Spaceship x range. self.xmax = screen_width - self.xmin def update(self, pos): self.centerx = max(self.xmin, min(self.xmax, pos)) #set a cooldown variable cooldown = 500 #milliseconds game_over = 0 #record current time time_now = pygame.time.get_ticks() #shoot, get key press key = pygame.key.get_pressed() if key[pygame.K_SPACE] and time_now - self.last_shot > cooldown: #laser_fx.play() bullet = Bullets(self.rect.centerx, self.rect.top) bullet_group.add(bullet) self.last_shot = time_now #update mask self.mask = pygame.mask.from_surface(self.image) #draw health bar pygame.draw.rect(screen, red, (self.rect.x, (self.rect.bottom + 10), self.rect.width, 15)) if self.health_remaining > 0: pygame.draw.rect(screen, green, (self.rect.x, (self.rect.bottom + 10), int(self.rect.width * (self.health_remaining / self.health_start)), 15)) elif self.health_remaining <= 0: explosion = Explosion(self.rect.centerx, self.rect.centery, 3) explosion_group.add(explosion) self.kill() game_over = -1 return game_over #create Bullets class class Bullets(pygame.sprite.Sprite): def __init__(self, x, y): pygame.sprite.Sprite.__init__(self) self.image = pygame.image.load("images/bullet.png") self.rect = self.image.get_rect() self.rect.center = [x, y] def update(self): self.rect.y -= 5 if self.rect.bottom < 0: self.kill() if pygame.sprite.spritecollide(self, alien_group, True, pygame.sprite.collide_mask): self.kill() #explosion_fx.play() explosion = Explosion(self.rect.centerx, self.rect.centery, 2) explosion_group.add(explosion) #create Aliens class class Aliens(pygame.sprite.Sprite): def __init__(self, x, y): pygame.sprite.Sprite.__init__(self) self.image = pygame.image.load("images/alien" + str(random.randint(1, 5)) + ".png") self.x = x self.y = y self.rect = self.image.get_rect() self.rect.center = [x, y] self.move_direction = 1 def update(self): self.rect.x += self.move_direction if self.rect.right >= screen_width or self.rect.left <= 0: self.move_direction *= -1 # update mask self.mask = pygame.mask.from_surface(self.image) #create Alien Bullets class class Alien_Bullets(pygame.sprite.Sprite): def __init__(self, x, y): pygame.sprite.Sprite.__init__(self) self.image = pygame.image.load("images/alien_bullet.png") self.rect = self.image.get_rect() self.rect.center = [x, y] def update(self): self.rect.y += 2 if self.rect.top > screen_height: self.kill() if pygame.sprite.spritecollide(self, spaceship_group, False, pygame.sprite.collide_mask): self.kill() #explosion2_fx.play() #reduce spaceship health spaceship.health_remaining -= 1 explosion = Explosion(self.rect.centerx, self.rect.centery, 1) explosion_group.add(explosion) #create Explosion class class Explosion(pygame.sprite.Sprite): def __init__(self, x, y, size): pygame.sprite.Sprite.__init__(self) self.images = [] for num in range(1, 8): img = pygame.image.load(f"images/explosion{num}.png") if size == 1: img = pygame.transform.scale(img, (20, 20)) if size == 2: img = pygame.transform.scale(img, (100, 100)) if size == 3: img = pygame.transform.scale(img, (160, 160)) #add the image to the list self.images.append(img) self.index = 0 self.image = self.images[self.index] self.rect = self.image.get_rect() self.rect.center = [x, y] self.counter = 0 def update(self): explosion_speed = 3 #update explosion animation self.counter += 1 if self.counter >= explosion_speed and self.index < len(self.images) - 1: self.counter = 0 self.index += 1 self.image = self.images[self.index] #if the animation is complete, delete explosion if self.index >= len(self.images) - 1 and self.counter >= explosion_speed: self.kill() #create sprite groups spaceship_group = pygame.sprite.Group() bullet_group = pygame.sprite.Group() alien_group = pygame.sprite.Group() alien_bullet_group = pygame.sprite.Group() explosion_group = pygame.sprite.Group() def create_aliens(): #generate aliens for row in range(rows): for item in range(cols): alien = Aliens(100 + item * 100, 100 + row * 100) alien_group.add(alien) create_aliens() #create player spaceship = Spaceship(int(screen_width / 2), screen_height - 100, 3) spaceship_group.add(spaceship) run = True while run: clock.tick(fps) #draw background draw_bg() if countdown == 0: #create random alien bullets #record current time time_now = pygame.time.get_ticks() #shoot if time_now - last_alien_shot > alien_cooldown and len(alien_bullet_group) < 5 and len(alien_group) > 0: attacking_alien = random.choice(alien_group.sprites()) alien_bullet = Alien_Bullets(attacking_alien.rect.centerx, attacking_alien.rect.bottom) alien_bullet_group.add(alien_bullet) last_alien_shot = time_now #check if all the aliens have been killed if len(alien_group) == 0: game_over = 1 if game_over == 0: #update spaceship game_over = spaceship.update() #update sprite groups bullet_group.update() alien_group.update() alien_bullet_group.update() else: if game_over == -1: draw_text('GAME OVER!', font40, white, int(screen_width / 2 - 100), int(screen_height / 2 + 50)) if game_over == 1: draw_text('YOU WIN!', font40, white, int(screen_width / 2 - 100), int(screen_height / 2 + 50)) if countdown > 0: draw_text('GET READY!', font40, white, int(screen_width / 2 - 110), int(screen_height / 2 + 50)) draw_text(str(countdown), font40, white, int(screen_width / 2 - 10), int(screen_height / 2 + 100)) count_timer = pygame.time.get_ticks() if count_timer - last_count > 1000: countdown -= 1 last_count = count_timer #update explosion group explosion_group.update() #draw sprite groups spaceship_group.draw(screen) bullet_group.draw(screen) alien_group.draw(screen) alien_bullet_group.draw(screen) explosion_group.draw(screen) #event handlers for event in pygame.event.get(): if event.type == pygame.QUIT: run = False elif event.type == pygame.MOUSEMOTION: spaceship.update(event.pos[0]) pygame.display.update() pygame.quit()