Добавить функцию на экран kivy

#python #kivy

#python #kivy

Вопрос:

Когда я покидаю главный экран в первый раз, экран дублируется. Когда я возвращаюсь на главный экран в первый раз, экран полностью черный. Но тогда это работает нормально.

Изображение второго экрана при первом пролистывании введите описание изображения здесь. Изображение на главном экране, когда я возвращаюсь в первый раз: введите описание изображения здесь. Но тогда она отлично работает для второго и других свайпов.

 Builder.load_string("""
<MenuScreen>:
    BoxLayout:
        Button:
            text: 'Go to main screen'
            on_press: root.manager.current = 'main'
            size_hint: None, None
            size: self.texture_size
        Button:
            text: 'Go to second screen'
            on_press: root.manager.current = 'second'
            size_hint: None, None
            size: self.texture_size
<MainScreen>:
    # add Game widget
    Game:
        power: powerbar
        lifes: lifesbar
        id: game
    BoxLayout:
        Button:
            text: 'Go to the menu screen'
            on_press: root.manager.current = 'menu'
            size_hint: None, None
            size: self.texture_size
    FloatLayout:
        ShootProgressBar:
            id: powerbar
            pos_hint: {'x': 0.035, 'y': 0.9}
            size_hint: (0.25, 0.1)
            max:10
        LifesProgressBar:
            canvas:
                Color:
                    rgba: 1, 0, 0, 1
            id: lifesbar
            pos_hint: {'x': 0.7, 'y': 0.92}
            size_hint: (0.25, 0.1)
            max:3
            value:3
        Image:
            id: ethereum
            size_hint: (0.04, 0.04)
            pos_hint: {'x': 0.002, 'y': 0.93}
            allow_stretch: True
            source: "ethereum.png"
        Image:
            id: lifes_img
            size_hint: (0.04, 0.04)
            pos_hint: {'x': 0.952, 'y': 0.93}
            allow_stretch: True
            source: "lifes.png"

<SecondScreen>:
    # add Game widget
    Game:
        power: powerbar
        lifes: lifesbar
        id: game
    BoxLayout:
        Button:
            text: 'Back to menu'
            on_press: root.manager.current = 'menu'
            size_hint: None, None
            size: self.texture_size
    FloatLayout:
        ShootProgressBar:
            id: powerbar
            pos_hint: {'x': 0.035, 'y': 0.9}
            size_hint: (0.25, 0.1)
            max:10
        LifesProgressBar:
            canvas:
                Color:
                    rgba: 1, 0, 0, 1
            id: lifesbar
            pos_hint: {'x': 0.7, 'y': 0.92}
            size_hint: (0.25, 0.1)
            max:3
            value:3
        Image:
            id: ethereum
            size_hint: (0.04, 0.04)
            pos_hint: {'x': 0.002, 'y': 0.93}
            allow_stretch: True
            source: "ethereum.png"
        Image:
            id: lifes_img
            size_hint: (0.04, 0.04)
            pos_hint: {'x': 0.952, 'y': 0.93}
            allow_stretch: True
            source: "lifes.png"
            
<-ShootProgressBar@ProgressBar>:
    canvas:
        Color:
            rgb: 1, 1, 1
        BorderImage:
            border: (12, 12, 12, 12)
            pos: self.x, self.center_y - 3
            size: self.width, 24
            source : 'black_bg.png'
        BorderImage:
            border: [int(min(self.width * (self.value / float(self.max)) if self.max else 0, 12))] * 4
            pos: self.x, self.center_y - 12
            size: self.width * (self.value / float(self.max)) if self.max else 0, 24
            source : 'blue_fg.png'
            
<-LifesProgressBar@ProgressBar>:
    canvas:
        Color:
            rgb: 1, 1, 1
        BorderImage:
            border: (12, 12, 12, 12)
            pos: self.x, self.center_y - 14
            size: self.width, 24
            source: 'black_bg.png'
        BorderImage:
            border: [int(min(self.width * (self.value / float(self.max)) if self.max else 0, 12))] * 4
            pos: self.x, self.center_y - 12
            size: self.width * (self.value / float(self.max)) if self.max else 0, 24
            source: 'green2_fg.png'

<ColourScreen>:
    BoxLayout:
        orientation: 'vertical'
        Label:
            text: 'colour {:.2},{:.2},{:.2} screen'.format(*root.colour[:3])
            font_size: 30
        Widget:
            canvas:
                Color:
                    rgba: root.colour
                Ellipse:
                    pos: self.pos
                    size: self.size
        BoxLayout:
            Button:
                text: 'goto first screen'
                font_size: 30
                on_release: app.root.current = 'first'
            Button:
                text: 'get random colour screen'
                font_size: 30
                on_release: app.root.new_colour_screen()
""")


# Declare both screens

class MenuScreen(Screen):
    pass


class MainScreen(Screen):
    def on_enter(self, *args):
        self.ids.game.initialize()
        self.ids.game.power.value = 0
        self.ids.game.lifes.value = 3
        self.update_event = Clock.schedule_interval(self.ids.game.update_glsl, 1.0 / 60.0)

    def on_leave(self, *args):
        self.update_event.cancel()
        self.ids.game.indices = []
        self.ids.game.vertices = []
        self.ids.game.particles = []
        self.ids.game.canvas.clear()
        self.update_event = None
            


class SecondScreen(Screen):

    def on_enter(self, *args):
        self.ids.game.initialize()
        self.ids.game.power.value = 0
        self.ids.game.lifes.value = 3
        self.update_event = Clock.schedule_interval(self.ids.game.update_glsl, 1.0 / 60.0)

    def on_leave(self, *args):
        self.update_event.cancel()
        self.ids.game.indices = []
        self.ids.game.vertices = []
        self.ids.game.particles = []
        self.ids.game.canvas.clear()
        self.update_event = None
  

Я хочу использовать условия для изменения экрана. Например, if self.parent.power.value == 10: sm.current = 'second'

Комментарии:

1. Какие функции не работают? Где ваш код, который должен выполнять анимацию?

Ответ №1:

Если я понимаю, что вы пытаетесь сделать, вы можете добавить свой Game виджет в MainScreen kv (вы также должны настроить размер Button , чтобы он не покрывал весь MainScreen ):

 <MainScreen>:
    # add Game widget
    Game:
        id: game
    BoxLayout:
        Button:
            text: 'Go to the second screen'
            on_press: root.manager.current = 'second'
            size_hint: None, None
            size: self.texture_size
    FloatLayout:
        ShootProgressBar:
            id: powerbar
            pos_hint: {'x': 0.035, 'y': 0.9}
            size_hint: (0.25, 0.1)
            max:10
        LifesProgressBar:
            canvas:
                Color:
                    rgba: 1, 0, 0, 1
            id: lifesbar
            pos_hint: {'x': 0.7, 'y': 0.92}
            size_hint: (0.25, 0.1)
            max:3
            value:3
        Image:
            id: ethereum
            size_hint: (0.04, 0.04)
            pos_hint: {'x': 0.002, 'y': 0.93}
            allow_stretch: True
            source: "ethereum.png"
        Image:
            id: lifes_img
            size_hint: (0.04, 0.04)
            pos_hint: {'x': 0.952, 'y': 0.93}
            allow_stretch: True
            source: "lifes.png"
  

Затем в классах MainScreen и SecondSceen вы можете выполнить инициализацию и запустить обновление:

 class MainScreen(Screen):
    def on_enter(self, *args):
        self.ids.game.initialize()
        self.ids.game.power.value = 0
        self.ids.game.lifes.value = 0
        self.update_event = Clock.schedule_interval(self.ids.game.update_glsl, 1.0 / 60.0)

    def on_leave(self, *args):
        self.update_event.cancel()
        self.ids.game.indices = []
        self.ids.game.vertices = []
        self.ids.game.particles = []
        self.ids.game.canvas.clear()
        self.update_event = None


class SecondScreen(Screen):

    def on_enter(self, *args):
        self.ids.game1.initialize()
        self.ids.game1.power.value = 0
        self.ids.game1.lifes.value = 0
        self.update_event = Clock.schedule_interval(self.ids.game1.update_glsl, 1.0 / 60.0)

    def on_leave(self, *args):
        self.update_event.cancel()
        self.ids.game1.indices = []
        self.ids.game1.vertices = []
        self.ids.game1.particles = []
        self.ids.game1.canvas.clear()
        self.update_event = None
  

и в Game.update_glsl() методе используйте super для доступа к PSWidget методу обновления, например:

 def update_glsl(self, nap):
    if self.use_mouse:
        self.player_x, self.player_y = Window.mouse_pos

    if self.firing:
        self.fire_delay -= nap

    self.spawn_delay -= nap

    super(Game, self).update_glsl(nap)
  

Также. в вашем PSWidget классе измените определение indices , vertices и particles чтобы сделать их Properties такими, как это:

 class PSWidget(Widget):
    indices = ListProperty([])
    vertices = ListProperty([])
    particles = ListProperty([])
  

Комментарии:

1. Используя ваш код и мои модификации, при его запуске появляются звезды и враги.

2. Я применил пример, вот что я получаю: i.stack.imgur.com/U4UwT.png Вот код, который я применил: pastebin.com/VpDKFjia

3. Можете ли вы поделиться примером полного кода с вашим решением? Я действительно заблокирован

4. В коде, который вы опубликовали в pastebin, большинство ваших классов дублируются и определяются как вложенные классы внутри ваших Screen классов. В результате этот код не будет работать. Кроме того, в моем ответе я сказал добавить on_enter() метод в MainScreen класс, но вы добавили его в один из двух Game классов в вашем коде. Здесь приведена моя версия вашего кода, но некоторые из них закомментированы, поскольку у меня не было некоторых изображений или аудиофайлов, которые вы использовали.

5. Кстати, вам не нужен Game1 класс, поскольку вы никогда его не используете, и это просто дубликат Game .