Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
249 views
in Technique[技术] by (71.8m points)

python - How to display a label for a short period of time in kivy?

I m using Window 10 Python -V 3.9 and Kivy -V 2.0.0 and my question is : I just follow the tutorial in the documentation. I want to display a label duce = StringProperty() for a short time like after 1 s it will disappear automatically. I can make it work but want to ask / search for some better solution :) thx

Code:

main.py

#import kivy

#kivyVersion = kivy.__version__  # check kivy version

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.properties import NumericProperty, StringProperty, ReferenceListProperty, ObjectProperty
from kivy.vector import Vector
from kivy.clock import Clock

class Ball(Widget):
    Vx = NumericProperty(0)
    Vy = NumericProperty(0)

    Velocity = ReferenceListProperty(Vx, Vy)

    def Move(self):
        self.pos = Vector(*self.Velocity) + self.pos


class Paddle(Widget):

    score = StringProperty("0")  # set the score label be a string with text "0" at the beginning

    def Bounce(self, ball):  # to make the ball move faster when touched the paddle --> increase difficulty + more fun
        if self.collide_widget(ball):

            Vx, Vy = ball.Velocity  # unpack the  ball.Velocity
        
            offset = (ball.center_y - self.center_y) / (self.height / 2)
            bounce = Vector((Vx * -1), Vy)
            bouncedVelocity = bounce * 1.1
            ball.Velocity = bouncedVelocity.x, bouncedVelocity.y + offset

    
class PongGame(Widget):  # ref. mypong.kv
    ball = ObjectProperty(None)
    leftplayer = ObjectProperty(None)
    rightplayer = ObjectProperty(None)

    duce = StringProperty()

    GameOver = False

    def ServeBall(self, v = (4, 0)):
        self.ball.center = self.center  # set the cennter of the ball at the center of the screen
        self.ball.Velocity = v  # start velocity  # Vector(4, 0).rotate(randint(0, 360))  # randomly set a Vx and Vy for the ball

    def Update(self, dt):
        
        self.ball.Move()  # Move() function to make the ball move with constant v

        self.leftplayer.Bounce(self.ball)  # bounce when touched player paddle
        self.rightplayer.Bounce(self.ball)

        if self.ball.y < self.y or self.ball.top > self.top:  # touch bottom or top --> bounce
            self.ball.Vy *= -1  # same velocity by in opposite direction

        if self.ball.x < self.x:  # touch left --> bounce and rightplayer score += 1
            self.rightplayer.score = str(int(self.rightplayer.score) + 1)
            self.ball.Vx *= -1
            self.ServeBall(v = (4, 0))

        if self.ball.right > self.width:  # touch right --> bounce and leftplayer score += 1
            self.leftplayer.score = str(int(self.leftplayer.score) + 1)
            self.ball.Vx *= -1
            self.ServeBall(v = (-4, 0))


        def Duce():  # duce | when one of the player score 10 . two player 's score different == 1
            self.GameOver = False
            Duce()

        ######################
        if int(self.leftplayer.score) == 11 or int(self.rightplayer.score) == 11:  # display the text "Duse !" for a short while
            self.duce = "Duce !"
        else:
            self.duce = ""
        ######################
                    
        if self.leftplayer.score != self.rightplayer.score:
            try:
                if int(self.leftplayer.score) >= 10 or int(self.rightplayer.score) >= 10:

                    if int(self.leftplayer.score) - int(self.rightplayer.score) == 1 or int(self.leftplayer.score) - int(self.rightplayer.score) == -1:
                        Duce()
                    
                    elif int(self.leftplayer.score) - int(self.rightplayer.score) >= 2 or int(self.leftplayer.score) - int(self.rightplayer.score) <= -2:
                        self.GameOver = True
                    
                        self.ServeBall(v = (0, 0))  # set the ball rest on the screen 's center
                    
                        if int(self.leftplayer.score) > int(self.rightplayer.score):
                            self.leftplayer.score = "You Win !"  # change label text
                            self.rightplayer.score = "Ops !"  # change label text
                        
                        elif int(self.rightplayer.score) > int(self.leftplayer.score):
                            self.leftplayer.score = "Ops !"  # change label text
                            self.rightplayer.score = "You Win !"  # change label text

            except RecursionError:
                pass

            except ValueError:
                pass
                        
            except Exception as e:
                print("Error :", e)
            

    def on_touch_move(self, touch):  # | widget | function name must be  on_touch_move
        if touch.x < (self.width / 3):
            self.leftplayer.center_y = touch.y
        
        if touch.x > (self.width - self.width / 3):
            self.rightplayer.center_y = touch.y

        if self.GameOver == True:  # when game is over
            if touch.x < self.width:  # when player toch screen  -->  reset all
                self.GameOver = False
                self.leftplayer.score = "0"
                self.rightplayer.score = "0"
                self.ServeBall()


class MyPongApp(App):  # name of the .kv file should be the text before "App"   # start up 

    def build(self):
        self.title = "My First Kivy Game"
        Game = PongGame()  # creating obj for  class PongGame
        Game.ServeBall()  # run  class PongGame  function  ServeBall()
        Clock.schedule_interval(Game.Update, 1.0/120.0)
        return Game


if __name__ == "__main__":
    MyPongApp().run()

mypong.kv :

#:kivy 2.0.0

<Ball>:
    size: 50, 50
    canvas:
        Ellipse:
            pos: self.pos
            size: self.size


<Paddle>:
    size: 25, 200
    canvas:
        Rectangle:
            pos: self.pos
            size: self.size


<PongGame>:
    ball: myBall
    leftplayer: left_player
    rightplayer: right_player

    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: root.leftplayer.score
        
    Label:
        font_size: 70  
        center_x: root.width * 3 / 4
        top: root.top - 50
        text: root.rightplayer.score

    Label:
        font_size: 70
        center_x: root.width /2
        center_y: root.top / 2
        text: root.duce


    Ball:
        id: myBall
        center: self.parent.center


    Paddle:
        id: left_player
        x: root.x
        center_y: root.center_y

    Paddle:
        id: right_player
        x: root.width - self.width
        center_y: root.center_y

my own solution :

#####################
if int(self.leftplayer.score) == 11 or int(self.rightplayer.score) == 11:  # display the text "Duse !" for a short while
    self.duce = "Duce !"
else:
    self.duce = ""
######################

and idk if i need to do / add sth on the mypong.kv also ?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can use Clock object refer to documentation here

This is how you hide the label after 1 second this will hide it not just remove the text. However you should give your label an id to be able to modify the property.

from kivy.clock import Clock


def hide_label(dt):
    self.ids.[labelId].size_hint_x=0 # to hide the label best practice is setting size to 0

self.ids.[labelId].size_hint_x=1 # Show the label 
Clock.schedule_once(hide_label, 1)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...