Как исправить неправильную загрузку изображения объекта

#python #python-3.x #image #class #pygame

#python #python-3.x #изображение #класс #pygame

Вопрос:

Я пишу код, в котором на экране может появиться несколько врагов. Атрибут enemy раньше принимал атрибут color, который использовался для всех врагов, и теперь я пытаюсь изменить его на изображение, которое я могу загрузить. Я также заинтересован в том, чтобы сделать это так, чтобы я мог get_rect () из изображения, которое я буду использовать для проверки, когда враги находятся в определенном положении на экране.

Проблема в том, что, когда я пытался заменить атрибут color атрибутом image, предыдущий код был настолько зависим от загрузки врагов с атрибутом color, что мне трудно заставить код работать. В текущем коде, который я написал, изображение загружается неправильно.

Это старый (функциональный, использующий атрибут color), с которого я начал:

 
import sys
import pygame as pg


class Enemy:

    def __init__(self, pos, color):
        self.rect = pg.Rect(pos, (26, 45))
        self.color = color
        self.pos = pg.math.Vector2(pos)

    def update(self, player):
        vel = (player.center - self.pos).normalize() * 4
        self.pos  = vel
        self.rect.center = self.pos

    def draw(self, screen):
        pg.draw.rect(screen, self.color, self.rect)


def main():
    screen = pg.display.set_mode((640, 480))
    bg_color = pg.Color('gray12')
    player_color = pg.Color('dodgerblue1')
    enemy_color = pg.Color('sienna1')
    clock = pg.time.Clock()
    player = pg.Rect((100, 300), (26, 50))
    enemy_list = [Enemy((100, 300), enemy_color)]

    done = False

    while not done:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                done = True
            elif event.type == pg.KEYDOWN:
                if event.key == pg.K_f:
                    enemy_list.append(Enemy((400, 0), enemy_color))

        keys = pg.key.get_pressed()
        if keys[pg.K_a]:
            player.x -= 5
        elif keys[pg.K_d]:
            player.x  = 5
        if keys[pg.K_w]:
            player.y -= 5
        elif keys[pg.K_s]:
            player.y  = 5

        for enemy in enemy_list:
            enemy.update(player)

        screen.fill(bg_color)
        pg.draw.rect(screen, player_color, player)
        for enemy in enemy_list:
            enemy.draw(screen)

        pg.display.flip()
        clock.tick(30)


if __name__ == '__main__':
    pg.init()
    main()
    pg.quit()
    sys.exit()

  

И ниже приведен код, который я пытался изменить, но на данный момент не могу приступить к работе:

 
import sys
import pygame as pg
import os
from os import path

pg.init()

screen = pg.display.set_mode((640, 480))

game_folder = os.path.dirname(__file__)
img_folder = os.path.join(game_folder, "images")

enemy_img = pg.image.load(path.join(img_folder, "goblin.png"))

class Enemy(pg.sprite.Sprite):
    def __init__(self, pos, image):
      pg.sprite.Sprite.__init__(self)
      self.image = pg.transform.scale(enemy_img, (48,37))
      self.image.set_colorkey((0,0,0))
      self.rect = self.image.get_rect()
      self.pos = pg.math.Vector2(pos)

    def update(self, player):
        vel = [-5,0]
        self.pos  = vel
        self.rect.center = self.pos

    def draw(self, screen):
        screen.blit(Enemy.image, Enemy.rect)


def main():
    bg_color = pg.Color('gray12')
    player_color = pg.Color('dodgerblue1')
    clock = pg.time.Clock()
    player = pg.Rect((100, 300), (26, 50))
    enemy_list = [Enemy((100, 300), enemy_img)]

    done = False

    while not done:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                done = True
            elif event.type == pg.KEYDOWN:
                if event.key == pg.K_f:
                    enemy_list.append(Enemy((400, 0), enemy_img))

        keys = pg.key.get_pressed()
        if keys[pg.K_a]:
            player.x -= 5
        elif keys[pg.K_d]:
            player.x  = 5
        if keys[pg.K_w]:
            player.y -= 5
        elif keys[pg.K_s]:
            player.y  = 5

        for enemy in enemy_list:
            enemy.update(player)

        screen.fill(bg_color)
        #pg.draw.rect(screen, player_color, player)
        for enemy in enemy_list:
            enemy.draw(screen)

        pg.display.flip()
        clock.tick(30)


if __name__ == '__main__':
    pg.init()
    main()
    pg.quit()
    sys.exit()

  

Может кто-нибудь, пожалуйста, помочь мне выяснить, что пошло не так и какой код я должен изменить или добавить? Большое вам спасибо за ваше время.

Ответ №1:

Ваша проблема в этой строке:

 screen.blit(Enemy.image, Enemy.rect)
  

Здесь вы пытаетесь получить доступ к image атрибуту класса Enemy , но у Enemy класса нет такого атрибута, а также нет rect атрибута.

Вы могли бы исправить это, используя

 screen.blit(self.image, self.rect)
  

который будет использовать атрибуты экземпляра.

Но поскольку вы уже используете Sprite класс, не утруждайте себя рисованием спрайтов на экране самостоятельно и используйте Group :

 import sys
import pygame as pg
import os
from os import path

pg.init()

screen = pg.display.set_mode((640, 480))

game_folder = os.path.dirname(__file__)
img_folder = os.path.join(game_folder, "images")

enemy_img = pg.image.load(path.join(img_folder, "goblin.png"))

class Enemy(pg.sprite.Sprite):
    def __init__(self, pos, image):
      pg.sprite.Sprite.__init__(self)
      self.image = pg.transform.scale(enemy_img, (48,37))
      self.image.set_colorkey((0,0,0))
      self.rect = self.image.get_rect()
      self.pos = pg.math.Vector2(pos)

    def update(self, player):
        vel = [-5,0]
        self.pos  = vel
        self.rect.center = self.pos

def main():
    bg_color = pg.Color('gray12')
    player_color = pg.Color('dodgerblue1')
    clock = pg.time.Clock()
    player = pg.Rect((100, 300), (26, 50))
    enemy_list = pg.sprite.Group([Enemy((100, 300), enemy_img)])

    done = False

    while not done:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                done = True
            elif event.type == pg.KEYDOWN:
                if event.key == pg.K_f:
                    enemy_list.append(Enemy((400, 0), enemy_img))

        keys = pg.key.get_pressed()
        if keys[pg.K_a]:
            player.x -= 5
        elif keys[pg.K_d]:
            player.x  = 5
        if keys[pg.K_w]:
            player.y -= 5
        elif keys[pg.K_s]:
            player.y  = 5

        enemy_list.update(player)

        screen.fill(bg_color)
        enemy_list.draw(screen)

        pg.display.flip()
        clock.tick(30)


if __name__ == '__main__':
    pg.init()
    main()
    pg.quit()
    sys.exit()