Reputation: 3
I am attempting to create a pong game using kivy. However, I am running into issues when I try to end a game after someone scores 10 points. Everything is working well except that I would like to show a Game Over text using a label. I created a label and currently the text is set to an empty string, but it should change after someone scores enough points.
I have looked through the kivy documentation and searched stackoverflow but I have not found an answer for this(or at least not one that I understand.)
If someone can point me in the right direction I would really appreciate it.
Here is my code:
.py file:
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
count1 = 0
count2 = 0
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
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)
def serve_ball(self, vel=(4, 0)):
self.ball.center = self.center
self.ball.velocity = vel
def update(self, dt):
global count1
global count2
self.ball.move()
#bounce of paddles
self.player1.bounce_ball(self.ball)
self.player2.bounce_ball(self.ball)
#bounce ball off bottom or top
if (self.ball.y < self.y) or (self.ball.top > self.top):
self.ball.velocity_y *= -1
#went of to a side to score point?
if self.ball.x < self.x:
self.player1.score += 1
count2 = count2 + 1
self.serve_ball(vel=(4, 0))
if self.ball.x > self.width:
self.player2.score += 1
self.serve_ball(vel=(-4, 0))
if count1 or count2 >= 10:
#
#
#
#I don't know what needs to be placed here to change the third label's text
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()
.kv file
#:kivy 1.0.9
<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.player2.score)
Label:
font_size: 70
center_x: root.width * 3/4
top: root.top - 50
text: str(root.player1.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
Label:
id: game_over_label
text: " "
font_size: 100
center_x: root.width / 2
center_y: root.height / 2
Upvotes: 0
Views: 1002
Reputation: 61
one way to find the ID inside the tree is to put a "redirector" in the root of the widget
In .kv, right under PongGame:
gameoverlabel: game_over_label
in .py under the " if count1 or count2 >= 10:" add
self.gameoverlabel.text = "win"
hope this is helpful
Upvotes: 0
Reputation: 7349
You would use the same method to change the game over label that you use to change the score labels when the score changes.
If you add an ObjectProperty
to PongGame
in main.py:
end_label = ObjectProperty()
And in your kv file under PongGame
, write:
end_label: game_over_label # linking them up
You could add a function to PongGame
class in main.py:
def check_score(self):
scores = [self.player1.score,
self.player2.score]
for s in scores:
if s == 10:
self.end_label = "Game Over"
return
Then in your update
function, you could call this function any time the scores are incremented, for instance:
self.player1.score += 1
self.check_score()
and the same for self.player2.score
Upvotes: 1