class HitscanWeapon(Weapon): def __init__(self, mask, damage, knockback, range=None): Weapon.__init__(self, mask, range, damage, knockback) if range is None: self.ray = CollisionRay(0, 0, 0, 0, 1, 0) else: self.ray = CollisionSegment(0, 0, 0, 1, 0, 0) rayNode = CollisionNode("playerRay") rayNode.addSolid(self.ray) rayNode.setFromCollideMask(mask) rayNode.setIntoCollideMask(0) self.rayNodePath = render.attachNewNode(rayNode) self.rayQueue = CollisionHandlerQueue() self.traverser = CollisionTraverser() self.traverser.addCollider(self.rayNodePath, self.rayQueue) def performRayCast(self, origin, direction): if isinstance(self.ray, CollisionRay): self.ray.setOrigin(origin) self.ray.setDirection(direction) else: self.ray.setPointA(origin) self.ray.setPointB(origin + direction * self.range) self.traverser.traverse(render) if self.rayQueue.getNumEntries() > 0: self.rayQueue.sortEntries() rayHit = self.rayQueue.getEntry(0) return True, rayHit else: return False, None def fire(self, owner, dt): Weapon.fire(self, owner, dt) rayDir = owner.weaponNP.getQuat(render).getForward() hit, hitEntry = self.performRayCast(owner.weaponNP.getPos(render), rayDir) if hit: hitNP = hitEntry.getIntoNodePath() if hitNP.hasPythonTag(TAG_OWNER): subject = hitNP.getPythonTag(TAG_OWNER) subject.alterHealth(-self.damage, rayDir * self.knockback, self.flinchValue) def cleanup(self): self.traverser.removeCollider(self.rayNodePath) self.traverser = None if self.rayNodePath is not None: self.rayNodePath.removeNode() self.rayNodePath = None Weapon.cleanup(self)
class Weapon(DirectObject): def __init__(self, _main, _name, _fireRate, _dmg=20,_mountSlot=0, weaponType="Pistol"): self.main = _main self.name = _name self.fireRate = _fireRate self.dmg = _dmg self.weaponType = weaponType self.mountSlot = _mountSlot self.muzzleFlash = loader.loadModel("muzzleflash") if weaponType == "Pistol": self.style = "OneHand" self.model = loader.loadModel("Pistol") self.muzzleFlash.setZ(0.65) self.muzzleFlash.setX(-0.04) self.muzzleFlash.setScale(0.25) self.muzzleFlash.find('**/+SequenceNode').node().setFrameRate(20) else: self.style = "TwoHand" self.model = loader.loadModel("MG") self.muzzleFlash.setZ(0.65) self.muzzleFlash.setX(0.08) self.muzzleFlash.setScale(0.3) self.muzzleFlash.find('**/+SequenceNode').node().setFrameRate(20) self.model.setY(2) self.muzzleFlash.reparentTo(self.model) self.muzzleFlash.find('**/+SequenceNode').node().stop() self.muzzleFlash.hide() # Load bullet model self.bullet = loader.loadModel("Bullet") self.bullet.setP(-90) self.bullet.setH(180) #self.bullet.setPos(0, 0.5, 0) # Control self.isFiring = False # Collision Stuff self.wepRay = None # Make weapon ray self.setupRay() self.model.show() def setAmmo(self): pass def setupRay(self): self.shootTraverser = CollisionTraverser() self.shootingQH = CollisionHandlerQueue() #self.shootingEH = CollisionHandlerEvent() #self.shootingEH.addInPattern('into-%in') # Create a collision Node shootNode = CollisionNode('WeaponRay') # set the nodes collision bitmask shootNode.setFromCollideMask(BitMask32.bit(1)) # create a collision segment (ray like) self.shootRay = CollisionSegment() shootNode.addSolid(self.shootRay) #self.pickerNP = self.main.player.model.attachNewNode(pickerNode) self.shootNP = render.attachNewNode(shootNode) #self.shootTraverser.addCollider(self.shootNP, self.shootingEH) self.shootTraverser.addCollider(self.shootNP, self.shootingQH) #self.shootNP.show() def doFire(self, _toPos=(0, 0, 0)): self.isFiring = True if self.weaponType == "Pistol": self.muzzleFlash.find('**/+SequenceNode').node().play(0, 1) else: self.muzzleFlash.find('**/+SequenceNode').node().loop(True) self.muzzleFlash.show() # For some reason the mouse ray end up at posZ -1 (which causes a problem when we make the enemy spheres smaller in radius) # so here for now.. ill make a quick fix. adjustedZ = (_toPos[0], _toPos[1], 0) self.shootRay.setPointA(self.main.player.model.getPos()) self.shootRay.setPointB(adjustedZ) fromPos = self.main.player.model.getPos() #self.model.getPos() #self.setProjectile(fromPos, adjustedZ)#_toPos) self.shootTraverser.traverse(self.main.enemyParent) if self.shootingQH.getNumEntries() > 0: self.shootingQH.sortEntries() enemyCol = self.shootingQH.getEntry(0).getIntoNodePath().node().getName() base.messenger.send("into-" + enemyCol, [self.dmg]) def stopFire(self): if self.weaponType == "Pistol" and \ self.muzzleFlash.find('**/+SequenceNode').node().isPlaying(): taskMgr.add(self.waitForFrame, "waitForFrame") return self.muzzleFlash.find('**/+SequenceNode').node().stop() self.muzzleFlash.hide() def waitForFrame(self, task): if self.muzzleFlash.find('**/+SequenceNode').node().isPlaying(): return task.cont self.muzzleFlash.find('**/+SequenceNode').node().stop() self.muzzleFlash.hide() def reload(self): pass def setProjectile(self, _from, _to): self.bullet.reparentTo(render)#self.model) # setup the projectile interval #self.bulletProjectile = ProjectileInterval(self.bullet, # startPos = Point3(_from), # duration = 1, # endPos = Point3(_to)) #self.bulletProjectile = self.bullet.posInterval(1.0, Point3(_to), startPos=Point3(_from)) #self.bulletProjectile = LerpPosInterval(self.bullet, 2.0, _to, _from) print "POSITIONS:" print _to print _from frm = render.getPos(self.main.player.model) print frm self.bulletProjectile = LerpPosInterval(self.bullet, 1.0, _to, _from) self.bulletProjectile.start()
class Physics: def __init__(self): self.rayCTrav = CollisionTraverser("collision traverser for ray tests") #self.pusher = PhysicsCollisionHandler() self.pusher = CollisionHandlerPusher() self.pusher.addInPattern('%fn-in-%in') self.pusher.addOutPattern('%fn-out-%in') self.pusher.addInPattern('%fn-in') self.pusher.addOutPattern('%fn-out') def startPhysics(self): #self.actorNode = ActorNode("playerPhysicsControler") #base.physicsMgr.attachPhysicalNode(self.actorNode) #self.actorNode.getPhysicsObject().setMass(self.player_mass) #self.mainNode = render.attachNewNode(self.actorNode) self.mainNode = render.attachNewNode("CharacterColliders") self.reparentTo(self.mainNode) charCollisions = self.mainNode.attachNewNode(CollisionNode(self.char_collision_name)) #charCollisions.node().addSolid(CollisionSphere(0, 0, self.player_height/4.0, self.player_height/4.0)) #charCollisions.node().addSolid(CollisionSphere(0, 0, self.player_height/4.0*3.05, self.player_height/4.0)) charCollisions.node().addSolid(CollisionSphere(0, 0, self.player_height/2.0, self.player_height/4.0)) charCollisions.node().setIntoCollideMask(BitMask32(0x80)) # 1000 0000 if self.show_collisions: charCollisions.show() self.pusher.addCollider(charCollisions, self.mainNode) base.cTrav.addCollider(charCollisions, self.pusher) charFFootCollisions = self.attachNewNode(CollisionNode("floor_ray")) charFFootCollisions.node().addSolid(CollisionRay(0, 0, 0.5, 0, 0, -1)) #charFFootCollisions.node().addSolid(CollisionSegment((0, 0, 0.2), (0, 0, -1))) charFFootCollisions.node().setIntoCollideMask(BitMask32.allOff()) charFFootCollisions.node().setFromCollideMask(BitMask32(0x7f)) # 0111 1111 if self.show_collisions: charFFootCollisions.show() self.floor_handler = CollisionHandlerFloor() self.floor_handler.addCollider(charFFootCollisions, self.mainNode) #self.floor_handler.setOffset(0) self.floor_handler.setMaxVelocity(5) base.cTrav.addCollider(charFFootCollisions, self.floor_handler) self.accept("{}-in".format(self.char_collision_name), self.checkCharCollisions) self.raytest_segment = CollisionSegment(0, 1) self.raytest_np = render.attachNewNode(CollisionNode("testRay")) self.raytest_np.node().addSolid(self.raytest_segment) self.raytest_np.node().setIntoCollideMask(BitMask32.allOff()) self.raytest_np.node().setFromCollideMask(BitMask32(0x7f)) # 0111 1111 if self.show_collisions: self.raytest_np.show() self.raytest_queue = CollisionHandlerQueue() self.rayCTrav.addCollider(self.raytest_np, self.raytest_queue) def stopPhysics(self): self.raytest_segment.removeNode() self.pusher.clearColliders() self.floor_handler.clearColliders() self.rayCTrav.clearColliders() def updatePlayerPos(self, speed, heading, dt): if heading is not None: self.mainNode.setH(camera, heading) self.mainNode.setP(0) self.mainNode.setR(0) self.mainNode.setFluidPos(self.mainNode, speed) self.doStep() def checkCharCollisions(self, args): self.doStep() def doStep(self): # do the step height check tmpNP = self.mainNode.attachNewNode("temporary") tmpNP.setPos(self.mainNode, 0, 0, -self.stepheight) pointA = self.mainNode.getPos(render) pointA.setZ(pointA.getZ() + self.player_height/1.8) pointB = tmpNP.getPos(render) if pointA == pointB: return char_step_collision = self.getFirstCollisionInLine(pointA, pointB) tmpNP.removeNode() if char_step_collision is not None: self.mainNode.setFluidZ(char_step_collision.getZ()) return True return False def getFirstCollisionInLine(self, pointA, pointB): """A simple raycast check which will return the first collision point as seen from point A towards pointB""" self.raytest_segment.setPointA(pointA) self.raytest_segment.setPointB(pointB) self.rayCTrav.traverse(render) self.raytest_queue.sortEntries() pos = None if self.raytest_queue.getNumEntries() > 0: pos = self.raytest_queue.getEntry(0).getSurfacePoint(render) return pos
class Physics: def __init__(self): self.rayCTrav = CollisionTraverser("collision traverser for ray tests") #self.pusher = PhysicsCollisionHandler() self.pusher = CollisionHandlerPusher() self.pusher.addInPattern('%fn-in-%in') self.pusher.addOutPattern('%fn-out-%in') self.pusher.addInPattern('%fn-in') self.pusher.addOutPattern('%fn-out') def startPhysics(self): #self.actorNode = ActorNode("playerPhysicsControler") #base.physicsMgr.attachPhysicalNode(self.actorNode) #self.actorNode.getPhysicsObject().setMass(self.player_mass) #self.mainNode = render.attachNewNode(self.actorNode) self.mainNode = render.attachNewNode("CharacterColliders") self.reparentTo(self.mainNode) charCollisions = self.mainNode.attachNewNode( CollisionNode(self.char_collision_name)) #charCollisions.node().addSolid(CollisionSphere(0, 0, self.player_height/4.0, self.player_height/4.0)) #charCollisions.node().addSolid(CollisionSphere(0, 0, self.player_height/4.0*3.05, self.player_height/4.0)) charCollisions.node().addSolid( CollisionSphere(0, 0, self.player_height / 2.0, self.player_height / 4.0)) charCollisions.node().setIntoCollideMask(BitMask32(0x80)) # 1000 0000 if self.show_collisions: charCollisions.show() self.pusher.addCollider(charCollisions, self.mainNode) base.cTrav.addCollider(charCollisions, self.pusher) charFFootCollisions = self.attachNewNode(CollisionNode("floor_ray")) charFFootCollisions.node().addSolid(CollisionRay(0, 0, 0.5, 0, 0, -1)) #charFFootCollisions.node().addSolid(CollisionSegment((0, 0, 0.2), (0, 0, -1))) charFFootCollisions.node().setIntoCollideMask(BitMask32.allOff()) charFFootCollisions.node().setFromCollideMask( BitMask32(0x7f)) # 0111 1111 if self.show_collisions: charFFootCollisions.show() self.floor_handler = CollisionHandlerFloor() self.floor_handler.addCollider(charFFootCollisions, self.mainNode) #self.floor_handler.setOffset(0) self.floor_handler.setMaxVelocity(5) base.cTrav.addCollider(charFFootCollisions, self.floor_handler) self.accept("{}-in".format(self.char_collision_name), self.checkCharCollisions) self.raytest_segment = CollisionSegment(0, 1) self.raytest_np = render.attachNewNode(CollisionNode("testRay")) self.raytest_np.node().addSolid(self.raytest_segment) self.raytest_np.node().setIntoCollideMask(BitMask32.allOff()) self.raytest_np.node().setFromCollideMask(BitMask32(0x7f)) # 0111 1111 if self.show_collisions: self.raytest_np.show() self.raytest_queue = CollisionHandlerQueue() self.rayCTrav.addCollider(self.raytest_np, self.raytest_queue) def stopPhysics(self): self.raytest_segment.removeNode() self.pusher.clearColliders() self.floor_handler.clearColliders() self.rayCTrav.clearColliders() def updatePlayerPos(self, speed, heading, dt): if heading is not None: self.mainNode.setH(camera, heading) self.mainNode.setP(0) self.mainNode.setR(0) self.mainNode.setFluidPos(self.mainNode, speed) self.doStep() def checkCharCollisions(self, args): self.doStep() def doStep(self): # do the step height check tmpNP = self.mainNode.attachNewNode("temporary") tmpNP.setPos(self.mainNode, 0, 0, -self.stepheight) pointA = self.mainNode.getPos(render) pointA.setZ(pointA.getZ() + self.player_height / 1.8) pointB = tmpNP.getPos(render) if pointA == pointB: return char_step_collision = self.getFirstCollisionInLine(pointA, pointB) tmpNP.removeNode() if char_step_collision is not None: self.mainNode.setFluidZ(char_step_collision.getZ()) return True return False def getFirstCollisionInLine(self, pointA, pointB): """A simple raycast check which will return the first collision point as seen from point A towards pointB""" self.raytest_segment.setPointA(pointA) self.raytest_segment.setPointB(pointB) self.rayCTrav.traverse(render) self.raytest_queue.sortEntries() pos = None if self.raytest_queue.getNumEntries() > 0: pos = self.raytest_queue.getEntry(0).getSurfacePoint(render) return pos
class WalkingEnemy(Enemy): def __init__(self, pos): Enemy.__init__( self, pos, "Models/Misc/simpleEnemy", { "stand": "Models/Misc/simpleEnemy-stand", "walk": "Models/Misc/simpleEnemy-walk", "attack": "Models/Misc/simpleEnemy-attack", "die": "Models/Misc/simpleEnemy-die", "spawn": "Models/Misc/simpleEnemy-spawn" }, 3.0, 7.0, "walkingEnemy") self.attackDistance = 0.75 self.attackDelay = 0.3 self.attackDelayTimer = 0 self.attackWaitTimer = 0 self.acceleration = 100.0 mask = BitMask32() mask.setBit(2) self.collider.node().setIntoCollideMask(mask) self.attackSegment = CollisionSegment(0, 0, 0, 1, 0, 0) segmentNode = CollisionNode("enemyAttackSegment") segmentNode.addSolid(self.attackSegment) mask = BitMask32() mask.setBit(1) segmentNode.setFromCollideMask(mask) mask = BitMask32() segmentNode.setIntoCollideMask(mask) self.attackSegmentNodePath = render.attachNewNode(segmentNode) self.segmentQueue = CollisionHandlerQueue() base.cTrav.addCollider(self.attackSegmentNodePath, self.segmentQueue) self.attackDamage = -1 self.deathSound = loader.loadSfx("Sounds/enemyDie.ogg") self.attackSound = loader.loadSfx("Sounds/enemyAttack.ogg") self.yVector = Vec2(0, 1) self.actor.play("spawn") def runLogic(self, player, dt): spawnControl = self.actor.getAnimControl("spawn") if spawnControl is not None and spawnControl.isPlaying(): return vectorToPlayer = player.actor.getPos() - self.actor.getPos() vectorToPlayer2D = vectorToPlayer.getXy() distanceToPlayer = vectorToPlayer2D.length() vectorToPlayer2D.normalize() heading = self.yVector.signedAngleDeg(vectorToPlayer2D) self.attackSegment.setPointA(self.actor.getPos()) self.attackSegment.setPointB(self.actor.getPos() + self.actor.getQuat().getForward() * self.attackDistance) if distanceToPlayer > self.attackDistance * 0.9: attackControl = self.actor.getAnimControl("attack") if not attackControl.isPlaying(): self.walking = True vectorToPlayer.setZ(0) vectorToPlayer.normalize() self.velocity += vectorToPlayer * self.acceleration * dt self.attackWaitTimer = 0.2 self.attackDelayTimer = 0 else: self.walking = False self.velocity.set(0, 0, 0) if self.attackDelayTimer > 0: self.attackDelayTimer -= dt if self.attackDelayTimer <= 0: if self.segmentQueue.getNumEntries() > 0: self.segmentQueue.sortEntries() segmentHit = self.segmentQueue.getEntry(0) hitNodePath = segmentHit.getIntoNodePath() if hitNodePath.hasPythonTag("owner"): hitObject = hitNodePath.getPythonTag("owner") hitObject.alterHealth(self.attackDamage) self.attackWaitTimer = 1.0 elif self.attackWaitTimer > 0: self.attackWaitTimer -= dt if self.attackWaitTimer <= 0: self.attackWaitTimer = random.uniform(0.5, 0.7) self.attackDelayTimer = self.attackDelay self.actor.play("attack") self.attackSound.play() self.actor.setH(heading) def alterHealth(self, dHealth): Enemy.alterHealth(self, dHealth) self.updateHealthVisual() def updateHealthVisual(self): perc = self.health / self.maxHealth if perc < 0: perc = 0 self.actor.setColorScale(perc, perc, perc, 1) def cleanup(self): base.cTrav.removeCollider(self.attackSegmentNodePath) self.attackSegmentNodePath.removeNode() GameObject.cleanup(self)
class PositionExaminer(DirectObject, NodePath): def __init__(self): try: self.__initialized return except: self.__initialized = 1 NodePath.__init__(self, hidden.attachNewNode('PositionExaminer')) self.cRay = CollisionRay(0.0, 0.0, 6.0, 0.0, 0.0, -1.0) self.cRayNode = CollisionNode('cRayNode') self.cRayNode.addSolid(self.cRay) self.cRayNodePath = self.attachNewNode(self.cRayNode) self.cRayNodePath.hide() self.cRayBitMask = CIGlobals.FloorBitmask self.cRayNode.setFromCollideMask(self.cRayBitMask) self.cRayNode.setIntoCollideMask(BitMask32.allOff()) self.cSphere = CollisionSphere(0.0, 0.0, 0.0, 1.5) self.cSphereNode = CollisionNode('cSphereNode') self.cSphereNode.addSolid(self.cSphere) self.cSphereNodePath = self.attachNewNode(self.cSphereNode) self.cSphereNodePath.hide() self.cSphereBitMask = CIGlobals.WallBitmask self.cSphereNode.setFromCollideMask(self.cSphereBitMask) self.cSphereNode.setIntoCollideMask(BitMask32.allOff()) self.ccLine = CollisionSegment(0.0, 0.0, 0.0, 1.0, 0.0, 0.0) self.ccLineNode = CollisionNode('ccLineNode') self.ccLineNode.addSolid(self.ccLine) self.ccLineNodePath = self.attachNewNode(self.ccLineNode) self.ccLineNodePath.hide() self.ccLineBitMask = CIGlobals.CameraBitmask self.ccLineNode.setFromCollideMask(self.ccLineBitMask) self.ccLineNode.setIntoCollideMask(BitMask32.allOff()) self.cRayTrav = CollisionTraverser('PositionExaminer.cRayTrav') self.cRayTrav.setRespectPrevTransform(False) self.cRayQueue = CollisionHandlerQueue() self.cRayTrav.addCollider(self.cRayNodePath, self.cRayQueue) self.cSphereTrav = CollisionTraverser('PositionExaminer.cSphereTrav') self.cSphereTrav.setRespectPrevTransform(False) self.cSphereQueue = CollisionHandlerQueue() self.cSphereTrav.addCollider(self.cSphereNodePath, self.cSphereQueue) self.ccLineTrav = CollisionTraverser('PositionExaminer.ccLineTrav') self.ccLineTrav.setRespectPrevTransform(False) self.ccLineQueue = CollisionHandlerQueue() self.ccLineTrav.addCollider(self.ccLineNodePath, self.ccLineQueue) def delete(self): del self.cRay del self.cRayNode self.cRayNodePath.removeNode() del self.cRayNodePath del self.cSphere del self.cSphereNode self.cSphereNodePath.removeNode() del self.cSphereNodePath del self.ccLine del self.ccLineNode self.ccLineNodePath.removeNode() del self.ccLineNodePath del self.cRayTrav del self.cRayQueue del self.cSphereTrav del self.cSphereQueue del self.ccLineTrav del self.ccLineQueue def consider(self, node, pos, eyeHeight): self.reparentTo(node) self.setPos(pos) result = None self.cRayTrav.traverse(render) if self.cRayQueue.getNumEntries() != 0: self.cRayQueue.sortEntries() floorPoint = self.cRayQueue.getEntry(0).getSurfacePoint(self.cRayNodePath) if abs(floorPoint[2]) <= 4.0: pos += floorPoint self.setPos(pos) self.cSphereTrav.traverse(render) if self.cSphereQueue.getNumEntries() == 0: self.ccLine.setPointA(0, 0, eyeHeight) self.ccLine.setPointB(-pos[0], -pos[1], eyeHeight) self.ccLineTrav.traverse(render) if self.ccLineQueue.getNumEntries() == 0: result = pos self.reparentTo(hidden) self.cRayQueue.clearEntries() self.cSphereQueue.clearEntries() self.ccLineQueue.clearEntries() return result
class Player(): def __init__(self, camera, accept, render, loader, maxJPHeight): #initial variables and sounds self.developer = True # Developer tools (building tools) will be accessible if this is turned on. self.gameMode = self.mode0 # the current playerUpdate function that is in use # self.playerModeParameters = () # the parameters being fed into the function above. self.groundContact = False # if the player is on the ground or a surface, gravity will not pull the player below the surface self.jetPack_energy = 100 self.maximumHeight = maxJPHeight # maximum height in which the jetpack can fly to, this is dependent on the map loaded. self.jetPack_AUDIO = loader.loadSfx("assets/base/sounds/jetpack2.wav") self.jetPack_AUDIO.setLoop(True) self.vertical_velocity = 0 # Current Z velocity, positive = Upwards. self.z_velocity = 0 # Current Y velocity self.x_velocity = 0 self.movingZ = False self.movingX = False #initiate GUI self.HUD = GUI() self.playerHolder = render.attachNewNode('player') # camera control - Hiding mouse and using it to rotate the camera props = WindowProperties() props.setCursorHidden(True) props.setMouseMode(WindowProperties.M_relative) base.win.requestProperties(props) # PLAYER MODEL SCENE GRAPH self.thirdPersonCamera_ZOOM = -50 # initial distance of third person camera. self.character = loader.loadModel( 'assets/base/models/playerModel/player.bam') self.toggleFPCam = False # Whether first person camera is on, this is initially off. self.character.setPos(0, 0, 0) self.character.reparentTo(self.playerHolder) self.playerBase = self.playerHolder.attachNewNode('camParent') self.thirdPersonNode = self.playerBase.attachNewNode('thirdPersonCam') camera.reparentTo(self.thirdPersonNode) self.mouseSeconds = [] self.playerHolder.setScale(4) self.monitor = loader.loadModel( 'assets/base/models/faces/playerMonitor.bam') self.monitor.reparentTo(self.playerHolder) self.cTrav = CollisionTraverser() # Horizontal collisions self.pusher = CollisionHandlerPusher() self.pusher.horizontal = True self.colliderNode = CollisionNode("player") self.colliderNode.addSolid(CollisionSphere(0, 0, 0, 2)) self.colliderNode.setFromCollideMask(CollideMask.bit(1)) self.colliderNode.setFromCollideMask(CollideMask.bit(0)) self.colliderNode.setIntoCollideMask(BitMask32.allOff()) collider = self.playerHolder.attachNewNode(self.colliderNode) collider.show() self.pusher.addCollider(collider, self.playerHolder) self.cTrav.addCollider(collider, self.pusher) # Vertical collisions - Downwards self.groundRay = CollisionRay() self.groundRay.setDirection(0, 0, -1) self.groundRayCol = CollisionNode('playerRay') self.groundRayCol.addSolid(self.groundRay) self.groundRayCol.setFromCollideMask(CollideMask.bit(1)) self.groundRayCol.setIntoCollideMask(CollideMask.allOff()) self.groundColNp = self.playerHolder.attachNewNode(self.groundRayCol) self.groundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.groundColNp, self.groundHandler) # Third Person Camera Collision self.cameraRay = CollisionSegment() self.cameraRayNode = CollisionNode('camerRay') self.cameraRayNode.addSolid(self.cameraRay) self.cameraRayNodePath = render.attachNewNode(self.cameraRayNode) self.cameraCollisionHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.cameraRayNodePath, self.cameraCollisionHandler) # Vertical collisions - Upwards self.upwardsRay = CollisionRay() self.upwardsRay.setDirection(0, 0, 1) self.upwardsRayCol = CollisionNode('playerupRay') self.upwardsRayCol.addSolid(self.upwardsRay) self.upwardsRayCol.setFromCollideMask(CollideMask.bit(1)) self.upwardsRayCol.setIntoCollideMask(CollideMask.allOff()) self.upwardsColNp = self.playerHolder.attachNewNode(self.upwardsRayCol) self.upwardsHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.upwardsColNp, self.upwardsHandler) #self.cTrav.showCollisions(render) if self.developer == True: self.tool = buildingTool( "newbuildings", self.playerHolder, loader, accept) # Load up building tool if developer modee is on. #self.setupLighting() # light #initial position self.playerHolder.setPos(45178.3, 43109.3, 0) self.keyMap = { "left": False, "right": False, "forward": False, "backwards": False, "change_camera": False, "leftClick": False, "space": False, "p": False, "scrollup": False, "scrolldown": False } accept("escape", sys.exit) accept("w", self.updateKey, ["forward", True]) # accept("w-up", self.updateKey, ["forward", False]) accept("a", self.updateKey, ["left", True]) accept("a-up", self.updateKey, ["left", False]) accept("s", self.updateKey, ["backwards", True]) accept("s-up", self.updateKey, ["backwards", False]) accept("d", self.updateKey, ["right", True]) accept("d-up", self.updateKey, ["right", False]) accept("c", self.updateKey, ["change_camera", True]) accept("wheel_up", self.updateKey, ["scrollup", True]) accept("wheel_down", self.updateKey, ["scrolldown", True]) accept("p", self.updateKey, ["p", True]) accept("p-up", self.updateKey, ["p", False]) accept("space", self.updateKey, ["space", True]) accept("space-up", self.updateKey, ["space", False]) self.playerMode = playerModes( self.playerBase, self.playerHolder, self.character, self.vertical_velocity, self.z_velocity, self.x_velocity, self.keyMap, self.monitor, self.thirdPersonNode, self.jetPack_energy, self.jetPack_AUDIO, self.thirdPersonCamera_ZOOM, self.toggleFPCam, self.HUD, self.cTrav, self.groundHandler, self.upwardsHandler, self.maximumHeight) def playerUpdate(self, task): # our UPDATE TASK self.gameMode() return task.cont def updateKey(self, key, value): self.keyMap[key] = value if key == "change_camera": self.changeCamera() self.scrollFactor = 10 if key == "scrollup": # third person zoom in/out self.thirdPersonCamera_ZOOM += self.scrollFactor if key == "scrolldown": self.thirdPersonCamera_ZOOM -= self.scrollFactor def changeCamera(self): # Toggle first person camera. if self.toggleFPCam == False: self.toggleFPCam = True else: self.toggleFPCam = False def recenterMouse(self): base.win.movePointer(0, int(base.win.getProperties().getXSize() / 2), int(base.win.getProperties().getYSize() / 2)) def setupLighting(self): plight = PointLight('plight') plight.setColor((1, 1, 1, 1)) plnp = self.playerHolder.attachNewNode(plight) plnp.setPos(0, 1, 7) render.setLight(plnp) # PLAYER MODES, HOW THE USER INTERACTS AND CONTROLS WITH THE USER # MODE 0 # Mode 0 is the default update mode, it allows WASD movement, # mouse controlled camera rotations, first person and third # person switching, it also has GUI display and player physics. def mode0(self): #THIRD PERSON CAMERA COLLISION # print("thirdpersonnode") # print(self.playerBase.getHpr()) # print("pb") # print(self.character.getHpr()) deltaTime = globalClock.getDt() self.movingZ = False self.movingX = False self.walkConstant = 25 self.rotateConstant = 750 # Keyboard controls # LEVITATION STUFF (FORMERLY CALLED JETPACK) if self.keyMap["space"] and self.jetPack_energy > 0: jetpack = 0.00001 * (( (self.playerHolder.getZ()) - self.maximumHeight)**2) + 9.81 self.playerHolder.setZ(self.playerBase, jetpack) self.jetPack_energy -= 15 * deltaTime self.walkConstant = 70 self.jetPack_AUDIO.play() else: self.jetPack_AUDIO.stop() if self.jetPack_energy < 100: self.jetPack_energy += 10 * deltaTime if self.jetPack_energy > 100: self.jetPack_energy = 100 self.HUD.jetpackStatus.text = "Levitation Battery: " + str( int(self.jetPack_energy)) + "%" if (self.keyMap["forward"] or self.keyMap["backwards"]) and (self.keyMap["right"] or self.keyMap["left"]): self.walkConstant = int(((self.walkConstant**2) / 2)**0.5) # WASD MOVEMENT if self.keyMap["forward"]: self.monitor.setH(self.playerBase.getH() - 90) self.movingZ = True self.z_velocity += 5 if self.z_velocity > self.walkConstant: self.z_velocity = self.walkConstant if self.keyMap["right"]: self.monitor.setH(self.playerBase.getH() - 180) self.movingX = True self.x_velocity += 5 if self.x_velocity > self.walkConstant: self.x_velocity = self.walkConstant if self.keyMap["p"]: print(self.playerHolder.getPos()) print(self.thirdPersonCamera_ZOOM) self.gameMode = self.mode1 if self.keyMap["left"]: self.monitor.setH(self.playerBase.getH()) self.movingX = True self.x_velocity -= 5 if self.x_velocity < -self.walkConstant: self.x_velocity = -self.walkConstant if self.keyMap["backwards"]: self.monitor.setH(self.playerBase.getH() + 90) self.movingZ = True self.z_velocity -= 20 if self.z_velocity < -self.walkConstant: self.z_velocity = -self.walkConstant if self.movingZ == False: if self.z_velocity <= 7 or ( self.z_velocity >= -5 and self.z_velocity < 0): # Shaking bug fix self.z_velocity = 0 if self.z_velocity > 0: self.z_velocity -= 10 elif self.z_velocity < 0: self.z_velocity += 10 if self.movingX == False: if self.x_velocity <= 5 or ( self.x_velocity >= -5 and self.x_velocity < 0): # Shaking bug fix self.x_velocity = 0 if self.x_velocity > 0: self.x_velocity -= 10 elif self.x_velocity < 0: self.x_velocity += 10 # MONITOR HEADINGS FOR DOUBLE INPUT if self.keyMap["forward"] and self.keyMap["right"]: self.monitor.setH(self.playerBase.getH() - 135) elif self.keyMap["forward"] and self.keyMap["left"]: self.monitor.setH(self.playerBase.getH() - 45) elif self.keyMap["backwards"] and self.keyMap["left"]: self.monitor.setH(self.playerBase.getH() + 45) elif self.keyMap["backwards"] and self.keyMap["right"]: self.monitor.setH(self.playerBase.getH() + 135) # third person camera control if (self.toggleFPCam == False): # third person camera controls if (base.mouseWatcherNode.hasMouse() == True): mouseposition = base.mouseWatcherNode.getMouse() self.thirdPersonNode.setP(mouseposition.getY() * 30) self.playerBase.setH(mouseposition.getX() * -50) if (mouseposition.getX() < 0.1 and mouseposition.getX() > -0.1): self.playerBase.setH(self.playerBase.getH()) if self.thirdPersonNode.getP() > 90: self.recenterMouse() self.thirdPersonNode.setP(90) # TRACK MOUSE elif self.thirdPersonNode.getP() < -90: self.recenterMouse() self.thirdPersonNode.setP(-90) if self.thirdPersonCamera_ZOOM > -20: # validate zoom self.thirdPersonCamera_ZOOM = -20 elif self.thirdPersonCamera_ZOOM < -390: self.thirdPersonCamera_ZOOM = -390 # CAMERA STUFF # FIRST PERSON CAMERA if self.toggleFPCam: # first person camera controls camera.setPos(self.character.getPos()) # 0,-50,-10 camera.setZ(camera.getZ() + 6) self.playerHolder.hide() if (base.mouseWatcherNode.hasMouse() == True): mouseposition = base.mouseWatcherNode.getMouse() camera.setP(mouseposition.getY() * 20) self.playerBase.setH(mouseposition.getX() * -50) if (mouseposition.getX() < 0.1 and mouseposition.getX() > -0.1): self.playerBase.setH(self.playerBase.getH()) if camera.getP() > 90: self.recenterMouse() camera.setP(90) # TRACK MOUSE elif camera.getP() < -90: self.recenterMouse() camera.setP(-90) else: # takes out of first person perspective if toggleFPS is turned off. self.playerHolder.show() camera.setPos(0, self.thirdPersonCamera_ZOOM, 0) # 0,-50,-4 camera.lookAt(self.character) # movement updates self.playerHolder.setY(self.playerBase, (self.z_velocity * deltaTime)) self.playerHolder.setX(self.playerBase, (self.x_velocity * deltaTime)) # forward/backward rolling axis = self.playerBase.getQuat().getRight() angle = (self.z_velocity * deltaTime * -8) quat = Quat() quat.setFromAxisAngle(angle, axis) newVec = self.character.getQuat() * quat # print(newVec.getHpr()) self.character.setQuat(newVec) # sideways rolling axis = self.playerBase.getQuat().getForward() angle = (self.x_velocity * deltaTime * 8) quat = Quat() quat.setFromAxisAngle(angle, axis) newVec = self.character.getQuat() * quat # print(self.playerBase.getPos()) self.character.setQuat(newVec) self.cameraRay.setPointA(self.playerBase.getPos()) if camera.getPos() != (0, 0, 0): self.cameraRay.setPointB(camera.getPos(base.render)) self.cTrav.traverse(render) # checking for camera collisions entries = list(self.cameraCollisionHandler.entries) for entry in entries: if str(entry.getIntoNodePath())[:19] != "render/worldTerrain": #camera.setPos(entry.getSurfacePoint(self.thirdPersonNode)) self.thirdPersonCamera_ZOOM += 1 # if len(entries) > 0: # if (self.playerHolder.getZ() < entries[-1].getSurfacePoint(render).getZ() + 8): # self.playerHolder.setZ(entries[-1].getSurfacePoint(render).getZ() + 8) # self.vertical_velocity = 0 # checking for collisions - downwards entries = list(self.groundHandler.entries) entries.sort(key=lambda x: x.getSurfacePoint(render).getZ()) self.performGravity = True if self.performGravity == True: self.vertical_velocity -= (deltaTime * 9.81) if self.vertical_velocity <= -15: self.vertical_velocity = -15 self.playerHolder.setPos(self.playerHolder, Vec3(0, 0, self.vertical_velocity)) # Gravity if len(entries) > 0: if (self.playerHolder.getZ() < entries[-1].getSurfacePoint(render).getZ() + 8): self.playerHolder.setZ( entries[-1].getSurfacePoint(render).getZ() + 8) self.vertical_velocity = 0 # checking for collisions - upwards entries = list(self.upwardsHandler.entries) entries.sort(key=lambda x: x.getSurfacePoint(render).getZ()) if len(entries) > 0: for entry in entries: if (self.playerHolder.getZ() > entry.getSurfacePoint(render).getZ() - 70): self.playerHolder.setZ( entry.getSurfacePoint(render).getZ() - 130) # PLAYER MODES, HOW THE USER INTERACTS AND CONTROLS WITH THE USER # MODE 1 # Mode 1 is a test update loop used to test player loop switching. # it simply freezes the controls. def mode1(self): self.playerHolder.hide() self.playerHolder.setHpr(0, 0, 0) if self.keyMap["backwards"]: self.playerHolder.show() self.gameMode = self.mode0