I'm new to Kivy, and can't find any real answers about adding and removing labels. I worked my way through the Pong tutorial (as you might have guessed), and adapted it for 4 players. Now, I'm trying to add a label to display the text Winner!
, and to click on that text to restart the game.
Up to there, it's working. Problem is, I can't get the label to disappear again after the new game starts. Also, I don't understand the formatting - I can't seem to make my label bigger or move it lower in the panel.
I'm going to post all the code, since hopefully you'd like to play the game anyway (once it's fixed), and I'm positive there's a better, less janky way to add and remove the text.
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.properties import NumericProperty, ReferenceListProperty,\
ObjectProperty
from kivy.vector import Vector
from kivy.clock import Clock
from random import randint
class PongPaddle(Widget):
score = NumericProperty(0)
orientation = ObjectProperty([0, 0])
can_move = ObjectProperty(0)
def bounce_ball(self, ball):
if self.collide_widget(ball):
vx, vy = ball.velocity
if self.orientation[0] == 25:
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
else:
offset = (ball.center_x - self.center_x) / (self.width / 2)
bounced = Vector(vx, -1 * vy)
vel = bounced * 1.1
ball.velocity = vel.x + offset, vel.y
class PongBall(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 PongGame(Widget):
ball = ObjectProperty(None)
player1 = ObjectProperty(None)
player2 = ObjectProperty(None)
player3 = ObjectProperty(None)
player4 = ObjectProperty(None)
def initialize(self):
SCORE = 1
self.player1.orientation = [25, 200]
self.player2.orientation = [25, 200]
self.player3.orientation = [200, 25]
self.player4.orientation = [200, 25]
self.player1.score = SCORE
self.player2.score = SCORE
self.player3.score = SCORE
self.player4.score = SCORE
self.player1.can_move = 1
self.player2.can_move = 1
self.player3.can_move = 1
self.player4.can_move = 1
self.serve_ball()
def serve_ball(self, vel=(4, 0)):
self.ball.center = self.center
self.ball.velocity = vel
def update(self, dt):
self.ball.move()
#bounce of paddles
self.player1.bounce_ball(self.ball)
self.player2.bounce_ball(self.ball)
self.player3.bounce_ball(self.ball)
self.player4.bounce_ball(self.ball)
#bounce ball off bottom or top
if ((self.ball.y < self.y) and not self.player3.can_move) \
or ((self.ball.top > self.top) and not self.player4.can_move):
self.ball.velocity_y *= -1
if ((self.ball.x < self.x) and not self.player1.can_move) \
or ((self.ball.right > self.width) and not self.player2.can_move):
self.ball.velocity_x *= -1
#went off to a side to score point?
if self.ball.x < self.x and self.player1.can_move == 1:
self.player1.score -= 1
self.serve_ball(vel=(4, randint(1, 4)))
if self.player1.score <= 0:
self.player1.can_move = 0
elif self.ball.x > self.width and self.player2.can_move == 1:
self.player2.score -= 1
self.serve_ball(vel=(-4, randint(1, 4)))
if self.player2.score <= 0:
self.player2.can_move = 0
elif self.ball.y > self.height and self.player4.can_move == 1:
self.player4.score -= 1
self.serve_ball(vel = (randint(1, 4), -4))
if self.player4.score <= 0:
self.player4.can_move = 0
elif self.ball.y < self.y and self.player3.can_move == 1:
self.player3.score -= 1
self.serve_ball(vel = (randint(1, 4), 4))
if self.player3.score <= 0:
self.player3.can_move = 0
if self.player1.can_move + self.player2.can_move + \
self.player3.can_move + self.player4.can_move == 1:
self.ball.velocity = (0, 0)
global win_label
win_label = Label(size_hint=(None, None),
text='[ref=winner]Winner![/ref]',
markup=True, text_size=(70, None))
#win_label.texture_update()
win_label.pos = (self.width / 2, self.height / 2 - 70)
## win_label.size = win_label.texture_size[0] + 20, \
## win_label.texture_size[1] + 20
win_label.bind(on_ref_press=self.click_win_label)
win_label.texture_update()
self.add_widget(win_label)
def click_win_label(self, instance, value):
self.initialize()
self.remove_widget(win_label)
def on_touch_move(self, touch):
if touch.x < self.width / 3 and touch.y > self.height / 6 \
and touch.y < 5 * self.height / 6 and self.player1.can_move:
self.player1.center_y = touch.y
if touch.x > self.width - self.width / 3 and touch.y > self.height / 6 \
and touch.y < 5 * self.height / 6 and self.player2.can_move:
self.player2.center_y = touch.y
if touch.y < self.height / 3 and touch.x > self.width / 6 \
and touch.x < 5 * self.width / 6 and self.player3.can_move:
self.player3.center_x = touch.x
if touch.y > 2* self.height / 3 and touch.x > self.width / 6 \
and touch.x < 5 * self.width / 6 and self.player4.can_move:
self.player4.center_x = touch.x
class PongApp(App):
def build(self):
game = PongGame()
game.initialize()
game.serve_ball()
Clock.schedule_interval(game.update, 1.0 / 60.0)
return game
if __name__ == '__main__':
PongApp().run()
And the .kv file:
#:kivy 1.0.9
<PongBall>:
size: 50, 50
canvas:
Ellipse:
pos: self.pos
size: self.size
<PongPaddle>:
size: root.orientation[0], root.orientation[1]
canvas:
Rectangle:
pos:self.pos
size:self.size
<PongGame>:
ball: pong_ball
player1: player_left
player2: player_right
player3: player_top
player4: player_bottom
Label:
font_size: 50
center_x: root.width / 6
top: root.top - root.height / 2 + 50
text: str(root.player1.score)
Label:
font_size: 50
center_x: root.width * 5 / 6
top: root.top - root.height / 2 + 50
text: str(root.player2.score)
Label:
font_size: 50
center_x: root.width / 2
top: root.height / 6
text: str(root.player3.score)
Label:
font_size: 50
center_x: root.width / 2
top: 5 * root.height / 6
text: str(root.player4.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
PongPaddle:
id: player_top
y: root.y
center_x: root.center_x
PongPaddle:
id: player_bottom
y: root.height - self.height
center_x: root.center_x