python - 如何在单独的模块中调用播放器 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
解决方案
有你想要的答案,也有你需要的答案。分别:
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)您必须直接导入非单例实例的事实就是代码异味-这个问题的存在应该向您发出的信号是,您可能有一个地方,您的代码必须能够与之交谈彼此,但您没有明确负责调解该过程的责任。
所以,为了解决我承诺的答案的第二部分:你不应该让这个问题发生在首位 - 构建专门用于管理玩家和敌人的东西,只导入类定义,然后在管理器中实例和它们之间的接口。
推荐阅读
- python - 单击按钮django时调用函数
- flutter - 如何在颤动中处理不同类型的字符(其他语言的字符和特殊字符)?
- angular - AmCharts Legend,如何在图表中的数据更改上重新单击未单击的图例
- python - 我可以像在交互模式下键入内容一样运行 Python 文件吗?
- javascript - API测试 | 验证响应
- python - python web抓取(如果使用所有标量值,则必须传递索引)
- javascript - 添加缓动/平滑滚动以使用js单击和拖动
- python - Python Gekko 流程图对象中有哪些方程式?
- java - 如果服务在集群模式下运行,则单独从数据库中读取
- algorithm - 平面上所有距离最小的最近点对