Python-如何以不同的方法与类进行交互

时间:2019-05-23 19:57:50

标签: python multithreading class pygame

我在与方法中的类变量进行交互时遇到问题。我想更改对象在pygame中的位置。这必须在方法中完成,因为我使用threading,它需要将其目标作为方法。 如何在enemy中定位特定的enemy_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中无效?

2 个答案:

答案 0 :(得分:1)

您不能简单地调用Enemy.X,因为Enemy是一个类定义。在另一行中,您有for enemy in enemy_list,它调用Enemy的所有 instances (实例是不同的,这里的enemy是小写字母)。要跟随玩家,您首先需要代码中的玩家!我还建议您不要为游戏的每个功能使用新线程。您可以投入逻辑将敌人移动到已经具有自己线程的普通游戏循环中。

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()

答案 1 :(得分:0)

您正在尝试到达X,因为它是future::future(..., globals = structure(TRUE, add = globals)) 类的静态成员,这是错误的,因为它是类 instance (对象)的属性。要达到此目的,您需要使用对象,即保存在Enemy列表中的对象。