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

问题描述 投票:0回答:1

我试着围绕一个原点移动一个球(就像月球在绕地球的轨道上)。一开始我在GameScreen里面创建了一个球的对象。然后我得到了AttributeError,我的对象没有 "move "属性。所以我创建了另一个名为MainGame的widget作为球对象的父对象。现在错误消失了,但球没有主动移动。我不知道我错过了什么,因为我对Kivy很陌生。我想这是关于时钟模块和我的自定义更新功能。感谢所有的答案和帮助,谢谢!

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
python python-2.7 kivy kivy-language
1个回答
1
投票

你的代码有几个问题。我在你的代码中看到了一个重要的问题,那就是当你真正想引用现有的实例时,却创建了新的对象实例。

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

And MainGame 可以成为。

class MainGame(Widget):
    game_ball = ObjectProperty(None)

    def update(self, dt):
        self.game_ball.move()

而启动动画现在的样子。

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,我加了一个 game_ballkv 作为:

MainGame:
    game_ball: game_ball
    id: main_game
    GameBall:
        id: game_ball
        center: self.parent.center
        canvas:
            Ellipse:
                size: 50, 50
                pos: self.pos
© www.soinside.com 2019 - 2024. All rights reserved.