Just thought it’d be interesting to share/compare code for WASD character control. I’ve been using sin/cos math for it. But I was thinking of trying a dummy node approach. Changes in HPR would affect the dummy node and then changes in XYZ would affect the player node.
I use this (in connection with key polling, a little bit modified to my taste):
from basePolling import I
class Player():
def __init__(self):
self.name = "player"
self.pivot = render.attachNewNode("pivot")
self.actor = Actor() # and so on to load actor
self.actor.reparentTo(self.pivot)
self.steerer = self.pivot.attachNewNode("steerer")
self.target = Point3(0, 0, 0)
self.speed = 15.0
self.lastsavedtime = 0
self.updateTask=taskMgr.add(self.update,"update")
def update(self, task):
elapsedTime = task.time - self.lastsavedtime
targetMoved = self.setTarget()
if targetMoved:
self.steerer.headsUp(self.target)
move = self.speed * elapsedTime
self.pivot.setY(self.steerer, move)
self.lastsavedtime = task.time
return Task.cont
def setTarget(self):
self.target = Point3(0, 0, 0)
if I.keyDown("w"):
self.target += Point3(0, 1, 0)
if I.keyDown("a"):
self.target += Point3(-1, 0, 0)
if I.keyDown("s"):
self.target += Point3(0, -1, 0)
if I.keyDown("d"):
self.target += Point3(1, 0, 0)
if self.target != Point3(0, 0, 0):
return True
else:
return False
Explain to me why you would need either for simple WASD control. It is as simple as:
class PlayerControls(object):
def __init__(self, char):
self.char = char
base.camera.reparentTo(char)
base.camera.setPos(0, -10, 10)
self.mvX = 0
self.mvY = 0
self.accept("a", self.__setattr__, ["mvX", -1])
self.accept("d", self.__setattr__, ["mvX", 1])
self.accept("w", self.__setattr__, ["mvY", 1])
self.accept("s", self.__setattr__, ["mvY", -1])
self.accept("a-up", self.__setattr__, ["mvX", 0])
self.accept("d-up", self.__setattr__, ["mvX", 0])
self.accept("w-up", self.__setattr__, ["mvY", 0])
self.accept("s-up", self.__setattr__, ["mvY", 0])
taskMgr.add(self.move, "moveTask")
def move(self, task):
self.char.setX(self.char, self.mvX * globalClock.getDt() * SPD)
self.char.setY(self.char, self.mvY * globalClock.getDt() * SPD)
self.char.setH(self.char.getH() + base.mouseWatcherNode.getMouseX())
self.char.setP(self.char.getP() + base.mouseWatcherNode.getMouseY())
base.win.movePointer(0, base.win.getXSize() / 2, base.win.getYSize() / 2)
return task.cont
A good rule-of-thumb is: if you have to use sin/cos/tan, you’re probably doing something wrong. (copyrighted by drwr)