Here’s a bigger test with movement
# Load the PANDA libraries
import direct.directbase.DirectStart
from direct.showbase.ShowBaseGlobal import *
from direct.interval.IntervalGlobal import *
from direct.gui.DirectGui import *
from direct.showbase import DirectObject
from direct.actor import Actor
from direct.task import Task
from pandac.PandaModules import *
from direct.showbase.PythonUtil import *
import random, sys, os, math, glob
GAMEDIR_WIN = os.path.abspath(sys.path[0])
GAMEDIR = Filename.fromOsSpecific(GAMEDIR_WIN).getFullpath()
SPD_MULTIPLIER = 20
ANIMS = {
'idle':'art/characters/_anims/_idle',
'run':'art/characters/_anims/_run',
}
map = loader.loadModel(GAMEDIR + "/art/maps/world/world")
map.reparentTo(render)
char1 = Actor.Actor(GAMEDIR + "/art/characters/guy/guy", ANIMS)
char1.setPos(0,0,0)
char1.SPD = 10
char1.isMoving = False
char1.isAlive = True
char1.reparentTo(render)
char2 = Actor.Actor(GAMEDIR + "/art/characters/guy/guy", ANIMS)
char2.setPos(600,600,0)
char2.SPD = 6
char2.isBusy = False
char2.reparentTo(render)
class World(DirectObject.DirectObject):
def __init__(self):
########################################
# Keyboard Controls
########################################
self.isViewMode = False
self.keyMap = {"left":0, "right":0, "forward":0}
self.accept("escape", sys.exit,[0])
self.accept("w", self.setKey, ["forward",1])
self.accept("w-up", self.setKey, ["forward",0])
self.accept("a", self.setKey, ["left",1])
self.accept("a-up", self.setKey, ["left",0])
self.accept("d", self.setKey, ["right",1])
self.accept("d-up", self.setKey, ["right",0])
self.accept("c", self.cameraView)
self.accept("x", base.screenshot)
self.accept("z", self.cameraInfo)
########################################
# Camera Controls
########################################
base.disableMouse()
base.camera.setPos((133, -132, 67))
base.camera.reparentTo(char1)
base.camera.setCompass(render)
base.camera.lookAt(char1)
self.camDist = 200
self.mx,self.my = 0,0
self.dragging = False
self.target = Vec3()
self.turnCameraAroundPoint(0,0,self.target, self.camDist)
self.accept("mouse3",self.startDrag)
self.accept("mouse3-up",self.stopDrag)
self.accept("wheel_up",lambda : self.adjustCamDist(0.9))
self.accept("wheel_down",lambda : self.adjustCamDist(1.1))
taskMgr.add(self.taskCamera,"cameraTask")
taskMgr.add(self.taskMove,"moveTask")
taskMgr.add(self.taskAI,"aiTask")
def setKey(self, key, value):
self.keyMap[key] = value
def cameraInfo(self):
print "Camera POS: ", base.camera.getPos()
print "Camera RTN: ", base.camera.getHpr()
print "Camera DIS: ", self.camDist
def cameraView(self):
if self.isViewMode == False:
base.camera.setCompass(char1)
self.isViewMode = True
else:
base.camera.setCompass(render)
self.isViewMode = False
def turnCameraAroundPoint(self,tx,ty,p,dist):
newCamHpr=Vec3()
camHpr=base.camera.getHpr()
newCamHpr.setX(camHpr.getX()+tx)
newCamHpr.setY(camHpr.getY()-ty)
newCamHpr.setZ(camHpr.getZ())
base.camera.setHpr(newCamHpr)
angleradiansX = newCamHpr.getX() * (math.pi / 180.0)
angleradiansY = newCamHpr.getY() * (math.pi / 180.0)
base.camera.setPos( dist*math.sin(angleradiansX)*math.cos(angleradiansY)+p.getX(),
-dist*math.cos(angleradiansX)*math.cos(angleradiansY)+p.getY(),
-dist*math.sin(angleradiansY)+p.getZ() )
base.camera.lookAt(p.getX(),p.getY(),p.getZ() )
def startDrag(self):
self.dragging = True
def stopDrag(self):
self.dragging = False
def adjustCamDist(self,aspect):
self.camDist = self.camDist*aspect
self.turnCameraAroundPoint(0,0,self.target,self.camDist)
########################################
# Camera TASK
########################################
def taskCamera(self,task):
if base.mouseWatcherNode.hasMouse():
mpos = base.mouseWatcherNode.getMouse()
if self.dragging:
self.turnCameraAroundPoint((self.mx-mpos.getX())*100,(self.my-mpos.getY())*100,self.target,self.camDist)
else:
moveY = False
moveX = False
if self.my>0.8:
angleradiansX = base.camera.getH() * (math.pi / 180.0)
aspect = (1-self.my-0.2)*10
moveY = True
if self.my<-0.8:
angleradiansX = base.camera.getH() * (math.pi / 180.0)+math.pi
aspect = (1+self.my-0.2)*10
moveY = True
if self.mx>0.8:
angleradiansX2 = base.camera.getH() * (math.pi / 180.0)+math.pi*0.5
aspect2 = (1-self.mx-0.2)*10
moveX = True
if self.mx<-0.8:
angleradiansX2 = base.camera.getH() * (math.pi / 180.0)-math.pi*0.5
aspect2 = (1+self.mx-0.2)*10
moveX = True
if moveY:
self.target.setX(self.target.getX() + math.sin(angleradiansX)*aspect)
self.target.setY(self.target.getY() - math.cos(angleradiansX)*aspect)
self.turnCameraAroundPoint(0,0,self.target,self.camDist)
if moveX:
self.target.setX( self.target.getX() - math.sin(angleradiansX2)*aspect2 )
self.target.setY( self.target.getY() + math.cos(angleradiansX2)*aspect2 )
self.turnCameraAroundPoint( 0,0,self.target,self.camDist )
self.mx = mpos.getX()
self.my = mpos.getY()
return Task.cont
########################################
# Movement TASK
########################################
def taskMove(self, task):
elapsed = globalClock.getDt()
anim_move = "run"
anim_idle = "idle"
speed = char1.SPD * SPD_MULTIPLIER
# move/rotate char
if (self.keyMap["left"]!=0):
char1.setH(char1.getH() + elapsed*300)
if (self.keyMap["right"]!=0):
char1.setH(char1.getH() - elapsed*300)
if (self.keyMap["forward"]!=0):
char1.setY(char1, - (elapsed * speed))
# handle anim
if (self.keyMap["forward"]!=0) or (self.keyMap["left"]!=0) or (self.keyMap["right"]!=0):
if char1.isMoving == False:
char1.loop(anim_move)
char1.isMoving = True
else:
if char1.isMoving:
char1.stop()
char1.loop(anim_idle)
char1.isMoving = False
return Task.cont
########################################
# AI TASK
########################################
def taskAI(self,task):
if char2.isBusy == False:
charAI(char2, [char1,])
return Task.cont
###########################################################################
# CHARAI
# Handles AI characters (movement, fighting)
###########################################################################
def charAI(char, targets):
target = getNearestTgtChar(char, targets)
distance = getDistance(char.getPos(), target.getPos())
if distance > 50:
charMove(char, target.getPos())
else:
charIdle(char)
########################################################################################################################
# CHARMOVE
# Tells a character to move towards a position, param for special motion anim, run is default
########################################################################################################################
def charMove(char, endPos=(0,0,0), anim="run"):
char.isBusy = True
char.loop(anim)
elapsed = max(globalClock.getDt(), 1.1) # at least 1.1 to make foes match player speeds
time = getDistance(char.getPos(), endPos) / (char.SPD * SPD_MULTIPLIER * elapsed) # Time = Distance / Speed
part1 = Func(char.lookAt, char1)
part2 = char.posInterval(time, endPos)
part3 = Func(charIdle, char)
mySequence = Sequence(part1, part2, part3)
mySequence.start()
###########################################################################
# GETNEARESTTGTCHAR
# Returns closest target char to specified char
###########################################################################
def getNearestTgtChar(char, targets):
minDistance = pow(10,6) # a very big number!!
nearestTarget = ''
for target in targets:
if target.isAlive:
distance = getDistance(char.getPos(), target.getPos() )
if distance < minDistance:
minDistance = distance
nearestTarget = target
return nearestTarget
########################################################################################################################
# GETDISTANCE
# Calcs distance between two x,y,z coords
########################################################################################################################
def getDistance(pos1=(0,0,0), pos2=(10,10,10)):
vector = pos1 - pos2
distance = abs(math.sqrt(vector[0] * vector[0] + vector[1] * vector[1] + vector[2] * vector[2]))
return distance
########################################################################################################################
# CHARIDLE
# Sets char's isBusy flag back to False
########################################################################################################################
def charIdle(char):
char.loop("idle")
char.isBusy = False
w = World()
run()
camera and player movement is basically roaming ralph, my code starts at AITASK.
This line in CHARMOVE:
part1 = Func(char.lookAt, char1)
is what I can’t get to work
(though it worked in the little program above)