gpt4 book ai didi

python - Kivy - 添加和删除标签

转载 作者:行者123 更新时间:2023-11-28 18:47:22 25 4
gpt4 key购买 nike

我是 Kivy 的新手,找不到关于添加和删除标签的任何真正答案。我按照自己的方式完成了 Pong 教程(您可能已经猜到了),并将其改编为适合 4 名玩家。现在,我尝试添加一个标签来显示文本 Winner!,然后单击该文本以重新启动游戏。

至此,一切正常。问题是,我无法让标签在新游戏开始后再次消失。另外,我不明白格式 - 我似乎无法让我的标签变大或将它移到面板中的较低位置。

我将发布所有代码,因为希望你无论如何都想玩这个游戏(一旦它被修复),而且我肯定有一个更好的、更少卡顿的方式来添加和删除文本。

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()

和 .kv 文件:

#: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

最佳答案

Label 正在被删除,问题是您正在添加无限数量的标签 :) 因为这里计划每 1/60 秒调用一次更新方法:

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

如果您的计算机不会死机,您需要在添加小部件之前取消计划:

Clock.unschedule(self.update)

下面的代码有效。我想建议不要使用全局变量(这只是一种非常糟糕的做法)。我也修改了那个。在这种情况下,您甚至不需要类属性,因为参数 instance 包含与 self.win_label 完全相同的参数。此外,我更改了居中方式 (self.win_label.center = self.center)。最后,使用 [Button][1] 而不是 Label 会更容易,因为您可以绑定(bind)其他方法,例如 on_presson_release。实际上,您不需要为此使用 ref。您可以简单地绑定(bind) on_touch_down

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)
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) # this should also work:
self.initialize()
Clock.schedule_interval(self.update, 1.0 / 60.0)



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()

关于python - Kivy - 添加和删除标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17984856/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com