在 Kivy 中,我如何从另一个用 kv 语言显示的屏幕中获取变量
In Kivy How do i get a variable from another screen displayed in another in kv language
我正在尝试修改来自 kivy 文档的乒乓球游戏。
我制作了一个“游戏结束”屏幕,应用程序在宣布获胜者后进入该屏幕,我想要一个标签来显示获胜者的分数,使用下面使用的方法我得到完全不同的输出标签,
有人可以解释一下我应该如何实现吗?谢谢!!
相关代码在两者的底部我只是包括整个代码以防问题出在其他地方。
import kivy
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.lang.builder import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.properties import NumericProperty, ReferenceListProperty, ObjectProperty
from kivy.vector import Vector
from kivy.uix.floatlayout import FloatLayout
from kivy.uix import label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.clock import Clock
from kivy.config import Config
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
class WindowManager(ScreenManager):
def On_Win(self):
p1 =self.Game.player_1.score
class MenuWindow(Screen):
pass
class PongBall(Widget):
velocity_y= NumericProperty(0)
velocity_x= NumericProperty(0)
velocity=ReferenceListProperty(velocity_x,velocity_y)
def move(self):
self.pos = Vector(self.velocity) +self.pos
class PongPad(Widget):
score=NumericProperty(0)
def Check_bounce(self,ball):
if self.collide_widget(ball) :
vx,vy= ball.velocity
bounced= Vector(-1* vx, vy )
speedup= abs(((ball.velocity_x *0.1) -(ball.center_y - self.center_y)) *0.002)
vel = bounced * (speedup +1.1)
offset=(((ball.center_y - self.center_y)/2) - (ball.velocity_x /2)) *0.1
if (ball.center_y - self.center_y) > 0:
ball.velocity=vel.x,vel.y
ball.velocity_y= 2
else:
ball.velocity= vel.x,vel.y
ball.velocity_y= -2
class Game(Screen):
ball = ObjectProperty(None)
player_1 = ObjectProperty(None)
player_2 = ObjectProperty(None)
win1=NumericProperty(0)
win2=NumericProperty(0)
def on_enter(self, *args):
self.serve_ball()
Clock.schedule_interval(self.update, 1.0/60.0)
def Winner(self):
Winner=""
if self.player_1.score==2:
if self.manager.current != "WinGame":
self.manager.current = "WinGame"
Winner = "P1 with",str(self.player_1.score)
if self.player_2.score == 2:
if self.manager.current !="WinGame":
self.manager.current = "WinGame"
Winner = "P2 with",str(self.player_2.score)
def TEST(self):#TESTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
Winner=""
if self.player_1.score>=2:
Winner = "P1 with",str(self.player_1.score)
print("1")
print(Winner)
return Winner
def serve_ball(self,vel=(4,0)):
print("234Served")
self.ball.velocity= vel
self.ball.center = self.center
self.player_1.center_y=self.center_y
self.player_2.center_y=self.center_y
def Check_Top_Bottom(self):
#Check bottom collion
if self.ball.y <0:
self.ball.velocity_y= abs(self.ball.velocity_y)
#Check top colision
if self.ball.y+50> self.height:
self.ball.velocity_y = -abs(self.ball.velocity_y)
def Check_if_score(self):#Score
if self.ball.x >self.width:
self.player_1.score +=1
self.win1 +=1
self.serve_ball()
if self.ball.x+50 <0:
self.player_2.score += 1
self.win2 +=1
self.serve_ball()
def update(self,dt):
self.ball.move()
self.Check_Top_Bottom()
self.Check_if_score()
self.player_1.Check_bounce(self.ball)
self.player_2.Check_bounce(self.ball)
self.Winner()
#print("from Update: ",self.Get_Score())
def on_touch_move(self,touch):
if touch.x > self.width/2:
self.player_2.center_y = touch.y
else:
self.player_1.center_y= touch.y
class WinGameScreen(Screen):
def Get_Win(self):
screen_manager = self.manager
game = screen_manager.get_screen('Game')
a= game.TEST()
return a
kv= Builder.load_file("myMenu.kv")
class myMenuApp(App):
def build(self):
return kv
if __name__ == "__main__":
myMenuApp().run()
这里是 kv 文件:
WindowManager:
MenuWindow:
Game:
WinGameScreen:
<MenuWindow>:
name: "Menu"
FloatLayout:
Button:
size_hint: 0.2,0.05
pos_hint: {"x":0.39,"y":0.75}
text:"Play"
on_release:
app.root.current= "Game"
root.manager.transition.direction= "left"
Button:
size_hint: 0.2,0.05
pos_hint: {"x":0.39,"y":0.7}
text:"Settings"
Button:
size_hint: 0.2,0.05
pos_hint: {"x":0.39,"y":0.65}
text:"High Score"
Button:
size_hint: 0.2,0.05
pos_hint: {"x":0.39,"y":0.6}
text:"Quit"
<PongBall>
size_hint: None, None
size: 50,50
canvas:
Ellipse:
pos:self.pos
size:self.size
<PongPad>
size_hint: None, None
size:25,150
canvas:
Rectangle:
pos:self.pos
size:self.size
<Game>:
name:"Game"
ball: Pong_ball
player_1: Player1
player_2: Player2
canvas:
Rectangle:
pos:self.center_x -5,0
size: 15,root.height
PongPad:
id: Player2
pos:root.width-25,root.center_y-75
PongPad:
id: Player1
pos:0,root.center_y-75
PongBall:
id: Pong_ball
center: self.parent.center
FloatLayout:
Label:
text:str(root.player_1.score)
top:root.top -1
x:root.width -100
Label:
text:"Player 2:"
top: root.top-1
x:root.width - 135
Label:
text: str(root.player_2.score)
top: root.top -1
x: root.x+25
Label
text: "Player 1:"
top:root.top-1
x:root.x -10
<WinGameScreen>:
name:"WinGame"
Label:
id: Final_score
text: str(root.Get_Win)
y:0.2
在您的 kv
行中:
text: str(root.Get_Win)
正在加载 kv
时将 Label
的文本设置为 Get_Win()
方法的字符串版本。它不是 运行 宁 Get_Win()
方法。您可以删除该行。
由于你在游戏结束时切换到 WinGameScreen
,你可以为 WinGameScreen
定义一个 on_enter()
方法,当 Screen
输入:
class WinGameScreen(Screen):
def on_enter(self, *args):
screen_manager = self.manager
game = screen_manager.get_screen('Game')
a= game.TEST()
self.ids.Final_score.text = str(a)
我正在尝试修改来自 kivy 文档的乒乓球游戏。
我制作了一个“游戏结束”屏幕,应用程序在宣布获胜者后进入该屏幕,我想要一个标签来显示获胜者的分数,使用下面使用的方法我得到完全不同的输出标签,
有人可以解释一下我应该如何实现吗?谢谢!!
相关代码在两者的底部我只是包括整个代码以防问题出在其他地方。
import kivy
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.lang.builder import Builder
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.properties import NumericProperty, ReferenceListProperty, ObjectProperty
from kivy.vector import Vector
from kivy.uix.floatlayout import FloatLayout
from kivy.uix import label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.button import Button
from kivy.clock import Clock
from kivy.config import Config
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.label import Label
class WindowManager(ScreenManager):
def On_Win(self):
p1 =self.Game.player_1.score
class MenuWindow(Screen):
pass
class PongBall(Widget):
velocity_y= NumericProperty(0)
velocity_x= NumericProperty(0)
velocity=ReferenceListProperty(velocity_x,velocity_y)
def move(self):
self.pos = Vector(self.velocity) +self.pos
class PongPad(Widget):
score=NumericProperty(0)
def Check_bounce(self,ball):
if self.collide_widget(ball) :
vx,vy= ball.velocity
bounced= Vector(-1* vx, vy )
speedup= abs(((ball.velocity_x *0.1) -(ball.center_y - self.center_y)) *0.002)
vel = bounced * (speedup +1.1)
offset=(((ball.center_y - self.center_y)/2) - (ball.velocity_x /2)) *0.1
if (ball.center_y - self.center_y) > 0:
ball.velocity=vel.x,vel.y
ball.velocity_y= 2
else:
ball.velocity= vel.x,vel.y
ball.velocity_y= -2
class Game(Screen):
ball = ObjectProperty(None)
player_1 = ObjectProperty(None)
player_2 = ObjectProperty(None)
win1=NumericProperty(0)
win2=NumericProperty(0)
def on_enter(self, *args):
self.serve_ball()
Clock.schedule_interval(self.update, 1.0/60.0)
def Winner(self):
Winner=""
if self.player_1.score==2:
if self.manager.current != "WinGame":
self.manager.current = "WinGame"
Winner = "P1 with",str(self.player_1.score)
if self.player_2.score == 2:
if self.manager.current !="WinGame":
self.manager.current = "WinGame"
Winner = "P2 with",str(self.player_2.score)
def TEST(self):#TESTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
Winner=""
if self.player_1.score>=2:
Winner = "P1 with",str(self.player_1.score)
print("1")
print(Winner)
return Winner
def serve_ball(self,vel=(4,0)):
print("234Served")
self.ball.velocity= vel
self.ball.center = self.center
self.player_1.center_y=self.center_y
self.player_2.center_y=self.center_y
def Check_Top_Bottom(self):
#Check bottom collion
if self.ball.y <0:
self.ball.velocity_y= abs(self.ball.velocity_y)
#Check top colision
if self.ball.y+50> self.height:
self.ball.velocity_y = -abs(self.ball.velocity_y)
def Check_if_score(self):#Score
if self.ball.x >self.width:
self.player_1.score +=1
self.win1 +=1
self.serve_ball()
if self.ball.x+50 <0:
self.player_2.score += 1
self.win2 +=1
self.serve_ball()
def update(self,dt):
self.ball.move()
self.Check_Top_Bottom()
self.Check_if_score()
self.player_1.Check_bounce(self.ball)
self.player_2.Check_bounce(self.ball)
self.Winner()
#print("from Update: ",self.Get_Score())
def on_touch_move(self,touch):
if touch.x > self.width/2:
self.player_2.center_y = touch.y
else:
self.player_1.center_y= touch.y
class WinGameScreen(Screen):
def Get_Win(self):
screen_manager = self.manager
game = screen_manager.get_screen('Game')
a= game.TEST()
return a
kv= Builder.load_file("myMenu.kv")
class myMenuApp(App):
def build(self):
return kv
if __name__ == "__main__":
myMenuApp().run()
这里是 kv 文件:
WindowManager:
MenuWindow:
Game:
WinGameScreen:
<MenuWindow>:
name: "Menu"
FloatLayout:
Button:
size_hint: 0.2,0.05
pos_hint: {"x":0.39,"y":0.75}
text:"Play"
on_release:
app.root.current= "Game"
root.manager.transition.direction= "left"
Button:
size_hint: 0.2,0.05
pos_hint: {"x":0.39,"y":0.7}
text:"Settings"
Button:
size_hint: 0.2,0.05
pos_hint: {"x":0.39,"y":0.65}
text:"High Score"
Button:
size_hint: 0.2,0.05
pos_hint: {"x":0.39,"y":0.6}
text:"Quit"
<PongBall>
size_hint: None, None
size: 50,50
canvas:
Ellipse:
pos:self.pos
size:self.size
<PongPad>
size_hint: None, None
size:25,150
canvas:
Rectangle:
pos:self.pos
size:self.size
<Game>:
name:"Game"
ball: Pong_ball
player_1: Player1
player_2: Player2
canvas:
Rectangle:
pos:self.center_x -5,0
size: 15,root.height
PongPad:
id: Player2
pos:root.width-25,root.center_y-75
PongPad:
id: Player1
pos:0,root.center_y-75
PongBall:
id: Pong_ball
center: self.parent.center
FloatLayout:
Label:
text:str(root.player_1.score)
top:root.top -1
x:root.width -100
Label:
text:"Player 2:"
top: root.top-1
x:root.width - 135
Label:
text: str(root.player_2.score)
top: root.top -1
x: root.x+25
Label
text: "Player 1:"
top:root.top-1
x:root.x -10
<WinGameScreen>:
name:"WinGame"
Label:
id: Final_score
text: str(root.Get_Win)
y:0.2
在您的 kv
行中:
text: str(root.Get_Win)
正在加载 kv
时将 Label
的文本设置为 Get_Win()
方法的字符串版本。它不是 运行 宁 Get_Win()
方法。您可以删除该行。
由于你在游戏结束时切换到 WinGameScreen
,你可以为 WinGameScreen
定义一个 on_enter()
方法,当 Screen
输入:
class WinGameScreen(Screen):
def on_enter(self, *args):
screen_manager = self.manager
game = screen_manager.get_screen('Game')
a= game.TEST()
self.ids.Final_score.text = str(a)