Please help. I can’t get anywhere further with my game until this is fixed.
Here is the code: (Just copy and paste, and run. No changes are needed.
Press play. Press escape to return to the menu, then press play again to see the problem.)
import direct.directbase.DirectStart
from direct.showbase import *
from direct.controls.GravityWalker import GravityWalker
from direct.actor.Actor import Actor
from direct.task import Task
from pandac.PandaModules import *
from direct.gui.DirectGui import *
from direct.interval.IntervalGlobal import *
from direct.showbase.PythonUtil import * # For player rotation
import random, sys, os, math
from math import pi, sin
class World(DirectObject.DirectObject):
def __init__( self ):
#########################################################
"""SETUP"""
#########################################################
#View Framerate
base.setFrameRateMeter(1)
# Make Background Black for Splash Screen
base.setBackgroundColor(0, 0, 0)
"""VARIABLES"""
self.page = 0
self.sceneOne = 0
self.quitter = 0
self.fontQuit = loader.loadFont('cmr12.egg') # Using an .egg
self.keyMap = {"left":0, "right":0, "forward":0, "cam-left":0, "cam-right":0}
self.zoomIn = 0
self.zoomOut = 0
self.angledegrees = 0.0
self.angleradians = self.angledegrees * (math.pi / 180.0)
#**************************************#
""" Loads up Title Screen Menu """
#**************************************#
#self.menuBack = DirectLabel(image="models/maps/gui/back01.png", scale = 1.4)
#self.menuBack.setPos(0, 0, 0)
self.playButton = DirectButton(text = "PLAY", scale = (0.4, 0.4, 0.1), command = self.activate)
self.playButton.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()
#**************************************#
""" LIGHTING """
#**************************************#
# Light1 - Sunlight
self.Light1 = PointLight('light1')
self.Light1.setColor(VBase4(2.5, 2.5, 2.5, 1))
self.pointLight1 = render.attachNewNode(self.Light1)
self.pointLight1.setPos(0, 0, 300)
# Light2 - Shadow light (ambient)
self.Light2 = AmbientLight('light2')
self.Light2.setColor(VBase4(0.75, 0.75, 0.75, 1))
self.ambientLight1 = render.attachNewNode(self.Light2)
# Light3 - Spotlight1
self.Light3 = Spotlight('light3')
self.Light3.setColor(VBase4(0.97, 0.98, 0.25, 1))
self.Light3Lens = PerspectiveLens()
self.Light3.setLens(self.Light3Lens)
self.spotLight1 = render.attachNewNode(self.Light3)
self.spotLight1.node().getLens().setFov(18)
#**************************************#
""" KEY INPUT """
#**************************************#
# Accept the control keys for movement and rotation
# key down
self.accept("escape", self.endGame)
taskMgr.add(self.move,"moveTask")
# Game state variables
self.prevtime = 0
self.isMoving = False
# 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)
#**************************************#
""" MODELS """
#**************************************#
# SCENE
self.env = loader.loadModel("models/world")
self.env.reparentTo( render )
self.env.setPos(0,0,0)
# MAIN CHARACTER
self.Mod1 = Actor("models/ralph",{"walk":"models/ralph-walk"})
self.Mod1StartPos = self.env.find("**/start_point").getPos()
self.Mod1.reparentTo(render)
self.Mod1.setScale(.2)
self.Mod1.setPos(self.Mod1StartPos)
#self.Mod1.loop("walk")
"""CAMERAS"""
# Camera setup
self.my_cam1 = Camera("cam1")
self.my_camera1 = render.attachNewNode(self.my_cam1)
self.my_camera1.setName("camera1")
self.my_camera1.setPos(20*math.sin(self.angleradians),-20.0*math.cos(self.angleradians),3)
#self.my_camera1.setPos(0,-20,155)
self.my_camera1.setHpr(self.angledegrees,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(0) # disable ( use displayRegion 0 )
# DisplayRegions.
self.window = self.dr.getWindow()
self.dr1 = self.window.makeDisplayRegion(0.026, 0.975, 0.35, 0.94)
self.dr1.setSort(self.dr.getSort())
# Setup each camera.
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)
"""Lights"""
# Apply lights
self.Mod1.setLight(self.pointLight1)
#self.env.setLight(self.pointLight1)
self.Mod1.setLight(self.ambientLight1)
self.env.setLight(self.ambientLight1)
self.spotLight1.setPos(self.Mod1.getX(), self.Mod1.getY()-10, -230)
self.spotLight1.lookAt(self.Mod1)
self.env.setLight(self.spotLight1)
"""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('ralphRay')
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)
self.playerZcol = CollisionTraverser()
self.playerZcolQueue = CollisionHandlerQueue()
self.playerZcol.addCollider(self.Mod1GroundColNp, self.playerZcolQueue)
self.playerZcol.showCollisions(render)
# Uncomment this line to see the collision rays
#self.ralphGroundColNp.show()
#self.camGroundColNp.show()
#Uncomment this line to show a visual representation of the
#collisions occuring
#self.cTrav.showCollisions(render)
"""**********************************************************"""
""" Movements by Intervals"""
#test1
self.Mod1HprIv = self.Mod1.hprInterval(0.5, Point3(40,0,0))
self.Mod1PosIv = self.Mod1.posInterval(5, Point3(-80,0,0), startPos=Point3(self.Mod1StartPos))
self.Mod1ActIv = self.Mod1.actorInterval("walk",loop=1,duration = 5)
# We create a LerpFunc Interval to correct the Z as we go along
self.Mod1Z = LerpFunc(self.updatePlayerZ, duration = 20)
self.delayMod = Wait(2.5)
self.WalkSeq = Sequence(Parallel(self.Mod1HprIv,self.Mod1PosIv,self.Mod1ActIv,self.Mod1Z),self.delayMod)
self.WalkSeq.start()
# Update Player Z (Keep player on Terrain)
def updatePlayerZ(self, time):
if self.page == 1:
startpos = self.Mod1.getPos()
self.playerZcol.traverse(render)
if self.playerZcolQueue.getNumEntries>0:
self.playerZcolQueue.sortEntries()
point = self.playerZcolQueue.getEntry(0).getSurfacePoint(self.env)
self.Mod1.setZ(point.getZ())
else:
self.Mod1.setPos(startpos)
# End updatePlayerZ
#Records the state of the arrow keys
def setKey(self, key, value):
self.zoomIn = 0
self.zoomOut = 0
self.keyMap[key] = value
# 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
# 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()
# 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()))
if (len(entries)>0) and (entries[0].getIntoNode().getName() == "terrain"):
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() == "terrain"):
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)
# Stop the task and return to menu
if self.quitter > 0:
self.returnOptions()
return Task.done
# Store the task time and continue.
self.prevtime = task.time
return Task.cont
#**************************************#
""" Setup Menu Functions """
#**************************************#
# This Function Ends the Setup Screen
def returnOptions(self):
self.page = 0
self.quitter = 0
# Cleanup scene 1
taskMgr.remove("moveTask")
# Disable cameras
self.dr1.setActive(0)
# remove models from scene graph (don't render)
self.Mod1.cleanup()
self.Mod1.removeNode()
# remove models from game
loader.unloadModel("models/world")
self.Mod1.delete()
self.showMainMenu()
#**************************************#
""" Functions to Swap Out the Menus """
#**************************************#
# Hides the Main Menu
def hideMainMenu(self):
#self.menuBack.hide()
self.playButton.hide()
# Shows the Main Menu
def showMainMenu(self):
#self.menuBack.show()
self.playButton.show()
"""Commence Game End"""
# For ending Game
def endGame(self):
if self.page > 0:
self.quitter = 1
world = World( )
run( )