I've been following official Kivy PongApp tutorial (link - whole program code at the bottom of site) and I've faced a problem I can't really understand.
I've defined the move function to change the position of the ball by a velocity vector on each frame. The code:
def move(self):
self.pos = Vector(*self.velocity) + self.pos
However, when I've written the code like this:
def move(self):
self.pos = self.pos + Vector(*self.velocity)
It results in an error: ValueError: PongBall.pos value length is immutable
Why, shouldn't it be the same?
self.pos is a kivy.properties.ObservableReferenceList.
When you attempt to set this property it checks to make sure that the new value is the same length as the old value.
From kivy.properties.ReferenceProperty:
cdef check(self, EventDispatcher obj, value):
cdef PropertyStorage ps = obj.__storage[self._name]
if len(value) != len(ps.properties):
raise ValueError('%s.%s value length is immutable' % (
obj.__class__.__name__, self.name))
In addition, kivy.properties.ObservableList subclasses list.
Unfortunately, so does kivy.vector.Vector, and as anyone with Python experience can tell you, list.__add__ concatenates its arguments.
What this means is that vector is added to self.pos by extending it, not by adding it elementwise, which then causes self.pos to complain because its length is changing.
It works the other way aronud because Vector overloads __add__ to do element-wise addition.
Because python favors __add__ over __radd__, the whole thing fails.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With