繁体   English   中英

Kivy中多屏时钟模块如何处理?

[英]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()

正在创建MainGameGameBall的新实例。 这些新实例都不在您的 GUI 中,因此您对这些新实例所做的任何更改都不会影响您的 GUI。

因此,您需要获取对现有MainGameGameBall的引用。 这些是您的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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM