python - Kivy - adding and removing labels -


i'm new kivy, , can't find real answers adding , removing labels. worked way through pong tutorial (as might have guessed), , adapted 4 players. now, i'm trying add label display text winner!, , click on text restart game.

up there, it's working. problem is, can't label disappear again after new game starts. also, don't understand formatting - can't seem make label bigger or move lower in panel.

i'm going post code, since you'd play game anyway (once it's fixed), , i'm positive there's better, less janky way add , remove text.

from kivy.app import app kivy.uix.widget import widget kivy.uix.label import label kivy.properties import numericproperty, referencelistproperty,\     objectproperty kivy.vector import vector kivy.clock import clock 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) , not self.player3.can_move) \            or ((self.ball.top > self.top) , not self.player4.can_move):             self.ball.velocity_y *= -1         if ((self.ball.x < self.x) , not self.player1.can_move) \            or ((self.ball.right > self.width) , not self.player2.can_move):             self.ball.velocity_x *= -1          #went off side score point?         if self.ball.x < self.x , 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 , 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 , 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 , 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 , touch.y > self.height / 6 \             , touch.y < 5 * self.height / 6 , self.player1.can_move:             self.player1.center_y = touch.y         if touch.x > self.width - self.width / 3 , touch.y > self.height / 6 \             , touch.y < 5 * self.height / 6 , self.player2.can_move:             self.player2.center_y = touch.y         if touch.y < self.height / 3 , touch.x > self.width / 6 \             , touch.x < 5 * self.width / 6 , self.player3.can_move:             self.player3.center_x = touch.x         if touch.y > 2* self.height / 3 , touch.x > self.width / 6 \             , touch.x < 5 * self.width / 6 , 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 .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 

the label being removed, problem adding infinite number of them :) because update method scheduled called each 1/60 seconds here:

clock.schedule_interval(game.update, 1.0 / 60.0) 

you need un-schedule before adding widget if not computer going freeze:

clock.unschedule(self.update) 

the code below works. suggest not use global variable (it bad practice). modified too. don't need class attribute case since parameter instance contains same of self.win_label. also, change way centering (self.win_label.center = self.center). finally, easier use [button][1] instead of label because can bind other methods on_press or on_release. actually, don't need ref this. can bind on_touch_down.

from kivy.app import app kivy.uix.widget import widget kivy.uix.label import label kivy.properties import numericproperty, referencelistproperty,\     objectproperty kivy.vector import vector kivy.clock import clock 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) , not self.player3.can_move) \            or ((self.ball.top > self.top) , not self.player4.can_move):             self.ball.velocity_y *= -1         if ((self.ball.x < self.x) , not self.player1.can_move) \            or ((self.ball.right > self.width) , not self.player2.can_move):             self.ball.velocity_x *= -1          #went off side score point?         if self.ball.x < self.x , 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 , 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 , 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 , 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)             clock.unschedule(self.update)              self.win_label = label(size_hint=(none, none),                               text='[ref=winner]winner![/ref]',                               markup=true, font_size=70, color=[1,0,0,1])             #win_label.texture_update()             #self.win_label.pos = (self.width / 2, self.height / 2 - 70)             self.win_label.center = self.center ##            win_label.size =  win_label.texture_size[0] + 20, \ ##                             win_label.texture_size[1] + 20             self.win_label.bind(on_ref_press=self.click_win_label)             self.win_label.texture_update()             self.add_widget(self.win_label)       def click_win_label(self, instance, value):         self.remove_widget(self.win_label)         #self.remove_widget(instance) # should work:         self.initialize()         clock.schedule_interval(self.update, 1.0 / 60.0)        def on_touch_move(self, touch):         if touch.x < self.width / 3 , touch.y > self.height / 6 \             , touch.y < 5 * self.height / 6 , self.player1.can_move:             self.player1.center_y = touch.y         if touch.x > self.width - self.width / 3 , touch.y > self.height / 6 \             , touch.y < 5 * self.height / 6 , self.player2.can_move:             self.player2.center_y = touch.y         if touch.y < self.height / 3 , touch.x > self.width / 6 \             , touch.x < 5 * self.width / 6 , self.player3.can_move:             self.player3.center_x = touch.x         if touch.y > 2* self.height / 3 , touch.x > self.width / 6 \             , touch.x < 5 * self.width / 6 , 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() 

Comments

Popular posts from this blog

basic authentication with http post params android -

vb.net - Virtual Keyboard commands -

How to get multiresult with multicondition in Sql Server -