Как я могу гарантировать, что действия моего второго экрана загружаются только тогда, когда он активно находится на переднем плане? - PullRequest
0 голосов
/ 19 июня 2020

Если я использую свой код, как указано ниже, init будет выполняться классом GameWindow при запуске программы. С инструкцией Clock.schedule_interval (self.update, .75) программа зависает, как только я вызываю второй экран (GameWindow). Как избежать зависания или убедиться, что Clock.schedule_interval (self.update, .75) ожидает вызова второго экрана?

Python код:

from kivy.app import App
from kivy.properties import ObjectProperty
from kivy.core.window import Window
from kivy.lang import Builder

from kivy.animation import Animation
from kivy.clock import Clock

from kivy.uix.screenmanager import ScreenManager, Screen

from kivy.graphics import Color, Rectangle, Ellipse, Rotate, PushMatrix, PopMatrix

from random import randint
from time import sleep


class WindowManager(ScreenManager):
    pass


class StartWindow(Screen):
    pass


class GameWindow(Screen):
    lbl1 = ObjectProperty(None)
    sq_im = ObjectProperty(None)
    bl_n = ObjectProperty(None)
    bl_w = ObjectProperty(None)
    bl_e = ObjectProperty(None)
    bl_s = ObjectProperty(None)

    angle = 0
    ball_states = [False, False, False, False]
    square_state = False
    counter = 0

    def __init__(self, **kwargs):
        super(GameWindow, self).__init__(**kwargs)
        Window.size = 400, 650
        Clock.schedule_interval(self.update, .75)

        with self.canvas.before:
            Color(rgba=(1, 1, 1, 1))
            self.rect = Rectangle(size=Window.size, pos=self.pos)

    def on_touch_down(self, touch):
        self.angle += 90
        anim_square = Animation(angle=self.angle, duration=.1)
        anim_square.start(self.sq_im)
        self.square_state = not self.square_state

    def update(self, *args):
        rand = randint(0, 3)
        while self.ball_states[rand]:
            rand = randint(0, 3)
        if rand == 0:
            anim = Animation(y=0.5 * Window.size[1], duration=1.5)
            anim.start(self.bl_n)
            self.ball_states[0] = True
            anim.bind(on_complete=self.reset)

        elif rand == 1:
            anim = Animation(x=0.48 * Window.size[0], duration=1.5)
            anim.start(self.bl_w)
            self.ball_states[1] = True
            anim.bind(on_complete=self.reset)

        elif rand == 2:
            anim = Animation(x=0.452 * Window.size[0], duration=1.5)
            anim.start(self.bl_e)
            self.ball_states[2] = True
            anim.bind(on_complete=self.reset)

        elif rand == 3:
            anim = Animation(y=0.48 * Window.size[1], duration=1.5)
            anim.start(self.bl_s)
            self.ball_states[3] = True
            anim.bind(on_complete=self.reset)

    def reset(self, *args):
        if args[1].uid == self.bl_n.uid:
            args[1].pos[1] = Window.size[1]
            self.ball_states[0] = False
            if not self.square_state:
                self.counter += 1
                self.lbl1.text = str(self.counter)

        elif args[1].uid == self.bl_w.uid:
            args[1].pos[0] = -self.bl_n.size[0]
            self.ball_states[1] = False
            if self.square_state:
                self.counter += 1
                self.lbl1.text = str(self.counter)

        elif args[1].uid == self.bl_e.uid:
            args[1].pos[0] = Window.size[0]
            self.ball_states[2] = False
            if self.square_state:
                self.counter += 1
                self.lbl1.text = str(self.counter)

        elif args[1].uid == self.bl_s.uid:
            args[1].pos[1] = -self.bl_n.size[1]
            self.ball_states[3] = False
            if not self.square_state:
                self.counter += 1
                self.lbl1.text = str(self.counter)


Gui = Builder.load_file("my.kv")


class MyApp(App):
    def build(self):
        return Gui


if __name__ == "__main__":
    MyApp().run()

код kivy:

WindowManager:
    StartWindow:
    GameWindow:

<Button>:
    size_hint: (0.2, 0.1)

<square_image@Image>:
    angle: 0
    canvas.before:
        PushMatrix
        Rotate:
            angle: root.angle
            axis: 0, 0, 1
            origin: root.center
    canvas.after:
        PopMatrix

<ball@Image>:
    size_hint: .05, .05
    source: "ball.png"

<StartWindow>:
    name: "start"
    Button:
        text: "Start"
        on_release:
            root.manager.current = "game"

<GameWindow>:
    name: "game"
    lbl1: lbl1
    sq_im: sq_im
    bl_n: bl_n
    bl_w: bl_w
    bl_e: bl_e
    bl_s: bl_s

    FloatLayout:

        Label:
            id: lbl1
            pos_hint: {"x":.2, "y":.85}
            size_hint: .1, .1
            font_size: "40sp"
            color: 0,0,0,1
            text: "0"
        ball:
            id: bl_n
            pos: (.475*root.size[0], root.size[1])
        ball:
            id: bl_w
            pos: (-self.size[0], .475*root.size[1])
        ball:
            id: bl_e
            pos: (root.size[0], .475*root.size[1])
        ball:
            id: bl_s
            pos: (.475*root.size[0], -self.size[1])
        square_image:
            id: sq_im
            pos_hint: {"x":.44, "y":.44}
            size_hint: .12, .12
            angle: 0
            source: "square.png"

Заранее спасибо !!

...