我在实体类方面遇到问题。下面是实体类的脚本:
import uuid, pyglet, random
class overworld_0001():
resources = {}
def __init__(self, engine, position, type_p, gender, **kwargs):
super(overworld_0001, self).__init__(**kwargs)
self.engine = engine
self.type_entity = "pk"
self.id = uuid.uuid4()
self.type_p = type_p
self.gender = gender
self.x = position[0]
self.y = position[1]
self.target_x = self.x
self.target_y = self.y
self.stat = "stand"
self.direction = 3
self.overworld = True
self.speed = engine.dict_pokemon["0001"]["overworld"]["speed"]
resource = engine.resouces["0001"]
self.resources["overworld"] = {}
if not type_p + "-" + gender in resource["overworld"]:
typ = resource["overworld"][type_p]
else:
typ = resource["overworld"][type_p + "-" + gender]
for stat in typ:
self.resources["overworld"][stat] = {}
for count in typ[stat]:
sprite = pyglet.sprite.Sprite(img=typ[stat][count], x=self.x, y=self.y)
sprite.target_x = self.target_x
sprite.target_y = self.target_y
self.resources["overworld"][stat][count] = sprite
self.current_sprite = self.resources["overworld"][self.stat][self.direction]
self.width = self.current_sprite.width
self.height = self.current_sprite.height
self.size = max(self.width, self.height)
def update(self, dt):
self.entity = self.engine.list_sprite_layers["3"]
if self.overworld:
self.update_overworld(dt)
def is_tile_free(self, x, y):
for entity in self.engine.list_sprite_layers["3"]:
if entity.id != self.id:
if (x < entity.x + entity.width and
x + self.width > entity.x and
y < entity.y + entity.height and
y + self.height > entity.y):
return False
return True
def update_overworld(self, dt):
if self.stat == "stand":
directions = {
0: (0, self.size),
1: (self.size, 0),
2: (-self.size, 0),
3: (0, -self.size)
}
possible_moves = []
for direction, (dx, dy) in directions.items():
new_x = self.x + dx
new_y = self.y + dy
if self.is_tile_free(new_x, new_y):
possible_moves.append((direction, new_x, new_y))
if possible_moves:
chosen_move = random.choice(possible_moves)
self.direction, self.target_x, self.target_y = chosen_move
self.stat = "run"
self.current_sprite.x = self.x
self.current_sprite.y = self.y
else:
self.stat = "stand"
if self.stat == "run":
if self.target_x != self.x:
direction_x = (self.target_x - self.x) / abs(self.target_x - self.x)
self.x += direction_x * self.speed * dt
if abs(self.target_x - self.x) < self.speed * dt:
self.x = self.target_x
if self.target_y != self.y:
direction_y = (self.target_y - self.y) / abs(self.target_y - self.y)
self.y += direction_y * self.speed * dt
if abs(self.target_y - self.y) < self.speed * dt:
self.y = self.target_y
if self.x == self.target_x and self.y == self.target_y:
self.stat = "stand"
self.current_sprite.x = self.x
self.current_sprite.y = self.y
#self.current_sprite = self.resources["overworld"][self.stat][self.direction]
self.current_sprite.x = self.x
self.current_sprite.y = self.y
def on_draw(self):
self.current_sprite.draw()
我知道规则要求放置一个带有错误的脚本以便重现它,我想这样做,但不幸的是我不知道错误是什么。
照原样,它可以工作并且没有问题:
图像
但是如果在
update_overworld
我插入
self.current_sprite = self.resources["overworld"][self.stat][self.direction]
这就是我得到的:
图像
现在,我不知道错误是什么,但我假设可能有两个,这是因为实体在单个时可以工作,但是当我创建两个或更多时,它开始执行您在图像中看到的操作(并且我创建的实体越多,或者在 init 中,当从加载的资源中获取纹理并将其转换为精灵时,不是创建单个精灵,而是每个实体共享该精灵,并且每个实体都会修改其他实体的精灵.
-
每个实体的update_overworld函数中,除了修改自身之外,还修改了其他实体。
-
我想到这两个假设,主要是因为如果实体是单一的,则不会出现问题。您有什么意见或帮助吗?我使用的是 Pyglet 2.0.16 和 Python 3.12
These two hypotheses come to me, mostly because if the entity is single, the problem does not occur. Do you have any opinions or help? What I am using is Pyglet 2.0.16 and Python 3.12
问题出在你如何创建和更新精灵。你只创建了一组精灵,然后在所有实体之间共享这些精灵。这就是为什么当有多个实体时,你会看到它们闪烁 - 它们都在争夺同一个精灵资源。
你需要为每个实体实例化自己的精灵集。试试这个修改过的代码:
import uuid, pyglet, random
class overworld_0001():
def __init__(self, engine, position, type_p, gender, **kwargs):
super(overworld_0001, self).__init__(**kwargs)
self.engine = engine
self.type_entity = "pk"
self.id = uuid.uuid4()
self.type_p = type_p
self.gender = gender
self.x = position[0]
self.y = position[1]
self.target_x = self.x
self.target_y = self.y
self.stat = "stand"
self.direction = 3
self.overworld = True
self.speed = engine.dict_pokemon["0001"]["overworld"]["speed"]
# 为每个实体实例化精灵
self.resources = self.load_resources(engine)
self.current_sprite = self.resources["overworld"][self.stat][self.direction]
self.width = self.current_sprite.width
self.height = self.current_sprite.height
self.size = max(self.width, self.height)
def load_resources(self, engine):
resources = {"overworld": {}}
resource = engine.resouces["0001"]
if not self.type_p + "-" + self.gender in resource["overworld"]:
typ = resource["overworld"][self.type_p]
else:
typ = resource["overworld"][self.type_p + "-" + self.gender]
for stat in typ:
resources["overworld"][stat] = {}
for count in typ[stat]:
sprite = pyglet.sprite.Sprite(img=typ[stat][count], x=self.x, y=self.y)
sprite.target_x = self.target_x
sprite.target_y = self.target_y
resources["overworld"][stat][count] = sprite
return resources
# ... rest of your code ...
更改:
-
从类级别删除
resources
:resources
现在是在__init__
中每个实例加载,而不是在类级别共享。 -
为每个实体创建
resources
:load_resources
函数现在是在每个实体的__init__
中调用,为该特定实体创建一组唯一的精灵。
此更改可确保每个实体都有自己的一组精灵,从而防止闪烁问题。
标签:python,python-3.x,pyglet,python-3.12 From: 78836238