Python-如何以不同的方法与类进行交互 [英] Python - How to interact with class in different method

查看:95
本文介绍了Python-如何以不同的方法与类进行交互的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在与方法中的类变量进行交互时遇到问题.我想更改对象在pygame中的位置.这必须在方法中完成,因为我使用threading,它需要将其目标作为方法. 如何在enemy_list中定位特定的enemy?

I am having an issue with interacting with a classes variables from within a method. I want to change the position of an object in pygame. This has to be done in a method as i use threading which needs its targets to be methods. How can i target a specific enemy in enemy_list?

我尝试将整个Enemy类放入EnemyMove方法中,但仍会输出:

I have tried putting the whole Enemy class into the EnemyMove Method and it still outputs:

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中工作?

What am I doing wrong? Why does it work in Gameplay but not in EnemyMove?

推荐答案

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

You can't simply call Enemy.X because Enemy is a class definition. In the other line you have for enemy in enemy_list which calls upon all the instances of Enemy (instances are different and here they are enemy with a lowercase). To follow a player you would first need a player in your code! I would also recommend you don't use a new thread for each functionality of your game. You can throw in your logic to move enemies into your normal game loop which already has its own thread.

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移动.

As @furas notes though you may be better off with just a mainloop that has sub-functions to check all these things! I suspect the next thing you would want to do is implement a keyboard listener to allow your player to move.

还请注意,这时我们有两个看上去非常相似的类.我们可能将从这两个类都继承的基类(例如Human)中受益.这样,我们可以用单行代码将特征添加到两个类中.如果需要,子类仍然可以覆盖提供的值:

Also note that at this point we have two classes that look very similar. We will probably benefit from having a base class (let's say Human) that both these classes inherit from. In this way we can add a trait to both classes with a single line of code. The child classes can still overwrite the values supplied though if needed:

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

这篇关于Python-如何以不同的方法与类进行交互的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆