【问题标题】:I need to create some objects and call some functions on the on_release event of the newgame button我需要在 newgame 按钮的 on_release 事件上创建一些对象并调用一些函数
【发布时间】:2020-10-25 11:10:50
【问题描述】:

当文本为“新游戏”的按钮的 on_release 事件发生时,我需要创建一个 GameScreen 类的对象并调用它的 init 和调度间隔来更新方法

以下是缩短的代码:

class Snake(Widget):
    def init(self, bool, list):
        pass    
    def update(self):
        pass
    
class Food(Widget):
    def init():
        pass
    def draw(snake_instance):
        pass
    def check(snake_instance):
        pass
    
class WindowManager(ScreenManager):
    pass

class MainMenuScreen(Screen):
    pass    

class GameScreen(Screen):   
    snk = ObjectProperty(None)
    fd = ObjectProperty(None)
    
    def init(self):
        self.snk.init(False, (0,1,0,1))
        self.fd.init()
        Clock.schedule_interval(self.update, 1/20)

    def update(self, deltaTime):
        self.snk.update()
        self.fd.draw(self.snk)
        self.fd.check(self.snk)

class GameOverScreen(Screen):
    pass

class OptionsScreen(Screen):
    pass

class HighScoreScreen(Screen):
    pass


kivyFile = Builder.load_string("""
#: import FadeTransition kivy.uix.screenmanager.FadeTransition

WindowManager:
    transition: FadeTransition()
    MainMenuScreen:
    GameScreen:
    GameOverScreen
    OptionsScreen:
    HighScoreScreen:
    

<Button>:
    font_size: 50
    size_hint: None, None
    background_color: 0,0,0,0
        
    color: self.parent.red if self.state=="normal" else self.parent.black
    
    canvas.before:
        Color:
            rgba: self.parent.black if self.state=="normal" else self.parent.red
        RoundedRectangle:
            size: self.size
            pos: self.pos
            radius: [self.height*0.4]
        Color:
            rgba: self.parent.red if self.state=="normal" else self.parent.black
        Line:
            width: 2
            rounded_rectangle: self.x, self.y, self.width, self.height, self.height*0.4



<MainMenuScreen>:
    name: "mainmenuscreen"
    red: (1,0,0,1)
    black: (0,0,0,1)
    
    canvas.before:
        Color:
            rgba: 0.15,0,0,1
        Rectangle:
            size: root.size
            pos: root.pos
    
    Widget:
        Label:
            text: "Snake Game"
            bold: True
            color: (0,0,0,1)
            font_size: 100
            
            outline_width: 3
            outline_color: (1,0,0,1)
            
            pos: 0, 1050
            center_x: root.center_x
        
    Button:
        text: "New Game"
        size: 350, 90
        pos: 0, 800
        center_x: root.center_x
        
        on_release:
            root.manager.current = "gamescreen"
    
    Button:
        text: "Options"
        size: 300, 90
        pos: 0, 650
        center_x: root.center_x
    
    Button:
        text: "High Scores"
        size: 350, 90
        pos: 0, 500
        center_x: root.center_x
    
    Button:
        text: "Exit"
        size: 200, 90
        pos: 0, 350
        center_x: root.center_x
        
        on_release: app.stop()


<GameScreen>:
    name: "gamescreen"
    snk: snake_id
    fd: fd_id
    
    canvas.before:
        Color:
            rgba: .2, .2, .2, 1
        Rectangle:
            pos: self.pos
            size: self.size
    
    Widget:
        Snake:
            id: snake_id
            Label:
                font_size: 50
                color: self.parent.color
                text: self.parent.disScore
                size: self.texture_size
                size_hint: None, None
                pos: root.width-self.width-20, root.height-self.height-10
    
        Food:
            id: fd_id
            
""")


runTouchApp(kivyFile)

一切正常,没有错误。 我需要一些方法来创建 GameScreen 类的实例并调用它的 init() 并安排一个间隔来调用它的 update() 方法。

如果我能猜到是这样的:

def someMethod():
    gs = GameScreen()
    gs.init()
    Clock.schedule_interval(gs.update,1/20)

任何人都可以帮助这个 noob kivy 开发人员吗??

【问题讨论】:

    标签: python kivy


    【解决方案1】:

    您的代码的一个问题是您似乎使用了init(),而您应该使用__init__()__init__() 方法在创建 Widget 时会自动调用,但 init() 只是另一种方法,除非您明确调用它,否则不会被调用。当你编写自己的__init__() 方法时,你应该调用基类__init__()。见this question

    因此,如果您将GameScreeninit() 方法替换为__init__(),那么您的update() 方法应该会被调度。

    也许更好的方法是仅在显示GameScreen 时才开始更新,使用on_enter() 方法:

    def on_enter(self, *args):
        self.snk.init(False, (0, 1, 0, 1))
        self.fd.init()
        self.update_event = Clock.schedule_interval(self.update, 1 / 20)
    
    def on_leave(self, *args):
        self.update_event.cancel()
    

    这样可以避免在 GameScreen 甚至不可见时进行更新。现在你甚至不需要 __init__() 覆盖,因为默认的会被调用。

    还有。以上关于 init()__init__() 的 cmets 也适用于您的 SnakeFood Widgets

    请注意,GameScreen 是在评估您的 kv 字符串时创建的,因此您永远不应真正调用 GameScreen()

    【讨论】:

      猜你喜欢
      • 2013-08-06
      • 1970-01-01
      • 1970-01-01
      • 2013-06-21
      • 2017-09-28
      • 1970-01-01
      • 2011-03-04
      • 1970-01-01
      • 2021-01-28
      相关资源
      最近更新 更多