O
O
OneCh4k2022-02-25 09:00:20
Python
OneCh4k, 2022-02-25 09:00:20

Why does it throw AttributeError: 'Enemy' object has no attribute 'get_height'?

import pygame
import random
import sys
import os
pygame.init()
pygame.mixer.init()
pygame.font.init()
width, height = 600,600
win = pygame.display.set_mode((width, height))
#load icon for game
#name for game 
pygame.display.set_caption("Space Invaders")
pygame.display.set_icon(pygame.image.load('image/icon-space-ship.png'))
'''load images'''
#load space ship 
RED_SPACE_SHIP = pygame.image.load('image/pixel_ship_red_small.png')
GREEN_SPACE_SHIP = pygame.image.load('image/pixel_ship_green_small.png')
BLUE_SPACE_SHIP = pygame.image.load('image/pixel_ship_blue_small.png')
#load player ship
YELLOW_SPACE_SHIP = pygame.image.load('image/pixel_ship_yellow.png')
#load laser
RED_LASER = pygame.image.load('image/pixel_laser_red.png')
YELLOW_LASER = pygame.image.load('image/pixel_laser_yellow.png')
GREEN_LASER = pygame.image.load('image/pixel_laser_green.png')
BLUE_LASER = pygame.image.load('image/pixel_laser_blue.png') 
#load background and transfor for game window
BG = pygame.transform.scale(pygame.image.load('image/background-black.png'),(width, height))

class Ship:
    COOLDOWN = 30

    def __init__(self, x, y, health=100):
        self.x = x
        self.y = y
        self.health = health
        self.ship_img = None
        self.laser_img = None
        self.lasers = []
        self.cool_down_counter = 0

    def draw(self, window):
        window.blit(self.ship_img, (self.x, self.y))
        for laser in self.lasers:
            laser.draw(window)

    def move_lasers(self, vel, obj):
        self.cooldown()
        for laser in self.lasers:
            laser.move(vel)
            if laser.off_screen(height):
                self.lasers.remove(laser)
            elif laser.collision(obj):
                obj.health -= 10
                self.lasers.remove(laser)

    def cooldown(self):
        if self.cool_down_counter >= self.COOLDOWN:
            self.cool_down_counter = 0
        elif self.cool_down_counter > 0:
            self.cool_down_counter += 1

class Lasers():
  def __init__(self, x, y, img):
    self.x = x
    self.y = y
    self.img = img
    self.mask = pygame.mask.from_surface(self.img)

  def draw(self, window):
    win.blit(self.img,(self.x, self.y))

  def move(self, vel):
    self.y += vel

  def off_screen(self, height):
    return self.y < height and self.y > 0
 
  def collision(self, obj):
    return collide(self, obj)  

class Player(Ship):
  def __init__(self, x, y, health = 100):
    super().__init__(x, y, health)
    self.ship_img = YELLOW_SPACE_SHIP
    self.laser_img = YELLOW_LASER
    self.mask = pygame.mask.from_surface(self.ship_img)

  def move_lasers(self, vel, objs):
    self.cooldown()
    for laser in self.lasers:
      laser.move(win)
      if laser.off_screen(height):
        self.lasers.remove(laser)
      else:
        for obj in objs:
          if laser.collision(objs):
            health -= 10
            objs.remove(obj) 
            self.lasers.remove(laser) 

class Enemy(Ship):
  #colors for lasers
  ship_color = {
        'red':(RED_SPACE_SHIP, RED_LASER),
        'green':(GREEN_SPACE_SHIP, GREEN_LASER),
        'blue':(BLUE_SPACE_SHIP, BLUE_LASER)
  }
  def __init__(self, x, y, color, health = 100):
    super().__init__(x, y, health)
    self.ship_img, self.lasers_img = self.ship_color[color]
    ship_mask = pygame.mask.from_surface(self.ship_img)

  def move(self, vel):
    self.y += vel
    
def collide(obj1, obj2):
    offset_x = obj2.x - obj1.x
    offset_y = obj2.y - obj1.y
    return obj1.mask.overlab(obj2 , (offset_x, offset_y)) != None

def main():
    main_font = pygame.font.SysFont('arial' , 30)
    lost_font = pygame.font.SysFont('comicsans' , 75)
    enemies = []
    wave_length = 5
    enemy_vel = 2
    run = True
    level = 0
    lives = 3    
    fps = 60
    player_vel = 6	
    player = Player(250,500)
    lost = False
    lost_count = 0
    laser_vel = 5
    def redraw_window():
        win.blit(BG, (0, 0))
        #draw text
        level_label = main_font.render(f'Level: {level}' , 1 ,(255, 255, 255))
        lives_label = main_font.render(f'Lives: {lives}', 1 , (255, 255, 255))
        win.blit(lives_label , (5 , 5))
        win.blit(level_label , (width - level_label.get_width() - 5, 5))
        for enemy in enemies:
        	enemy.draw(win)

        if lost:
        	lost_lable = lost_font.render("Ты проиграл!", 1 ,(255, 255, 255))
        	win.blit(lost_lable, (width / 2 - lost_lable.get_width()/2 , 300)) 

        player.draw(win)
        pygame.display.update()       
    clock = pygame.time.Clock()    
    while run:
        clock.tick(fps)
        redraw_window() 
        if len(enemies) == 0:
        	level += 1
        	wave_length += 5        
        	
        	for i in range(wave_length):
        		enemy = Enemy(random.randrange(50, width - 100), random.randrange(-1200, -120), random.choice(['red', 'green', 'blue']))
        		enemies.append(enemy)
        
        if lives <= 0 or player.health <= 0:
        	lost = True
        	lost_count += 1 
        if lost:
        	if lost_count > fps * 5:
        		sys.exit()
        	else:
        		continue 
        
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()       
        
        keys = pygame.key.get_pressed()
        if keys[pygame.K_a] and player.x- player_vel > 0:        	
        	player.x -= player_vel #left
        if keys[pygame.K_d] and player.x + player_vel + player.get_width() < width:        	
        	player.x += player_vel #right
        if keys[pygame.K_w] and player.y - player_vel > 0:        	
        	player.y -= player_vel #up 
        if keys[pygame.K_s] and player.y + player_vel + player.get_height() < height:
        	player.y += player_vel #down 
        if keys[pygame.K_SPACE]:
        	player.shoot()     
        for enemy in enemies:
        	enemy.move(enemy_vel)
        	enemy.move_lasers(laser_vel, player) 
        	if enemy.y + enemy.get_height() > height:
        		lives -= 1
        		enemies.remove(enemy)
        player.move_lasers(laser_vel, self.enemies) 
        

main()

Answer the question

In order to leave comments, you need to log in

2 answer(s)
I
Igor Markin, 2022-02-25
@OneCh4k

You have created an Enemy object that inherits from Ship. But none of them defined a methodget_height() . Hence the error.

I
Ivan Chetchasov, 2022-02-26
@TalismanChet

You've created Enemy , and based on what you wrote, you should probably use enemy.ship_img.get_height() instead of enemy.get_height() if you want to get the height of the enemy image image .
If my answer was helpful, please tick it. Thanks

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question