Reputation: 194
When the program runs, the ScreenManager
shows the Main screen on which I added the white little square(Ball)
.
The widget Ball should be moving around but I cannot figure out why it is still static. The update method is working but the position of the widget is not being updated. I tried to move things around and no effect.
If someone could help me to understand where I am wrong, would be great. Thx so much.
import kivy
kivy.require('1.10.1')
from kivy.app import App
from kivy.core.window import Window
from kivy.uix.screenmanager import ScreenManager,Screen
from kivy.graphics import Rectangle
from kivy.uix.widget import Widget
from kivy.properties import ListProperty
from kivy.clock import Clock
# simple Screen on which the ball should move
class Main(Screen):
def __init__(self, **kwargs):
super(Main, self).__init__(**kwargs)
self.add_widget(Ball())
with self.canvas.before:
Rectangle(source = 'BG1.png',
size = Window.size,
pos = self.pos)
# the Ball should be bouncing around
class Ball(Widget):
velocity = ListProperty([10, 15])
def __init__(self, **kwargs):
super(Ball, self).__init__(**kwargs)
Clock.schedule_interval (self.update, 1 / 60)
with self.canvas:
Rectangle (color=[0, 0, 0, 1],
size=(10, 10),
pos = self.pos)
def update(self, *args):
print('wtf')
self.x += self.velocity[0]
self.y += self.velocity[1]
if self.x < 0 or (self.x + self.width) > Window.width:
self.velocity[0] *= -1
if self.y < 0 or (self.y + self.height) > Window.height:
self.velocity[1] *= -1
Window.size = (400, 300)
sm = ScreenManager()
sm.add_widget(Main(name = 'main'))
class Bubble(App):
def build(self):
return sm
if __name__ == '__main__':
Bubble().run()
Upvotes: 0
Views: 283
Reputation: 194
Thank you Embryo and John, your answers led me to find the right answer. I found this code on this blog. Solved it all:Kivy blog
from kivy.uix.widget import Widget
from kivy.graphics import Rectangle, Color
class CornerRectangleWidget(Widget)
def __init__(self, **kwargs):
super(CornerRectangleWidget, self).__init__(**kwargs)
with self.canvas:
Color(1, 0, 0, 1) # set the colour to red
self.rect = Rectangle(pos=self.center,
size=(self.width/2.,
self.height/2.))
self.bind(pos=self.update_rect,
size=self.update_rect)
def update_rect(self, *args):
self.rect.pos = self.pos
self.rect.size = self.size
Upvotes: 2
Reputation: 38822
The problem is that when you set up Canvas
instructions in python (rather than in kv
), you don't get the automatic bindings that kv
does for you. So the Rectangle
that you define in the Ball.__init__()
method gets its pos
defined as the pos
of the Ball
at its __init__()
moment (which is [0,0]), and it does not change automatically. You can fix that by doing the update yourself. First, in your Ball.__init__()
change your with self.canvas
block to:
with self.canvas:
Color(0,0,0,1)
self.rect = Rectangle (size=(10, 10),
pos = self.pos)
One change is defining the Color
, and the second is creating a reference to the Rectangle
. Then in your update method add the line:
self.rect.pos = self.pos
This will move the rectangle with the Ball position.
Also, your update
method has some problems because the size
of the Ball
is the same size as the Window
. It is not the size
you provide in the Rectangle
.
Upvotes: 1
Reputation: 2231
Well, what is happening is this...
You are drawing the rectangle once, when you instantiate the Ball
widget.
This is what you see in the bottom left corner.
After that you move the widget, but you don't draw it again.
If you print(self.pos)
in the update function, you'll see it moving...
Upvotes: 0