I am wondering why my 'collide_with_hero' method does not seem to be working? Is there something wrong with my Npcs class?
I am just trying to detect when widgets collide (the hero and the tree widget), I stripped out all the additional code in the method, and I am at the point now where I am just simply trying to detect collision and print something if True. When I run the game and walk my hero character into the tree, nothing prints, nothing happens.
I call self.tree.collide_with_widget in the build. Any advice on what I am doing wrong here?
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()
You need a main game loop to check for collision after some interval in time or on a keypress event. You can take a look at the Pong example here: http://kivy.org/docs/tutorials/pong.html to get an idea about how to achieve that.
More specifically start reading from this section: http://kivy.org/docs/tutorials/pong.html#adding-ball-animation.
Clock.schedule_interval(game.update, 1.0/60.0)
It uses Clock.schedule_interval to schedule a main loop function called "update".
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
You will need to write the collision detection code in a function like that. If your game involves more complex Physics simulation then you may consider using a library like http://box2d.org/. It will manage all the collisions and stuff for you.