为什么collide_widget不能在这里工作?

时间:2014-03-21 03:07:04

标签: collision-detection kivy

我想知道为什么我的'collide_with_hero'方法似乎不起作用?我的Npcs课有什么问题吗?

我只是试图检测小部件何时发生碰撞(英雄和树小部件),我删除了方法中的所有其他代码,而我现在正处于我只是试图检测碰撞和打印的位置如果是真的话。当我运行游戏并将我的英雄角色带入树中时,没有任何打印,没有任何反应。

我在构建中调用self.tree.collide_with_widget。我在这里做错了什么建议?

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.image import Image
from kivy.core.window import Window
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.label import Label
from kivy.uix.behaviors import ButtonBehavior
from kivy.core.audio import SoundLoader
from kivy.uix.relativelayout import RelativeLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.screenmanager import FallOutTransition


gamelayout = RelativeLayout(size=(300, 300))
bglayout = RelativeLayout()

class Game(Screen):
    pass    

class Bg(Image):

    def __init__(self, **kwargs):
        super(Bg, self).__init__(**kwargs)
        self.allow_stretch = True
        self.size_hint = (None, None)
        self.size = (1440, 1440)

class Npcs(Image):
    def __init__(self, **kwargs):
        super(Npcs, self).__init__(**kwargs)

    def collide_with_hero(self, hero):
        if self.collide_widget(hero):
            print "you ran into a tree"

            #dir1 = self.hero.x - self.x
            #if self.x < self.hero.x:
            #    self.hero.x = self.x + dir1


class MoveableImage(Image):

    def __init__(self, **kwargs):
        super(MoveableImage, self).__init__(**kwargs)
        self._keyboard = Window.request_keyboard(None, self)
        if not self._keyboard:
            return
        self._keyboard.bind(on_key_down=self.on_keyboard_down)
        self._keyboard.bind(on_key_up=self.on_keyboard_up)
        self.size_hint = (.11, .11)
        self.y = (Window.height/2.1)
        self.app = App.get_running_app()


    def on_keyboard_down(self, keyboard, keycode, text, modifiers):
        if keycode[1] == 'left':
            self.source = 'selectionscreen/left.zip'
            self.anim_delay=.20
            if self.x < (Window.width * .25):
                bglayout.x += 4
            else:
                self.x -= 6
        elif keycode[1] == 'right':
            self.source ='selectionscreen/right.zip'
            self.anim_delay=.20
            if self.x > (Window.width * .70):
                bglayout.x -= 4
            else:
                self.x += 6
        elif keycode[1] == 'down':
            self.source ='selectionscreen/right.zip'
            self.anim_delay=.20
            if self.y < (Window.height * .25):
                bglayout.y += 4
            else:
                self.y -= 6
        elif keycode[1] == 'up':
            self.source = 'selectionscreen/back.zip'
            self.anim_delay=.1
            if self.y > (Window.height * .70):
                bglayout.y -= 4
            else:
                self.y += 6
        else:
            return False
        return True

    def on_keyboard_up(self, keyboard, keycode):
        if keycode[1] == 'left':
            self.source = 'selectionscreen/left1.png'
        elif keycode[1] == 'right':
            self.source ='selectionscreen/right1.png'
        elif keycode[1] == 'down':
            self.source ='selectionscreen/right1.png'
        elif keycode[1] == 'up':
            self.source ='selectionscreen/back2.png'
        else:
            return False
        return True


class gameApp(App):
    def build(self):
        global sm
        sm = ScreenManager()
        game = Game(name='game')
        sm.add_widget(game)
        hero = MoveableImage(source='selectionscreen/right1.png', pos=(75, 40))
        self.tree = Npcs(source='selectionscreen/tree.zip', pos=(100, 200))
        self.tree.collide_with_hero(hero)
        self.background=Bg(source='selectionscreen/background9.png')

        #add widgets to bglayout
        bglayout.add_widget(self.background)
        bglayout.add_widget(self.tree)

        #add bglayout and moveable hero to gamelayout
        gamelayout.add_widget(bglayout)
        gamelayout.add_widget(hero)
        game.add_widget(gamelayout)

        return sm



if __name__ == '__main__':
    gameApp().run()

2 个答案:

答案 0 :(得分:0)

首先,你使self.tree成为一个Image,但是没有一个collide_with_hero方法。您需要使它成为您定义的新类的实例,Npcs。

其次,您没有调用collide_with_hero方法。您需要self.tree.collide_with_hero(hero)来实际调用它,包括将您的英雄作为参数传递给函数。

答案 1 :(得分:0)

您需要一个主游戏循环来检查一段时间间隔或按键事件后的碰撞。您可以在这里查看Pong示例:http://kivy.org/docs/tutorials/pong.html以了解如何实现这一点。

更具体地说,从本节开始阅读:http://kivy.org/docs/tutorials/pong.html#adding-ball-animation

    Clock.schedule_interval(game.update, 1.0/60.0)

它使用Clock.schedule_interval来安排一个名为&#34;更新&#34;的主循环函数。

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

        #bounce off top and bottom
        if (self.ball.y < 0) or (self.ball.top > self.height):
            self.ball.velocity_y *= -1

        #bounce off left and right
        if (self.ball.x < 0) or (self.ball.right > self.width):
            self.ball.velocity_x *= -1

您需要在类似的函数中编写碰撞检测代码。如果您的游戏涉及更复杂的物理模拟,那么您可以考虑使用像http://box2d.org/这样的库。它将为您管理所有碰撞和内容。