Object defined with classes does not inherit Kivy color property

I am trying to learn how to use Kivy and follow their positioning tutorial. Now I am trying to do this myself by changing the code in some way. I am currently trying to change the color of the lanterns.

I got one of them to do this, but the other one I call using the same class doesn't.

class PongPaddle(Widget):
    score = NumericProperty(0)

    def bounce_ball(self, ball):
            if self.collide_widget(ball):
                    vx, vy = ball.velocity
                    offset = (ball.center_y - self.center_y) / (self.height /2)
                    bounced = Vector(-1 * vx , vy)
                    vel = bounced * 1.1
                    ball.velocity = vel.x, vel.y + offset

    def on_touch_down(self, touch):
            color = (random(), random(), random())
            with self.canvas:
                    Color(*color)

class PongBall(Widget):

    #velocity of the ball on the X and Y Axis
    velocity_x = NumericProperty(0)
    velocity_y = NumericProperty(0)  #Shorthand for referencelist
    velocity = ReferenceListProperty(velocity_x, velocity_y)

    #Used for ball movement.
    def move(self):
            self.pos = Vector(*self.velocity) + self.pos

class PongGame(Widget):
    ball = ObjectProperty(None)
    player1 = ObjectProperty(None)
    player2 = ObjectProperty(None)

    def __init__(self, **kwargs):
            super(PongGame, self).__init__(**kwargs)

self._keyboard = Window.request_keyboard(self._keyboard_closed, self)
            self._keyboard.bind(on_key_down=self._on_keyboard_down)

    def _keyboard_closed(self):
            self.keyboard.unbind(on_key_down=self._on_keyboard_down)
            self._keyboard = None

    def _on_keyboard_down(self, keyboard, keycode, text, modifiers):
            if keycode[1] == 'w':
                    self.player1.center_y += 10
            elif keycode[1] == 's':
                    self.player1.center_y -= 10
            elif keycode[1] == 'k':
                    self.player2.center_y += 10
            elif keycode[1] == 'l':
                    self.player2.center_y -= 10
            return True

    def serve_ball(self, vel=(4, 0)):
            self.ball.center = self.center
            self.ball.velocity = vel

    def update(self, dt):
            self.ball.move()

            self.player1.bounce_ball(self.ball)
            self.player2.bounce_ball(self.ball)

            #Bounce ball
            if (self.ball.y < 0) or (self.ball.top > self.height):
                    self.ball.velocity_y *= -1

            #Scoring
            if self.ball.x < self.x:
                    self.player2.score += 1
                    self.serve_ball(vel=(4, 0))
            if self.ball.x > self.width:
                    self.player1.score += 1
                    self.serve_ball(vel=(-4, 0))

    def on_touch_move(self, touch):
            if touch.x < self.width / 3:
                    self.player1.center_y = touch.y
            if touch.x > self.width - self.width / 3:
                    self.player2.center_y = touch.y
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()

      

And the accompanying KV language file.

#:kivy 1.8.0

<PongBall>:
    size: 50, 50
    canvas:
            Ellipse:
                    pos: self.pos
                    size: self.size
<PongPaddle>:
    size: 25, 200
    canvas:
            Rectangle:
                    pos: self.pos
                    size: self.size

<PongGame>:
    ball: pong_ball
    player1: player_left
    player2: player_right
    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: str(root.player1.score)
    Label:
            font_size: 70
            center_x: root.width * 3 / 4       
            text: str(root.player2.score)
    PongBall:
            id: pong_ball
            center: self.parent.center
    PongPaddle:
            id: player_left
            x: root.x
            center_y: root.center_y
    PongPaddle:
            id: player_right
            x: root.width-self.width
            center_y: root.center_y

      

Any idea why the paddle on the left doesn't change color?

+3


source to share


1 answer


If a color is not declared prior to painting on the canvas, the default color instructions (1,1,1,1) are white. So when you use:

with self.canvas:
    Color(*color)

      

You only change the color of objects drawn after declaring a new color. So, looking at your kv file:

Label:
    font_size: 70
    center_x: root.width / 4
    top: root.top - 50
    text: str(root.player1.score)
Label:
    font_size: 70
    center_x: root.width * 3 / 4       
    text: str(root.player2.score)
PongBall:
    id: pong_ball
    center: self.parent.center
PongPaddle:
    id: player_left
    x: root.x
    center_y: root.center_y
PongPaddle:
    id: player_right
    x: root.width-self.width
    center_y: root.center_y

      



The color instructions that you added to the canvas after drawing player_left will be used by widgets created after the color declaration (player_right). Change the Pong Paddle on_touch_down function to the following to see how Color is used with the canvas:

    def on_touch_down(self, touch):
        color = (random(), random(), random())
        with self.canvas:
            Color(*color)
            Rectangle(size=(self.width-5,self.height-5),pos=self.pos)

      

You will notice that the first rectangle (on top of the left paddle) and the right paddle are the same color. Then your second color is used to draw a second rectangle on top of the right paddle. If you want to add instructions before executing the main ones, you can use:

with self.canvas.before:
    Color(*color)

      

+1


source







All Articles