Note: you usually don’t need this, there is global inputState, this snippet is tied to single object.
For example if you have pong like game, and you use panda’s internal input state, all players will be controlled by input from any of them. There is way to go around that behaviour( like adding playerId to inputState), but that sounds like improper way of doing things
You can copy and paste code in your favorite editor and try running it
from direct.showbase.DirectObject import DirectObject
from direct.showbase.ShowBase import ShowBase
class Player(DirectObject):
def __init__(self):
#set is python collection, just like list and dictionary
#if you want to know more, google it
self.inputStates = set()
self.NP = loader.loadModel("smiley")
self.NP.reparentTo(render)
# in real program, you will probably want to read controls from
# config file (i use yaml)
controls = {'keyboard': {'forward': 'w',
'turbo': 'q',
'right': 'd',
'back': 's',
'left': 'a'} }
#i usually call this from other function which creates more than
# instance of player and send different controls for it
self.setupControls(controls)
def setupControls(self, controls):
taskMgr.add(self.processInput, "Process Input")
#keyboard shortcuts
#action = "left"
#key = "a"
for action, bind in controls["keyboard"].items():
#if bind is clicked, we set input state (third arguments must be list,
# and it will pass all elements in that
# list as argument to function called - self.setInputState)
self.accept(bind, self.setInputState, [action])
#if bind is released, we want to remove input state
self.accept(bind + "-up", self.removeInputState, [action])
def setInputState(self, action):
#accepts String
#comment next line, i am using it for debugging purposes
print "Player setting state %s" % (action)
# we add string which represents action to set
# left, turbo, jump for example
# dont worry about doubles, if you have two keys that move left there will
# be only one "left" in set
self.inputStates.add(action)
def removeInputState(self, action):
#accepts String
#this try block is needed in case that there are 2 keys mapped to same action
#when you release first, action will get removed from input states set
#and when you release second, you would get error, here we just pass silently
try:
self.inputStates.remove(action)
except:
pass
def state(self, state):
#accepts String
#function which checks if there is state in inputStates and return True/False
return state in self.inputStates
def processInput(self, task):
self.dt = globalClock.getDt()
speed = 40
turboModifier = 4
if self.state('turbo'):
speed = speed * turboModifier
if self.state('left'):
self.NP.setX(self.NP, -self.dt * speed)
if self.state('right'):
self.NP.setX(self.NP, self.dt * speed)
if self.state('forward'):
self.NP.setY(self.NP, self.dt * speed)
if self.state('back'):
self.NP.setY(self.NP, -self.dt * speed)
return task.cont
class Game(ShowBase):
def __init__(self):
ShowBase.__init__(self)
x = Player()
x = Game()
x.run()