[英]How to handle clock module with multiple screens in Kivy?
我試圖圍繞一個原點移動一個球(比如繞地球運行的月球)。 起初我在 GameScreen 中創建了球 object。 然后我得到了我的 object 沒有“移動”屬性的 AttributeError。 所以我創建了另一個名為 MainGame 的小部件作為球 object 的父級。 現在錯誤消失了,但球沒有主動移動。 我不知道我錯過了什么,因為我對 Kivy 很陌生。 我猜這是關於時鍾模塊和我的自定義更新 function。 感謝所有答案和幫助,謝謝!
from kivy.app import App
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.lang import Builder
import math
from kivy.uix.widget import Widget
from kivy.properties import NumericProperty, ReferenceListProperty, ObjectProperty
from kivy.clock import Clock
class GameBall(Widget):
org_x, org_y = 300, 300
dist = 100
ang_deg = 0
pos_x = NumericProperty(org_x+dist)
pos_y = NumericProperty(org_y)
pos = ReferenceListProperty(pos_x, pos_y)
def move(self):
self.ang_deg += 5
self.ang_rad = math.radians(self.ang_deg)
self.pos_x, self.pos_y = self.org_x + self.dist*math.cos(self.ang_rad), self.org_y + self.dist*math.sin(self.ang_rad)
class MainGame(Widget):
game_ball = GameBall()
def update(self, dt):
self.game_ball.move()
class ScreenManagement(ScreenManager):
pass
class MenuScreen(Screen):
pass
class GameScreen(Screen):
pass
GUI = Builder.load_file("gui.kv")
class MobileGameApp(App):
def build(self):
game = MainGame()
Clock.schedule_interval(game.update, 1.0/60.0)
return GUI
if __name__ == "__main__":
MobileGameApp().run()
---- Kv文件:
ScreenManagement:
MenuScreen:
GameScreen:
<MenuScreen>:
name: "menu_screen"
Button:
size_hint: .2, .2
pos: root.width/2 - self.width/2, root.height/2 - self.height/2
text: "Play Game"
on_release:
root.manager.transition.direction = "left"
root.manager.current = "game_screen"
<GameScreen>:
game_ball: main_game.game_ball
name: "game_screen"
Button:
size_hint: .2, .2
pos_hint: {'top': 1}
text: "Go to menu"
on_release:
root.manager.transition.direction = "right"
root.manager.current = "menu_screen"
MainGame:
id: main_game
GameBall:
id: game_ball
center: self.parent.center
canvas:
Ellipse:
size: 50, 50
pos: self.pos
您的代碼有幾個問題。 我在您的代碼中看到的一件重要的事情是在您實際想要引用現有實例時創建新的 object 實例:
game = MainGame()
和
game_ball = GameBall()
正在創建MainGame
和GameBall
的新實例。 這些新實例都不在您的 GUI 中,因此您對這些新實例所做的任何更改都不會影響您的 GUI。
因此,您需要獲取對現有MainGame
和GameBall
的引用。 這些是您的kv
文件創建的實例。 一種方法是對您的代碼進行以下更改。
您可以將GameBall
簡化為:
class GameBall(Widget):
org_x, org_y = 300, 300
dist = 100
ang_deg = 0
def move(self):
self.ang_deg += 5
self.ang_rad = math.radians(self.ang_deg)
self.pos = (self.org_x + self.dist*math.cos(self.ang_rad), self.org_y + self.dist*math.sin(self.ang_rad))
MainGame
可以變成:
class MainGame(Widget):
game_ball = ObjectProperty(None)
def update(self, dt):
self.game_ball.move()
啟動 animation 現在看起來像:
class MobileGameApp(App):
def build(self):
Clock.schedule_once(self.start_updates)
return GUI
def start_updates(self, dt):
Clock.schedule_interval(self.root.get_screen('game_screen').ids.main_game.update, 1.0/60)
然后,為了簡化對GameBall
的訪問,我在kv
中添加了一個game_ball
,如下所示:
MainGame:
game_ball: game_ball
id: main_game
GameBall:
id: game_ball
center: self.parent.center
canvas:
Ellipse:
size: 50, 50
pos: self.pos
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.