Как позвонить игроку в прямоугольник в отдельном модуле - PullRequest
0 голосов
/ 29 августа 2018

Я недавно внедрил врага, который стреляет через равные промежутки времени в назначенную точку на экране. Однако, попытавшись сделать это правильно, игрок отказался работать. Поскольку класс врага определяется в модуле комнат, который затем определяется в основном игровом модуле, я не совсем уверен в том, как вызвать игрока прямо в модуле врага.

Рабочий код следующим образом:

Игровой модуль

import pygame
from constants import *
from player import Player
from pygame.math import Vector2
from enemy import *
from Rooms import Room0


pygame.init()

screen_rect = pygame.display.set_mode([500, 500])

pygame.display.set_caption('Labyrinth')


all_sprites_list = pygame.sprite.Group()
projectiles = pygame.sprite.Group()
enemy_sprites = pygame.sprite.Group()

# Assign rooms
rooms = []
room = Room0()
rooms.append(room)

current_room_no = 0
current_room = rooms[current_room_no]


# Spawn player

player = Player(50, 50)
all_sprites_list.add(player)


clock = pygame.time.Clock()


done = False


# ----- Event Loop

while not done:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True


# ----- Game Logic

    all_sprites_list.update()
    current_room.projectiles.update()
    current_room.enemy_sprites.update()



    screen_rect.fill(GREEN)

    all_sprites_list.draw(screen_rect)
    current_room.projectiles.draw(screen_rect)
    current_room.enemy_sprites.draw(screen_rect)


    pygame.display.flip()

    clock.tick(60)

pygame.quit()

комнатный модуль

import pygame
from enemy import Enemy
import Projectile
from pygame.math import Vector2


class Room(object):
    enemy_sprites = None
    projectiles = None

    def __init__(self):

        self.enemy_sprites = pygame.sprite.Group()
        self.projectiles = pygame.sprite.Group()



class Room0(Room):
    def __init__(self):
        super().__init__()

        enemy = Enemy(380, 280, self.projectiles)
        self.enemy_sprites.add(enemy)

Модуль плеера

from constants import *
import pygame


class Player(pygame.sprite.Sprite):


    def __init__(self, x, y):

        super().__init__()

        self.image = pygame.Surface([15, 15])
        self.image.fill(BLACK)

        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y

Вражеский модуль

from constants import *
import pygame
from Projectile import Bullet
from pygame.math import Vector2

target = Vector2(400, 400)

class Enemy(pygame.sprite.Sprite):

    def __init__(self, x, y, projectiles):

        super().__init__()

        self.image = pygame.Surface([10, 10])
        self.image.fill(RED)

        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y

        self.previous_time = pygame.time.get_ticks()
        self.shoot_delay = 1000
        self.speed = 12
        self.projectiles = projectiles

    def update(self):

        now = pygame.time.get_ticks()
        if now - self.previous_time > self.shoot_delay:
            self.previous_time = now
            bullet = Bullet(self.rect.x, self.rect.y, target)
            self.projectiles.add(bullet)

Модуль снаряда

import pygame
from constants import *
from pygame.math import Vector2

class Bullet(pygame.sprite.Sprite):

    def __init__(self, x, y, target):

        super().__init__()

        self.image = pygame.Surface((10, 10))
        self.image.fill(RED)

        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y

        self.position = Vector2(self.rect.x, self.rect.y)


        direction = target - self.position

        radius, angle = direction.as_polar()
        self.image = pygame.transform.rotozoom(self.image, -angle, 1)

        self.velocity = direction.normalize() * 11

    def update(self):

        self.position += self.velocity
        self.rect.center = self.position 

1 Ответ

0 голосов
/ 29 августа 2018

Есть ответ, который вы хотите, и ответ, который вам нужен. Соответственно:

SomeModule.py:

from game import player # imports the Player *instance* you've created in the main module

some_func(player) # as argument
player.another_func # method access

Так вот, таким способом вы обычно получаете доступ к подобным вещам, и это было бы прекрасно. В этом случае, хотя:

a) Вы создадите совершенно новый игровой цикл, потому что вы помещаете настройки игры в область видимости модуля, а не в какую-то функцию или, по крайней мере, прямо под if __name__ == '__main__'. При импорте модуля выполняется весь код в области видимости модуля.

b) Сам факт того, что вы должны импортировать не-одиночный экземпляр напрямую, является запахом кода - то, что само существование этой проблемы должно сигнализировать вам, это то, что у вас, вероятно, есть место, где Ваши кусочки кода должны иметь возможность общаться друг с другом, но вы не несете никакой однозначной ответственности за посредничество в этом процессе.

Итак, для решения второй части моего обещанного ответа: вы не должны позволять этой проблеме возникать в первую очередь - создайте что-то, предназначенное для управления игроками и врагами , импортируйте только определения классов, а затем экземпляр и интерфейс между ними в диспетчере.

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