首页 > 解决方案 > 如何在单独的模块中调用播放器 rect

问题描述

我最近实现了一个敌人,它会定期在屏幕上的指定点射击。然而,在试图让玩家正确理解这一点时,它拒绝工作。由于敌人类是在房间模块中定义的,然后在主游戏模块中定义,我不太确定如何在敌人模块中调用玩家 rect。

工作代码如下:

游戏模块

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 

标签: pythonpygame

解决方案


有你想要的答案,也有你需要的答案。分别:

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)您必须直接导入非单例实例的事实就是代码异味-这个问题的存在应该向您发出的信号是,您可能有一个地方,您的代码必须能够与之交谈彼此,但您没有明确负责调解该过程的责任。

所以,为了解决我承诺的答案的第二部分:你不应该让这个问题发生在首位 - 构建专门用于管理玩家和敌人的东西,只导入类定义,然后在管理器中实例和它们之间的接口。


推荐阅读