Okay… here’s all the code, with nothing missing. I was trying to avoid a large code block. Oh well… the best laid plans…
# Models: Jeff Styers, Reagan Heller
import direct.directbase.DirectStart
from pandac.PandaModules import *
from direct.interval.IntervalGlobal import *
from direct.gui.DirectGui import *
from direct.actor import Actor
from direct.showbase.DirectObject import *
import random, sys, os, math
SPEED = 0.5
# Figure out what directory this program is in.
MYDIR=os.path.abspath(sys.path[0])
MYDIR=Filename.fromOsSpecific(MYDIR).getFullpath()
# Function to put instructions on the screen.
def addInstructions(pos, msg):
return OnscreenText(text=msg, style=1, fg=(1,1,1,1),
pos=(-1.3, pos), align=TextNode.ALeft, scale = .05)
# Function to put title on the screen.
def addTitle(text):
return OnscreenText(text=text, style=1, fg=(1,1,1,1),
pos=(1.3,-0.95), align=TextNode.ARight, scale = .07)
class World(DirectObject):
def __init__(self):
self.keyMap = {"left":0, "right":0, "forward":0, "backward":0}
base.win.setClearColor(Vec4(0,0,0,1))
# Post the instructions
self.inst1 = addInstructions(0.95, "[ESC]: Quit")
self.inst2 = addInstructions(0.90, "[Left Arrow]: Rotate Left")
self.inst3 = addInstructions(0.85, "[Right Arrow]: Rotate Right")
self.inst4 = addInstructions(0.80, "[Up Arrow]: Move Forward")
self.inst5 = addInstructions(0.75, "[Down Arrow]: Move Backward")
# Set up the environment
self.environ = loader.loadModel(MYDIR+"/models/world")
self.environ.reparentTo(render)
self.environ.setPos(0,0,0)
# Get our starting position
startPos = self.environ.find("**/start_point").getPos()
base.disableMouse()
base.camera.setPos(startPos.getX(),startPos.getY(),5)
# Accept the control keys for movement and rotation
self.accept("escape", sys.exit)
self.accept("arrow_left", self.setKey, ["left",1])
self.accept("arrow_right", self.setKey, ["right",1])
self.accept("arrow_up", self.setKey, ["forward",1])
self.accept("arrow_down", self.setKey, ["backward",1])
self.accept("arrow_left-up", self.setKey, ["left",0])
self.accept("arrow_right-up", self.setKey, ["right",0])
self.accept("arrow_up-up", self.setKey, ["forward",0])
self.accept("arrow_down-up", self.setKey, ["backward",0])
# Simulation state variables
self.prevtime = 0
self.isMoving = False
taskMgr.add(self.move,"moveTask")
# We will detect the height of the terrain by creating a collision
# ray and casting it downward toward the terrain, above the camera.
# A ray may hit the terrain, or it may hit a rock or a tree. If it
# hits the terrain, we can detect the height. If it hits anything
# else, we rule that the move is illegal.
self.cTrav = CollisionTraverser()
self.environ.setCollideMask(BitMask32.bit(1))
self.camGroundRay = CollisionRay()
self.camGroundRay.setOrigin(0,0,1000)
self.camGroundRay.setDirection(0,0,-1)
self.camGroundCol = CollisionNode('camRay')
self.camGroundCol.addSolid(self.camGroundRay)
self.camGroundCol.setFromCollideMask(BitMask32.bit(1))
self.camGroundCol.setIntoCollideMask(BitMask32.allOff())
self.camGroundColNp = base.camera.attachNewNode(self.camGroundCol)
self.camGroundHandler = CollisionHandlerQueue()
self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler)
#Records the state of the arrow keys
def setKey(self, key, value):
self.keyMap[key] = value
def move(self, task):
elapsed = task.time - self.prevtime
# save our initial position so that we can restore it,
# in case we fall off the map or run into something.
startpos = base.camera.getPos()
# If a move-key is pressed, move in the specified direction.
if (self.keyMap["left"] != 0):
base.camera.setH(base.camera.getH() + elapsed * 200)
if (self.keyMap["right"] != 0):
base.camera.setH(base.camera.getH() - elapsed * 200)
if (self.keyMap["forward"] != 0):
forward = base.camera.getNetTransform().getMat().getRow3(1)
forward.setZ(0)
forward.normalize()
base.camera.setPos(base.camera.getPos() + forward*(elapsed*10))
if (self.keyMap["backward"] != 0):
backward = base.camera.getNetTransform().getMat().getRow3(1)
backward.setZ(0)
backward.normalize()
base.camera.setPos(base.camera.getPos() - backward*(elapsed*10))
# Now check for collisions.
self.cTrav.traverse(render)
# Adjust Z coordinate. If the ray hit terrain,
# update our Z. If it hit anything else, or didn't hit anything, put
# us back where we were last frame.
# Keep the camera at five feet above the terrain,
entries = []
for i in range(self.camGroundHandler.getNumEntries()):
entry = self.camGroundHandler.getEntry(i)
entries.append(entry)
entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
x.getSurfacePoint(render).getZ()))
if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
base.camera.setZ(entries[0].getSurfacePoint(render).getZ()+5.0)
else:
base.camera.setPos(startpos)
# Store the task time and continue.
self.prevtime = task.time
return Task.cont
w = World()
run()
[/code]