Reputation: 509
I'm trying to learn the basics of the Kivy package for Python GUI programming. I've worked through the Pong Tutorial (here) and wanted to test my comprehension by changing the color of the pong ball every time it hit the wall. It is not working - every time the ball hits the wall, I get a fault saying that there is not Color attribute. What am I doing wrong?
main.py
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import NumericProperty, ReferenceListProperty, ObjectProperty
from kivy.vector import Vector
from kivy.clock import Clock
from kivy.graphics import Color
from random import randint
class PongBall(Widget):
vel_x = NumericProperty(0)
vel_y = NumericProperty(0)
vel = ReferenceListProperty(vel_x,vel_y)
def move(self):
self.pos = Vector(*self.vel) + self.pos
class PongGame(Widget):
ball = ObjectProperty(None)
def serve_ball(self):
self.ball.center = self.center
self.ball.vel = Vector(4,0).rotate(randint(0,360))
def update(self, dt):
self.ball.move()
if(self.ball.y < 0) or (self.ball.top > self.height):
self.ball.vel_y *= -1
self.ball.Color(1,0,0)
if(self.ball.x < 0) or (self.ball.right > self.width):
self.ball.vel_x *= -1
self.ball.Color(0,1,0)
class PongApp(App):
def build(self):
game = PongGame()
game.serve_ball()
Clock.schedule_interval(game.update, 1.0/60.0)
return game
if __name__ == '__main__':
PongApp().run()
KV File:
#:kivy 1.0.9
<PongBall>:
size: 50, 50
canvas:
Ellipse:
pos: self.pos
size: self.size
Color:
rgba: 1, 1, 0, 0
<PongGame>:
ball: pong_ball
canvas:
Rectangle:
pos: self.center_x - 5, 0
size: 10, self.height
Label:
font_size: 70
center_x: root.width / 4
top: root.top - 50
text: "0"
Label:
font_size: 70
center_x: root.width * 3 / 4
top: root.top - 50
text: "0"
PongBall:
id: pong_ball
center: self.parent.center
Upvotes: 1
Views: 1008
Reputation: 243897
You have to do the following:
Create a ListProperty to have the color information and make a binding in the .kv.
The Color instruction must be before the Ellipse instruction:
class PongBall(Widget):
vel_x = NumericProperty(0)
vel_y = NumericProperty(0)
vel = ReferenceListProperty(vel_x,vel_y)
color = ListProperty((1, 1, 1, 1)) # <---
def move(self):
self.pos = Vector(*self.vel) + self.pos
class PongGame(Widget):
ball = ObjectProperty(None)
def serve_ball(self):
self.ball.center = self.center
self.ball.vel = Vector(4,0).rotate(randint(0,360))
def update(self, dt):
self.ball.move()
if(self.ball.y < 0) or (self.ball.top > self.height):
self.ball.vel_y *= -1
self.ball.color = (1, 0, 0, 1) # <---
if(self.ball.x < 0) or (self.ball.right > self.width):
self.ball.vel_x *= -1
self.ball.color = (0, 1, 0, 1) # <---
# ...
<PongBall>:
size: 50, 50
canvas:
Color:
rgba: self.color # <---
Ellipse:
pos: self.pos
size: self.size
# ...
Upvotes: 2