0

我正在尝试为乒乓球游戏编写代码,但是在尝试控制球拍位置的范围时遇到了一个问题,问题是:python中有没有办法将变量保持在一定范围内(使用最大值和最小值)当变量变化(增加)时,它会停留在该范围的最大值上,当这个变量减少时,它会停留在最小值上?.

我写了这段代码:

Range = range(HALF_PAD_HEIGHT, HEIGHT - HALF_PAD_HEIGHT) 
if (paddle1_pos[1] in Range) and (paddle2_pos[1] in Range):    
      paddle1_pos[1] += paddle1_vel[1]
      paddle2_pos[1] += paddle2_vel[1]  

当桨位置的值(paddle1_pos[1] 和 paddle2_pos[1])超出范围时,我无法再使用键盘更新其位置(通过变量(paddle1_vel[1] 和 paddle2_val[2 ]) 所以,我在想python中可能存在一些允许我更新paddle_pos的东西,当我到达范围的一侧时,它会让我保持在那一边,直到我改变更新的方向。希望问题很清楚。

谢谢

4

2 回答 2

1

您可以定义自己的“有界”数字类型。例如,如果paddle1_pos[1]是一个整数值,您可以创建一个如下所示的类并使用它来代替

class BoundedInt(int):
    def __new__(cls, *args, **kwargs):
        lower, upper = bounds = kwargs.pop('bounds')

        val = int.__new__(cls, *args, **kwargs)  # supports all int() args
        val = lower if val < lower else upper if val > upper else val

        val = super(BoundedInt, cls).__new__(cls, val)
        val._bounds = bounds
        return val

    def __add__(self, other):
        return BoundedInt(int(self)+other, bounds=self._bounds)
    __iadd__ = __add__

    def __sub__(self, other):
        return BoundedInt(int(self)-other, bounds=self._bounds)
    __isub__ = __sub__

    def __mul__(self, other):
        return BoundedInt(int(self)*other, bounds=self._bounds)
    __imul__ = __mul__

    # etc, etc...

if __name__ == '__main__':
    v = BoundedInt(100, bounds=(0, 100))
    print type(v), v
    v += 10
    print type(v), v
    w = v + 10
    print type(w), w
    x = v - 110
    print type(x), x

输出:

<class '__main__.BoundedInt'> 100
<class '__main__.BoundedInt'> 100
<class '__main__.BoundedInt'> 100
<class '__main__.BoundedInt'> 0
于 2012-11-09T23:30:37.650 回答
1

为了完整起见,这是另一个答案,它显示了如何使用元类以编程方式将整数具有的所有算术方法添加到自定义类中。请注意,尚不清楚在每种情况下返回与操作数具有相同边界的 BoundedInt 是否有意义。该代码还与 Python 2 和 3 兼容。

class MetaBoundedInt(type):
    # int arithmetic methods that return an int
    _specials = ('abs add and div floordiv invert lshift mod mul neg or pos '
                 'pow radd rand rdiv rfloordiv rlshift rmod rmul ror rpow '
                 'rrshift rshift rsub rtruediv rxor sub truediv xor').split()
    _ops = set('__%s__' % name for name in _specials)

    def __new__(cls, name, bases, attrs):
        classobj = type.__new__(cls, name, bases, attrs)
        # create wrappers for specified arithmetic operations
        for name, meth in ((n, m) for n, m in vars(int).items() if n in cls._ops):
            setattr(classobj, name, cls._WrappedMethod(cls, meth))
        return classobj

    class _WrappedMethod(object):
        def __init__(self, cls, func):
            self.cls, self.func = cls, func

        def __get__(self, obj, cls=None):
            def wrapper(*args, **kwargs):
                # convert result of calling self.func() to cls instance
                return cls(self.func(obj, *args, **kwargs), bounds=obj._bounds)
            for attr in '__module__', '__name__', '__doc__':
                setattr(wrapper, attr, getattr(self.func, attr, None))
            return wrapper

def with_metaclass(meta, *bases):
    """ Py 2 & 3 compatible way to specifiy a metaclass. """
    return meta("NewBase", bases, {})

class BoundedInt(with_metaclass(MetaBoundedInt, int)):
    def __new__(cls, *args, **kwargs):
        lower, upper = bounds = kwargs.pop('bounds')
        val = int.__new__(cls, *args, **kwargs)  # supports all int() args
        val = super(BoundedInt, cls).__new__(cls, min(max(lower, val), upper))
        val._bounds = bounds
        return val

if __name__ == '__main__':
    # all results should be BoundInt instances with values within bounds
    v = BoundedInt('64', 16, bounds=(0, 100))  # 0x64 == 100
    print('type(v)={}, value={}, bounds={}'.format(type(v).__name__, v, v._bounds))
    v += 10
    print('type(v)={}, value={}, bounds={}'.format(type(v).__name__, v, v._bounds))
    w = v + 10
    print('type(w)={}, value={}, bounds={}'.format(type(w).__name__, w, w._bounds))
    x = v - 110
    print('type(x)={}, value={}, bounds={}'.format(type(x).__name__, x, x._bounds))

输出:

type(v)=BoundedInt, value=100, bounds=(0, 100)
type(v)=BoundedInt, value=100, bounds=(0, 100)
type(w)=BoundedInt, value=100, bounds=(0, 100)
type(x)=BoundedInt, value=0, bounds=(0, 100)
于 2014-02-24T00:33:36.187 回答