首页 > 解决方案 > Python - 如何以不同的方法与类交互

问题描述

我在与方法内的类变量交互时遇到问题。我想在pygame中改变一个对象的位置。这必须在我使用的方法中完成,该方法threading需要其目标是方法。我怎样才能针对特定enemyenemy_list

我已经尝试将整个Enemy类放入EnemyMove方法中,它仍然输出:

AttributeError: type object 'Enemy' has no attribute 'X'

这里的代码:

import pygame
import threading
from random import randint
from time import sleep

pygame.init()
window = pygame.display.set_mode((900, 900))
bg = pygame.image.load("Background.png").convert()

class Enemy:
    def __init__(self):
        self.W = 50
        self.H = 50
        self.X = 420
        self.Y = 850

def Gameplay():
    global enemy_list
    speed=2
    while True:
        window.blit(bg, [0, 0])
        for enemy in enemy_list:
            pygame.draw.rect(window, (255, 50, 49), (enemy.X, enemy.Y, enemy.W, enemy.H))
        pygame.display.update()

def EnemySpawn():
    global enemy_list
    while True: # make enemies forever
        print("Spawned an enemy")
        enemy_list.append(Enemy()) # make an instance of our class
        sleep(randint(1, 5))

def EnemyMove():
    print(Enemy.X) #ISSUE OCURS HERE

enemy_list = [] # to maintain records of all enemies made
enemyMovement_thread = threading.Thread(target=EnemyMove)
enemyMovement_thread.start()
game_thread = threading.Thread(target=Gameplay)
game_thread.start()
enemy_spawner_thread = threading.Thread(target=EnemySpawn)
enemy_spawner_thread.start()

我究竟做错了什么?为什么它可以工作Gameplay但不能工作EnemyMove

标签: pythonmultithreadingclasspygame

解决方案


您不能简单地调用Enemy.X,因为Enemy它是一个类定义。在另一行中for enemy in enemy_list,您调用了( instances are different and here they are with a smallcase)的所有实例。要关注玩家,您首先需要在代码中添加玩家!我还建议您不要为游戏的每个功能都使用新线程。您可以投入逻辑将敌人移动到已经有自己线程的正常游戏循环中。Enemyenemy

import pygame
import threading
from random import randint
from time import sleep

pygame.init()
window = pygame.display.set_mode((900, 900))
bg = pygame.image.load("Background.png").convert()

class Enemy:
    def __init__(self):
        self.W = 50
        self.H = 50
        self.X = 420
        self.Y = 850
        self.speed = 1

class Player: # make a new class so players can have better stats
    def __init__(self):
        self.W = 50
        self.H = 50
        self.X = 300
        self.Y = 300
        self.speed = 10

def Gameplay():
    global enemy_list
    global player
    while True:
        window.blit(bg, [0, 0])
        pygame.draw.rect(window, (255, 255, 255), (player.X, player.Y, player.W, player.H))
        for enemy in enemy_list:
            if enemy.X > player.X:
                enemy.X = enemy.X - enemy.speed
            else:
                enemy.X = enemy.X + enemy.speed
            if enemy.Y > player.Y:
                enemy.Y = enemy.Y - enemy.speed
            else:
                enemy.Y = enemy.Y + enemy.speed
            pygame.draw.rect(window, (255, 50, 49), (enemy.X, enemy.Y, enemy.W, enemy.H))
        pygame.display.update()

def EnemySpawn():
    global enemy_list
    while True: # make enemies forever
        print("Spawned an enemy")
        enemy_list.append(Enemy()) # make an instance of our class
        sleep(randint(1, 5))

if __name__ == "__main__":
    player = Player() # notice the difference in capitalization!
    enemy_list = [] # to maintain records of all enemies made
    game_thread = threading.Thread(target=Gameplay)
    game_thread.start()
    enemy_spawner_thread = threading.Thread(target=EnemySpawn)
    enemy_spawner_thread.start()

正如@furas 指出的那样,尽管您可能最好只使用mainloop具有检查所有这些东西的子功能!我怀疑您要做的下一件事是实现一个键盘侦听器以允许您player移动。

另请注意,此时我们有两个看起来非常相似的类。我们可能会受益于拥有Human这两个类都继承自的基类(比方说)。通过这种方式,我们可以用一行代码为两个类添加一个特征。如果需要,子类仍然可以覆盖提供的值:

import pygame
import threading
from random import randint
from time import sleep

pygame.init()
window = pygame.display.set_mode((900, 900))
bg = pygame.image.load("Video & Image Processing/Image Processing/InputImage.jpg").convert()

class Human:
    def __init__(self):
        self.W = 50
        self.H = 50
        self.X = 420
        self.Y = 850
        self.speed = 1

class Enemy(Human): # inherit Human
    def __init__(self):
        Human.__init__(self) # get all traits a Human has

class Player(Human): # inherit Human
    def __init__(self):
        Human.__init__(self) # get all traits a Human has
        self.X = 300 # overwrite specific traits
        self.Y = 300

def Gameplay():
    global enemy_list
    global player
    while True:
        window.blit(bg, [0, 0])
        pygame.draw.rect(window, (255, 255, 255), (player.X, player.Y, player.W, player.H))
        for enemy in enemy_list:
            if enemy.X > player.X:
                enemy.X = enemy.X - enemy.speed
            else:
                enemy.X = enemy.X + enemy.speed
            if enemy.Y > player.Y:
                enemy.Y = enemy.Y - enemy.speed
            else:
                enemy.Y = enemy.Y + enemy.speed
            pygame.draw.rect(window, (255, 50, 49), (enemy.X, enemy.Y, enemy.W, enemy.H))
        pygame.display.update()

def EnemySpawn():
    global enemy_list
    while True: # make enemies forever
        print("Spawned an enemy")
        enemy_list.append(Enemy()) # make an instance of our class
        sleep(randint(1, 5))


if __name__ == "__main__":
    player = Player() # notice the difference in capitalization!
    enemy_list = [] # to maintain records of all enemies made
    game_thread = threading.Thread(target=Gameplay)
    game_thread.start()
    enemy_spawner_thread = threading.Thread(target=EnemySpawn)
    enemy_spawner_thread.start()

推荐阅读