0

I need to create an object of class GameScreen and call it's init and schedule interval to it's update method when the on_release event of a button with text as "New Game" happens

Here is the shortened code:

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)

Everything works fine, no errors. I need some way to create an instance of the GameScreen class and call it's init() and also schedule an interval to call its update() method.

Something Like this if i can guess:

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

Can anybody help this noob kivy developer ??

Shubham V
  • 5
  • 2

1 Answers1

0

One problem with your code is that you seem to be using init() where you should be using __init__(). The __init__() method is automatically called when a Widget is created, but init() is just another method that won't get called unless you explicitly call it. And when you do write your own __init__() method, you should call the base class __init__(). See this question.

So, if you replace the init() method of GameScreen, with __init__(), then your update() method should get scheduled.

Perhaps a better approach might be to start the updating only when the GameScreen is displayed, using the on_enter() method:

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

This avoids having the GameScreen updating when it isn't even visible. And now you don't even need an __init__() over ride, since the default one will be called.

Also. the above comments regarding init() vs __init__() apply to your Snake and Food Widgets as well.

Note that the GameScreen is created when your kv string is evaluated, so you should never actually call GameScreen().

John Anderson
  • 35,991
  • 4
  • 13
  • 36