I am learning to use Kivy, so I walked through the Pong tutorial and started messing around with the code. So, I removed everything but the bouncing ball and decided to generate multiple balls on demand. The problem I am having is that while I can place balls where I want them when application is already running (for example, adding a ball on touch works fine), but when I add balls in the app build() they don't get placed right. Here is the code I have. The balls placed on touch, correctly start from the center. But the ball added in build() starts from the lower left corner. Why? I wanted to add more moving widgets with different properties, but I cannot seem to figure out how to place them on application start.
#:kivy 1.0.9 <World>: canvas: Ellipse: pos: self.center size: 10, 10 <Agent>: size: 50, 50 canvas: Ellipse: pos: self.pos size: self.size
from random import randint from kivy.app import App from kivy.uix.widget import Widget from kivy.properties import NumericProperty, ReferenceListProperty, ListProperty from kivy.vector import Vector from kivy.clock import Clock class World(Widget): agents = ListProperty() def add(self): agent = Agent() agent.center = self.center agent.velocity = Vector(4, 0).rotate(randint(0, 360)) self.agents.append(agent) self.add_widget(agent) def on_touch_down(self, touch): self.add() def update(self, dt): for agent in self.agents: agent.move() if agent.y < 0 or agent.top > self.height: agent.velocity_y *= -1 if agent.x < 0 or agent.right > self.width: agent.velocity_x *= -1 class Agent(Widget): velocity_x = NumericProperty(0) velocity_y = NumericProperty(0) velocity = ReferenceListProperty(velocity_x, velocity_y) def move(self): self.pos = Vector(*self.velocity) + self.pos class WorldApp(App): def build(self): world = World() # add one ball by default world.add() Clock.schedule_interval(world.update, 1.0/60.0) return world if __name__ == '__main__': WorldApp().run()