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