Python - Как взаимодействовать с классом в другом методе - PullRequest
0 голосов
/ 23 мая 2019

У меня проблема с взаимодействием с переменными классов внутри метода. Я хочу изменить положение объекта в 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 ]

1 голос
/ 24 мая 2019

Вы не можете просто позвонить Enemy.X, потому что Enemy - это определение класса.В другой строке у вас есть for enemy in enemy_list, который вызывает все экземпляры из Enemy (экземпляры отличаются, и здесь они 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()
0 голосов
/ 23 мая 2019

Вы пытаетесь достичь X, поскольку он является статическим членом класса Enemy, что неверно, поскольку он является атрибутом класса instance (object). Чтобы достичь этого, вам нужно использовать объект, который вы храните в списке enemy_list.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...