【问题标题】:How to apply class methods to my own class' property in Python如何在 Python 中将类方法应用于我自己的类的属性
【发布时间】:2020-01-30 22:04:42
【问题描述】:

我为 Pygame 创建了一个名为 Thing 的类,稍后将对其进行子类化以开发更具体的类和对象。此类需要存储对象的位置大小等属性。

然而,Pygame 有一个非常强大的名为Rect 的类,它已经可以做到这一点,并且有许多有用的内置方法和属性。我可以在我的Thing 类中使用单个Rect 属性,但它将位置存储在整数中,我希望将它存储在浮点数中(Thing 可能需要少移动每帧一个像素)。

这就是我的想法。

class Thing:
    def __init__(self, pos, size):
        self.x: float = pos[0]
        self.y: float = pos[1]
        self.size = size

    @property
    def rect(self):
        return pygame.Rect((self.x, self.y), self.size)

    @rect.setter
    def rect(self, var: pygame.Rect):
        self.x = var.x
        self.y = var.y
        self.size = var.size

这将允许我获取和设置ThingRect,但我无法根据需要使用Rect 的内置设置器:

foo = Thing((10, 10), (20, 20))
foo.draw(win)

foo.x += 100
foo.draw(win)

# This has no effect
foo.rect.y += 100
foo.draw(win)

temp = foo.rect
temp.x -= 100
foo.rect = temp
foo.draw(win)

上述代码的期望行为是让方块向右移动,向下,然后向左移动。

有没有办法:

  • Rect 用作Thing 属性,但在更改时更新xy
  • 将方法应用于Rect 属性
  • 您能想到的其他一些解决方案

TL;DR:如果我有 Rect 作为属性,我不能做 self.rect.center = (500,500)

提前致谢!

【问题讨论】:

  • 您的属性有点奇怪,因为每次访问它时它都会返回一个新的Rect 实例,而不是返回Thing现有 部分。
  • 是的!那是因为我必须分别跟踪 xy 以便将位置存储在浮点数中。但我也想使用Rect 方法来检测碰撞,获取和设置中心坐标等。
  • @SamuelCabrera 如果您只需要中心坐标,那么也可以创建一个center 属性。

标签: python methods properties pygame


【解决方案1】:

你的类应该继承自pygame.Rect。这是自动获取Rect 方法的唯一方法。但是,通过这样做,您还将继承坐标的int 类型转换,因为这是在pygame.Rect 的原始实现中。恐怕继承不能解决你的问题。

您知道Rect 方法应该做什么(documentation 写得很好),所以恐怕唯一的方法是为您自己重新实现它们(或至少重新实现您需要的那些)@ 987654327@ 类,用浮点数模拟 Rect 行为。

我做了类似的事情:这是我写的课程的一部分(我不会全部展示,因为太长了)给你一个想法:

class FlRect:
    """Similar to pygame.Rect but uses float numbers.

    The class stores internally only coordinates, width and height.
    Other attributes are rendered through properties, with getter and setter:
    x, y: coordinates of the top-left corner of the rectangle.
    top, bottom: y coordinates of the top and bottom edges respectively.
    left, right: x coordinates of the left and right edges respectively.
    centerx, centery: coordinates of the centre of the rectangle.
    width, height: self-explanatory. 
    """

    def __init__(self, x, y, w, h):
        """Initialization:

        x, y - coordinates of top-left corner of the rectangle
        w, h - width and height
        """
        self._x = x
        self._y = y
        self._w = w
        self._h = h

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

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

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

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

    @property
    def width(self):
        return self._w

    @width.setter
    def width(self, value):
        self._w = value

    @property
    def height(self):
        return self._h

    @height.setter
    def height(self, value):
        self._h = value

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

    @top.setter
    def top(self, value):
        self._y = value

    @property
    def bottom(self):
        return self._y + self._h

    @bottom.setter
    def bottom(self, value):
        self._y = value - self._h

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

    @left.setter
    def left(self, value):
        self._x = value

    @property
    def right(self):
        return self._x + self._w

    @right.setter
    def right(self, value):
        self._x = value - self._w

    @property
    def centerx(self):
        return self._x + (self._w / 2)

    @centerx.setter
    def centerx(self, value):
        self._x = value - (self._w / 2)

    @property
    def centery(self):
        return self._y + (self._h / 2)

    @centery.setter
    def centery(self, value):
        self._h = value - (self._h / 2)

    def get_rect(self):
        """Return a pygame.Rect object with rounded coordinates"""
        return Rect(round(self._x), round(self._y), round(self._w), round(self._h))

当然,这不会像pygame.Rect 那样高效,因为这是用 python 编写的,而 pygame Rect 类是用 C 语言编写的。

【讨论】:

  • 谢谢!我担心 可能不得不做这样的事情,但不知道该怎么做。现在你只是为我做了。再次感谢!
猜你喜欢
  • 2014-05-07
  • 2019-05-27
  • 1970-01-01
  • 2011-05-27
  • 1970-01-01
  • 1970-01-01
  • 2022-06-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多