Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kivy official Pong tutorial - usage of Vector (kivy.vector)

Tags:

python

kivy

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?

like image 724
chilliq Avatar asked Aug 17 '14 17:08

chilliq


1 Answers

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.

like image 101
John Tyree Avatar answered Sep 20 '22 19:09

John Tyree