Kivy - 无法在添加到第二个屏幕的小部件上运行游戏

时间:2015-07-08 09:24:07

标签: python kivy

我几天前发布了两篇关于同一问题的帖子,但我仍然无法让它运行。

我有两个屏幕。第一个屏幕上的两个按钮(播放和如何播放)。第二个做我想要的,但我希望第一个在发布时开始游戏,以及将屏幕更改为第二个屏幕(这样可以正常)。 我已经尝试了很多东西,我总是得到关于没有定义SnakeWidget,不包含self等的错误。

这是我得到的错误:

 File "C:\Users\Lara\Desktop\KIVY\LARA\poskus.py", line 33, in <module>
     class GameScreen(Screen):
 File "C:\Users\Lara\Desktop\KIVY\LARA\poskus.py", line 34, in GameScreen
     snaky_game = SnakeWidget()
NameError: name 'SnakeWidget' is not defined

.py文件:

import kivy
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.popup import Popup
from kivy.vector import Vector
from kivy.clock import Clock
from kivy.lang import Builder


class RootScreen(ScreenManager):
    pass

class StartScreen(Screen):
    def show_popup(self):
        p = InstructionsPopup(content=Label(text="Instructions"))
        p.open()

class GameScreen(Screen):
    snaky_game = SnakeWidget()
    snaky_game.begin()
    Clock.schedule_interval(self.update, 1.0 / 60.0)

class InstructionsPopup(Popup):
    pass

class SnakeWidget(Widget):
    snaky = ObjectProperty(None)

    def __init__(self, *args, **kwargs):
        super(SnakeWidget, self).__init__(*args, **kwargs)
        Clock.schedule_interval(self.update, 1.0 / 60.0)

    def begin(self, vel=(4, 0)):
        self.snaky.center = self.center
        self.snaky.velocity = vel

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

        if (self.snaky.y < self.y) or (self.snaky.top > self.top):
            self.snaky.velocity_y *= -1

class Snake(Widget):
    velocity_x = NumericProperty(0)
    velocity_y = NumericProperty(0)
    velocity = ReferenceListProperty(velocity_x, velocity_y)

    def move(self):
        self.pos = Vector(*self.velocity) + self.pos

class PoskusApp(App):
    def build(self):
        self.load_kv("poskus.kv")
        return RootScreen()


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

和.kv文件:

#:import FadeTransition kivy.uix.screenmanager.FadeTransition

<RootScreen>:
    id: screen_manager
    transition: FadeTransition()
    StartScreen:
        name: "start"
    GameScreen:
        name: "game"

<StartScreen>:
    FloatLayout:
        name: "start"
        Button: 
            id: play
            text: "Play!"
            size_hint: 0.4, 0.3
            pos_hint: {'center_x':.5, 'center_y':.5}
            font_size: 70
            on_release: root.manager.current = "game"
        Button: 
            id: how
            text: "How to play"
            size_hint: 0.4, 0.1
            pos_hint: {'center_x':.5, 'center_y':.3}
            font_size: 40
            on_press: root.show_popup()
<InstructionsPopup>:
    size_hint: .5, .5
    title: "How to play"

<GameScreen>:
    name: "game"
    SnakeWidget:
    Button:
        id: menu
        text: "Menu"
        size_hint: 0.2, 0.1
        pos_hint: {"x": 0.8,"y":0.9}
        font_size: 17
        on_release: root.manager.current  = "start"

<SnakeWidget>:
    id: snake_widget
    snaky: snake
    canvas: 
        Rectangle:
            size: self.size
            pos: self.pos
    Snake: 
        id: snake
        center: self.parent.center  

<Snake>:
    size: 50, 50 
    canvas:
        Ellipse:
            pos: self.pos
            size: 40, 40

如果可以,请帮助我,因为我被困住了,无处可去。

1 个答案:

答案 0 :(得分:1)

我认为你错过了几个python基础知识。我将以点的形式解释。

<强> 1 即可。您忘记导入在python代码中使用的属性。

from kivy.properties import NumericProperty,ReferenceListProperty,ObjectProperty

<强> 2 即可。您需要知道python解释器的工作原理,它从上到下读取您的代码,在定义GameScreen类之前定义类SnakeWidget,所以当您尝试制作时一个SnakeWidget类的对象,对于解释器来说并不存在。它显示错误。 NameError: name 'SnakeWidget' is not defined。所以基本上,将您的班级GameScreen移到班级SnakeWidget下方,这样可以解决错误。

第3 即可。您尝试安排功能时使用了selfClock.schedule_interval(self.update, 1.0 / 60.0)

使用self会说同一个类本身有一个名为update的方法,而不是查看SnakeWidget类。

class GameScreen(Screen):
    snaky_game = SnakeWidget()
    snaky_game.begin()
    Clock.schedule_interval(snaky_game.update, 1.0 / 60.0)