You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现Entity类中position与tile_position属性的联动更新?

双向联动position与tile_position的优雅实现方案

核心思路是给通用的Vector类添加可选的分量变化回调,让Entity类监听两个Vector的变化,在回调中完成双向同步,同时通过标志位避免循环更新。

1. 修改Vector类,添加变化回调

给Vector增加一个on_change可选参数,当x/y分量修改时触发该回调,确保Vector仍保持通用属性,无需持有Entity引用:

class Vector:
    def __init__(self, x=0, y=0, on_change=None):
        self._x = x
        self._y = y
        self.on_change = on_change  # 分量变化时触发的回调

    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, value):
        if self._x != value:
            self._x = value
            if self.on_change:
                self.on_change(self)

    @property
    def y(self):
        return self._y

    @y.setter
    def y(self, value):
        if self._y != value:
            self._y = value
            if self.on_change:
                self.on_change(self)

    def __repr__(self):
        return f"Vector({self.x}, {self.y})"

2. 实现Entity类的双向同步逻辑

在Entity中维护两个Vector实例,分别绑定回调函数,通过_updating标志避免循环更新,同时覆盖直接赋值整个属性和修改分量两种场景:

def tile_to_position(entity, x, y):
    return (x + entity.tile_width / 2, y + entity.tile_height / 2)

def position_to_tile(entity, x, y):
    return (round(x - entity.tile_width / 2), round(y - entity.tile_height / 2))

class Entity:
    def __init__(self, tile_width=1, tile_height=1):
        self.tile_width = tile_width
        self.tile_height = tile_height
        self._updating = False  # 防止循环更新的锁标志

        # 初始化两个Vector,绑定各自的变化回调
        self._position = Vector(on_change=self._on_position_change)
        self._tile_position = Vector(on_change=self._on_tile_position_change)
        # 初始同步位置
        self._sync_position_to_tile()

    def _on_position_change(self, _):
        if not self._updating:
            self._updating = True
            self._sync_position_to_tile()
            self._updating = False

    def _on_tile_position_change(self, _):
        if not self._updating:
            self._updating = True
            self._sync_tile_to_position()
            self._updating = False

    def _sync_position_to_tile(self):
        # 根据position计算并更新tile_position
        tile_x, tile_y = position_to_tile(self, self._position.x, self._position.y)
        self._tile_position.x = tile_x
        self._tile_position.y = tile_y

    def _sync_tile_to_position(self):
        # 根据tile_position计算并更新position
        pos_x, pos_y = tile_to_position(self, self._tile_position.x, self._tile_position.y)
        self._position.x = pos_x
        self._position.y = pos_y

    @property
    def position(self):
        return self._position

    @position.setter
    def position(self, value):
        if not self._updating:
            self._updating = True
            self._position.x = value.x
            self._position.y = value.y
            self._sync_position_to_tile()
            self._updating = False

    @property
    def tile_position(self):
        return self._tile_position

    @tile_position.setter
    def tile_position(self, value):
        if not self._updating:
            self._updating = True
            self._tile_position.x = value.x
            self._tile_position.y = value.y
            self._sync_tile_to_position()
            self._updating = False

3. 额外优化:支持tile_width/tile_height动态修改

如果需要在运行时修改tile尺寸后自动同步位置,可以给tile_width和tile_height添加setter:

class Entity:
    # ... 保留其他代码 ...

    def __init__(self, tile_width=1, tile_height=1):
        self._tile_width = tile_width
        self._tile_height = tile_height
        # ... 保留其他初始化代码 ...

    @property
    def tile_width(self):
        return self._tile_width

    @tile_width.setter
    def tile_width(self, value):
        if self._tile_width != value:
            self._tile_width = value
            if not self._updating:
                self._updating = True
                self._sync_position_to_tile()
                self._updating = False

    @property
    def tile_height(self):
        return self._tile_height

    @tile_height.setter
    def tile_height(self, value):
        if self._tile_height != value:
            self._tile_height = value
            if not self._updating:
                self._updating = True
                self._sync_position_to_tile()
                self._updating = False

方案优势

  • Vector保持通用性:回调是可选参数,不影响Vector在其他场景的使用,也不会产生循环引用。
  • 全场景覆盖:无论是直接赋值整个position/tile_position,还是修改它们的x/y分量,都能触发双向同步。
  • 避免循环更新:通过_updating标志阻断回调的循环触发,防止死循环。
  • 扩展性强:可以轻松扩展支持tile尺寸动态修改等需求。

内容的提问来源于stack exchange,提问作者RedRuin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 19:08:21