My script was working perfectly until I put a collision mesh.
When I press escape, the game is supposed to return to the menu.
Instead I keep getting this error:
[i]Assertion failed: !is_empty() at line 944 of panda/src/pgraph/nodePath.cxx
Traceback (most recent call last):
File “help1.py”, line 428, in ?
run()
File “C:\Panda3D-1.4.2\direct\src\showbase\ShowBase.py”, line 2176, in run
self.taskMgr.run()
File “C:\Panda3D-1.4.2\direct\src\task\Task.py”, line 930, in run
self.step()
File “C:\Panda3D-1.4.2\direct\src\task\Task.py”, line 862, in step
self.__stepThroughList(taskPriList)
File “C:\Panda3D-1.4.2\direct\src\task\Task.py”, line 764, in __stepThroughList
ret = self.__executeTask(task)
File “C:\Panda3D-1.4.2\direct\src\task\Task.py”, line 684, in __executeTask
ret = task(*task.extraArgs)
File “help1.py”, line 276, in move
startpos = self.Mod1.getPos()
AssertionError: !is_empty() at line 944 of panda/src/pgraph/nodePath.cxx
**** End of process output ****[/i]
Could you please look at the code, and tell me what might be wrong?
You just have to replace the terrain model, and change it’s name.
Appreciate any help I can get. Thanks
import direct.directbase.DirectStart
from direct.showbase.ShowBaseGlobal import *
from direct.gui.DirectGui import *
from direct.showbase import *
from direct.task import Task
from pandac.PandaModules import *
from direct.actor import Actor
from direct.interval.SoundInterval import SoundInterval
from direct.interval.MetaInterval import Sequence,Parallel
from direct.interval.LerpInterval import LerpFunc
from direct.interval.IntervalGlobal import *
from direct.showbase.InputStateGlobal import inputState
import random, sys, os, math
from math import pi, sin
#Define font to use
font = loader.loadFont('cmr12.egg') #Using an .egg has advantages
#**************************************#
""" Creates a Title Screen Menu """
#**************************************#
class StartMenu(DirectObject.DirectObject):
def __init__(self):
# View Framerate
base.setFrameRateMeter(1)
# Make Background Black for Splash Screen
base.setBackgroundColor(0, 0, 0)
# Variables
self.page = 0
self.sceneOne = 0
self.windowOver = 0
self.fontQuit = loader.loadFont('cmr12.egg') #Using an .egg
# Control the speed of the camera's rotation and zoom
self.camera1Speed = .10
self.keyMap = {"left":0, "right":0, "forward":0, "cam-left":0, "cam-right":0}
self.zoomIn = 0
self.zoomOut = 0
#**************************************#
""" Loads up Title Screen Menu """
#**************************************#
self.menuLabel = DirectLabel(text = "MAIN MENU", scale = (0.4, 0.4, 0.4), text_fg=(1, 1, 1, 1), relief = None)
self.menuLabel.setTransparency(1)
self.menuLabel.setPos(0, 0, 0.6)
self.playButton = DirectButton(text = "PLAY", scale = (0.4, 0.4, 0.1), text_fg=(1, 1, 1, 1), relief = None, clickSound = None, command = self.activate)
self.playButton.setTransparency(1)
self.playButton.setPos(0, 0, -0.15)
self.exitButton = DirectButton(text = "EXIT", scale = (0.4, 0.4, 0.1), text_fg=(1, 1, 1, 1), relief = None, clickSound = None, command = sys.exit)
self.exitButton.setTransparency(1)
self.exitButton.setPos(0, 0, -0.4)
#**************************************#
""" Main Menu Functions
Running The Game - Scene 1 """
#**************************************#
# This Function Starts the Game
def activate(self):
self.page = 1
self.sceneOne = 1
self.windowOver = 1
self.hideMainMenu()
# 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)
"""KEYS"""
self.accept('escape', self.returnOptions)
self.accept("wheel_up", self.cameraZoom,[-1])
self.accept("wheel_down", self.cameraZoom,[1])
self.accept("t",self.jumpMod2)
self.accept("f",self.turnMod2,[-1])
self.accept("g",self.turnMod2,[1])
# key down
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("a", self.setKey, ["cam-left",1])
self.accept("s", self.setKey, ["cam-right",1])
# Key up
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("a-up", self.setKey, ["cam-left",0])
self.accept("s-up", self.setKey, ["cam-right",0])
# zoom
self.accept("v", self.zoomCameraIn, [-1])
self.accept("b", self.zoomCameraOut, [1])
self.accept("v-up", self.zoomStop, [0])
self.accept("b-up", self.zoomStop, [0])
taskMgr.add(self.move,"moveTask")
# Game state variables
self.prevtime = 0
self.isMoving = False
self.environ1 = loader.loadModel("models/terrain001")
self.environ1.reparentTo(render)
self.environ1.setScale(0.15,0.15,0.15)
self.environ1.setPos(0,0,147.7)
self.environ1.setHpr(0,0,0)
#self.environ1.setColor(0.3, 0.4, 1)
self.Mod1StartPos = self.environ1.find("**/start_point").getPos()
self.Mod1 = Actor.Actor("models/ralph",{"run":"models/ralph-run","walk":"models/ralph-walk"})
self.Mod1.reparentTo(render)
self.Mod1.setScale(0.2,0.2,0.2)
#self.Mod1.setPos(0,-10,150)
self.Mod1.setHpr(90,0,0)
self.Mod1.setPos(self.Mod1StartPos)
# Camera 3
self.my_cam1 = Camera("cam1")
self.my_camera1 = render.attachNewNode(self.my_cam1)
self.my_camera1.setName("camera1")
self.my_camera1.setPos(self.Mod1.getX()-10, self.Mod1.getY()-10, 155)
#self.my_camera1.setPos(0,-20,155)
#self.my_camera1.setHpr(0,0,0)
self.my_camera1.lookAt(self.Mod1)
self.my_camera1.node().getLens().setAspectRatio(4.0/2.0)
# Disable the default DisplayRegion, which covers the whole screen.
self.dr = base.camNode.getDisplayRegion(0)
self.dr.setActive(1) # Don't disable
self.window = self.dr.getWindow()
self.dr1 = self.window.makeDisplayRegion(0.026, 0.975, 0.35, 0.94)
self.dr1.setSort(self.dr.getSort())
self.dr1.setCamera(self.my_camera1)
## # Set up the camera
## base.disableMouse()
## self.my_camera1.setPos(self.Mod1.getX(), self.Mod1.getY()+10, 1.5)
"""COLLISIONS"""
"""************************************************************"""
# 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 mod'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.cTrav = CollisionTraverser()
self.Mod1GroundRay = CollisionRay()
self.Mod1GroundRay.setOrigin(0,0,1000)
self.Mod1GroundRay.setDirection(0,0,-1)
self.Mod1GroundCol = CollisionNode('modRay')
self.Mod1GroundCol.addSolid(self.Mod1GroundRay)
self.Mod1GroundCol.setFromCollideMask(BitMask32.bit(0))
self.Mod1GroundCol.setIntoCollideMask(BitMask32.allOff())
self.Mod1GroundColNp = self.Mod1.attachNewNode(self.Mod1GroundCol)
self.Mod1GroundHandler = CollisionHandlerQueue()
self.cTrav.addCollider(self.Mod1GroundColNp, self.Mod1GroundHandler)
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(0))
self.camGroundCol.setIntoCollideMask(BitMask32.allOff())
self.camGroundColNp = self.my_camera1.attachNewNode(self.camGroundCol)
self.camGroundHandler = CollisionHandlerQueue()
self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler)
# Uncomment this line to see the collision rays
#self.modGroundColNp.show()
#self.camGroundColNp.show()
#Uncomment this line to show a visual representation of the
#collisions occuring
#self.cTrav.showCollisions(render)
"""**********************************************************"""
"""CAMERA"""
#Task to move the camera
def SpinCameraTask(task):
#rotate camera 6 degrees every second
angledegrees = task.time * 0.0
#compute desired orientation of camera (degrees, radians)
angleradians = angledegrees * (math.pi / 180.0)
#setPos = set position of the camera
base.camera.setPos(20*math.sin(angleradians),-20.0*math.cos(angleradians),3)
#setHpr = set orientation
base.camera.setHpr(angledegrees, 0, 0)
return Task.cont
taskMgr.add(SpinCameraTask, "SpinCameraTask")
#taskMgr.add = call the subroutine SpinCameraTask every frame
"""Key Movements"""
# Camera zoom in function.
def zoomCameraIn(self, dir):
self.zoomOut = 0
self.zoomIn = 1
# Camera zoom out function.
def zoomCameraOut(self, dir):
self.zoomIn = 0
self.zoomOut = 1
# Stop zooming camera.
def zoomStop(self, dir):
self.zoomIn = 2
self.zoomOut = 2
#Records the state of the arrow keys
def setKey(self, key, value):
self.zoomIn = 0
self.zoomOut = 0
self.keyMap[key] = value
#Records the state of the arrow keys
def setKey(self, key, value):
self.zoomIn = 0
self.zoomOut = 0
self.keyMap[key] = value
# Turn model2.
def turnMod2(self,dir):
modelTurn = self.Mod1.hprInterval(.2,Vec3(self.Mod1.getH()-(10*dir),0,0))
## posInterval and hprInterval contain (speed, x, y, z)
modelTurn.start()
def jumpMod2(self):
## Using math
dist = 5.0 # jump forward 5 feet in facing direction
angle = self.Mod1.getH()*math.pi/180.0
dx = dist*math.sin(angle)
dy = dist*-math.cos(angle)
modelWalk = Parallel(
self.Mod1.posInterval(0.8,Vec3(self.Mod1.getX()+dx,self.Mod1.getY()+dy,0)),
self.Mod1.actorInterval("jump",loop=1,duration=0.8)
)
modelWalk.start()
# Accepts arrow keys to move either the player or the menu cursor,
# Also deals with grid checking and collision detection
def move(self, task):
elapsed = task.time - self.prevtime
# If the camera-left key is pressed, move camera left.
# If the camera-right key is pressed, move camera right.
camright = self.my_camera1.getNetTransform().getMat().getRow3(0)
camright.normalize()
if (self.keyMap["cam-left"]!=0):
self.my_camera1.setPos(self.my_camera1.getPos() - camright*(elapsed*10))
if (self.keyMap["cam-right"]!=0):
self.my_camera1.setPos(self.my_camera1.getPos() + camright*(elapsed*10))
if self.zoomIn > 0:
self.my_camera1.setPos(Point3(self.my_camera1.getX(), self.my_camera1.getY()-5*(elapsed*.5), self.my_camera1.getZ()))
if self.zoomOut > 0:
self.my_camera1.setPos(Point3(self.my_camera1.getX(), self.my_camera1.getY()+5*(elapsed*.5), self.my_camera1.getZ()))
# save mod's initial position so that we can restore it,
# in case he falls off the map or runs into something.
startpos = self.Mod1.getPos()
self.my_camera1.lookAt(self.Mod1)
# If a move-key is pressed, move mod in the specified direction.
if (self.keyMap["left"]!=0):
self.Mod1.setH(self.Mod1.getH() + elapsed*300)
if (self.keyMap["right"]!=0):
self.Mod1.setH(self.Mod1.getH() - elapsed*300)
if (self.keyMap["forward"]!=0):
backward = self.Mod1.getNetTransform().getMat().getRow3(1)
backward.setZ(0)
backward.normalize()
self.Mod1.setPos(self.Mod1.getPos() - backward*(elapsed*5))
# If a move-key is pressed, move camera in the specified direction.
## if (self.keyMap["cam-in"]!=0):
## self.my_camera1.setPos(self.my_camera1.getPos() + elapsed*300)
## if (self.keyMap["cam-out"]!=0):
## self.my_camera1.setPos(self.my_camera1.getPos() - elapsed*300)
# If ralph is moving, loop the run animation.
# If he is standing still, stop the animation.
if (self.keyMap["forward"]!=0) or (self.keyMap["left"]!=0) or (self.keyMap["right"]!=0):
if self.isMoving is False:
self.Mod1.loop("run")
self.isMoving = True
else:
if self.isMoving:
self.Mod1.stop()
self.Mod1.pose("walk",5)
self.isMoving = False
# If the camera is too far from mod, move it closer.
# If the camera is too close to mod, move it farther.
self.camvec = self.Mod1.getPos() - self.my_camera1.getPos()
self.camvec.setZ(0)
self.camdist = self.camvec.length()
self.camvec.normalize()
if (self.camdist > 10.0) and self.zoomIn < 1 and self.zoomOut < 1:
self.my_camera1.setPos(self.my_camera1.getPos() + self.camvec*(self.camdist-10))
self.camdist = 10.0
if (self.camdist < 5.0) and self.zoomIn < 1 and self.zoomOut < 1:
self.my_camera1.setPos(self.my_camera1.getPos() - self.camvec*(5-self.camdist))
self.camdist = 5.0
# Now check for collisions.
self.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.
entries = []
for i in range(self.Mod1GroundHandler.getNumEntries()):
entry = self.Mod1GroundHandler.getEntry(i)
entries.append(entry)
entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(),
x.getSurfacePoint(render).getZ()))
"""I had to change <Dart> { 1 } to <Dart> { 0 } in my egg file to move ralph.
This apparently is the models z coordinates. The 0 places him on the ground.
medTerrain01 is the name of the mesh (group) found in the egg file."""
if (len(entries)>0) and (entries[0].getIntoNode().getName() == "medTerrain01"):
self.Mod1.setZ(entries[0].getSurfacePoint(render).getZ())
else:
self.Mod1.setPos(startpos)
# Keep the camera at one foot above the terrain,
# or two feet above mod, whichever is greater.
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() == "medTerrain01"):
self.my_camera1.setZ(entries[0].getSurfacePoint(render).getZ()+1.5)
if (self.my_camera1.getZ() < self.Mod1.getZ() + 1.5):
self.my_camera1.setZ(self.Mod1.getZ() + 1.5)
# The camera should look in mod's direction,
# but it should also try to stay horizontal, so look at
# a floater which hovers above mod's head.
self.floater.setPos(self.Mod1.getPos())
self.floater.setZ(self.Mod1.getZ() + 1.5)
self.my_camera1.lookAt(self.floater)
# Store the task time and continue.
self.prevtime = task.time
return Task.cont
# Define the cameraZoom function.
def cameraZoom(self,dir):
self.camZoom = LerpPosInterval(self.my_camera1, self.camera1Speed, Point3(self.my_camera1.getX(), self.my_camera1.getY()-(2*dir), self.my_camera1.getZ()+(.8*dir)))
self.camZoom.start()
#**************************************#
""" Setup Menu Functions """
#**************************************#
# This Function Loads the Setup Screen
def loadSetup(self):
self.windowOver = 0
if self.windowOver < 1:
self.hideMainMenu()
# This Function Ends the Setup Screen
def returnOptions(self):
self.page = 0
self.showMainMenu()
# Cleanup scene 1
if self.sceneOne > 0:
self.dr1.setActive(0)
self.sceneOne = 0
self.Mod1.removeNode()
#self.Mod1.delete()
#**************************************#
""" Functions to Swap Out the Menus """
#**************************************#
# Hides the Main Menu
def hideMainMenu(self):
self.menuLabel.hide()
self.playButton.hide()
self.exitButton.hide()
# Shows the Main Menu
def showMainMenu(self):
self.menuLabel.show()
self.playButton.show()
self.exitButton.show()
#**************************************#
""" Functions to Swap Out the Scenes """
#**************************************#
# Cleanup scene 1
def hideScene1(self):
if self.page < 1:
self.Mod1.removeNode()
self.Mod1.delete()
self.dr1.setActive(0)
menu = StartMenu() # Start Menu class
run()