Hello if you execute my source code that I have here:
import direct.directbase.DirectStart
from panda3d.core import CollisionTraverser,CollisionNode
from panda3d.core import CollisionHandlerQueue,CollisionRay, CollisionSphere, CollisionHandlerPusher
from panda3d.core import Filename,AmbientLight,DirectionalLight
from panda3d.core import PandaNode,NodePath,Camera,TextNode
from panda3d.core import Vec3,Vec4,BitMask32
from direct.gui.OnscreenText import OnscreenText
from direct.actor.Actor import Actor
from direct.showbase.DirectObject import DirectObject
import random, sys, os, math
SPEED = 0.5
class World(object, DirectObject):
def __init__(self):
self.winXhalf = base.win.getXSize()/2
self.winYhalf = base.win.getYSize()/2
base.cTrav = CollisionTraverser()
pusher = CollisionHandlerPusher()
base.win.setClearColor(Vec4(0,0,0,1))
# Set up the environment
#
# This environment model contains collision meshes. If you look
# in the egg file, you will see the following:
#
# <Collide> { Polyset keep descend }
#
# This tag causes the following mesh to be converted to a collision
# mesh -- a mesh which is optimized for collision, not rendering.
# It also keeps the original mesh, so there are now two copies ---
# one optimized for rendering, one for collisions.
self.terrain = loader.loadModel('models/world')
self.terrain.reparentTo(render)
self.terrain.setPos(0,0,0)
# Create the main character, Ralph
ralphStartPos = self.terrain.find("**/start_point").getPos()
self.ralph = loader.loadModel('frowney')
self.ralph.reparentTo(render)
self.ralph.setScale(.1)
self.ralph.setPos(ralphStartPos)
"""
Cnode = CollisionNode('ralph')
Cnode.addSolid(CollisionSphere(0,0,0,1))
Cnode.setFromCollideMask(BitMask32.bit(2))
Cralph = self.ralph.attachNewNode(Cnode)
"""
# Create a floater object. We use the "floater" as a temporary
# variable in a variety of calculations.
self.floater = NodePath(PandaNode("floater"))
self.floater.reparentTo(render)
# Accept the control keys for movement and rotation
speed = 25
Forward = Vec3(0,speed*2,0)
Back = Vec3(0,-speed,0)
Left = Vec3(-speed,0,0)
Right = Vec3(speed,0,0)
Stop = Vec3(0)
self.walk = Stop
self.strife = Stop
taskMgr.add(self.move, 'move-task')
self.accept( "escape",sys.exit )
self.accept( "s" , self.__setattr__,["walk",Back] )
self.accept( "w" , self.__setattr__,["walk",Forward])
self.accept( "s-up" , self.__setattr__,["walk",Stop] )
self.accept( "w-up" , self.__setattr__,["walk",Stop] )
self.accept( "a" , self.__setattr__,["strife",Left])
self.accept( "d" , self.__setattr__,["strife",Right] )
self.accept( "a-up" , self.__setattr__,["strife",Stop] )
self.accept( "d-up" , self.__setattr__,["strife",Stop] )
taskMgr.add(self.move,"moveTask")
# Game state variables
self.isMoving = False
# Set up the camera
base.disableMouse()
base.camera.reparentTo(self.ralph)
base.camera.setPos(0, 4, 4)
base.camLens.setNearFar(1.1,1000)
base.disableMouse()
# We will detect the height of the terrain by creating a collision
# ray and casting it downward toward the terrain. One ray will
# start above ralph's head, and the other will start 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.ralphGroundRay = CollisionRay()
self.ralphGroundRay.setOrigin(0,0,1000)
self.ralphGroundRay.setDirection(0,0,-1)
self.ralphGroundCol = CollisionNode('ralphRay')
self.ralphGroundCol.addSolid(self.ralphGroundRay)
self.ralphGroundCol.setFromCollideMask(BitMask32.bit(0))
self.ralphGroundCol.setIntoCollideMask(BitMask32.allOff())
self.ralphGroundColNp = self.ralph.attachNewNode(self.ralphGroundCol)
self.ralphGroundHandler = CollisionHandlerQueue()
base.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler)
base.cTrav.showCollisions(render)
"""
base.cTrav.addCollider(Cralph, pusher)
pusher.addCollider(Cralph, self.ralph, base.drive.node())
"""
# Create some lighting
ambientLight = AmbientLight("ambientLight")
ambientLight.setColor(Vec4(.3, .3, .3, 1))
directionalLight = DirectionalLight("directionalLight")
directionalLight.setDirection(Vec3(-5, -5, -5))
directionalLight.setColor(Vec4(1, 1, 1, 1))
directionalLight.setSpecularColor(Vec4(1, 1, 1, 1))
render.setLight(render.attachNewNode(ambientLight))
render.setLight(render.attachNewNode(directionalLight))
#Records the state of the arrow keys
def setKey(self, key, value):
self.keyMap[key] = value
def move(self, task):
dt=globalClock.getDt()
# mouse
md = base.win.getPointer(0)
x = md.getX()
y = md.getY()
if base.win.movePointer(0, self.winXhalf, self.winYhalf):
self.ralph.setH(self.ralph, (x - self.winXhalf)*-0.1)
base.camera.setP( clampScalar(-90,90, base.camera.getP() - (y - self.winYhalf)*0.1) )
# move where the keys set it
moveVec=(self.walk+self.strife)*dt # horizontal
self.ralph.setFluidPos(self.ralph,moveVec)
# Now check for collisions.
base.cTrav.traverse(render)
# Adjust ralph's Z coordinate. If ralph's ray hit terrain,
# update his Z. If it hit anything else, or didn't hit anything, put
# him back where he was last frame.
startpos = self.ralph.getPos()
entries = []
for i in range(self.ralphGroundHandler.getNumEntries()):
entry = self.ralphGroundHandler.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"):
self.ralph.setZ(entries[0].getSurfacePoint(render).getZ())
else:
self.ralph.setPos(startpos)
return task.cont
w = World()
run()
you may notice when you execute this code that if you collide with a tree/rock you will walk straight through it but in the roaming-ralph tutorial you stop when you hit a tree/rock so can someone point out the bit of code that makes ralph stop when he hits a rock/tree.
thanks