class Explosion: def __init__(self, base): self.base = base self.p = Particles() self.p.setFactory("PointParticleFactory") self.p.setRenderer("LineParticleRenderer") self.p.setEmitter("SphereSurfaceEmitter") self.p.setPoolSize(256) self.p.setBirthRate(0.01) self.p.setLitterSize(256) self.p.setSystemLifespan(2) self.p.factory.setLifespanBase(5.0000) self.p.renderer.setTailColor(Vec4(1.0, 1.0, 0.0, 1.0)) self.p.renderer.setHeadColor(Vec4(1.0, 0.0, 0.0, 1.0)) self.p.renderer.setAlphaMode(BaseParticleRenderer.PRALPHAOUT) self.p.renderer.setUserAlpha(1.00) self.p.renderer.setLineScaleFactor(32.00) self.p.emitter.setRadius(2.0000) self.p.setRenderParent(base.render) self.p.enable() self.pn = base.render.attachNewNode("particleExpNode") # self.pn.setDepthWrite(False) # self.pn.setBin("fixed", 0) self.pe = ParticleEffect("exp-effect", self.p) self.pe.reparentTo(self.pn) self.pe.enable()
class Application(ShowBase): def __init__(self): ShowBase.__init__(self) self.enableParticles() particles = Particles() particles.setPoolSize(1000) particles.setBirthRate(0.1) particles.setLitterSize(10) particles.setLitterSpread(3) particles.setFactory("PointParticleFactory") particles.setRenderer("GeomParticleRenderer") particles.setEmitter("SphereVolumeEmitter") smiley = loader.loadModel("smiley") smiley.setScale(0.1) particles.getRenderer().setGeomNode(smiley.node()) particles.enable() self.effect = ParticleEffect("peffect", particles) self.effect.reparentTo(render) self.effect.enable() self.cam.setPos(0, -10, 0)
class ParticleVfx(): """ Wrapper class for ParticleEffect """ def __init__(self, name='particles-1'): self.node = ParticleEffect() self.p0 = Particles.Particles(name) self.p0.setFactory('PointParticleFactory') self.p0.setRenderer('PointParticleRenderer') self.p0.setLocalVelocityFlag(1) self.p0.setSystemGrowsOlderFlag(0) self.f0 = ForceGroup.ForceGroup('default') self.birth_set = False self.emitter_set = False self.force = {} def setHpr(self, node=render, hpr=Vec3(0, 0, 0), r=None): if not r is None: hpr = Vec3(node, hpr, r) node = render elif type(node).__name__ != 'NodePath': hpr = node node = render self.node.setHpr(node, hpr) def setPos(self, node=render, pos=Point3(0, 0, 0), z=None): if not z is None: pos = Vec3(node, pos, z) node = render elif type(node).__name__ != 'NodePath': pos = node node = render self.node.setPos(node, pos) def hide(self): #self.node.disable() # ParticleEffect.disable() would detach the node and the info on pos/hpr will be lost for f in self.node.forceGroupDict.values(): f.disable() for p in self.node.particlesDict.values(): p.setRenderParent(p.node) p.disable() def show(self): self.node.enable() def setBirth(self, pool=300, rate=0.1, number=10, spread=5, life=1.0, life_spread=0.1, mass=10.0, mass_spread=5.0): if mass_spread >= mass: mass_spread = mass * 0.95 self.p0.setPoolSize(pool) self.p0.setBirthRate(rate) self.p0.setLitterSize(number) self.p0.setLitterSpread(spread) self.p0.factory.setLifespanBase(life) self.p0.factory.setLifespanSpread(life_spread) self.p0.factory.setMassBase(mass) self.p0.factory.setMassSpread(mass_spread) self.birth_set = True def setEmiter(self, emmiter_type='PointEmitter', force=Vec3(0, 0, 0), emmision_type=EXPLICIT, **kwargs): self.p0.setEmitter(emmiter_type) self.p0.emitter.setEmissionType(emmision_type) self.p0.emitter.setOffsetForce(force) self.p0.emitter.setExplicitLaunchVector(Vec3(0, 0, 0)) self.p0.emitter.setRadiateOrigin(Point3(0, 0, 0)) self.emitter_set = True if emmiter_type == 'BoxEmitter': self.p0.emitter.setMaxBound(kwargs['max_bound']) self.p0.emitter.setMinBound(kwargs['min_bound']) elif emmiter_type == 'DiscEmitter': self.p0.emitter.setRadius(kwargs['radius']) self.p0.emitter.setInnerAngle(kwargs['inner_angle']) self.p0.emitter.setInnerMagnitude(kwargs['inner_mag']) self.p0.emitter.setOuterAngle(kwargs['outer_angle']) self.p0.emitter.setOuterMagnitude(kwargs['outer_mag']) elif emmiter_type == 'LineEmitter': self.p0.emitter.setEndpoint1(kwargs['endpoint1']) self.p0.emitter.setEndpoint2(kwargs['endpoint2']) #elif emmiter_type == 'PointEmitter': # pass #no options here elif emmiter_type == 'RectangleEmitter': self.p0.emitter.setMaxBound(kwargs['max_bound']) self.p0.emitter.setMinBound(kwargs['min_bound']) elif emmiter_type == 'RingEmitter': self.p0.emitter.setAngle(kwargs['angle']) self.p0.emitter.setRadius(kwargs['radius']) self.p0.emitter.setRadiusSpread(kwargs['spread']) elif emmiter_type == 'SphereSurfaceEmitter': self.p0.emitter.setRadius(kwargs['radius']) elif emmiter_type == 'SphereVolumeEmitter': self.p0.emitter.setRadius(kwargs['radius']) elif emmiter_type == 'TangentRingEmitter': self.p0.emitter.setRadius(kwargs['radius']) self.p0.emitter.setRadiusSpread(kwargs['spread']) self.node.addParticles(self.p0) def setColor(self, color): self.p0.renderer.setStartColor(color) self.p0.renderer.setEndColor(color) def setAdditiveBlend(self): color_attrib = ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OIncomingAlpha, ColorBlendAttrib.OOne) for geom in self.node.findAllMatches('**/+GeomNode'): geom.setAttrib(color_attrib) geom.setDepthWrite(False) geom.setDepthTest(False) def setShader(self, v_shader, f_shader, inputs={}): shader_attrib = ShaderAttrib.make( Shader.load(Shader.SLGLSL, v_shader, f_shader)) shader_attrib = shader_attrib.setFlag(ShaderAttrib.F_shader_point_size, True) for geom in self.node.findAllMatches('**/+GeomNode'): geom.setAttrib(shader_attrib) for name, value in inputs.items(): geom.setShaderInput(name, value) def addForce(self, force, name): force.setVectorMasks(1, 1, 1) force.setActive(1) self.f0.addForce(force) self.force[name] = force def setForce(self, name, active=1): if name in self.force: self.force[name].setVectorMasks(active, active, active) #self.force[name].setActive(active) #somehow this fails (?) def start(self, parent=render, renderParent=render): if not self.emitter_set: self.setEmiter() if not self.birth_set: self.setBirth() self.node.addForceGroup(self.f0) self.node.start(parent=parent, renderParent=renderParent)
class GameContainer(ShowBase): def __init__(self): ShowBase.__init__(self) ########## Window configuration ######### wp = WindowProperties() wp.setSize(1024, 860) wp.setTitle("") wp.setOrigin(-2, -2) self.win.requestProperties(wp) self.win.movePointer(0, wp.getXSize() / 2, wp.getYSize() / 2) print wp.getXSize() / 2, wp.getYSize() / 2 ########## Gameplay settings ######### self.gameMode = {"display": PLAY, "play": TERRAIN} self.level = 1.5 self.mode_initialized = False ######### Camera ######### self.disableMouse() self.mainCamera = Camera(self.camera) self.mainCamera.camObject.setHpr(0, 0, 0) self.loadLevel() ######### Events ######### self.taskMgr.add(self.gameLoop, "gameLoop", priority=35) self.keys = {"w": 0, "s": 0, "a": 0, "d": 0, "space": 0, "escape": 0} self.accept("w", self.setKey, ["w", 1]) self.accept("w-up", self.setKey, ["w", 0]) self.accept("s", self.setKey, ["s", 1]) self.accept("s-up", self.setKey, ["s", 0]) self.accept("a", self.setKey, ["a", 1]) self.accept("a-up", self.setKey, ["a", 0]) self.accept("d", self.setKey, ["d", 1]) self.accept("d-up", self.setKey, ["d", 0]) self.accept("space", self.setKey, ["space", 1]) self.accept("space-up", self.setKey, ["space", 0]) self.accept("escape", self.setKey, ["escape", 1]) self.accept("escape-up", self.setKey, ["escape", 0]) self.accept("wheel_up", self.zoomCamera, [-1]) self.accept("wheel_down", self.zoomCamera, [1]) self.accept("window-event", self.handleWindowEvent) ######### GUI ######### #self.fonts = {"failure" : loader.loadFont('myfont.ttf')} self.guiElements = [] self._GCLK = None self._FT = None #Trigger game chain #self.enableParticles() #self.buildMainMenu() def setKey(self, key, value): self.keys[key] = value def zoomCamera(self, direction): if self.gameMode["play"] == TERRAIN: Camera.AVATAR_DIST += direction def toggleCursor(self, state): props = WindowProperties() props.setCursorHidden(state) base.win.requestProperties(props) def handleWindowEvent(self, window=None): wp = window.getProperties() self.win_center_x = wp.getXSize() / 2 self.win_center_y = wp.getYSize() / 2 def processKeys(self): if self.keys["escape"]: if self.gameMode["display"] == PLAY: self.switchDisplayMode(IN_GAME_MENU) elif self.gameMode["display"] == IN_GAME_MENU: self.switchDisplayMode(PLAY) self.setKey("escape", 0) ######### Level specific features ######### def maintainTurrets(self): pass def switchDisplayMode(self, newGameMode): self.cleanupGUI() if self.gameMode["display"] == MAIN_MENU: pass elif self.gameMode["display"] == IN_GAME_MENU: if newGameMode == PLAY: render.clearFog() self.togglePhysicsPause() elif newGameMode == MAIN_MENU: pass elif self.gameMode["display"] == PLAY: if newGameMode == IN_GAME_MENU: self.togglePhysicsPause() self.gameMode["display"] = newGameMode self.mode_initialized = False def advanceLevel(self): self.level += .5 self.loadLevel() def evenButtonPositions(self, button_spacing, button_height, num_buttons): centerOffset = (button_spacing / (2.0) if (num_buttons % 2 == 0) else 0) buttonPositions = [] current_pos = centerOffset + ((num_buttons - 1) / 2) * button_spacing for i in range(0, num_buttons): buttonPositions.append(current_pos + (button_height / 2.0)) current_pos -= button_spacing return buttonPositions def buildInGameMenu(self): self.toggleCursor(False) resume_button = DirectButton( text="Resume", scale=.1, command=(lambda: self.switchDisplayMode(PLAY)), rolloverSound=None) main_menu_button = DirectButton(text="Main Menu", scale=.1, command=None, rolloverSound=None) options_button = DirectButton(text="Settings", scale=.1, command=None, rolloverSound=None) exit_button = DirectButton(text="Exit", scale=.1, command=exit, rolloverSound=None) BUTTON_SPACING = .2 BUTTON_HEIGHT = resume_button.getSy() button_positions = self.evenButtonPositions(BUTTON_SPACING, BUTTON_HEIGHT, 4) resume_button.setPos(Vec3(0, 0, button_positions[0])) main_menu_button.setPos(Vec3(0, 0, button_positions[1])) options_button.setPos(Vec3(0, 0, button_positions[2])) exit_button.setPos(Vec3(0, 0, button_positions[3])) self.guiElements.append(resume_button) self.guiElements.append(main_menu_button) self.guiElements.append(options_button) self.guiElements.append(exit_button) def buildMainMenu(self): self.toggleCursor(False) start_game_button = DirectButton(text="Start", scale=.1, command=None) select_level_button = DirectButton(text="Select Level", scale=.1, command=None) game_options_button = DirectButton(text="Settings", scale=.1, command=None) exit_button = DirectButton(text="Exit", scale=.1, command=exit) BUTTON_SPACING = .2 BUTTON_HEIGHT = start_game_button.getSy() button_positions = self.evenButtonPositions(BUTTON_SPACING, BUTTON_HEIGHT, 4) start_game_button.setPos(Vec3(0, 0, button_positions[0])) select_level_button.setPos(Vec3(0, 0, button_positions[1])) game_options_button.setPos(Vec3(0, 0, button_positions[2])) exit_button.setPos(Vec3(0, 0, button_positions[3])) self.guiElements.append(start_game_button) self.guiElements.append(select_level_button) self.guiElements.append(game_options_button) self.guiElements.append(exit_button) particles = Particles() particles.setPoolSize(1000) particles.setBirthRate(.1) particles.setLitterSize(10) particles.setLitterSpread(3) particles.setFactory("PointParticleFactory") particles.setRenderer("PointParticleRenderer") particles.setEmitter("SphereVolumeEmitter") particles.enable() self.effect = ParticleEffect("peffect", particles) self.effect.reparentTo(render) #self.effect.setPos(self.avatar.objectNP.getX(), self.avatar.objectNP.getY(), self.avatar.objectNP.getZ() + 5) self.effect.setPos(-1, 0, 0) self.effect.enable() def buildDeathScreen(self): self.toggleCursor(False) backFrame = DirectFrame(frameColor=(1, 0, 0, .7), frameSize=(-.5, .5, -.3, .3), pos=(0, 0, 0)) deadMessage = DirectLabel(text="MISSION FAILURE", scale=.1, pos=(0, 0, .16), relief=None, text_font=None) restartButton = DirectButton(text="Restart", scale=.1, pos=(0, 0, -.1), command=self.resetLevel) deadMessage.reparentTo(backFrame) restartButton.reparentTo(backFrame) self.guiElements.append(backFrame) self.guiElements.append(deadMessage) self.guiElements.append(restartButton) def cleanupGUI(self): for guiElement in self.guiElements: guiElement.destroy() def loadSpaceTexture(self, level): if level < 10: return 'textures/space#.jpg' elif level < 15: pass def resetLevel(self): self.switchDisplayMode(PLAY) self.loadLevel(True) def loadLevel(self, reset=False): #Resets self.avatarActor = Actor("models/panda", {"walk": "models/panda-walk"}) self.avatarActor.setScale(.5, .5, .5) self.avatarActor.setHpr(180, 0, 0) self.avatarActor.setCollideMask(BitMask32.allOff()) self.asteroidManager = AsteroidManager() self.cTrav = CollisionTraverser() #Alternate modes if int(self.level) == self.level: self.gameMode["play"] = TERRAIN else: self.gameMode["play"] = SPACE #Specifics if self.gameMode["play"] == SPACE: if reset: self.avatar.reset() else: self.avatar = Avatar(self.avatarActor, self.level) self.avatar.objectNP.reparentTo(render) ########## Sky ######### cubeMap = loader.loadCubeMap(self.loadSpaceTexture(self.level)) self.spaceSkyBox = loader.loadModel('models/box') self.spaceSkyBox.setScale(100) self.spaceSkyBox.setBin('background', 0) self.spaceSkyBox.setDepthWrite(0) self.spaceSkyBox.setTwoSided(True) self.spaceSkyBox.setTexGen(TextureStage.getDefault(), TexGenAttrib.MWorldCubeMap) self.spaceSkyBox.setTexture(cubeMap, 1) parentNP = render.attachNewNode('parent') self.spaceSkyBox.reparentTo(parentNP) self.spaceSkyBox.setPos(-self.spaceSkyBox.getSx() / 2, -self.spaceSkyBox.getSy() / 2, -self.spaceSkyBox.getSz() / 2) ########## Collisions ######### bound = self.avatarActor.getBounds() self.pandaBodySphere = CollisionSphere( bound.getCenter()[0] / self.avatar.objectNP.getSx() - self.avatar.objectNP.getX(), bound.getCenter()[1] / self.avatar.objectNP.getSx() - self.avatar.objectNP.getY(), bound.getCenter()[2] / self.avatar.objectNP.getSx() - self.avatar.objectNP.getZ(), 5) self.pandaBodySphere.setRadius(bound.getRadius() + 1) self.pandaBodySphereNode = CollisionNode("playerBodyRay") self.pandaBodySphereNode.addSolid(self.pandaBodySphere) self.pandaBodySphereNode.setFromCollideMask(BitMask32.bit(0)) self.pandaBodySphereNode.setIntoCollideMask(BitMask32.allOff()) self.pandaBodySphereNodepath = self.avatar.objectNP.attachNewNode( self.pandaBodySphereNode) self.pandaBodySphereNodepath.show() self.collisionNotifier = CollisionHandlerEvent() self.collisionNotifier.addInPattern("%fn-in") self.collisionNotifier.addOutPattern("%fn-out") self.cTrav.addCollider(self.pandaBodySphereNodepath, self.collisionNotifier) self.accept("playerGroundRayJumping-in", self.avatar.handleCollisionEvent, ["in"]) self.accept("playerGroundRayJumping-out", self.avatar.handleCollisionEvent, ["out"]) self.accept("playerBodyRay-in", self.avatar.handleCollisionEvent, ["in"]) self.asteroidManager.initialize(self.level) elif self.gameMode["play"] == TERRAIN: ########## Terrain ######### #self.environ = loader.loadModel("../mystuff/test.egg") self.environ = loader.loadModel("models/environment") self.environ.setName("terrain") self.environ.reparentTo(render) self.environ.setPos(0, 0, 0) self.environ.setCollideMask(BitMask32.bit(0)) ######### Physics ######### self.enableParticles() gravityForce = LinearVectorForce(0, 0, -9.81) gravityForce.setMassDependent(False) gravityFN = ForceNode("world-forces") gravityFN.addForce(gravityForce) render.attachNewNode(gravityFN) base.physicsMgr.addLinearForce(gravityForce) self.avatarPhysicsActorNP = render.attachNewNode( ActorNode("player")) self.avatarPhysicsActorNP.node().getPhysicsObject().setMass(50.) self.avatarActor.reparentTo(self.avatarPhysicsActorNP) base.physicsMgr.attachPhysicalNode( self.avatarPhysicsActorNP.node()) self.avatarPhysicsActorNP.setPos(15, 10, 5) ######### Game objects ######### self.avatar = Avatar(self.avatarPhysicsActorNP, self.level) ######### Collisions ######### self.pandaBodySphere = CollisionSphere(0, 0, 4, 3) self.pandaBodySphereNode = CollisionNode("playerBodySphere") self.pandaBodySphereNode.addSolid(self.pandaBodySphere) self.pandaBodySphereNode.setFromCollideMask(BitMask32.bit(0)) self.pandaBodySphereNode.setIntoCollideMask(BitMask32.allOff()) self.pandaBodySphereNodepath = self.avatar.objectNP.attachNewNode( self.pandaBodySphereNode) self.pandaBodySphereNodepath.show() self.pandaBodyCollisionHandler = PhysicsCollisionHandler() self.pandaBodyCollisionHandler.addCollider( self.pandaBodySphereNodepath, self.avatar.objectNP) #Keep player on ground self.pandaGroundSphere = CollisionSphere(0, 0, 1, 1) self.pandaGroundSphereNode = CollisionNode("playerGroundRay") self.pandaGroundSphereNode.addSolid(self.pandaGroundSphere) self.pandaGroundSphereNode.setFromCollideMask(BitMask32.bit(0)) self.pandaGroundSphereNode.setIntoCollideMask(BitMask32.allOff()) self.pandaGroundSphereNodepath = self.avatar.objectNP.attachNewNode( self.pandaGroundSphereNode) self.pandaGroundSphereNodepath.show() self.pandaGroundCollisionHandler = PhysicsCollisionHandler() self.pandaGroundCollisionHandler.addCollider( self.pandaGroundSphereNodepath, self.avatar.objectNP) #Notify when player lands self.pandaGroundRayJumping = CollisionSphere(0, 0, 1, 1) self.pandaGroundRayNodeJumping = CollisionNode( "playerGroundRayJumping") self.pandaGroundRayNodeJumping.addSolid(self.pandaGroundRayJumping) self.pandaGroundRayNodeJumping.setFromCollideMask(BitMask32.bit(0)) self.pandaGroundRayNodeJumping.setIntoCollideMask( BitMask32.allOff()) self.pandaGroundRayNodepathJumping = self.avatar.objectNP.attachNewNode( self.pandaGroundRayNodeJumping) self.pandaGroundRayNodepathJumping.show() self.collisionNotifier = CollisionHandlerEvent() self.collisionNotifier.addInPattern("%fn-in") self.collisionNotifier.addOutPattern("%fn-out") self.cTrav.addCollider(self.pandaGroundSphereNodepath, self.pandaGroundCollisionHandler) self.cTrav.addCollider(self.pandaGroundRayNodepathJumping, self.collisionNotifier) self.cTrav.addCollider(self.pandaBodySphereNodepath, self.pandaBodyCollisionHandler) self.accept("playerGroundRayJumping-in", self.avatar.handleCollisionEvent, ["in"]) self.accept("playerGroundRayJumping-out", self.avatar.handleCollisionEvent, ["out"]) self.accept("playerBodyRay-in", self.avatar.handleCollisionEvent, ["in"]) def togglePhysicsPause(self): if (self._GCLK == None): self.disableParticles() self._GCLK = ClockObject.getGlobalClock() self._FT = self._GCLK.getFrameTime() self._GCLK.setMode(ClockObject.MSlave) else: self._GCLK.setRealTime(self._FT) self._GCLK.setMode(ClockObject.MNormal) self.enableParticles() self._GCLK = None def gameLoop(self, task): dt = globalClock.getDt() self.processKeys() if self.gameMode["display"] == MAIN_MENU: if not self.mode_initialized: self.buildMainMenu() self.mode_initialized = True if self.gameMode["display"] == IN_GAME_MENU: if not self.mode_initialized: #Fog out background inGameMenuFogColor = (50, 150, 50) inGameMenuFog = Fog("inGameMenuFog") inGameMenuFog.setMode(Fog.MExponential) inGameMenuFog.setColor(*inGameMenuFogColor) inGameMenuFog.setExpDensity(.01) render.setFog(inGameMenuFog) self.buildInGameMenu() self.mode_initialized = True if self.gameMode["display"] == DEAD: if not self.mode_initialized: self.buildDeathScreen() self.mode_initialized = True if self.gameMode["display"] == PLAY: alive = self.avatar.states["alive"] if not self.mode_initialized: self.toggleCursor(True) self.last_mouse_x = self.win.getPointer(0).getX() self.last_mouse_y = self.win.getPointer(0).getY() self.mode_initialized = True if self.gameMode["play"] == TERRAIN: if alive: self.maintainTurrets() self.avatar.move(dt) else: self.switchDisplayMode(DEAD) elif self.gameMode["play"] == SPACE: if alive: self.asteroidManager.maintainAsteroidField( self.avatar.objectNP.getPos(), self.avatar.speed, Camera.AVATAR_DIST, dt) else: self.switchDisplayMode(DEAD) if alive: #Handle keyboard input self.avatar.handleKeys(self.keys, self.gameMode["play"]) ########## Mouse-based viewpoint rotation ########## mouse_pos = self.win.getPointer(0) current_mouse_x = mouse_pos.getX() current_mouse_y = mouse_pos.getY() #Side to side if self.gameMode["play"] == TERRAIN: mouse_shift_x = current_mouse_x - self.last_mouse_x self.last_mouse_x = current_mouse_x if current_mouse_x < 5 or current_mouse_x >= ( self.win_center_x * 1.5): base.win.movePointer(0, self.win_center_x, current_mouse_y) self.last_mouse_x = self.win_center_x yaw_shift = -((mouse_shift_x) * Camera.ROT_RATE[0]) self.avatar.yawRot += yaw_shift self.avatar.objectNP.setH(self.avatar.yawRot) #Up and down mouse_shift_y = current_mouse_y - self.last_mouse_y self.last_mouse_y = current_mouse_y if current_mouse_y < 5 or current_mouse_y >= ( self.win_center_y * 1.5): base.win.movePointer(0, current_mouse_x, self.win_center_y) self.last_mouse_y = self.win_center_y pitch_shift = -((mouse_shift_y) * Camera.ROT_RATE[1]) self.mainCamera.pitchRot += pitch_shift if self.mainCamera.pitchRot > Camera.FLEX_ROT_BOUND[0]: self.mainCamera.pitchRot = Camera.FLEX_ROT_BOUND[0] elif self.mainCamera.pitchRot < -Camera.FLEX_ROT_BOUND[0]: self.mainCamera.pitchRot = -Camera.FLEX_ROT_BOUND[0] xy_plane_cam_dist = Camera.AVATAR_DIST cam_x_adjust = xy_plane_cam_dist * sin( radians(self.avatar.yawRot)) cam_y_adjust = xy_plane_cam_dist * cos( radians(self.avatar.yawRot)) cam_z_adjust = Camera.ELEVATION self.mainCamera.camObject.setH(self.avatar.yawRot) self.mainCamera.camObject.setP(self.mainCamera.pitchRot) self.mainCamera.camObject.setPos( self.avatar.objectNP.getX() + cam_x_adjust, self.avatar.objectNP.getY() - cam_y_adjust, self.avatar.objectNP.getZ() + cam_z_adjust) #Find collisions self.cTrav.traverse(render) return Task.cont