class Cat(enemy.Enemy): def __init__(self, pos,file_loc): enemy.Enemy.__init__(self, pos, file_loc) self._is_chase = False self._is_cat = True self._walk_rate = 45 self._setup_cat_collision() def _load_models(self, pos): self._model = Actor("models/cat",{"enemove":"models/catanim.egg"}) self._model.setScale(1 * settings.GLOBAL_SCALE) self._model.setPos(pos[0], pos[1], pos[2]) #self._model.reparentTo(render) def _setup_cat_collision(self): # Player sight target self._sphere_handler = CollisionHandlerQueue() self._sphere = CollisionSphere(0, 6, 0, 5) self._coll_sphere = CollisionNode('collision-chase-sphere') self._coll_sphere.addSolid(self._sphere) self._coll_sphere.setFromCollideMask(BitMask32.allOff()) self._coll_sphere.setIntoCollideMask(BitMask32.bit(6)) self._coll_sphere_path = self._model.attachNewNode(self._coll_sphere) #self._coll_sphere_path.show() self._coll_trav.addCollider(self._coll_sphere_path, self._sphere_handler) # Player collision self._player_handler = CollisionHandlerQueue() self._player = CollisionSphere(0, 0, 0, 3) self._player_coll = CollisionNode('collision-with-player-cat') self._player_coll.addSolid(self._player) self._player_coll.setFromCollideMask(BitMask32.bit(7)) self._player_coll.setIntoCollideMask(BitMask32.bit(7)) self._player_coll_path = self._model.attachNewNode(self._player_coll) #self._player_coll_path.show() self._coll_trav.addCollider(self._player_coll_path, self._player_handler)
class Agent: def __init__(self, model, run, walk, startPos, scale, select,ralph,saysome): self.actor = Actor(model, {"run":run, "walk":walk}) self.actor.reparentTo(render) self.actor.setScale(scale) self.actor.setPos(startPos) self.actor.setHpr(90,0,0) self.playerGUI = saysome self.myralph = ralph self.setAI() self.cTrav = CollisionTraverser() self.groundRay = CollisionRay(0,0,1000,0,0,-1) self.groundCol = CollisionNode('dinoRay') self.groundCol.addSolid(self.groundRay) self.groundCol.setFromCollideMask(BitMask32.bit(1)) self.groundCol.setIntoCollideMask(BitMask32.allOff()) self.groundColNp = self.actor.attachNewNode(self.groundCol) self.groundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.groundColNp, self.groundHandler) self.sphere = CollisionSphere(0,0,5,13) self.spherecol = CollisionNode('dinoSphere') self.spherecol.addSolid(self.sphere) self.spherecol.setCollideMask(BitMask32.bit(1)) self.dinocolhs = self.actor.attachNewNode(self.spherecol) #self.dinocolhs.show() #self.groundColNp.show() #self.cTrav.showCollisions(render) def setAI(self): #Creating AI World self.AIworld = AIWorld(render) self.AIchar = AICharacter("seeker",self.actor, 380, 50, 250) self.AIworld.addAiChar(self.AIchar) self.AIbehaviors = self.AIchar.getAiBehaviors() self.AIbehaviors.pursue(self.myralph) self.actor.loop('run') #AI World update taskMgr.add(self.AIUpdate,"AIUpdate") #to update the AIWorld def AIUpdate(self,task): if self.playerGUI.getpausevalue(): self.AIworld.update() return Task.cont def setControl(self, control, value): self.controlMap[control] = value def getactor(self): return self.actor
class trap: def __init__(self, _x, _y, _type): self.x = _x self.y = _y self.type = _type self.load_model() def load_model(self): self.model = Actor("models/panda-model", {"walk":"panda-walk4"}) self.model.reparentTo(render) self.model.setScale(0.005) self.model.setPos(self.x, self.y, 0) def set_up_collision_handler_event(self): self.collision_handler = CollisionHandlerEvent() self.collision_handler.setInPattern("trap-%in") def set_up_collisions(self): collision_sphere = CollisionSphere((0,0,0), 500) collision_node = CollisionNode("trap") collision_node.addSolid(collision_sphere) collision_node_path = self.model.attachNewNode(collision_node) collision_node_path.show() #TODO add collision_node_path to collision traverser # Ex: collision_traverser.addCollider(collision_node_path, collision_handler) #TODO accept collisions # Ex: self.accept("trap-panda", self.hit) def hit(self, collision_entry): pass #https://www.panda3d.org/manual/index.php/Collision_Entries
class MyPanda: count=0 def __init__(self, tempworld): MyPanda.count += 1 self.id = MyPanda.count self.world = tempworld self.pandaNode=render.attachNewNode('pandaNode') self.actor=Actor("models/panda-model", {"walk": "models/panda-walk4"}) self.actor.reparentTo(self.pandaNode) self.actor.setPos(int(self.id) * 30,0,0) self.actor.setScale(0.002, 0.002, 0.002) self.cNode = CollisionNode('panda') self.cNode.addSolid(CollisionSphere(2, 0, 400, 500)) self.frowneyC = self.actor.attachNewNode(self.cNode) base.cTrav.addCollider(self.frowneyC, self.world.pusher) self.world.pusher.addCollider(self.frowneyC, self.actor, base.drive.node()) def getActor(self): return self.actor def getPandaCount(self): return MyRalph.count def getMyPandaId(self): return self.id
def loadModel(file, collision=None, animation=None): model=None if animation: model=Actor(file, animation) #default anim if 'default' in animation: model.loop('default') elif 'idle' in animation: model.loop('idle') else: #some random anim model.loop(animation.items()[0]) else: model=loader.loadModel(file) model.setPythonTag('model_file', file) #load shaders for geom in model.findAllMatches('**/+GeomNode'): if geom.hasTag('light'): model.setPythonTag('hasLight', True) if geom.hasTag('particle'): file='particle/'+geom.getTag('particle') if os.path.exists(file): with open(file) as f: values=json.load(f) p=createEffect(values) model.setPythonTag('particle', p) p.start(parent=model, renderParent=render) if geom.hasTag('cg_shader'): geom.setShader(loader.loadShader("shaders/"+geom.getTag('cg_shader'))) elif geom.hasTag('glsl_shader'): glsl_shader=geom.getTag('glsl_shader') geom.setShader(Shader.load(Shader.SLGLSL, "shaders/{0}_v.glsl".format(glsl_shader),"shaders/{0}_f.glsl".format(glsl_shader))) else: #geom.setShader(loader.loadShader("shaders/default.cg")) geom.setShader(Shader.load(Shader.SLGLSL, "shaders/default_v.glsl","shaders/default_f.glsl")) #collisions model.setCollideMask(BitMask32.allOff()) if collision: coll=loader.loadModel(collision) coll.reparentTo(model) coll.find('**/collision').setCollideMask(BitMask32.bit(2)) coll.find('**/collision').setPythonTag('object', model) if animation: model.setPythonTag('actor_files', [file,animation,coll]) else: try: model.find('**/collision').setCollideMask(BitMask32.bit(2)) model.find('**/collision').setPythonTag('object', model) except: print "WARNING: Model {0} has no collision geometry!\nGenerating collision sphere...".format(file) bounds=model.getBounds() radi=bounds.getRadius() cent=bounds.getCenter() coll_sphere=model.attachNewNode(CollisionNode('collision')) coll_sphere.node().addSolid(CollisionSphere(cent[0],cent[1],cent[2], radi)) coll_sphere.setCollideMask(BitMask32.bit(2)) coll_sphere.setPythonTag('object', model) #coll_sphere.show() if animation: model.setPythonTag('actor_files', [file,animation,None]) return model
class GameObject: def __init__(self, modelName, model_anims, max_health, speed, collider_name, base, pos, hpr=Vec3(0, 0, 0), scale=1.0): self.actor = Actor(modelName, model_anims) self.actor.reparentTo(base.render) self.actor.setPos(pos) self.actor.setHpr(hpr) self.actor.setScale(Vec3(scale, scale, scale)) self.base = base self.max_health = max_health self.health = max_health self.speed = speed colliderNode = CollisionNode(collider_name) colliderNode.addSolid( CollisionCapsule( Vec3(0, 0, 2) * 1 / scale, Vec3(0, 0, 9) * 1 / scale, 6 * 1 / scale)) # colliderNode.addSolid(CollisionSphere(0, 0, 0, 0.3)) self.collider = self.actor.attachNewNode(colliderNode) self.collider.setPythonTag("owner", self) # self.collider.show() def get_position(self): return self.actor.getPos() def rotate(self, angle): self.actor.setHpr(self.actor, angle) def change_health(self, dHealth): self.health += dHealth if self.health > self.max_health: self.health = self.max_health elif self.health < 0: self.health = 0 print(self.health) def cleanup(self): # Remove various nodes, and clear the Python-tag--see below! if self.collider is not None and not self.collider.isEmpty(): # self.collider.clearPythonTag("owner") self.base.cTrav.removeCollider(self.collider) self.base.pusher.removeCollider(self.collider) if self.actor is not None: self.actor.cleanup() self.actor.removeNode() self.actor = None self.collider = None
class Obj_actifs: def __init__(self,parent,pos,modelName, modelAnims,colliderName,scale): self.parent=parent self.pos_init=pos self.actor = Actor(modelName, modelAnims) self.actor.setPos(self.pos_init) self.colliderName=colliderName self.actor.setScale(scale) self.Init_coll() print(f" Objet : {self.colliderName} : init collisions") self.parent.base.pusher.addCollider(self.collider, self.actor) self.parent.base.cTrav.addCollider(self.collider, base.pusher) # ================================================================ # Initialisation des collisions # #================================================================= def Init_coll(self): colliderNode = CollisionNode(self.colliderName) colliderNode.addSolid(CollisionSphere(0, 0, 0, 0.5)) self.collider = self.actor.attachNewNode(colliderNode) self.collider.show() # masque collision mask = BitMask32() mask.setBit(2) mask.setBit(0) self.collider.node().setIntoCollideMask(mask) mask = BitMask32() mask.setBit(2) mask.setBit(1) self.collider.node().setFromCollideMask(mask) self.collider.setPythonTag("owner", self)
class GameObject(): def __init__(self, pos, modelName, modelAnims, maxHealth, maxSpeed, colliderName): self.actor = Actor(modelName, modelAnims) self.actor.reparentTo(render) self.actor.setPos(pos) self.maxHealth = maxHealth self.health = maxHealth self.maxSpeed = maxSpeed self.velocity = Vec3(0, 0, 0) self.acceleration = 300.0 self.walking = False colliderNode = CollisionNode(colliderName) colliderNode.addSolid(CollisionSphere(0, 0, 0, 0.3)) self.collider = self.actor.attachNewNode(colliderNode) self.collider.setPythonTag("owner", self) def update(self, dt): speed = self.velocity.length() if speed > self.maxSpeed: self.velocity.normalize() self.velocity *= self.maxSpeed speed = self.maxSpeed if not self.walking: frictionVal = FRICTION * dt if frictionVal > speed: self.velocity.set(0, 0, 0) else: frictionVec = -self.velocity frictionVec.normalize() frictionVec *= frictionVal self.velocity += frictionVec self.actor.setPos(self.actor.getPos() + self.velocity * dt) def alterHealth(self, dHealth): self.health += dHealth if self.health > self.maxHealth: self.health = self.maxHealth def cleanup(self): if self.collider is not None and not self.collider.isEmpty(): self.collider.clearPythonTag("owner") base.cTrav.removeCollider(self.collider) base.pusher.removeCollider(self.collider) if self.actor is not None: self.actor.cleanup() self.actor.removeNode() self.actor = None self.collider = None
class MyRalph: count = 0 def __init__(self, tempworld): self.world = tempworld MyRalph.count += 1 self.id = MyRalph.count self.actor = Actor("models/ralph/ralph", {"run":"models/ralph/ralph-run", "walk":"models/ralph/ralph-walk"}) self.actor.reparentTo(render) self.actor.setScale(.2) self.actor.setPos(int(self.id)*20, 0, 0) # Create a collsion node for this object. self.cNode = CollisionNode('ralph') # Attach a collision sphere solid to the collision node. self.cNode.addSolid(CollisionSphere(0, 0, 3, 3)) # Attach the collision node to the object's model. self.smileyC = self.actor.attachNewNode(self.cNode) base.cTrav.addCollider(self.smileyC, self.world.pusher) self.world.pusher.addCollider(self.smileyC, self.actor, base.drive.node()) def getActor(self): return self.actor def getRalphCount(self): return MyRalph.count def getMyRalphId(self): return self.id
def loadModel(file, collision=None, animation=None): model = None if animation: model = Actor(file, animation) #default anim if 'default' in animation: model.loop('default') elif 'idle' in animation: model.loop('idle') else: #some random anim model.loop(list(animation.items())[0]) else: model = loader.loadModel(file) model.setPythonTag('model_file', file) #load shaders for geom in model.findAllMatches('**/+GeomNode'): if geom.hasTag('cg_shader'): geom.setShader( loader.loadShader("shaders/" + geom.getTag('cg_shader'))) elif geom.hasTag('glsl_shader'): glsl_shader = geom.getTag('glsl_shader') geom.setShader( Shader.load(Shader.SLGLSL, "shaders/{0}_v.glsl".format(glsl_shader), "shaders/{0}_f.glsl".format(glsl_shader))) else: #geom.setShader(loader.loadShader("shaders/default.cg")) geom.setShader( Shader.load(Shader.SLGLSL, "shaders/default_v.glsl", "shaders/default_f.glsl")) #collisions model.setCollideMask(BitMask32.allOff()) if collision: coll = loader.loadModel(collision) coll.reparentTo(model) coll.find('**/collision').setCollideMask(BitMask32.bit(2)) coll.find('**/collision').setPythonTag('object', model) if animation: model.setPythonTag('actor_files', [file, animation, coll]) else: try: model.find('**/collision').setCollideMask(BitMask32.bit(2)) model.find('**/collision').setPythonTag('object', model) except: print( "WARNING: Model {0} has no collision geometry!\nGenerating collision sphere..." .format(file)) bounds = model.getBounds() radi = bounds.getRadius() cent = bounds.getCenter() coll_sphere = model.attachNewNode(CollisionNode('collision')) coll_sphere.node().addSolid( CollisionSphere(cent[0], cent[1], cent[2], radi)) coll_sphere.setCollideMask(BitMask32.bit(2)) coll_sphere.setPythonTag('object', model) #coll_sphere.show() if animation: model.setPythonTag('actor_files', [file, animation, None]) return model
class FieldActor(FSM): def __init__(self, name, indexNumber, modelName, stage, actorsList, hero): self.indexNumber = indexNumber self.modelName = modelName self.stage = stage self.name = name self.actorsList = actorsList self.hero = hero FSM.__init__( self, "FSM-FieldActor-{}_{}".format(self.name, self.indexNumber)) self.initActor() def initActor(self): faEmpty = self.stage.find("**/{}_{}".format(self.name, self.indexNumber)) faPos = faEmpty.getPos() self.actor = Actor( "{}".format(self.modelName), { "idle": "{}-idle".format(self.modelName), "walk": "{}-walk".format(self.modelName) }) self.actor.reparentTo(self.stage) self.actor.setPos(faPos) cNode = CollisionNode("{}_{}".format(self.name, self.indexNumber)) cNode.addSolid(CollisionBox(0, 1.5, 1.5, 1)) faCollision = self.actor.attachNewNode(cNode) ##################################################### # faCollision.show() ##################################################### base.pusher.addCollider(faCollision, self.actor, base.drive.node()) base.cTrav.addCollider(faCollision, base.pusher) self.actorsList.append(self) AIchar = AICharacter("{}_{}".format(self.name, self.indexNumber), self.actor, 100, 0.05, 5) base.AIworld.addAiChar(AIchar) self.AIbehaviors = AIchar.getAiBehaviors() # FSM ################################################################## def enterIdle(self): self.actor.loop('idle') def enterWander(self): self.actor.loop('walk') self.AIbehaviors.wander(5, 0, 10, 1.0) def enterPursue(self): self.actor.loop('walk') self.AIbehaviors.pursue(self.hero) def enterHide(self): self.actor.hide() def enterShow(self): self.actor.show() def enterDeleteActor(self): self.actor.delete()
def loadPlaneModel(self, modelname): """Loads models and animations from the planes directory.""" animcontrols = {} model = loader.loadModel("planes/{0}/{0}".format(modelname)) actor = Actor(model, setFinal=True, mergeLODBundles=True, allowAsyncBind=False, okMissing=False) #actor = Actor(model, lodNode="mid") subparts = ( # subpart, joints, animations ("Doors", ["Windscreen*", "Door*"], ("Open", "Close")), #("Landing Gear", ["Landing?Gear*", "LG*"], ("LG Out", "LG In")), ("Landing Gear", ["Landing?Gear*", "LG*"], ("LG Out", )), ("Ailerons", ["Aileron*"], ("Roll Left", "Roll Right")), ("Rudders", ["Rudder*"], ("Head Left", "Head Right")), ("Elevators", ["Elevator*"], ("Pitch Up", "Pitch Down"))) for line in subparts: subpart, joints, anims = line actor.makeSubpart(subpart, joints) path = "planes/{0}/{0}-{{0}}".format(modelname) d = dict((anim, path.format(anim)) for anim in anims) #actor.loadAnims(d, subpart, "mid") actor.loadAnims(d, subpart) for anim in anims: #actor.bindAnim(anim, subpart, "mid") actor.bindAnim(anim, subpart) #animcontrols[anim] = actor.getAnimControls(anim, subpart, # "mid", False)[0] animcontrols[anim] = actor.getAnimControls( anim, subpart, None, False)[0] actor.makeSubpart("propellers", "Propeller*") actor.verifySubpartsComplete() actor.setSubpartsComplete(True) for p in actor.getJoints("propellers", "Propeller*", "lodRoot"): self.propellers.append( actor.controlJoint(None, "propellers", p.getName())) #actor.pprint() cams = model.findAllMatches("**/camera ?*") if not cams.isEmpty(): cameras = actor.attachNewNode("cameras") cams.reparentTo(cameras) return actor, animcontrols
def loadPlaneModel(self, modelname): """Loads models and animations from the planes directory.""" animcontrols = {} model = loader.loadModel("planes/{0}/{0}".format(modelname)) actor = Actor(model, setFinal=True, mergeLODBundles=True, allowAsyncBind=False, okMissing=False) #actor = Actor(model, lodNode="mid") subparts = ( # subpart, joints, animations ("Doors", ["Windscreen*", "Door*"], ("Open", "Close")), #("Landing Gear", ["Landing?Gear*", "LG*"], ("LG Out", "LG In")), ("Landing Gear", ["Landing?Gear*", "LG*"], ("LG Out",)), ("Ailerons", ["Aileron*"], ("Roll Left", "Roll Right")), ("Rudders", ["Rudder*"], ("Head Left", "Head Right")), ("Elevators", ["Elevator*"], ("Pitch Up", "Pitch Down")) ) for line in subparts: subpart, joints, anims = line actor.makeSubpart(subpart, joints) path = "planes/{0}/{0}-{{0}}".format(modelname) d = dict((anim, path.format(anim)) for anim in anims) #actor.loadAnims(d, subpart, "mid") actor.loadAnims(d, subpart) for anim in anims: #actor.bindAnim(anim, subpart, "mid") actor.bindAnim(anim, subpart) #animcontrols[anim] = actor.getAnimControls(anim, subpart, # "mid", False)[0] animcontrols[anim] = actor.getAnimControls(anim, subpart, None, False)[0] actor.makeSubpart("propellers", "Propeller*") actor.verifySubpartsComplete() actor.setSubpartsComplete(True) for p in actor.getJoints("propellers", "Propeller*", "lodRoot"): self.propellers.append(actor.controlJoint(None, "propellers", p.getName())) #actor.pprint() cams = model.findAllMatches("**/camera ?*") if not cams.isEmpty(): cameras = actor.attachNewNode("cameras") cams.reparentTo(cameras) return actor, animcontrols
class PlayerObject(): def __init__(self, render, player): self.username = player.getUsername() self.isMoving = False self.render = render self.keyMap = {"left":0, "right":0, "forward":0, "cam-left":0, "cam-right":0} self.actor = Actor("models/ralph", {"run":"models/ralph-run", "walk":"models/ralph-walk"}) self.actor.reparentTo(render) self.actor.setScale(0.2) self.actor.setPos(player.getX(), player.getY(), player.getZ()) self.actor.setH(player.getH()) self.cTrav = CollisionTraverser() self.GroundRay = CollisionRay() self.GroundRay.setOrigin(0,0,1000) self.GroundRay.setDirection(0,0,-1) self.GroundCol = CollisionNode('actorRay') self.GroundCol.addSolid(self.GroundRay) self.GroundCol.setFromCollideMask(BitMask32.bit(0)) self.GroundCol.setIntoCollideMask(BitMask32.allOff()) self.GroundColNp = self.actor.attachNewNode(self.GroundCol) self.GroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.GroundColNp, self.GroundHandler) # def getUsername(self): # return self.username def getActor(self): return self.actor def setPos(self, x, y, z): self.actor.setPos(x, y, z) def setH(self, h): self.actor.setH(h) def move(self, isActorMove): if isActorMove == "True": if self.isMoving is False: self.actor.loop("run") self.isMoving = True else: if self.isMoving: self.actor.stop() self.actor.pose("walk",5) self.isMoving = False
class fireSystem(): lifeSpanSeconds = 20 lifeRemaining = 0 isAlight = False def __init__(self, id, parent): self.id = id self.actor = Actor() self.actor.reparentTo(parent) self.lifeRemaining = self.lifeSpanSeconds self.fire = ParticleEffect() self.fire.loadConfig('fire.ptf') self.fire.reparentTo(self.actor) self.fire.setPos(0.000, 0.000, 4.250) fireSphere = CollisionSphere(0, 0, 4.25, 2.5) self.collisionNodeName = "fire{}Collision".format(self.id) fireCollisionNode = CollisionNode(self.collisionNodeName) fireCollisionNode.addSolid(fireSphere) self.collision = self.actor.attachNewNode(fireCollisionNode) base.cTrav.addCollider(self.collision, base.handler) self.burn = taskMgr.add(self.burnTask, "burnTask") self.notifier = CollisionHandlerEvent def burnTask(self, task): if self.isAlight: deltaTime = globalClock.getDt() self.lifeRemaining -= deltaTime if self.lifeRemaining <= 0: self.fire.softStop() else: return task.cont else: return task.cont def ignite(self): self.isAlight = True self.fire.start()
class spike(trap): def __init__(self, _x, _y): trap.__init__(self, _x, _y, "spike") def load_model(self): self.model = Actor("models/spikes.egg", {"act":"models/spikes.egg"}) self.model.reparentTo(render) self.model.setScale(5.7) self.model.setPos(self.x+25, self.y+25, 0) #self.act_control = self.model.getAnimControl('act') #self.act_control.setPlayRate(0.5) #self.act_control.loop('act') self.model.loop('act') self.set_up_collisions() #self.model.play("act") def set_up_collisions(self): self.collision_sphere = CollisionSphere((0,0,0), 4.5) self.collision_node = CollisionNode("spikes") self.collision_node.addSolid(self.collision_sphere) self.collision_node_path = self.model.attachNewNode(self.collision_node)
def rain(self): meteoBall = Actor("models/gamedev/fireball") meteoBall.reparentTo(render) meteoBall.setScale(2) meteoBall.setH(-15) boundsB = meteoBall.getChild(0).getBounds() centerB = boundsB.getCenter() radiusB = boundsB.getRadius()*0.65 cSphereB = CollisionSphere(centerB,radiusB) cNodeB = CollisionNode("meteor") cNodeB.addSolid(cSphereB) cNodePathB = meteoBall.attachNewNode(cNodeB) #cNodePathB.show() ProjectileInterval(meteoBall, startPos = Point3(random.randint(15,211),0,170),startVel = Point3(-12,0,0), endZ = -50).start() cHandler = CollisionHandlerEvent() cHandler.addInPattern('%fn-into-%in') self.cTrav.addCollider(cNodePathB,cHandler) self.accept("meteor-into-player1",self.player2Wins) self.accept("meteor-into-player2",self.player1Wins)
class DogCatcher(enemy.Enemy): def __init__(self, pos,file_loc): enemy.Enemy.__init__(self, pos, file_loc) self._setup_catcher_collisions() def _load_models(self, pos): self._model = Actor("models/cthr", {"enemove":"models/cthr"}) self._model.setScale(1 * settings.GLOBAL_SCALE) self._model.setPos(pos[0], pos[1], pos[2]) #self._model.reparentTo(render) def _setup_catcher_collisions(self): # Player collision self._player_handler = CollisionHandlerQueue() self._player = CollisionSphere(0, -5, 0, 3) self._player_coll = CollisionNode('collision-with-player-dcatcher') self._player_coll.addSolid(self._player) self._player_coll.setFromCollideMask(BitMask32.bit(7)) self._player_coll.setIntoCollideMask(BitMask32.bit(7)) self._player_coll_path = self._model.attachNewNode(self._player_coll) #self._player_coll_path.show() self._coll_trav.addCollider(self._player_coll_path, self._player_handler)
class World(DirectObject): # necessary to accept events # initializer def __init__(self): # turn off default mouse control, otherwise camera is not repositionable base.disableMouse() # camera.setPosHpr(0, -15, 7, 0, -15, 0) render.setShaderAuto() self.keyMap = {"left": 0, "right": 0, "forward": 0, "reverse": 0} self.loadModels() camera.reparentTo(self.panda) # Move camera Up camera.setZ(2000) # Move camera Back camera.setY(3600) # Turn camera 180 degrees camera.setH(180) # Tilt the camera down camera.setP(-15) self.setupLights() self.setupCollisions() taskMgr.add(self.move, "moveTask") self.prevtime = 0 self.isMoving = False # self.eatSound = loader.loadSfx("something.wav") # self.music = loader.loadMusic("music.mp3") # self.accept("escape", sys.exit) #message name, function to call, list of arguments # "mouse1" is the event when the left mouse button is clicked # other interval methods: loop(), pause(), resuem(), finish() # start() can take arguments: start(starttime, endtime, playrate) self.accept("arrow_up", self.setKey, ["forward", 1]) self.accept("arrow_left", self.setKey, ["left", 1]) self.accept("arrow_right", self.setKey, ["right", 1]) self.accept("arrow_up-up", self.setKey, ["forward", 0]) self.accept("arrow_left-up", self.setKey, ["left", 0]) self.accept("arrow_right-up", self.setKey, ["right", 0]) self.accept("arrow_down", self.setKey, ["reverse", 1]) self.accept("arrow_down-up", self.setKey, ["reverse", 0]) self.accept("ate-smiley", self.test_eat) # startPos = self.env.find("**/start_point").getPos() # self.panda.setPos(startPos) self.panda.setZ(100) def setKey(self, key, value): self.keyMap[key] = value def loadModels(self): """loads initial models into the world""" self.panda = Actor("panda-model", {"walk": "panda-walk4", "eat": "panda-eat"}) self.panda.reparentTo(render) self.panda.setScale(0.0005) self.panda.setH(180) self.env = loader.loadModel("models/world") self.env.reparentTo(render) self.env.setScale(0.25) self.env.setPos(0, 0, 0) # load targets self.targets = [] for i in range(5): target = loader.loadModel("smiley") target.setScale(0.5) target.setPos(random.uniform(-20, 20), i, 2) target.reparentTo(render) self.targets.append(target) def setupLights(self): """Loads initial lighting""" self.dirLight = DirectionalLight("dirLight") self.dirLight.setColor((0.6, 0.6, 0.6, 1)) # alpha is largely irrelevant # create a NodePath, and attach it directly in the scene self.dirLightNP = render.attachNewNode(self.dirLight) self.dirLightNP.setHpr(0, -26, 0) # the NP that calls setLight is what is illuminated by the light # use clearLight() to turn it off # render.setLight(self.dirLightNP) self.ambientLight = AmbientLight("ambientLight") self.ambientLight.setColor((0.25, 0.25, 0.25, 1)) self.ambientLightNP = render.attachNewNode(self.ambientLight) render.setLight(self.ambientLightNP) self.headLight = Spotlight("headLight") self.headLight.setColor((1, 1, 1, 1)) self.headLight.setLens(PerspectiveLens()) self.headLight.getLens().setFov(45, 15) self.headLight.setAttenuation(Vec3(1.0, 0.0, 0.0)) self.headLight.setExponent(0.5) self.headLightNP = self.panda.attachNewNode(self.headLight) self.headLightNP.setH(180) self.headLightNP.setZ(100) self.headLightNP.setP(-20) # Display the cone self.headLight.showFrustum() render.setLight(self.headLightNP) def move(self, task): """Compound interval for walking""" self.cTrav.traverse(render) startpos = self.panda.getPos() elapsed = task.time - self.prevtime # camera.lookAt(self.panda) if self.keyMap["left"]: self.panda.setH(self.panda.getH() + elapsed * 100) if self.keyMap["right"]: self.panda.setH(self.panda.getH() - elapsed * 100) if self.keyMap["forward"]: dist = 0.1 angle = deg2Rad(self.panda.getH()) dx = dist * math.sin(angle) dy = dist * -math.cos(angle) self.panda.setPos(self.panda.getX() + dx, self.panda.getY() + dy, 0) if self.keyMap["reverse"]: dist = -0.1 angle = deg2Rad(self.panda.getH()) dx = dist * math.sin(angle) dy = dist * -math.cos(angle) self.panda.setPos(self.panda.getX() + dx, self.panda.getY() + dy, 0) if self.keyMap["left"] or self.keyMap["right"] or self.keyMap["forward"]: if self.isMoving == False: self.isMoving = True self.panda.loop("walk") else: if self.isMoving: self.panda.stop() self.panda.pose("walk", 4) self.isMoving = False self.prevtime = task.time 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.panda.setZ(entries[0].getSurfacePoint(render).getZ()) else: self.panda.setPos(startpos) entries = [] for i in range(self.ralphGroundHandlerRear.getNumEntries()): entry = self.ralphGroundHandlerRear.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.panda.setZ(entries[0].getSurfacePoint(render).getZ()) else: self.panda.setPos(startpos) return Task.cont def setupCollisions(self): self.cHandler = CollisionHandlerEvent() # sets the pattern for the event sent on collision # "%in" is substituted with the name of the into object self.cHandler.setInPattern("ate-%in") # makes a collision traverser and sets it to the default base.cTrav = CollisionTraverser() # cSphere = CollisionSphere((0,0,0), 500) #panda is scaled way down # cNode = CollisionNode("panda") # cNode.addSolid(cSphere) # cNode.setIntoCollideMask(BitMask32.allOff()) # cNodePath = self.panda.attachNewNode(cNode) # cNodePath.show() # base.cTrav.addCollider(cNodePath, self.cHandler) # cNodePath.show() self.cTrav = CollisionTraverser() self.ralphGroundRay = CollisionRay() self.ralphGroundRay.setOrigin(0, -250, 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.panda.attachNewNode(self.ralphGroundCol) # self.ralphGroundColNp.show() self.ralphGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler) self.ralphGroundRayRear = CollisionRay() self.ralphGroundRayRear.setOrigin(0, 250, 1000) self.ralphGroundRayRear.setDirection(0, 0, -1) self.ralphGroundColRear = CollisionNode("ralphRay") self.ralphGroundColRear.addSolid(self.ralphGroundRayRear) self.ralphGroundColRear.setFromCollideMask(BitMask32.bit(0)) self.ralphGroundColRear.setIntoCollideMask(BitMask32.allOff()) self.ralphGroundColNpRear = self.panda.attachNewNode(self.ralphGroundColRear) # self.ralphGroundColNp.show() self.ralphGroundHandlerRear = CollisionHandlerQueue() self.cTrav.addCollider(self.ralphGroundColNpRear, self.ralphGroundHandlerRear) def eat(self, cEntry): """handles panda eating a smiley""" self.targets.remove(cEntry.getIntoNodePath().getParent()) cEntry.getIntoNodePath().getParent().remove() def test_eat(self, cEntry): self.eat(cEntry) if len(self.targets) <= 0: sys.exit()
class Demo(ShowBase): _speed = 25 def reset(self): x = random.random() * 40 - 20 y = random.random() * 40 - 20 self.ralph.setPos((x, y, 0)) def __init__(self, img_size=512, screen_off=True): self.img_size = img_size loadPrcFileData("", "transform-cache false") loadPrcFileData("", "audio-library-name null") # Prevent ALSA errors loadPrcFileData("", "win-size %d %d" % (img_size, img_size)) loadPrcFileData("", "parallax-mapping-samples 3\n" "parallax-mapping-scale 0.1") if screen_off: # Spawn an offscreen buffer loadPrcFileData("", "window-type offscreen") # Initialize the ShowBase class from which we inherit, which will # create a window and set up everything we need for rendering into it. ShowBase.__init__(self) # Load the 'abstract room' model. This is a model of an # empty room containing a pillar, a pyramid, and a bunch # of exaggeratedly bumpy textures. self.room = loader.loadModel("models/abstractroom") self.room.reparentTo(render) # Create the main character, Ralph self.ralph = Actor("models/ralph", {"run": "models/ralph-run", "walk": "models/ralph-walk"}) self.ralph.reparentTo(render) self.ralph.setScale(.2) self.reset() self.pieces = [Piece(self.room) for _ in range(200)] ################################################## cnodePath = self.room.attachNewNode(CollisionNode('cnode')) plane = CollisionPlane(Plane(Vec3(1, 0, 0), Point3(-60, 0, 0))) # left cnodePath.node().addSolid(plane) plane = CollisionPlane( Plane(Vec3(-1, 0, 0), Point3(60, 0, 0))) # right cnodePath.node().addSolid(plane) plane = CollisionPlane(Plane(Vec3(0, 1, 0), Point3(0, -60, 0))) # back cnodePath.node().addSolid(plane) plane = CollisionPlane( Plane(Vec3(0, -1, 0), Point3(0, 60, 0))) # front cnodePath.node().addSolid(plane) sphere = CollisionSphere(-25, -25, 0, 12.5) cnodePath.node().addSolid(sphere) box = CollisionBox(Point3(5, 5, 0), Point3(45, 45, 10)) cnodePath.node().addSolid(box) # Make the mouse invisible, turn off normal mouse controls self.disableMouse() self.camLens.setFov(80) # Set the current viewing target self.focus = LVector3(55, -55, 20) self.heading = 180 self.pitch = 0 self.mousex = 0 self.mousey = 0 self.last = 0 self.mousebtn = [0, 0, 0] # Add a light to the scene. self.lightpivot = render.attachNewNode("lightpivot") self.lightpivot.setPos(0, 0, 25) self.lightpivot.hprInterval(10, LPoint3(360, 0, 0)).loop() plight = PointLight('plight') plight.setColor((5, 5, 5, 1)) plight.setAttenuation(LVector3(0.7, 0.05, 0)) plnp = self.lightpivot.attachNewNode(plight) plnp.setPos(45, 0, 0) self.room.setLight(plnp) # Add an ambient light alight = AmbientLight('alight') alight.setColor((0.2, 0.2, 0.2, 1)) alnp = render.attachNewNode(alight) self.room.setLight(alnp) # Create a sphere to denote the light sphere = loader.loadModel("models/icosphere") sphere.reparentTo(plnp) self.cameraModel = self.ralph camera.reparentTo(self.cameraModel) camera.setZ(2) self.cTrav = CollisionTraverser() cs = CollisionSphere(0, 0, 0, 1) cnodePath = self.ralph.attachNewNode(CollisionNode('cnode')) cnodePath.node().addSolid(cs) cnodePath.show() self.ralphGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(cnodePath, self.ralphGroundHandler) self.cnodePath = cnodePath # Tell Panda that it should generate shaders performing per-pixel # lighting for the room. self.room.setShaderAuto() self.shaderenable = 1 tex = Texture() self.depthmap = tex tex.setFormat(Texture.FDepthComponent) altBuffer = self.win.makeTextureBuffer( "hello", img_size, img_size, tex, True) self.altBuffer = altBuffer altCam = self.makeCamera(altBuffer) altCam.reparentTo(self.ralph) # altRender) altCam.setZ(2) l = altCam.node().getLens() l.setFov(80) ################### end init def step(self, rotation): dt = 0.02 self.ralph.setH(self.ralph.getH() + rotation * dt) self.ralph.setY(self.ralph, self._speed * dt) for _ in range(5): random.choice(self.pieces).step(dt) f = taskMgr.getAllTasks()[-1].getFunction() f(None) f = taskMgr.getAllTasks()[2].getFunction() f(None) entries = (self.ralphGroundHandler.getEntries()) if len(entries) > 0: self.reset() return 1 else: return 0 def resetGame(self): while True: self.reset() for p in self.pieces: p.reset() if 0 == self.step(0): break def renderFrame(self): base.graphicsEngine.renderFrame() def getDepthMapT(self): tex = self.depthmap #tex = self.altBuffer.getTexture() r = tex.getRamImage() s = r.getData() i = np.fromstring(s, dtype='float32') i = i.reshape((self.img_size, self.img_size)) i = np.flipud(i) return i
class RoamingPenguinDemo(ShowBase): def __init__(self): # Set up the window, camera, etc. ShowBase.__init__(self) # This is used to store which keys are currently pressed. self.keyMap = { "left": 0, "right": 0, "forward": 0, "backward": 0, "cam-left": 0, "cam-right": 0, } ########################################################################### self.environ = loader.loadModel("models/world") self.environ.reparentTo(render) # We do not have a skybox, so we will just use a sky blue background color #self.setBackgroundColor(0.53, 0.80, 0.92, 1) self.setBackgroundColor(.1, .1, .1, 1) # Create the main character, person #personStartPos = self.environ.find("**/start_point").getPos() #self.person = Actor("models/panda", # {"run": "models/panda-walk", # "walk": "models/panda-walk"}) person2StartPos = self.environ.find("**/start_point").getPos() self.person2 = Actor("models/passenger_penguin", {"run": "models/passenger_penguin", "walk": "models/passenger_penguin"}) self.person2.reparentTo(render) self.person2.setScale(.1) self.person2.setPos(person2StartPos + (px, py, 1)) person3StartPos = self.environ.find("**/start_point").getPos() self.person3 = Actor("models/MagicBunny", {"run": "models/MagicBunny", "walk": "models/MagicBunny"}) #px = random.randint(-1,1) #py = random.randint(-1,1) self.person3.reparentTo(render) self.person3.setScale(.04) #self.person.setPos(personStartPos + (0, 0, 2)) self.person3.setPos(person3StartPos + (px/1.5+3, py/2, 0)) personStartPos = self.environ.find("**/start_point").getPos() self.person = Actor("models/panda", {"run": "models/panda-walk", "walk": "models/panda-walk"}) self.person.reparentTo(render) self.person.setScale(.1) self.person.setPos(personStartPos + (0, 0, 1.5)) self.person.loop("run") arenaStartPos = self.environ.find("**/start_point").getPos() self.arena = Actor("models/FarmHouse") self.arena.reparentTo(render) self.arena.setScale(.1) self.arena.setPos(arenaStartPos + (-1, 0, 0)) arena2StartPos = self.environ.find("**/start_point").getPos() self.arena2 = Actor("models/fence") self.arena2.reparentTo(render) self.arena2.setScale(5.9) self.arena.setPos(arenaStartPos + (px, py-12, 1)) self.arena2.setPos(arenaStartPos + (8, 5, -1)) arena2StartPos = self.environ.find("**/start_point").getPos() self.arena3 = Actor("models/gate") self.arena3.reparentTo(render) self.arena3.setScale(.01) self.arena3.setPos(arenaStartPos + (px/2+random.randint(12,15), py/2, -1)) self.arena4 = Actor("models/FarmHouse") self.arena4.reparentTo(render) self.arena4.setScale(.1) self.arena4.setPos(arenaStartPos + (px/3-random.randint(18,22), py/3, -1)) self.arena5 = Actor("models/gate") self.arena5.reparentTo(render) self.arena5.setScale(.008) self.arena5.setPos(arenaStartPos + (px/1.2-9, py/1.2, -1)) ##################################################################################################################################### base.enableParticles() self.t = loader.loadModel("teapot") # for the particle enhancer self.t.setScale(10) self.t.setPos(-10, -20, -1) self.t.reparentTo(render) #self.setupLights() self.p = ParticleEffect() self.p.setScale(1000) self.loadParticleConfig('smoke.ptf') # looks like a storm at night self.p.setScale(20) #################################################3 # Create a floater object, which floats 2 units above person. We # use this as a target for the camera to look at. self.floater = NodePath(PandaNode("floater")) self.floater.reparentTo(self.person) self.floater.setZ(2.0) # Accept the control keys for movement and rotation taskMgr.add(self.move, "moveTask") # Set up the camera self.disableMouse() self.camera.setPos(self.person.getX(), self.person.getY() + 10, 2) self.cTrav = CollisionTraverser() self.personCol = CollisionNode('person') self.personCol.addSolid(CollisionSphere(center=(0, 0, 2), radius=1.5)) self.personCol.addSolid(CollisionSphere(center=(0, -0.25, 4), radius=1.5)) self.personCol.setFromCollideMask(CollideMask.bit(0)) self.personCol.setIntoCollideMask(CollideMask.allOff()) self.personColNp = self.person.attachNewNode(self.personCol) self.personPusher = CollisionHandlerPusher() self.personPusher.horizontal = True self.personPusher.addCollider(self.personColNp, self.person) self.cTrav.addCollider(self.personColNp, self.personPusher) self.personGroundRay = CollisionRay() self.personGroundRay.setOrigin(0, 0, 9) self.personGroundRay.setDirection(0, 0, -1) self.personGroundCol = CollisionNode('personRay') self.personGroundCol.addSolid(self.personGroundRay) self.personGroundCol.setFromCollideMask(CollideMask.bit(0)) self.personGroundCol.setIntoCollideMask(CollideMask.allOff()) self.personGroundColNp = self.person.attachNewNode(self.personGroundCol) self.personGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.personGroundColNp, self.personGroundHandler) self.camGroundRay = CollisionRay() self.camGroundRay.setOrigin(0, 0, 9) self.camGroundRay.setDirection(0, 0, -1) self.camGroundCol = CollisionNode('camRay') self.camGroundCol.addSolid(self.camGroundRay) self.camGroundCol.setFromCollideMask(CollideMask.bit(0)) self.camGroundCol.setIntoCollideMask(CollideMask.allOff()) self.camGroundColNp = self.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler) # Create some lighting ambientLight = AmbientLight("ambientLight") ambientLight.setColor((.3, .3, .3, .2)) directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection((-5, -5, -5)) directionalLight.setColor((.2, .2, .2, 1)) directionalLight.setSpecularColor((.1, .1, .1, 1)) render.setLight(render.attachNewNode(ambientLight)) render.setLight(render.attachNewNode(directionalLight)) def loadParticleConfig(self, filename): # Start of the code from steam.ptf self.p.cleanup() self.p = ParticleEffect() self.p.loadConfig(Filename(filename)) self.p.start(self.t) self.p.setPos(3.000, 0.000, 2.250) # Records the state of the arrow keys def setKey(self, key, value): self.keyMap[key] = value def move(self, task): dt = globalClock.getDt() #z = abs(py) self.person.setX(self.person, 4 * dt) self.person.setX(self.person, -4 * dt) ## this is how the Panda finds his friend if px < 0 : #if self.person.getPos() - self.person2.getPos() < (0, 0, 0) : if self.person.getY() - self.person2.getY() < 6 : #self.person.getPos(personStartPos + (0, py, 1.5)) self.person.setY(self.person, 0 * dt) self.person.stop() self.person.pose("walk", 5) self.isMoving = False else: self.person.setY(self.person, py * dt) self.person.setX(self.person, px * dt) self.person.setH(self.person, px/(abs(px)+6)* dt) else: if self.person.getY() - self.person2.getY() < 6 : #self.person.getPos(personStartPos + (0, py, 1.5)) self.person.setY(self.person, 0 * dt) self.person.stop() self.person.pose("walk", 5) self.isMoving = False else: self.person.setY(self.person, py * dt) self.person.setX(self.person, px * dt) self.person.setH(self.person, px/(abs(px)+6)* dt) if self.keyMap["cam-left"]: self.camera.setX(self.camera, -20 * dt) if self.keyMap["cam-right"]: self.camera.setX(self.camera, +20 * dt) camvec = self.person.getPos() - self.camera.getPos() camvec.setZ(0) camdist = camvec.length() camvec.normalize() if camdist > 10.0: self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10)) camdist = 10.0 if camdist < 5.0: self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist)) camdist = 5.0 entries = list(self.personGroundHandler.entries) entries.sort(key=lambda x: x.getSurfacePoint(render).getZ()) for entry in entries: if entry.getIntoNode().getName() == "terrain": self.person.setZ(entry.getSurfacePoint(render).getZ()) entries = list(self.camGroundHandler.entries) entries.sort(key=lambda x: x.getSurfacePoint(render).getZ()) for entry in entries: if entry.getIntoNode().getName() == "terrain": self.camera.setZ(entry.getSurfacePoint(render).getZ() + 3.5) if self.camera.getZ() < self.person.getZ() + 4.0: self.camera.setZ(self.person.getZ() + 4.0) self.camera.lookAt(self.floater) return task.cont
class GrenadeLauncher: """Grenade launcher locomotive upgrade. Represents an active weapon, which can do a lot of damage on some radius. Args: loc_model (panda3d.core.NodePath): The locomotive model. """ def __init__(self, loc_model): self.is_up = False # flag, which indicates if the launcher # is in (un-)loading process self._is_loading = False self._range_col_np = None self._loc_model = loc_model self._model = Actor(address("grenade_launcher")) self._model.reparentTo(loc_model) self._sight = loader.loadModel(address("grenade_sight")) # noqa: F821 self._sight.reparentTo(loc_model) self._sight.hide() self._grenade_explosion = ParticleEffect() self._grenade_explosion.loadConfig("effects/grenade_explode.ptf") self._grenade_smoke = ParticleEffect() self._grenade_smoke.loadConfig("effects/bomb_smoke1.ptf") self._hole_sprite = loader.loadModel(address("ground_hole")) # noqa: F821 self._hole_sprite.reparentTo(loc_model) self._hole_sprite.setTransparency(TransparencyAttrib.MAlpha) self._hole_sprite.hide() base.accept("1", self.change_state) # noqa: F821 self._shot_snd = loader.loadSfx( # noqa: F821 "sounds/combat/grenade_launcher_shot.ogg" ) self._explosion_snd = loader.loadSfx( # noqa: F821 "sounds/combat/bomb_explosion1.ogg" ) self._explosion_snd.setVolume(0.15) self._load_snd = loader.loadSfx( # noqa: F821 "sounds/combat/grenade_launcher_load.ogg" ) def _change_mode(self, task): """Change controls mode - common or grenade launcher shooting.""" if self.is_up: self._sight.hide() self._end_aiming() else: self._smoke = ParticleEffect() self._smoke.loadConfig("effects/grenade_launcher_smoke.ptf") self._smoke.setPos(0.026, -0.15, 0.35) taskMgr.doMethodLater( # noqa: F821 0.05, self._sight.show, "show_sight", extraArgs=[] ) base.common_ctrl.deselect() # noqa: F821 self._start_aiming() self.is_up = not self.is_up self._is_loading = False return task.done def change_state(self): """Change the launcher state.""" if not base.world.is_on_et or self._is_loading: # noqa: F821 return base.train.disable_enabled_weapon(self) # noqa: F821 self._is_loading = True self._model.setPlayRate(-4 if self.is_up else 4, "gun_up") self._model.play("gun_up") if not self.is_up: self._load_snd.play() taskMgr.doMethodLater( # noqa: F821 0.2, self._change_mode, "grenade_launcher_aim" ) def _do_grenade_damage(self, event): """Event which is called by the grenade explosion. The method do damage to the enemy units, which were in the grenade explosion area. """ base.world.enemy.active_units[ # noqa: F821 event.getFromNodePath().getName() ].get_damage(40) def _end_aiming(self): """Stop aiming and disable aiming GUI.""" self._range_col_np.removeNode() base.common_ctrl.set_mouse_events() # noqa: F82 def _explode_grenade(self, grenade_pos): """Explode the grenade, shot from the launcher. Args: grenade_pos (panda3d.core.Point3): The position, where the sight was when player made the shot. """ col_node = CollisionNode("grenade_explosion") col_node.setFromCollideMask(NO_MASK) col_node.setIntoCollideMask(SHOT_RANGE_MASK) col_node.addSolid(CollisionSphere(0, 0, 0, 0.096)) base.accept("into-grenade_explosion", self._do_grenade_damage) # noqa: F821 col_np = self._model.attachNewNode(col_node) col_np.setPos(grenade_pos) self._hole_sprite.setPos(grenade_pos) self._hole_sprite.wrtReparentTo( base.world.current_block.rails_mod # noqa: F821 ) self._hole_sprite.show() self._grenade_explosion.setPos(grenade_pos) self._grenade_explosion.start(self._model, render) # noqa: F821 self._grenade_explosion.softStart() self._grenade_smoke.setPos(grenade_pos) self._grenade_smoke.start(self._model, render) # noqa: F82 self._grenade_smoke.softStart() self._explosion_snd.play() taskMgr.doMethodLater( # noqa: F821 1, self._grenade_explosion.softStop, "stop_grenade_explosion", extraArgs=[] ) taskMgr.doMethodLater( # noqa: F821 2.5, self._grenade_smoke.softStop, "stop_grenade_smoke", extraArgs=[] ) taskMgr.doMethodLater( # noqa: F821 0.1, col_np.removeNode, "remove_grenade_solid", extraArgs=[] ) taskMgr.doMethodLater( # noqa: F821 4, self._return_hole_sprite, "hide_ground_hole", ) def _return_hole_sprite(self, task): """Return the hole sprite to the grenade launcher model.""" self._hole_sprite.hide() self._hole_sprite.reparentTo(self._loc_model) return task.done def _move_sight(self, event): """Move the launcher sight sprite. The launcher sight can be moved only within the Train part shooting range. """ if event.getIntoNodePath().getName() != "grenade_launcher_range": return point = event.getSurfacePoint(base.train.model) # noqa: F821 self._sight.setPos(point.getX(), point.getY(), 0.01) def _shot(self): """Make a shot.""" self._shot_snd.play() self.change_state() base.ignore("1") # noqa: F82 self._smoke.start(self._model, render) # noqa: F82 self._smoke.softStart() taskMgr.doMethodLater( # noqa: F82 0.5, self._explode_grenade, "explode_grenade", extraArgs=[self._sight.getPos()], ) taskMgr.doMethodLater( # noqa: F82 1.45, self._stop_smoke, "stop_launcher_smoke" ) taskMgr.doMethodLater( # noqa: F82 13, base.accept, # noqa: F82 "unblock_launcher", extraArgs=["1", self.change_state], ) base.train.make_shot("Grenade Launcher") # noqa: F82 def _start_aiming(self): """Show aiming GUI and tweak shooting events.""" col_node = CollisionNode("grenade_launcher_range") col_node.setFromCollideMask(NO_MASK) col_node.setIntoCollideMask(MOUSE_MASK) col_node.addSolid( CollisionPolygon( Point3(-1.2, -0.3, 0), Point3(-1.2, 1.5, 0), Point3(1.2, 1.5, 0), Point3(1.2, -0.3, 0), ) ) self._range_col_np = base.train.model.attachNewNode(col_node) # noqa: F821 base.accept("mouse1", self._shot) # noqa: F821 base.accept("mouse_ray-into", self._move_sight) # noqa: F821 base.accept("mouse_ray-again", self._move_sight) # noqa: F82 def _stop_smoke(self, task): """Stop the launcher shot smoke.""" self._smoke.disable() self._smoke.cleanup() return task.done
class World(DirectObject): def __init__(self): self.startvar = 0 self.startdialog = YesNoDialog(dialogName="START GAME", text="START GAME", command=self.endbox) self.timepass = model() self.timepass1 = model1() self.keyMap = {"left": 0, "right": 0, "forward": 0, "backward": 0} base.win.setClearColor(Vec4(0, 0, 0, 1)) # number of collectibles self.numObjects = 0 #music self.backmusic = base.loader.loadSfx("sounds/tales.mp3") self.backmusic.setLoop(True) self.backmusic.setVolume(0.2) self.backmusic.play() self.skatemusic = base.loader.loadSfx("sounds/skate.mp3") self.skatemusic.setVolume(.65) self.skatemusic.setLoop(True) self.bombmusic = base.loader.loadSfx("sounds/bomb.mp3") self.bombmusic.setVolume(.85) self.springmusic = base.loader.loadSfx("sounds/spring.mp3") self.springmusic.setVolume(.65) self.springmusic.setLoop(True) self.colmusic = base.loader.loadSfx("sounds/collect.mp3") self.colmusic.setVolume(.65) # print the number of objects printNumObj(self.numObjects) # Post the instructions # self.title = addTitle("Roaming Ralph (Edited by Adam Gressen)") # self.inst1 = addInstructions(0.95, "[ESC]: Quit") # self.inst2 = addInstructions(0.90, "[A]: Rotate Ralph Left") # self.inst3 = addInstructions(0.85, "[D]: Rotate Ralph Right") # self.inst4 = addInstructions(0.80, "[W]: Run Ralph Forward") # self.inst5 = addInstructions(0.75, "[S]: Run Ralph Backward") # self.inst6 = addInstructions(0.70, "[Space]: Run, Ralph, Run") # 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.environ = loader.loadModel("models/world") self.environ.reparentTo(render) self.environ.setPos(0, 0, 0) # Timer to increment in the move task self.time = 0 # Get bounds of environment min, max = self.environ.getTightBounds() self.mapSize = max - min # Create the main character, Ralph self.ralphStartPos = self.environ.find("**/start_point").getPos() self.ralph = Actor( "models/ralph", { "run": "models/ralph-run", "jump": "models/ralph-jump", "walk": "models/ralph-walk" }) self.ralph.reparentTo(render) self.ralph.setScale(.30) self.ralph.setPos(self.ralphStartPos) #skate self.skate = loader.loadModel("models/Skateboard") self.skate.reparentTo(render) self.skate.setScale(.02) self.skate.setPos(-random.randint(38, 50), -random.randint(15, 37), -0.015) # ralph's health self.health = 100 #spring self.spring = loader.loadModel("models/spring") self.spring.reparentTo(render) self.spring.setScale(.8) self.spring.setPos(-random.randint(72, 78), -random.randint(10, 15), 6.715) # ralph's stamina self.stamina = 100 # 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 self.accept("escape", sys.exit) # these don't work well in combination with the space bar 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("arrow_down", self.setKey, ["backward", 1]) 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("arrow_down-up", self.setKey, ["backward", 0]) self.accept("a", self.setKey, ["left", 1]) self.accept("d", self.setKey, ["right", 1]) self.accept("w", self.setKey, ["forward", 1]) self.accept("s", self.setKey, ["backward", 1]) self.accept("a-up", self.setKey, ["left", 0]) self.accept("d-up", self.setKey, ["right", 0]) self.accept("w-up", self.setKey, ["forward", 0]) self.accept("s-up", self.setKey, ["backward", 0]) # Game state variables self.isMoving = False self.isRunning = False self.onboard = 0 self.boardtime = 0 self.onspring = 0 self.isjumping = False # Set up the camera base.disableMouse() #base.camera.setPos(self.ralph.getX(),self.ralph.getY()+10,2) base.camera.setPos(0, 0, 0) base.camera.reparentTo(self.ralph) base.camera.setPos(0, 40, 2) base.camera.lookAt(self.ralph) # 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. base.cTrav = CollisionTraverser() self.ralphGroundRay = CollisionRay() self.ralphGroundRay.setOrigin(0, 0, 300) 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) # camera ground collision handler self.camGroundRay = CollisionRay() self.camGroundRay.setOrigin(0, 0, 300) 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 = base.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() base.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler) # Place the health items self.placeHealthItems() # Place the collectibles self.placeCollectibles() # Place the bomb self.placebombItems() # Uncomment this line to show a visual representation of the # collisions occuring #base.cTrav.showCollisions(render) # 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)) #print self.startvar taskMgr.add(self.move, "moveTask") #taskMgr.doMethodLater(0.5, self.healthDec, "healthTask") # Display ralph's health def displayHealth(self): healthBar['scale'] = (self.health * 0.01 * BAR_WIDTH, 0.2, 0.2) # Display ralph's stamina def displayStamina(self): sprintBar['scale'] = (self.stamina * 0.01 * BAR_WIDTH, 0.2, 0.2) # Allow ralph to collect the health items def collectHealthItems(self, entry): # refill ralph's health self.colmusic.play() if (self.health < 100): self.health = self.health + 15.5 # reposition the collectible self.placeItem(entry.getIntoNodePath().getParent()) def collectCollectibles(self, entry): # remove the collectible #entry.getIntoNodePath().getParent().removeNode() self.colmusic.play() self.placeItem(entry.getIntoNodePath().getParent()) # update the number of objects self.numObjects += 1 #self.tot=10-self.numObjects printNumObj(self.numObjects) def blastbomb(self): # remove the collectible #self.placeItem(entry.getIntoNodePath().getParent()) # blast self.fire = loader.loadModel("models/fire") self.fire.reparentTo(render) self.fire.setScale(.01) self.fire.setHpr(0, -90, 0) self.bombmusic.play() self.backmusic.stop() self.fire.setPos(self.ralph.getPos()) self.die() # Places an item randomly on the map def placeItem(self, item): # Add ground collision detector to the health item self.collectGroundRay = CollisionRay() self.collectGroundRay.setOrigin(0, 0, 300) self.collectGroundRay.setDirection(0, 0, -1) self.collectGroundCol = CollisionNode('colRay') self.collectGroundCol.addSolid(self.collectGroundRay) self.collectGroundCol.setFromCollideMask(BitMask32.bit(0)) self.collectGroundCol.setIntoCollideMask(BitMask32.allOff()) self.collectGroundColNp = item.attachNewNode(self.collectGroundCol) self.collectGroundHandler = CollisionHandlerQueue() base.cTrav.addCollider(self.collectGroundColNp, self.collectGroundHandler) placed = False while placed == False: # re-randomize position item.setPos(-random.randint(-40, 140), -random.randint(-40, 40), 0) base.cTrav.traverse(render) # Get Z position from terrain collision entries = [] for j in range(self.collectGroundHandler.getNumEntries()): entry = self.collectGroundHandler.getEntry(j) 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"): item.setZ(entries[0].getSurfacePoint(render).getZ() + 1) placed = True # remove placement collider self.collectGroundColNp.removeNode() def placeHealthItems(self): self.placeholder = render.attachNewNode("HealthItem-Placeholder") self.placeholder.setPos(0, 0, 0) # Add the health items to the placeholder node for i in range(5): # Load in the health item model self.healthy = loader.loadModel("models/sphere") self.healthy.setPos(0, 0, 0) self.healthy.setScale(.4) self.healthy.reparentTo(self.placeholder) self.placeItem(self.healthy) # Add spherical collision detection healthSphere = CollisionSphere(0, 0, 0, 1.4) sphereNode = CollisionNode('healthSphere') sphereNode.addSolid(healthSphere) sphereNode.setFromCollideMask(BitMask32.allOff()) sphereNode.setIntoCollideMask(BitMask32.bit(0)) sphereNp = self.healthy.attachNewNode(sphereNode) sphereColHandler = CollisionHandlerQueue() base.cTrav.addCollider(sphereNp, sphereColHandler) #bomb def placebombItems(self): self.placebomb = render.attachNewNode("bomb-Placeholder") self.placebomb.setPos(0, 0, 0) # Add the bomb items to the placeholder node for i in range(30): # Load in the health item model self.bomby = loader.loadModel("models/bomb") self.bomby.setPos(0, 0, 0) self.bomby.setScale(.4) self.bomby.reparentTo(self.placebomb) self.placeItem(self.bomby) # Add spherical collision detection bombSphere = CollisionSphere(0, 0, 0, 1.4) sphereNode = CollisionNode('bombSphere') sphereNode.addSolid(bombSphere) sphereNode.setFromCollideMask(BitMask32.allOff()) sphereNode.setIntoCollideMask(BitMask32.bit(0)) sphereNp = self.bomby.attachNewNode(sphereNode) sphereColHandler = CollisionHandlerQueue() base.cTrav.addCollider(sphereNp, sphereColHandler) #blue def placeCollectibles(self): self.placeCol = render.attachNewNode("Collectible-Placeholder") self.placeCol.setPos(0, 0, 0) # Add the health items to the placeCol node for i in range(50): # Load in the health item model self.collect = loader.loadModel("models/jack") self.collect.setPos(0, 0, 0) self.collect.setScale(.4) self.collect.reparentTo(self.placeCol) self.placeItem(self.collect) # Add spherical collision detection colSphere = CollisionSphere(0, 0, 0, 1.4) sphereNode = CollisionNode('colSphere') sphereNode.addSolid(colSphere) sphereNode.setFromCollideMask(BitMask32.allOff()) sphereNode.setIntoCollideMask(BitMask32.bit(0)) sphereNp = self.collect.attachNewNode(sphereNode) sphereColHandler = CollisionHandlerQueue() base.cTrav.addCollider(sphereNp, sphereColHandler) #Records the state of the arrow keys def setKey(self, key, value): self.keyMap[key] = value # Makes ralph's health decrease over time # Accepts arrow keys to move either the player or the menu cursor, # Also deals with grid checking and collision detection def move(self, task): #print self.ralph.getPos() self.time += globalClock.getDt() timeText['text'] = str(self.time) # save ralph's initial position so that we can restore it, # in case he falls off the map or runs into something. startpos = self.ralph.getPos() # If a move-key is pressed, move ralph in the specified direction. # and rotate the camera to remain behind ralph if (self.keyMap["left"] != 0) and (self.onboard == 0): self.ralph.setH(self.ralph.getH() + 100 * globalClock.getDt()) if (self.keyMap["right"] != 0) and (self.onboard == 0): self.ralph.setH(self.ralph.getH() - 100 * globalClock.getDt()) if (self.keyMap["forward"] != 0) and (self.onboard == 0): self.ralph.setY(self.ralph, -45 * globalClock.getDt()) if (self.keyMap["backward"] != 0) and (self.onboard == 0): self.ralph.setY(self.ralph, 45 * globalClock.getDt()) if (self.keyMap["forward"] != 0) and (self.onboard == 0) and (self.onspring > 0): self.ralph.setY(self.ralph, -65 * globalClock.getDt()) if (self.keyMap["backward"] != 0) and (self.onboard == 0) and (self.onspring > 0): self.ralph.setY(self.ralph, +65 * globalClock.getDt()) # If ralph is moving, loop the run animation. # If he is standing still, stop the animation. if (self.isMoving): if (self.health <= 0): self.ralph.setPos(10000, 10000, 1000) self.ralph.stop() self.blastbomb() else: self.health -= .07 if ((self.keyMap["forward"] != 0) or (self.keyMap["left"] != 0) or (self.keyMap["right"] != 0) or (self.keyMap["backward"] != 0)) and (self.onboard == 0): if self.isMoving is False: self.ralph.loop("run") self.isMoving = True else: if self.isMoving and (self.onspring == 0): self.ralph.stop() self.ralph.pose("walk", 5) self.isMoving = False #skate if (math.fabs(self.skate.getX() - self.ralph.getX()) < 2) and (math.fabs(self.skate.getY() - self.ralph.getY()) < 5) and (self.onspring == 0) and (self.onboard == 0): self.onboard = 1 self.ralph.stop() self.ralph.pose("walk", 5) self.isMoving = False self.isjumping = False self.skatemusic.play() if (self.onboard == 1): if (self.keyMap["left"] != 0): self.ralph.setH(self.ralph.getH() + 60 * globalClock.getDt()) self.skate.setH(self.ralph.getH()) if (self.keyMap["right"] != 0): self.ralph.setH(self.ralph.getH() - 60 * globalClock.getDt()) self.skate.setH(self.ralph.getH()) if (self.keyMap["forward"] != 0): self.ralph.setY(self.ralph, -100 * globalClock.getDt()) self.skate.setY(self.ralph.getY()) self.skate.setZ(self.ralph.getZ()) self.skate.setX(self.ralph.getX()) if (self.keyMap["backward"] != 0): self.ralph.setY(self.ralph, 100 * globalClock.getDt()) self.skate.setY(self.ralph.getY()) self.skate.setZ(self.ralph.getZ()) self.skate.setX(self.ralph.getX()) self.boardtime = self.boardtime + 1 #self.ralph.stop() #self.ralph.pose("walk",5) #print self.onboard if (self.boardtime == 1000): self.onboard = 0 self.boardtime = 0 self.skate.setPos(-random.randint(72, 78), -random.randint(10, 15), 6.715) self.skatemusic.stop() #spring #spring if (math.fabs(self.spring.getX() - self.ralph.getX()) < 2) and (math.fabs(self.spring.getY() - self.ralph.getY()) < 2) and (self.onboard == 0) and (self.onspring == 0): self.onspring = 500 self.springmusic.play() self.spring.setPos(-random.randint(38, 50), -random.randint(15, 37), -0.015) if (self.onspring > 0): self.onspring = self.onspring - 1 #print self.onspring if (self.isjumping is False): self.ralph.loop("jump") self.isjumping = True else: #print self.ralph.getX() if self.isjumping: if ((self.keyMap["forward"] != 0) or (self.keyMap["left"] != 0) or (self.keyMap["right"] != 0)): self.ralph.loop("run") self.isMoving = True else: self.ralph.stop() self.ralph.pose("walk", 5) self.isjumping = False self.onspring = 0 self.springmusic.stop() # so the following line is unnecessary 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. 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()) #base.camera.setZ(entries[0].getSurfacePoint(render).getZ()+5) elif (len(entries) > 0) and (entries[0].getIntoNode().getName() == "healthSphere"): self.collectHealthItems(entries[0]) elif (len(entries) > 0) and (entries[0].getIntoNode().getName() == "colSphere"): self.collectCollectibles(entries[0]) elif (len(entries) > 0) and (entries[0].getIntoNode().getName() == "bombSphere"): self.blastbomb() else: self.ralph.setPos(startpos) # Keep the camera above the terrain 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"): modZ = entries[0].getSurfacePoint(render).getZ() base.camera.setZ(10.0 + modZ + (modZ - self.ralph.getZ())) self.floater.setPos(self.ralph.getPos()) self.floater.setZ(self.ralph.getZ() + 2.0) base.camera.lookAt(self.floater) self.displayHealth() return task.cont # End def die(self): # end all running tasks self.ralph.setPos(10000, 10000, 10000) taskMgr.remove("moveTask") taskMgr.remove("healthTask") self.ralph.stop() self.skatemusic.stop() self.springmusic.stop() self.backmusic.stop() colObj = self.numObjects myscore = str(colObj) self.highscore = OkDialog(dialogName="highscoreDialog", text="Your Score: " + myscore, command=self.endResult) # Handle the dialog result def endResult(self, arg): sys.exit() def endbox(self, arg): if (arg): self.startvar = 1 self.startdialog.cleanup() # restart the game #self.restart() else: sys.exit()
class World(DirectObject): def __init__(self): ## Add the default values to the dictionary. self.keyMap = {"left":0, "right":0, "forward":0, \ "boost":0, "strafeL":0, "strafeR":0, \ "cam-left":0, "cam-right":0} base.win.setClearColor(Vec4(0, 0, 0, 1)) self.jump = False self.jumped = False # Post the instructions self.title = addTitle( "Panda3D Tutorial: Roaming Ralph (Walking on Uneven Terrain)") self.inst1 = addInstructions(0.95, "[ESC]: Quit") self.inst2 = addInstructions(0.90, "[Left Arrow]: Rotate Ralph Left") self.inst3 = addInstructions(0.85, "[Right Arrow]: Rotate Ralph Right") self.inst4 = addInstructions(0.80, "[Up Arrow]: Run Ralph Forward") self.inst6 = addInstructions(0.70, "[A]: Rotate Camera Left") self.inst7 = addInstructions(0.65, "[D]: Rotate Camera Right") self.inst8 = addInstructions(0.60, "[B]: Ralph Boost") self.inst9 = addInstructions(0.55, "[V]: Strafe Left") self.inst10 = addInstructions(0.50, "[N]: Strafe Right") # 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.environ = loader.loadModel("models/world") self.environ.reparentTo(render) self.environ.setPos(0, 0, 0) ## Stops the sound as soon as the world renders ## Note:Sound won't play very long becasue the game takes seconds to compile and load ## Remove loading screen after world is rendered and ready to go. loadingText.cleanup() mySound.stop() # Create the main character, Ralph ralphStartPos = self.environ.find("**/start_point").getPos() self.ralph = Actor("models/ralph", { "run": "models/ralph-run", "walk": "models/ralph-walk" }) self.ralph.reparentTo(render) self.ralph.setScale(.2) self.ralph.setPos(ralphStartPos) # 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 self.accept("escape", sys.exit) 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("d", self.setKey, ["cam-right", 1]) self.accept("b", self.setKey, ["boost", 1]) self.accept("v", self.setKey, ["strafeL", 1]) self.accept("n", self.setKey, ["strafeR", 1]) ## -up to signify what happens when you let go of the key self.accept("b-up", self.setKey, ["boost", 0]) self.accept("v-up", self.setKey, ["strafeL", 0]) self.accept("n-up", self.setKey, ["strafeR", 0]) 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("d-up", self.setKey, ["cam-right", 0]) taskMgr.add(self.move, "moveTask") # Game state variables self.isMoving = False # Set up the camera base.disableMouse() base.camera.setPos(self.ralph.getX(), self.ralph.getY() + 10, 2) # 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.cTrav = CollisionTraverser() 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() self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler) 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 = base.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler) # 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) # 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 setZ(self, task): x = self.ralph.getX() y = self.ralph.getY() z = self.ralph.getZ() self.ralph.setPos(x, y, 0) self.jumped = False # Accepts arrow keys to move either the player or the menu cursor, # Also deals with grid checking and collision detection def move(self, task): # If the camera-left key is pressed, move camera left. # If the camera-right key is pressed, move camera right. base.camera.lookAt(self.ralph) if (self.keyMap["cam-left"] != 0): base.camera.setX(base.camera, -50 * globalClock.getDt()) # Increased camera rotation speed to match rotation speed of Ralph if (self.keyMap["cam-right"] != 0): base.camera.setX(base.camera, +50 * globalClock.getDt()) # save ralph's initial position so that we can restore it, # in case he falls off the map or runs into something. startpos = self.ralph.getPos() # If a move-key is pressed, move ralph in the specified direction. if (self.keyMap["left"] != 0): self.ralph.setH(self.ralph.getH() + 300 * globalClock.getDt()) if (self.keyMap["right"] != 0): self.ralph.setH(self.ralph.getH() - 300 * globalClock.getDt()) if (self.keyMap["forward"] != 0): self.ralph.setY(self.ralph, -25 * globalClock.getDt()) ## What to do if b was pressed? if (self.keyMap["boost"] != 0): self.jump = True # What to do if n is pressed # Ralph will strafe right. If b is also pressed, Ralph will strafe to the right quicker if (self.keyMap["strafeR"] != 0): self.ralph.setX(self.ralph, -25 * globalClock.getDt()) if (self.keyMap["strafeL"] != 0): self.ralph.setX(self.ralph, 25 * globalClock.getDt()) # If ralph is moving, loop the run animation. # If he is standing still, stop the animation. # Function to make Ralph jump up the y-axis and fall back down # when 'j' is released ## Add boost, strafeL, and strafeR to the animation alteration conditions here. if (self.keyMap["forward"]!=0) or (self.keyMap["left"]!=0) \ or (self.keyMap["right"]!=0) or (self.keyMap["boost"]!=0) \ or (self.keyMap["strafeL"]!=0) or (self.keyMap["strafeR"]!=0): if self.isMoving is False: self.ralph.loop("run") self.isMoving = True else: if self.isMoving: self.ralph.stop() self.ralph.pose("walk", 5) self.isMoving = False # If the camera is too far from ralph, move it closer. # If the camera is too close to ralph, move it farther. camvec = self.ralph.getPos() - base.camera.getPos() camvec.setZ(0) camdist = camvec.length() camvec.normalize() if (camdist > 10.0): base.camera.setPos(base.camera.getPos() + camvec * (camdist - 10)) camdist = 10.0 if (camdist < 5.0): base.camera.setPos(base.camera.getPos() - camvec * (5 - camdist)) 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.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"): if self.jump is True: self.ralph.setZ(entries[0].getSurfacePoint(render).getZ() + 1) self.jumped = True self.jump = False else: if self.jumped is True: taskMgr.doMethodLater(0.1, self.setZ, 'setZ') else: self.ralph.setZ(entries[0].getSurfacePoint(render).getZ()) else: self.ralph.setPos(startpos) # Keep the camera at one foot above the terrain, # or two feet above ralph, 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"): base.camera.setZ(entries[0].getSurfacePoint(render).getZ() + 1.0) if (base.camera.getZ() < self.ralph.getZ() + 2.0): base.camera.setZ(self.ralph.getZ() + 2.0) # The camera should look in ralph's direction, # but it should also try to stay horizontal, so look at # a floater which hovers above ralph's head. self.floater.setPos(self.ralph.getPos()) self.floater.setZ(self.ralph.getZ() + 2.0) base.camera.lookAt(self.floater) return task.cont
class Game(ShowBase): def __init__(self): ShowBase.__init__(self) self.disableMouse() properties = WindowProperties() properties.setSize(1000, 750) self.win.requestProperties(properties) mainLight = DirectionalLight("main light") self.mainLightNodePath = render.attachNewNode(mainLight) self.mainLightNodePath.setHpr(45, -45, 0) render.setLight(self.mainLightNodePath) ambientLight = AmbientLight("ambient light") ambientLight.setColor(Vec4(0.2, 0.2, 0.2, 1)) self.ambientLightNodePath = render.attachNewNode(ambientLight) render.setLight(self.ambientLightNodePath) render.setShaderAuto() self.environment = loader.loadModel("Models/Misc/environment") self.environment.reparentTo(render) self.tempActor = Actor("Models/PandaChan/act_p3d_chan", {"walk" : "Models/PandaChan/a_p3d_chan_run"}) self.tempActor.getChild(0).setH(180) self.tempActor.reparentTo(render) self.tempActor.loop("walk") self.camera.setPos(0, 0, 32) self.camera.setP(-90) self.keyMap = { "up" : False, "down" : False, "left" : False, "right" : False, "shoot" : False } self.accept("w", self.updateKeyMap, ["up", True]) self.accept("w-up", self.updateKeyMap, ["up", False]) self.accept("s", self.updateKeyMap, ["down", True]) self.accept("s-up", self.updateKeyMap, ["down", False]) self.accept("a", self.updateKeyMap, ["left", True]) self.accept("a-up", self.updateKeyMap, ["left", False]) self.accept("d", self.updateKeyMap, ["right", True]) self.accept("d-up", self.updateKeyMap, ["right", False]) self.accept("mouse1", self.updateKeyMap, ["shoot", True]) self.accept("mouse1-up", self.updateKeyMap, ["shoot", False]) self.pusher = CollisionHandlerPusher() self.cTrav = CollisionTraverser() self.pusher.setHorizontal(True) colliderNode = CollisionNode("player") colliderNode.addSolid(CollisionSphere(0, 0, 0, 0.3)) collider = self.tempActor.attachNewNode(colliderNode) base.pusher.addCollider(collider, self.tempActor) base.cTrav.addCollider(collider, self.pusher) wallSolid = CollisionTube(-8.0, 0, 0, 8.0, 0, 0, 0.2) wallNode = CollisionNode("wall") wallNode.addSolid(wallSolid) wall = render.attachNewNode(wallNode) wall.setY(8.0) wallSolid = CollisionTube(-8.0, 0, 0, 8.0, 0, 0, 0.2) wallNode = CollisionNode("wall") wallNode.addSolid(wallSolid) wall = render.attachNewNode(wallNode) wall.setY(-8.0) wallSolid = CollisionTube(0, -8.0, 0, 0, 8.0, 0, 0.2) wallNode = CollisionNode("wall") wallNode.addSolid(wallSolid) wall = render.attachNewNode(wallNode) wall.setX(8.0) wallSolid = CollisionTube(0, -8.0, 0, 0, 8.0, 0, 0.2) wallNode = CollisionNode("wall") wallNode.addSolid(wallSolid) wall = render.attachNewNode(wallNode) wall.setX(-8.0) self.updateTask = taskMgr.add(self.update, "update") def updateKeyMap(self, controlName, controlState): self.keyMap[controlName] = controlState def update(self, task): dt = globalClock.getDt() if self.keyMap["up"]: self.tempActor.setPos(self.tempActor.getPos() + Vec3(0, 5.0*dt, 0)) if self.keyMap["down"]: self.tempActor.setPos(self.tempActor.getPos() + Vec3(0, -5.0*dt, 0)) if self.keyMap["left"]: self.tempActor.setPos(self.tempActor.getPos() + Vec3(-5.0*dt, 0, 0)) if self.keyMap["right"]: self.tempActor.setPos(self.tempActor.getPos() + Vec3(5.0*dt, 0, 0)) if self.keyMap["shoot"]: print ("Zap!") return Task.cont
class Terrain(DirectObject): def __init__(self): #load the wall terrain model self.wall_terrain = loader.loadModel("wall_terrain.egg") self.wall_terrain.reparentTo(render) self.wall_terrain.setScale(.85) #load the jumps and floor terrain model self.ground_terrain = loader.loadModel("ground_terrain.egg") self.ground_terrain.reparentTo(render) self.ground_terrain.setScale(.85) #set a collide mask #self.terrain.setCollideMask(BitMask32.allOff()) #self.terrain.setCollideMask(BitMask32.bit(0)) self.ground_terrain.setCollideMask(2) self.wall_terrain.setCollideMask(1) taskMgr.add(self.powerUpUpdate, "powerUpTask") #setup walls #wall1 wall1 = CollisionPlane(Plane(Vec3(-1, 0, 0), Point3(82, -77, 77))) cNodeWall1 = CollisionNode("wall1") cNodeWall1.addSolid(wall1) cNodeWall1.setIntoCollideMask(1) self.cNodePathWall1 = render.attachNewNode(cNodeWall1) #self.cNodePathWall1.show() #wall 2 wall2 = CollisionPlane(Plane(Vec3(1, 0, 0), Point3(-82, -77, 77))) cNodeWall2 = CollisionNode("wall2") cNodeWall2.addSolid(wall2) cNodeWall2.setIntoCollideMask(1) self.cNodePathWall2 = render.attachNewNode(cNodeWall2) #self.cNodePathWall2.show() #wall3 wall3 = CollisionPlane(Plane(Vec3(0, -1, 0), Point3(82, 82, 77))) cNodeWall3 = CollisionNode("wall3") cNodeWall3.addSolid(wall3) cNodeWall3.setIntoCollideMask(1) self.cNodePathWall3 = render.attachNewNode(cNodeWall3) #self.cNodePathWall3.show() #wall4 wall4 = CollisionPlane(Plane(Vec3(0, 1, 0), Point3(82, -82, 77))) cNodeWall4 = CollisionNode("wall4") cNodeWall4.addSolid(wall4) cNodeWall4.setIntoCollideMask(1) self.cNodePathWall4 = render.attachNewNode(cNodeWall4) #self.cNodePathWall4.show() #setup power up collision spheres and the associated model #powerup1 collision sphere (invincibility) self.shield = Actor('shield.egg', {'rotate':'shield_anim.egg'}) self.shield.reparentTo(render) self.shield.setPos(0, -.3, 16.5) self.shield.setScale(0.5) self.shield.loop('rotate') cPowerSphere1 = CollisionSphere((0,0,0),8) cPowerNode1 = CollisionNode("powerup1") cPowerNode1.addSolid(cPowerSphere1) cPowerNode1.setIntoCollideMask(1) self.cPowerNode1Path = self.shield.attachNewNode(cPowerNode1) #self.cPowerNode1Path.show() self.powerUp1 = True self.powerUp1Count = 0 #powerup2 collision sphere (matched with powerup3) self.shotgun = Actor('shotgun.egg', {'rotate':'shotgun_anim.egg'}) self.shotgun.reparentTo(render) self.shotgun.setPos(.5, 77, 18.5) self.shotgun.setScale(0.5) self.shotgun.loop('rotate') cPowerSphere2 = CollisionSphere((0,0,0),8) cPowerNode2 = CollisionNode("powerup2") cPowerNode2.addSolid(cPowerSphere2) cPowerNode2.setIntoCollideMask(1) self.cPowerNode2Path = self.shotgun.attachNewNode(cPowerNode2) #self.cPowerNode2Path.show() self.powerUp2 = True self.powerUp2Count = 0 #powerup3 collision sphere (matched with powerup2) self.shotgun2 = Actor('shotgun.egg', {'rotate':'shotgun_anim.egg'}) self.shotgun2.reparentTo(render) self.shotgun2.setPos(.5, -77, 18.5) self.shotgun2.setScale(0.5) self.shotgun2.loop('rotate') cPowerSphere3 = CollisionSphere((0,0,0),8) cPowerNode3 = CollisionNode("powerup3") cPowerNode3.addSolid(cPowerSphere3) cPowerNode3.setIntoCollideMask(1) self.cPowerNode3Path = self.shotgun2.attachNewNode(cPowerNode3) #self.cPowerNode3Path.show() self.powerUp3 = True self.powerUp3Count = 0 #powerup4 collision sphere (matched with powerup5) self.health = Actor('health.egg', {'rotate':'health_anim.egg'}) self.health.reparentTo(render) self.health.setPos(77, -1, 18.5) self.health.setScale(0.5) self.health.loop('rotate') cPowerSphere4 = CollisionSphere((0,0,0),8) cPowerNode4 = CollisionNode("powerup4") cPowerNode4.addSolid(cPowerSphere4) cPowerNode4.setIntoCollideMask(1) self.cPowerNode4Path = self.health.attachNewNode(cPowerNode4) #self.cPowerNode4Path.show() self.powerUp4 = True self.powerUp4Count = 0 #powerup5 collision sphere (matched with powerup4) self.health2 = Actor('health.egg', {'rotate':'health_anim.egg'}) self.health2.reparentTo(render) self.health2.setPos(-77, -1, 18.5) self.health2.setScale(0.5) self.health2.loop('rotate') cPowerSphere5 = CollisionSphere((0,0,0),8) cPowerNode5 = CollisionNode("powerup5") cPowerNode5.addSolid(cPowerSphere5) cPowerNode5.setIntoCollideMask(1) self.cPowerNode5Path = self.health2.attachNewNode(cPowerNode5) #self.cPowerNode5Path.show() self.powerUp5 = True self.powerUp5Count = 0 #setup lights for outer box plight5 = PointLight('plight1') plight5.setColor(VBase4(1,1,1,1)) plight5.setAttenuation(Point3(0,0,.01)) plnp5 = render.attachNewNode(plight5) plnp5.setPos(-37.5,39.5,13.5) render.setLight(plnp5) plight6 = PointLight('plight1') plight6.setColor(VBase4(1,1,1,1)) plight6.setAttenuation(Point3(0,0,.01)) plnp6 = render.attachNewNode(plight6) plnp6.setPos(37.5,39.5,13.5) render.setLight(plnp6) plight7 = PointLight('plight1') plight7.setColor(VBase4(1,1,1,1)) plight7.setAttenuation(Point3(0,0,.01)) plnp7 = render.attachNewNode(plight7) plnp7.setPos(37.5,-39.5,13.5) render.setLight(plnp7) plight8 = PointLight('plight1') plight8.setColor(VBase4(1,1,1,1)) plight8.setAttenuation(Point3(0,0,.01)) plnp8 = render.attachNewNode(plight8) plnp8.setPos(-37.5,-39.5,13.5) render.setLight(plnp8) def powerUpUpdate(self, task): #check powerup1 if self.powerUp1 == False: #print('increasing count') self.powerUp1Count += 1 if self.powerUp1Count == 500: #print('making a new one') self.powerUp1 = True self.powerUp1Count = 0 self.shield = Actor('shield.egg', {'rotate':'shield_anim.egg'}) self.shield.reparentTo(render) self.shield.setPos(0, -.3, 16.5) self.shield.setScale(0.5) self.shield.loop('rotate') cPowerSphere1 = CollisionSphere((0,0,0),8) cPowerNode1 = CollisionNode("powerup1") cPowerNode1.addSolid(cPowerSphere1) cPowerNode1.setIntoCollideMask(1) self.cPowerNode1Path = self.shield.attachNewNode(cPowerNode1) #check powerup2 if self.powerUp2 == False: #print('increasing count') self.powerUp2Count += 1 if self.powerUp2Count == 250: #print('making a new one') self.powerUp2 = True self.powerUp2Count = 0 self.shotgun = Actor('shotgun.egg', {'rotate':'shotgun_anim.egg'}) self.shotgun.reparentTo(render) self.shotgun.setPos(.5, 77, 18.5) self.shotgun.setScale(0.5) self.shotgun.loop('rotate') cPowerSphere2 = CollisionSphere((0,0,0),8) cPowerNode2 = CollisionNode("powerup2") cPowerNode2.addSolid(cPowerSphere2) cPowerNode2.setIntoCollideMask(1) self.cPowerNode2Path = self.shotgun.attachNewNode(cPowerNode2) #check powerup3 if self.powerUp3 == False: #print('increasing count') self.powerUp3Count += 1 if self.powerUp3Count == 250: #print('making a new one') self.powerUp3 = True self.powerUp3Count = 0 self.shotgun2 = Actor('shotgun.egg', {'rotate':'shotgun_anim.egg'}) self.shotgun2.reparentTo(render) self.shotgun2.setPos(.5, -77, 18.5) self.shotgun2.setScale(0.5) self.shotgun2.loop('rotate') cPowerSphere3 = CollisionSphere((0,0,0),8) cPowerNode3 = CollisionNode("powerup3") cPowerNode3.addSolid(cPowerSphere3) cPowerNode3.setIntoCollideMask(1) self.cPowerNode3Path = self.shotgun2.attachNewNode(cPowerNode3) #check powerup4 if self.powerUp4 == False: #print('increasing count') self.powerUp4Count += 1 if self.powerUp4Count == 250: #print('making a new one') self.powerUp4 = True self.powerUp4Count = 0 self.health = Actor('health.egg', {'rotate':'health_anim.egg'}) self.health.reparentTo(render) self.health.setPos(77, -1, 18.5) self.health.setScale(0.5) self.health.loop('rotate') cPowerSphere4 = CollisionSphere((0,0,0),8) cPowerNode4 = CollisionNode("powerup4") cPowerNode4.addSolid(cPowerSphere4) cPowerNode4.setIntoCollideMask(1) self.cPowerNode4Path = self.health.attachNewNode(cPowerNode4) #check powerup5 if self.powerUp5 == False: #print('increasing count') self.powerUp5Count += 1 if self.powerUp5Count == 250: #print('making a new one') self.powerUp5 = True self.powerUp5Count = 0 self.health2 = Actor('health.egg', {'rotate':'health_anim.egg'}) self.health2.reparentTo(render) self.health2.setPos(-77, -1, 18.5) self.health2.setScale(0.5) self.health2.loop('rotate') cPowerSphere5 = CollisionSphere((0,0,0),8) cPowerNode5 = CollisionNode("powerup5") cPowerNode5.addSolid(cPowerSphere5) cPowerNode5.setIntoCollideMask(1) self.cPowerNode5Path = self.health2.attachNewNode(cPowerNode5) return Task.cont
class moveMario(ShowBase): def __init__(self): # Set up the window, camera, etc. ShowBase.__init__(self) self.ser = serial.Serial('/dev/tty.usbmodem1421', 9600) # Set the background color to black self.win.setClearColor((0, 0, 0, 1)) # This is used to store which keys are currently pressed. self.keyMap = { "left": 0, "right": 0, "forward": 0, "reverse": 0, "cam-left": 0, "cam-right": 0 } #Initialize Track self.track = self.loader.loadModel("luigi_circuit") self.track.setScale(1.5) self.track.reparentTo(render) #Intitial where Mario needs to be #marioStartPos = self.track.find("**/start_point").getPos() marioStartPos = Vec3(50, -29, 0.35) #Actual start possition #Using ralph because the model is made with correct collision masking and animation self.marioActor = Actor("models/ralph", { "run": "models/ralph-run", "walk": "models/ralph-walk" }) self.marioActor.setScale(0.1, 0.1, 0.1) self.marioActor.setH(self.marioActor, 270) self.marioActor.reparentTo(self.render) self.marioActor.setPos(marioStartPos + (0, 0, 0.5)) #Floater above so Camera has something to look at self.floater = NodePath(PandaNode("floater")) self.floater.reparentTo(self.marioActor) self.floater.setZ(2.0) taskMgr.add(self.move, "moveTask") # Game state variables self.isMoving = False # Set up the camera self.disableMouse() self.camera.setPos(self.marioActor.getX() + 100, self.marioActor.getY(), 1) #Collision Rays self.cTrav = CollisionTraverser() self.marioGroundRay = CollisionRay() self.marioGroundRay.setOrigin(0, 0, 9) self.marioGroundRay.setDirection(0, 0, -1) self.marioGroundCol = CollisionNode('marioRay') self.marioGroundCol.addSolid(self.marioGroundRay) self.marioGroundCol.setFromCollideMask(CollideMask.bit(0)) self.marioGroundCol.setIntoCollideMask(CollideMask.allOff()) self.marioGroundColNp = self.marioActor.attachNewNode( self.marioGroundCol) self.marioGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.marioGroundColNp, self.marioGroundHandler) self.camGroundRay = CollisionRay() self.camGroundRay.setOrigin(0, 0, 9) self.camGroundRay.setDirection(0, 0, -1) self.camGroundCol = CollisionNode('camRay') self.camGroundCol.addSolid(self.camGroundRay) self.camGroundCol.setFromCollideMask(CollideMask.bit(0)) self.camGroundCol.setIntoCollideMask(CollideMask.allOff()) self.camGroundColNp = self.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler) # Records the state of the arrow keys def setKey(self, key, value): self.keyMap[key] = value def move(self, task): elapsed = globalClock.getDt() # If a move-key is pressed, move Mario in the specified direction. startpos = self.marioActor.getPos() line = self.ser.readline() listOfCoord = line.split(":") if (len(listOfCoord) == 7): x = listOfCoord[1] g = listOfCoord[3] r = listOfCoord[5] if (10 <= float(x) <= 180): #MAKE IT TURN RIGHT self.setKey("right", True) self.setKey("left", False) elif (180 < float(x) <= 350): #MAKE IT TURN LEFT self.setKey("right", False) self.setKey("left", True) else: self.setKey("right", False) self.setKey("left", False) #Make it move forward if (int(g) == 1): self.setKey("forward", True) else: self.setKey("forward", False) #Make it move in Reverse if (int(r) == 1): self.setKey("reverse", True) else: self.setKey("reverse", False) if self.keyMap["left"]: self.marioActor.setH(self.marioActor.getH() + 50 * elapsed) self.camera.setX(self.camera, +5 * elapsed) if self.keyMap["right"]: self.marioActor.setH(self.marioActor.getH() - 50 * elapsed) self.camera.setX(self.camera, -5 * elapsed) if self.keyMap["forward"]: self.marioActor.setY(self.marioActor, -100 * elapsed) if self.keyMap["reverse"]: self.marioActor.setY(self.marioActor, 100 * elapsed) #When moving - run the animation - Taken from roaming ralph example if self.keyMap["forward"] or self.keyMap["left"] or self.keyMap[ "right"]: if self.isMoving is False: self.marioActor.loop("run") self.isMoving = True else: if self.isMoving: self.marioActor.stop() self.marioActor.pose("walk", 5) self.isMoving = False #Camera uses - modified from roaming ralph camvec = self.marioActor.getPos() - self.camera.getPos() camvec.setZ(0) camdist = camvec.length() camvec.normalize() if camdist > 5.0: self.camera.setPos(self.camera.getPos() + camvec * (camdist - 5)) camdist = 5.0 if camdist < 2.5: self.camera.setPos(self.camera.getPos() - camvec * (2.5 - camdist)) camdist = 2.5 #Collission terrain checking - taken from roaming ralph entries = list(self.marioGroundHandler.getEntries()) entries.sort(key=lambda x: x.getSurfacePoint(render).getZ()) if len(entries) > 0 and entries[0].getIntoNode().getName( ) == "terrain": self.marioActor.setZ(entries[0].getSurfacePoint(render).getZ()) else: self.marioActor.setPos(startpos) # Keep the camera at level - taken from roaming ralph entries = list(self.camGroundHandler.getEntries()) entries.sort(key=lambda x: x.getSurfacePoint(render).getZ()) if len(entries) > 0 and entries[0].getIntoNode().getName( ) == "terrain": self.camera.setZ(entries[0].getSurfacePoint(render).getZ() + 1.0) if self.camera.getZ() < self.marioActor.getZ() + 1.0: self.camera.setZ(self.marioActor.getZ() + 1.0) self.camera.lookAt(self.floater) return task.cont
class RaceDrone(ShowBase): def __init__(self): ShowBase.__init__(self) # initalize the window base.disableMouse() self.win.setClearColor((0, 0, 0, 1)) props = WindowProperties() props.setCursorHidden(True) props.setSize(1700,1000) base.win.requestProperties(props) # store keys self.keyMap = { "left": 0, "right": 0, "forward": 0, "backward": 0, "drift-left": 0, "drift-right": 0, "up": 0, "down": 0, "restart": 0, "firstPerson": 0, "gravity": 0} #instructions self.ins2 = addInstructions(0.12, "[Left/Right Arrow]: Rotate Left/Right") self.ins3 = addInstructions(0.18, "[Up/Down Arrow]: Fly Forward/Backward") self.ins4 = addInstructions(0.24, "[A, D]: Move Camera") self.ins5 = addInstructions(0.30, "[W, S]: Lift / Descent") self.ins6 = addInstructions(0.36, "[F]: Toggle First Person/ Third Person") self.ins7 = addInstructions(0.42, "[G]: Toggle Gravity") self.ins8 = addInstructions(0.48, "[R]: Restart") # Set up the playground # other maps: # models/toon/phase_15/hood/toontown_central.bam # models/world # CS_Map/myCSMAP.egg # Race/RaceTrack/FullTrack.blend self.environ = loader.loadModel("models/world") self.environ.reparentTo(render) self.mapScale = 1 """ self.environ = loader.loadModel("The City/The City.obj") self.environ.reparentTo(render) myTexture = loader.loadTexture("The City/Maps/cty1.jpg") self.environ.setTexture(myTexture) self.environ.setHpr(0,90,0) self.environ.setScale(.1) """ # Create drone and initalize drone position self.Drone = Actor("models/mydrone.egg") self.Drone.reparentTo(render) # resize and reposition the drone self.Drone.setScale(.1) self.Drone.setPos(5,5,8) self.Drone.setH(180) # initial position is saved for restarting the game self.DroneStartPos = self.Drone.getPos() # User Controls self.accept('escape', __import__('sys').exit, [0]) self.accept("arrow_left", self.setKey, ["left", True]) self.accept("arrow_right", self.setKey, ["right", True]) self.accept("arrow_up", self.setKey, ["forward", True]) self.accept("arrow_down", self.setKey, ["backward", True]) self.accept("a", self.setKey, ["drift-left", True]) self.accept("d", self.setKey, ["drift-right", True]) self.accept("arrow_left-up", self.setKey, ["left", False]) self.accept("arrow_right-up", self.setKey, ["right", False]) self.accept("arrow_up-up", self.setKey, ["forward", False]) self.accept("arrow_down-up", self.setKey, ["backward", False]) self.accept("a-up", self.setKey, ["drift-left", False]) self.accept("d-up", self.setKey, ["drift-right", False]) self.accept("w", self.setKey, ["up", True]) self.accept("w-up", self.setKey, ["up", False]) self.accept("s", self.setKey, ["down", True]) self.accept("s-up", self.setKey, ["down", False]) self.accept("r", self.setKey, ["restart", True]) self.accept("r-up", self.setKey, ["restart", False]) self.accept("f", self.setKey, ["firstPerson", True]) self.accept("f-up", self.setKey, ["firstPerson", False]) self.accept("g", self.setKey, ["gravity", True]) self.accept("g-up", self.setKey, ["gravity", False]) taskMgr.add(self.move, "moveTask") # Disable Mouse self.disableMouse() # Camera settings self.cameraDistance = 5 self.cameraPitch = -10 # create the collision box for the drone # this collision box will be used for collision detection self.droneBox = CollisionBox((0,0,2.5), 3, 3, 0.7) self.cnodePath = self.Drone.attachNewNode(CollisionNode('cnode')) self.cnodePath.node().addSolid(self.droneBox) # collision detection set up self.cTrav = CollisionTraverser() self.queue = CollisionHandlerQueue() self.cTrav.addCollider(self.cnodePath, self.queue) self.cTrav.traverse(render) # Lighting portion are modified from an example provided by Panda3d – Roaming Ralph ambientLight = AmbientLight("ambientLight") ambientLight.setColor((1, 1, 1, 1)) directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection((-5, -5, -5)) directionalLight.setColor((1, 1, 1, 1)) directionalLight.setSpecularColor((1, 1, 1, 1)) render.setLight(render.attachNewNode(ambientLight)) render.setLight(render.attachNewNode(directionalLight)) # Crashed Text self.crashed = OnscreenText() self.firstPerson = False # HPR setting self.angle = 0 self.angleChange = 0.5 self.maxAngle = 15 # Speed Control self.FBSpeed = self.mapScale * 6 self.LRSpeed = self.mapScale * 4 self.turnSpeed = 80 self.liftSpeed = self.mapScale * 80 self.downSpeed = self.mapScale * 80 # AI set up self.AI = True if self.AI: self.droneAI = Actor("models/mydrone.egg") self.droneAI.reparentTo(render) self.droneAI.setScale(.1) self.droneAI.setPos(5,5,5) self.AI_actions = open("AI/RoamingRalph/AI_easy.txt", "r").readlines() ####################### # additional features # ####################### # acceleration self.FBacceleration = 0 self.LRacceleration = 0 self.accelMax = 40 self.accelIncrement = 2 # gravity self.gravity = True self.gravity_value = 15 * self.mapScale # Record user inputs def setKey(self, key, value): self.keyMap[key] = value # Main Function (Deal with user interface and collision detection) def move(self, task): #debug #print(self.queue.getEntries()) #print(self.drone.getPos()) #print(self.FBacceleration, self.LRacceleration) # crash message self.crashed.destroy() self.crashed = OnscreenText(text="Crashed!!!" if len(self.queue.getEntries()) != 0 else "", pos = (-0.5, 0.02), scale = 0.07, mayChange = True, fg = (255,255,255,1)) # Get the time that elapsed since last frame. dt = globalClock.getDt() # control the movement of AI if self.AI: if self.AI_actions != []: curAction = self.AI_actions[0].split(" ") self.droneAI.setX(float(curAction[0])) self.droneAI.setY(float(curAction[1])) self.droneAI.setZ(float(curAction[2])) self.droneAI.setH(float(curAction[3])) self.droneAI.setP(float(curAction[4])) self.droneAI.setR(float(curAction[5])) self.AI_actions.pop(0) # Drone is movable only when it's not crashed if len(self.queue.getEntries()) == 0: # initial height curHeight = self.Drone.getZ() # move by acceleration if self.FBacceleration != 0: self.Drone.setX(self.Drone, self.FBSpeed * self.FBacceleration * dt) self.FBacceleration += 1 if self.FBacceleration < 0 else -1 if self.LRacceleration != 0: self.Drone.setY(self.Drone, self.LRSpeed * self.LRacceleration * dt) self.LRacceleration += 1 if self.LRacceleration < 0 else -1 self.Drone.setZ(curHeight) # tilting while drift left and right if self.keyMap["drift-left"]: #self.Drone.setY(self.Drone, self.LRSpeed * dt) # tilt left when drift left if self. angle > -self.maxAngle: self.angle -= self.angleChange self.Drone.setP(self.angle) if self.LRacceleration < self.accelMax: self.LRacceleration += self.accelIncrement elif self.keyMap["drift-right"]: #self.Drone.setY(self.Drone, -self.LRSpeed * dt) # tilt right when drift right if self. angle < self.maxAngle: self.angle += self.angleChange self.Drone.setP(self.angle) if self.LRacceleration > -self.accelMax: self.LRacceleration -= self.accelIncrement # gradually stablize itself while drift-keys are not pressed else: if self.angle >=self.angleChange: self.angle -= self.angleChange elif self.angle <=-self.angleChange: self.angle +=self.angleChange self.Drone.setP(self.angle) # turn left if self.keyMap["left"]: self.Drone.setH(self.Drone.getH() + self.turnSpeed * dt) # turn right if self.keyMap["right"]: self.Drone.setH(self.Drone.getH() - self.turnSpeed * dt) # go forward if self.keyMap["forward"]: #self.Drone.setX(self.Drone, self.FBSpeed * dt) if self.FBacceleration < self.accelMax: self.FBacceleration += self.accelIncrement elif self.keyMap["backward"]: #self.Drone.setX(self.Drone, -self.FBSpeed * dt) if self.FBacceleration > -self.accelMax: self.FBacceleration -= self.accelIncrement # lift up if self.keyMap["up"]: self.Drone.setZ(self.Drone, self.liftSpeed * dt) # go down if self.keyMap["down"]: self.Drone.setZ(self.Drone, -self.downSpeed * dt) # gravity if self.gravity: self.Drone.setZ(self.Drone, -self.gravity_value * dt) # restart game / reset position if self.keyMap["restart"]: self.Drone.setPos(self.DroneStartPos + (0, 0, 5)) self.collisionCount = False self.crashed.destroy() self.Drone.setH(180) # First Person View / Third Person View Toggle if self.keyMap["firstPerson"]: self.firstPerson = not self.firstPerson # Gravity Toggle if self.keyMap["gravity"]: self.gravity = not self.gravity # uncomment the following code to see the collision box ######################## #self.cnodePath.show() # ######################## # set the position and HPR of the camera according to the position of the drone # First Person View if self.firstPerson: base.camera.setH(self.Drone.getH()-90) base.camera.setP(self.Drone.getR()) base.camera.setR(self.Drone.getP()) base.camera.setPos(self.Drone.getPos()) # Third Person View else: base.camera.setHpr(self.Drone.getHpr()+(180,0,0)) h,p,r = self.Drone.getHpr() base.camera.setPos(self.Drone.getPos() + (math.cos(math.pi * h / 180) * -self.cameraDistance, \ math.sin(math.pi * h / 180) * -self.cameraDistance, 0.5)) viewTarget = Point3(self.Drone.getPos() + (0,0,0)) # the look-at point can be changed base.camera.lookAt(viewTarget) return task.cont
class Swifter: def __init__(self, model, run, walk, idle, jump, crouch, crouchWalk, startPos, scale): #(self, model, run, walk, startPos, scale): """Initialise the character. Arguments: model -- The path to the character's model file (string) run : The path to the model's run animation (string) walk : The path to the model's walk animation (string) startPos : Where in the world the character will begin (pos) scale : The amount by which the size of the model will be scaled (float) """ #Define movement map and speeds self.speedSprint = 20 self.speedWalk = 7 self.speedCrouch = 5 self.speed = self.speedWalk #Capture control status self.isMoving = False self.isJumping = False self.isIdle = False self.isCrouching = False self.movementMap = {"forward":Vec3(0,-self.speed,0), "back":Vec3(0,self.speed,0), \ "left":Vec3(self.speed,0,0), "right":Vec3(-self.speed,0,0), \ "crouch":0, "sprint":0, "jump":1, "punch":0, "kick":0, "stop":Vec3(0), "changeView":0} #Set up key state variables self.strafe_left = self.movementMap["stop"] self.strafe_right = self.movementMap["stop"] self.forward = self.movementMap["stop"] self.back = self.movementMap["stop"] self.jump = False self.sprint = False self.crouch = False #Stop player by default self.walk = self.movementMap["stop"] self.strafe = self.movementMap["stop"] #Define the actor and his animations self.actor = Actor(model, {"run":run, "walk":walk, "idle":idle, "jump":jump, "crouch":crouch, "crouchWalk":crouchWalk}) #self.actor.enableBlend() self.actor.setBlend(frameBlend = True)#Enable interpolation self.actor.reparentTo(render) self.actor.setScale(scale) self.actor.setPos(startPos) #Set up FSM controller self.FSM = ActorFSM(self.actor) taskMgr.add(self.move,"moveTask") # Note: deriving classes DO NOT need # to add their own move tasks to the # task manager. If they override # self.move, then their own self.move # function will get called by the # task manager (they must then # explicitly call Character.move in # that function if they want it). self.prevtime = 0 # 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.cTrav = CollisionTraverser() self.groundRay = CollisionRay() self.groundRay.setOrigin(0,0,1000) self.groundRay.setDirection(0,0,-1) self.groundCol = CollisionNode('actorRay') self.groundCol.addSolid(self.groundRay) self.groundCol.setFromCollideMask(BitMask32.bit(1)) self.groundCol.setIntoCollideMask(BitMask32.allOff()) self.groundColNp = self.actor.attachNewNode(self.groundCol) self.groundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.groundColNp, self.groundHandler) # Uncomment this line to see the collision rays self.groundColNp.show() #Uncomment this line to show a visual representation of the #collisions occuring self.cTrav.showCollisions(render) """ def jumpUpdate(self,task): # this task simulates gravity and makes the player jump # get the highest Z from the down casting ray highestZ = -100 for i in range(self.nodeGroundHandler.getNumEntries()): entry = self.nodeGroundHandler.getEntry(i) z = entry.getSurfacePoint(self.render).getZ() if z > highestZ and entry.getIntoNode().getName() == "Cube": highestZ = z # gravity effects and jumps self.node.setZ(self.node.getZ()+self.jump*globalClock.getDt()) self.jump -= 1*self.globalClock.getDt() if highestZ > self.node.getZ()-.3: self.jump = 0 self.node.setZ(highestZ+.3) if self.readyToJump: self.jump = 1 return task.cont """ def move(self, task): """Move and animate the character for one frame. This is a task function that is called every frame by Panda3D. The character is moved according to which of it's movement controls are set, and the function keeps the character's feet on the ground and stops the character from moving if a collision is detected. This function also handles playing the characters movement animations. Arguments: task -- A direct.task.Task object passed to this function by Panda3D. Return: Task.cont -- To tell Panda3D to call this task function again next frame. """ elapsed = task.time - self.prevtime # save the character's initial position so that we can restore it, # in case he falls off the map or runs into something. startpos = self.actor.getPos() #Calculate stateful movement self.walk = self.forward + self.back self.strafe = self.strafe_left + self.strafe_right # move the character if any of the move controls are activated. self.actor.setPos(self.actor,self.walk*globalClock.getDt()*self.speed) self.actor.setPos(self.actor,self.strafe*globalClock.getDt()*self.speed) #If strafing rotate the model -90 / 90 degrees to go in the direction specified #if going backwards rotate model 180 degrees # If the character is moving, loop the run animation. # If he is standing still, stop the animation. ##CALLL CONTROLLER CLASS AND CALL FSM's INSTEAD OF DOING IT HERE #Decide what type of movement anim to use if(self.sprint is True): #If we are sprinting.. self.walkAnim = 'Run' self.speed = self.speedSprint elif(self.crouch is True): # Can't sprint while crouching ;) #If we are crouching.. print ("Crouching!") self.walkAnim = "CrouchWalk" self.idleAnim = "Crouch" self.speed = self.speedCrouch else: #Otherwise were walking.. self.walkAnim = 'Walk' self.idleAnim = 'Idle' self.speed = self.speedWalk #Idling if(self.isJumping is False and self.isMoving is False and self.isIdle is True and self.FSM.state != self.idleAnim): #If were not moving and not jumping and were supposed to be idle, play the idle anim if we aren't already self.FSM.request(self.idleAnim,1) #We are idle, feel free to do something else, setting isIdle = False. print ("We are Idle but ready to do something: isIdle = False") elif(self.isJumping is False and self.isMoving is False and self.isIdle is False): #If were not moving or jumping, were not doing anything, we should probably be idle if we aren't already self.isIdle = True #locomotion #TODO: Separate out into animations for forward, back and side stepping if( (self.walk != self.movementMap["stop"] or self.strafe != self.movementMap["stop"]) and self.isJumping is False): #Check if actor is walking forward/back if(self.walk != self.movementMap["stop"]): if(self.isMoving is False or self.FSM.state != self.walkAnim): self.isMoving = True # were now moving self.isIdle = False # were not idle right now self.FSM.request(self.walkAnim,1) print ("Started running or walking") #Check if actor is strafing if(self.strafe != self.movementMap["stop"]): if(self.isMoving is False or self.FSM.state != self.walkAnim): #MAKE THE NODE ROTATE SO THE LEGS POINT THE DIRECTION MOVING #myLegRotate = actor.controlJoint(None,"modelRoot",) #http://www.panda3d.org/manual/index.php/Controlling_a_Joint_Procedurally self.isMoving = True # were now moving self.isIdle = False # were not idle right now self.FSM.request(self.walkAnim,1) print ("Started running or walking") elif(self.isMoving is True and self.isIdle is False): #Only switch of isMoving if we were moving and not idle self.isMoving = False print ("Finished walking") #if were moving, set isMoving = 1 and call walking FSM ''' Jumping Check if the user is jumping, if they currently aren't jumping: make them not idle and mark them as jumping and request the Jump FSM. If the jump anim isn't playing but we were jumping, mark actor as not jumping. ''' if(self.jump is True): #if user pressed jump and were not already jumping, jump if(self.isJumping is False and self.FSM.state != 'Jump'): self.isJumping = True # were jumping self.isIdle = False # were not idle right now self.FSM.request('Jump',1) print ("Started jumping") #if we are jumping, check the anim has finished and stop jumping self.JumpQuery = self.actor.getAnimControl('jump') if(self.isJumping is True and self.JumpQuery.isPlaying() is False): self.isJumping = False # finished jumping print ("Finished Jumping") # Now check for collisions. self.cTrav.traverse(render) # Adjust the character's Z coordinate. If the character'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.groundHandler.getNumEntries()): entry = self.groundHandler.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.actor.setZ(entries[0].getSurfacePoint(render).getZ()) else: self.actor.setPos(startpos) # Store the task time and continue. self.prevtime = task.time return Task.cont def setMove(self, key, moveType): """ Used by keyboard setup This gets the input from keyBoardSetup and will capture inputs """ if (moveType == "strafe_left"): self.strafe_left = self.movementMap[key] if (moveType == "strafe_right"): self.strafe_right = self.movementMap[key] if (moveType == "forward"): self.forward = self.movementMap[key] if (moveType == "back"): self.back = self.movementMap[key] if (moveType == "sprint"): self.sprint = key if (moveType == "jump"): self.jump = key if (moveType == "crouch"): self.crouch = key
class PandaHW(ShowBase): def __init__(self): messenger.toggleVerbose() ShowBase.__init__(self) self.environ = self.loader.loadModel("models/falcon") self.environ.reparentTo(self.render) self.environ.setScale(0.25, 0.25, 0.25) self.environ.setPos(-8, 42, 0) self.taskMgr.add(self.spinCameraTask, "SpinCameraTask") self.taskMgr.add(self.moveCameraTask, "MoveCameraTask") self.taskMgr.add(self.playerGravity, "PlayerGravity") #self.taskMgr.add(self.collTask, "CollisionTask") self.pandaActor = Actor("models/panda-model", {"walk": "models/panda-walk4"}) self.pandaActor.setScale(0.005, 0.005, 0.005) self.pandaActor.setPos(0, 0, 10) self.pandaActor.reparentTo(self.render) # Initialize the collision traverser. self.cTrav = CollisionTraverser() self.cTrav.showCollisions(self.render) # Initialize the Pusher collision handler. pusher = CollisionHandlerPusher() # Create a collision node for this object. cNode = CollisionNode('panda') # Attach a collision sphere solid to the collision node. cNode.addSolid(CollisionSphere(0, 0, 0, 600)) # Attach the collision node to the object's model. pandaC = self.pandaActor.attachNewNode(cNode) # Set the object's collision node to render as visible. pandaC.show() # Create a collsion node for this object. cNode = CollisionNode('environnement') # Attach a collision sphere solid to the collision node. cNode.addSolid(CollisionSphere(-1.3, 19, 0.5, 2.5)) cNode.addSolid(CollisionPlane(Plane(Vec3(0,0,1), Point3(0,0,0.2)))) # Attach the collision node to the object's model. environC = self.environ.attachNewNode(cNode) # Set the object's collision node to render as visible. environC.show() # Add the Pusher collision handler to the collision traverser. self.cTrav.addCollider(pandaC, pusher) # Add the 'frowney' collision node to the Pusher collision handler. pusher.addCollider(pandaC, self.environ, base.drive.node()) fromObject = self.pandaActor.attachNewNode(CollisionNode('colNode')) fromObject.node().addSolid(CollisionRay(0, 0, 0, 0, 0, -1)) lifter = CollisionHandlerFloor() lifter.addCollider(fromObject, self.pandaActor) self.cTrav.addCollider(pandaC, lifter) # Have the 'smiley' sphere moving to help show what is happening. #frowney.posInterval(5, Point3(5, 25, 0), startPos=Point3(-5, 25, 0), fluid=1).loop() #self.stuff = Actor("models/panda-model") #self.stuff.setScale(0.005, 0.005, 0.005) #self.stuff.setPos(-1.3, 19., 0.5) #self.stuff.reparentTo(self.render) # cTrav = CollisionTraverser() # ceh = CollisionHandlerQueue() # #ceh.addInPattern('%fn-into-%in') # #ceh.addAgainPattern('%fn-again-%in') # #ceh.addOutPattern('%fn-outof-%in') # self.pandaColl = self.pandaActor.attachNewNode(CollisionNode('cnode')) # self.pandaColl.node().addSolid(CollisionSphere(self.pandaActor.getChild( 0 ).getBounds( ).getCenter(), 400)) # self.pandaColl.show() # cTrav.addCollider( self.pandaColl, ceh ) # self.cTrav = cTrav # self.cTrav.showCollisions(self.render) # self.queue = ceh # cs = CollisionSphere(-1.3, 19, 0.5, 2.5) # pl = CollisionPlane(Plane(Vec3(0,0,1), Point3(0,0,0.2))) # # ray = CollisionRay(self.pandaActor.getPos(), Vec3(0,0,-1)) # cnodePath = self.render.attachNewNode(CollisionNode('cnode')) # # rayNodePath = self.render.attachNewNode(CollisionNode('raynode')) # cnodePath.node().addSolid(cs) # cnodePath.node().addSolid(pl) # # rayNodePath.node().addSolid(ray) # cnodePath.show() # # rayNodePath.show() # #rayNodePath.reparentTo(self.pandaActor) #self.accept('car-into-rail', handleRailCollision) #cTrav.addCollider(cnodePath, ceh) self.camera.reparentTo(self.pandaActor) self.camera.setPos(0., 1050., 1000.) self.camAlpha = 180 self.camBeta = 0 self.moving = [] self.playerAltitude = 0 self.jumping = False self.inJump = False self.playerFallingSpeed = 0 self.player = Mass(80) base.useDrive() #base.disableMouse( ) # disable the default camera controls that are created for us self.keyBoardSetup() def collEvent(self, entry): print "Collide event", entry # A task is a procedure that is called every frame def spinCameraTask(self, task): rotation_speed = 20 invert_camY = True w, h = self.getSize() if base.mouseWatcherNode.hasMouse(): cx = base.mouseWatcherNode.getMouseX() cy = base.mouseWatcherNode.getMouseY() self.camAlpha -= cx * rotation_speed self.camBeta -= (cy * rotation_speed) * (-1 if invert_camY else 1) for win in self.winList: if win.hasPointer(0): win.movePointer(0,w/2,h/2) self.pandaActor.setHpr(self.camAlpha, self.camBeta, 0.) self.camera.setHpr(180., -self.camBeta, 0.) return Task.cont def moveCameraTask(self, task): walk_speed = 1 newX = self.pandaActor.getX() newY = self.pandaActor.getY() newZ = self.pandaActor.getZ() if self.moving: self.pandaActor.loop("walk") else: self.pandaActor.stop() if 1 in self.moving: # Forward newX -= sin(degtorad(self.camAlpha)) * walk_speed newY += cos(degtorad(self.camAlpha)) * walk_speed newZ += sin(degtorad(self.camBeta)) * walk_speed if 2 in self.moving: # Backward newX += sin(degtorad(self.camAlpha)) * walk_speed newY -= cos(degtorad(self.camAlpha)) * walk_speed newZ -= sin(degtorad(self.camBeta)) * walk_speed if 3 in self.moving: # left newX -= cos(degtorad(self.camAlpha)) * walk_speed newY -= sin(degtorad(self.camAlpha)) * walk_speed if 4 in self.moving: # right newX += cos(degtorad(self.camAlpha)) * walk_speed newY += sin(degtorad(self.camAlpha)) * walk_speed newZ -= self.playerFallingSpeed #if newZ >= (self.playerAltitude - 0.1) and newZ <= (self.playerAltitude + 0.1) and not self.jumping: # Tolerance # newZ = self.playerAltitude self.pandaActor.setPos(newX, newY, newZ) self.player.pos = VBase3(newX, newY, newZ) return Task.cont def move(self, direction): if direction < 0 and -direction in self.moving: self.moving.remove(-direction) else: self.moving.append(direction) def playerGravity(self, task): self.player.simulate(task.time) self.pandaActor.setPos(self.player.pos) z = self.player.pos.getZ() pa = self.playerAltitude if self.jumping and z >= (pa - 0.1) and z <= (pa + 0.1): # Tolerance self.inJump = True self.player.vel = VBase3(0, 0, 0.05) self.player.force = VBase3(0, 0, 0) return Task.cont def jump(self, jumping = True): self.jumping = jumping def keyBoardSetup( self ): self.accept("escape", sys.exit ) key_directions = { "arrow_up": 1, "z" : 1, "arrow_down": 2, "s" : 2, "arrow_left": 3, "q" : 3, "arrow_right": 4, "d" : 4, } for key_name, direction in key_directions.items(): self.accept(key_name, self.move, [direction]) self.accept("%s-up" % (key_name,), self.move, [-direction]) self.accept("space", self.jump, [True]) self.accept("space-up", self.jump, [False])
class Character(DirectObject): def __init__(self, name, char_rig): from pandac.PandaModules import CollisionNode, CollisionRay, CollisionSphere self.name = name self.char_rig = char_rig self.actor = Actor('models/robot3', {'run': 'models/robot3-run'}) self.actor.setPlayRate(2.0, 'run') self.actor.reparentTo(self.char_rig) self.actor.setCompass() self.actor.setCollideMask(0) self.actor_from_floor = self.actor.attachNewNode( CollisionNode('blockchar_floor')) self.actor_from_floor.node().addSolid( CollisionRay(0, 0, 0.25, 0, 0, -10)) self.actor_from_floor.node().setCollideMask(0) self.actor_from_floor.node().setFromCollideMask(FLOOR_MASK) self.actor_from_obstacle = self.actor.attachNewNode( CollisionNode('blockchar_obstacle')) self.actor_from_obstacle.node().addSolid( CollisionSphere(0, 0, 0.35, 0.35)) self.actor_from_obstacle.node().setCollideMask(0) self.actor_from_obstacle.node().setFromCollideMask(OBSTACLE_MASK) self.actor_from_zone = self.actor.attachNewNode( CollisionNode('blockchar_zone')) self.actor_from_zone.node().addSolid(CollisionSphere(0, 0, 0.55, 0.55)) self.actor_from_zone.node().setCollideMask(0) self.actor_from_zone.node().setFromCollideMask(ZONE_MASK) self.move_forward = False self.move_left = False self.move_backward = False self.move_right = False self.moving = False self.spinning = False self.move_prev_time = None # Based on a jogging speed of 6mph self.move_speed = 2.7 # m/s def begin_forward(self): self.move_forward = True self.actor.loop('run') def begin_left(self): self.move_left = True self.actor.loop('run') def begin_backward(self): self.move_backward = True self.actor.loop('run') def begin_right(self): self.move_right = True self.actor.loop('run') def end_forward(self): self.move_forward = False def end_left(self): self.move_left = False def end_backward(self): self.move_backward = False def end_right(self): self.move_right = False def MoveTask(self, task): keys = 0 if self.move_left ^ self.move_right: keys += 1 if self.move_backward ^ self.move_forward: keys += 1 self.moving = False if keys and self.move_prev_time: heading = 0 if self.move_left and not self.move_right: heading += 90 elif self.move_right and not self.move_left: heading -= 90 if self.move_backward and not self.move_forward: if self.move_left and not self.move_right: heading += 180 else: heading -= 180 elif self.move_forward and not self.move_backward: heading += 0 heading /= keys speed = self.move_speed * (task.time - self.move_prev_time) if heading % 90 == 45: speed = 0.70710678118654746 * speed if heading == 0: vector = (0, speed, 0) elif heading == 45: vector = (-speed, speed, 0) elif heading == 90: vector = (-speed, 0, 0) elif heading == 135: vector = (-speed, -speed, 0) elif heading == -45: vector = (speed, speed, 0) elif heading == -90: vector = (speed, 0, 0) elif heading == -135: vector = (speed, -speed, 0) elif heading == -180: vector = (0, -speed, 0) h = self.actor.getH() rig_h = self.char_rig.getH() self.actor.setH(avg_deg_sign(h, rig_h + heading)) self.moving = True self.char_rig.setFluidPos(self.char_rig, *vector) print 'POSITION SET' else: self.actor.stop() self.move_prev_time = task.time return task.cont def begin_spin(self): self.spinning = True def end_spin(self): self.spinning = False self.prev_pos = None def spin(self, new_h): if self.spinning and not self.moving: char_new_h = avg_deg_sign(self.actor.getH(), new_h) self.actor.setH(char_new_h)
class World(DirectObject): def __init__(self): #Let's start the Music mySound = base.loader.loadSfx("music/music.mp3") mySound.setLoopCount(0) #And Keep it On Loop mySound.play() base.setFrameRateMeter(True) #Shows the FrameRate in The Top Corner self.walking = Vec3() self.isMoving = False self.dest = None base.win.setClearColor(Vec4(0,0,0,1)) self.keyMap = {"left":0, "right":0, "forward":0, "backward":0} base.win.setClearColor(Vec4(0,0,0,1)) #Here is the number of collectibles in the game self.rare = 1; self.vasenum = 10; self.coinnum = 30; self.silvernum = 5; self.chestnum = 2; #Here is the Obstacles in the game self.rocknum = 500; #Here is the Score self.score = 0; #Here is the total Number of Objects to collect self.numObjects = self.rare + self.vasenum + self.coinnum + self.silvernum + self.chestnum # print the number of objects printNumObj(self.score) # Post the instructions self.title = addTitle("Mighty Mountain") self.inst1 = addInstructions(0.95, "[ESC]: Quit") self.inst2 = addInstructions(0.90, "[A]: Rotate Ralph Left") self.inst3 = addInstructions(0.85, "[D]: Rotate Ralph Right") self.inst4 = addInstructions(0.80, "[W]: Run Ralph Forward") self.inst5 = addInstructions(0.75, "[S]: Run Ralph Backward") self.inst6 = addInstructions(0.70, "[Space]: Run, Ralph, Run") # 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.environ = loader.loadModel("models/world") self.environ.reparentTo(render) self.environ.setPos(0,0,0) # Timer to increment in the move task self.time = 0 # Get bounds of environment min, max = self.environ.getTightBounds() self.mapSize = max-min # Create the main character, Ralph self.ralphStartPos = self.environ.find("**/start_point").getPos() self.ralph = Actor("models/ralph", {"run":"models/ralph-run", "walk":"models/ralph-walk"}) self.ralph.reparentTo(render) self.ralph.setScale(.2) self.ralph.setPos(self.ralphStartPos) # ralph's stamina self.stamina = 200 # 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 self.accept("escape", self.endgame) # these don't work well in combination with the space bar 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("arrow_down", self.setKey, ["backward",1]) 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("arrow_down-up", self.setKey, ["backward",0]) self.accept("space", self.runRalph, [True]) self.accept("space-up", self.runRalph, [False]) self.accept("a", self.setKey, ["left",1]) self.accept("d", self.setKey, ["right",1]) self.accept("w", self.setKey, ["forward",1]) self.accept("s", self.setKey, ["backward",1]) self.accept("a-up", self.setKey, ["left",0]) self.accept("d-up", self.setKey, ["right",0]) self.accept("w-up", self.setKey, ["forward",0]) self.accept("s-up", self.setKey, ["backward",0]) # Game state variables self.isMoving = False self.isRunning = False # Set up the camera base.disableMouse() #base.camera.setPos(self.ralph.getX(),self.ralph.getY()+10,2) base.camera.setPos(0, 0, 0) base.camera.reparentTo(self.ralph) base.camera.setPos(0, 40, 2) base.camera.lookAt(self.ralph) # 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. base.cTrav = CollisionTraverser() self.ralphGroundRay = CollisionRay() self.ralphGroundRay.setOrigin(0,0,300) 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) # camera ground collision handler self.camGroundRay = CollisionRay() self.camGroundRay.setOrigin(0,0,300) 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 = base.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() base.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler) # Place the collectibles self.placeCollectibles() #Platinum self.placeVases() self.placeCoins() self.placeSilver() self.placeGold() self.placeChests() #Place the obstacles self.placeRocks() #Cactus # Uncomment this line to show a visual representation of the # collisions occuring #base.cTrav.showCollisions(render) # 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)) taskMgr.add(self.move,"moveTask") #Reinitialize all necessary parts of the game def restart(self): #self.numObjects = 10 self.score = 0 printNumObj(self.score) self.ralph.setPos(self.ralphStartPos) self.stamina = 200 self.time = 0 base.camera.setPos(0, 0, 0) base.camera.reparentTo(self.ralph) base.camera.setPos(0, 40, 2) base.camera.lookAt(self.ralph) # Place the collectibles self.placeCollectibles() #Platinum self.placeVases() self.placeCoins() self.placeSilver() self.placeGold() self.placeChests() #Place the obstacles self.placeRocks() #Total number of obstacles self.numObjects = self.rare + self.vasenum + self.coinnum + self.silvernum + self.chestnum taskMgr.add(self.move,"moveTask") # Display ralph's stamina def displayStamina(self): sprintBar['scale'] = (self.stamina*0.01*BAR_WIDTH,0.2,0.2) #Collects the item and modifies score def collectCollectibles(self, entry): #Platinum #Remove the collectible entry.getIntoNodePath().getParent().removeNode() # Update the number of objects self.score = self.score * self.numObjects + 500 self.numObjects = self.numObjects - 1 printNumObj(self.score) def collectVase(self, entry): # Remove the collectible entry.getIntoNodePath().getParent().removeNode() # Update the number of objects self.score = self.score + 10 self.numObjects = self.numObjects - 1 printNumObj(self.score) def collectCoins(self, entry): # Remove the collectible entry.getIntoNodePath().getParent().removeNode() # Update the number of objects self.score = self.score + 1 printNumObj(self.score) self.numObjects = self.numObjects - 1 def collectSilver(self, entry): # Remove the collectible entry.getIntoNodePath().getParent().removeNode() # Update the number of objects self.score = self.score + 20 printNumObj(self.score) self.numObjects = self.numObjects - 1 def collectGold(self, entry): # Remove the collectible entry.getIntoNodePath().getParent().removeNode() # Update the number of objects self.score = self.score + 30 printNumObj(self.score) self.numObjects = self.numObjects - 1 def collectChest(self, entry): # Remove the collectible entry.getIntoNodePath().getParent().removeNode() # Update the number of objects self.score = self.score + 100 printNumObj(self.score) self.numObjects = self.numObjects - 1 #Unique function which handles collisions with a deduction obstacles. def deductRocks(self, entry): # Remove the collectible entry.getIntoNodePath().getParent().removeNode() # Update the number of objects if self.score > 500: randomnum = random.randint(1,2) if randomnum == 1: self.score = self.score - 100 #Removes Score if randomnum == 2: self.score = self.score + 100 #Removes Score if self.score < 500: self.score = self.score - 100 randomnum = random.randint(1,2) if randomnum == 1: result =buttonbox(msg='A kind wizard wishes to help you on your quest? Trust him?', title='Alert!', choices=("Yes", "No")) if result == "Yes": othernum = random.randint(1,100) othernum = othernum * self.score + self.numObjects #Y = MX + B if othernum > 1000: msgbox("Good choice! Add 1,000 Points to your Score!") self.score = self.score + 1000 if othernum < 1000: msgbox("The wizard tricked you!He stole 100 Points!") self.score = self.score - 100 printNumObj(self.score) # Places an item randomly on the map def placeItem(self, item): # Add ground collision detector to the health item self.collectGroundRay = CollisionRay() self.collectGroundRay.setOrigin(0,0,300) self.collectGroundRay.setDirection(0,0,-1) self.collectGroundCol = CollisionNode('colRay') self.collectGroundCol.addSolid(self.collectGroundRay) self.collectGroundCol.setFromCollideMask(BitMask32.bit(0)) self.collectGroundCol.setIntoCollideMask(BitMask32.allOff()) self.collectGroundColNp = item.attachNewNode(self.collectGroundCol) self.collectGroundHandler = CollisionHandlerQueue() base.cTrav.addCollider(self.collectGroundColNp, self.collectGroundHandler) placed = False; while placed == False: # re-randomize position item.setPos(-random.randint(0,140),-random.randint(0,40),0) base.cTrav.traverse(render) # Get Z position from terrain collision entries = [] for j in range(self.collectGroundHandler.getNumEntries()): entry = self.collectGroundHandler.getEntry(j) 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"): item.setZ(entries[0].getSurfacePoint(render).getZ()+1) placed = True # remove placement collider self.collectGroundColNp.removeNode() #Places all obstacles on map. def placeCollectibles(self): self.placeCol = render.attachNewNode("Collectible-Placeholder") self.placeCol.setPos(0,0,0) # Add the health items to the placeCol node for i in range(self.rare): # Load in the health item model self.collect = loader.loadModel("models/moneyBag") self.collect.setPos(0,0,0) self.collect.reparentTo(self.placeCol) self.placeItem(self.collect) # Add spherical collision detection colSphere = CollisionSphere(0,0,0,1) sphereNode = CollisionNode('colSphere') sphereNode.addSolid(colSphere) sphereNode.setFromCollideMask(BitMask32.allOff()) sphereNode.setIntoCollideMask(BitMask32.bit(0)) sphereNp = self.collect.attachNewNode(sphereNode) sphereColHandler = CollisionHandlerQueue() base.cTrav.addCollider(sphereNp, sphereColHandler) def placeVases(self): self.placeV = render.attachNewNode("Collectible-Placeholder") self.placeV.setPos(0,0,0) # Add the health items to the placeCol node for i in range(self.vasenum): # Load in the health item model self.collect = loader.loadModel("models/jar.egg") self.collect.setPos(0,0,0) self.collect.reparentTo(self.placeV) self.placeItem(self.collect) # Add spherical collision detection vaseSphere = CollisionSphere(0,0,0,1) sphereNode = CollisionNode('vaseSphere') sphereNode.addSolid(vaseSphere) sphereNode.setFromCollideMask(BitMask32.allOff()) sphereNode.setIntoCollideMask(BitMask32.bit(0)) sphereNp = self.collect.attachNewNode(sphereNode) sphereColHandler = CollisionHandlerQueue() base.cTrav.addCollider(sphereNp, sphereColHandler) def placeCoins(self): self.placeC = render.attachNewNode("Collectible-Placeholder") self.placeC.setPos(0,0,0) # Add the health items to the placeCol node for i in range(self.coinnum): # Load in the health item model self.collect = loader.loadModel("models/Cookie.egg") self.collect.setPos(0,0,0) self.collect.reparentTo(self.placeC) self.placeItem(self.collect) # Add spherical collision detection coinSphere = CollisionSphere(0,0,0,1) sphereNode = CollisionNode('coinSphere') sphereNode.addSolid(coinSphere) sphereNode.setFromCollideMask(BitMask32.allOff()) sphereNode.setIntoCollideMask(BitMask32.bit(0)) sphereNp = self.collect.attachNewNode(sphereNode) sphereColHandler = CollisionHandlerQueue() base.cTrav.addCollider(sphereNp, sphereColHandler) def placeSilver(self): self.placeS = render.attachNewNode("Collectible-Placeholder") self.placeS.setPos(0,0,0) # Add the health items to the placeCol node for i in range(self.silvernum): # Load in the health item model self.collect = loader.loadModel("models/Anvil.egg") self.collect.setPos(0,0,0) self.collect.reparentTo(self.placeS) self.placeItem(self.collect) # Add spherical collision detection silverSphere = CollisionSphere(0,0,0,1) sphereNode = CollisionNode('silverSphere') sphereNode.addSolid(silverSphere) sphereNode.setFromCollideMask(BitMask32.allOff()) sphereNode.setIntoCollideMask(BitMask32.bit(0)) sphereNp = self.collect.attachNewNode(sphereNode) sphereColHandler = CollisionHandlerQueue() base.cTrav.addCollider(sphereNp, sphereColHandler) def placeGold(self): self.placeG = render.attachNewNode("Collectible-Placeholder") self.placeG.setPos(0,0,0) # Add the health items to the placeCol node for i in range(self.silvernum): # Load in the health item model self.collect = loader.loadModel("models/key.egg") self.collect.setPos(0,0,0) self.collect.reparentTo(self.placeS) self.placeItem(self.collect) # Add spherical collision detection goldSphere = CollisionSphere(0,0,0,1) sphereNode = CollisionNode('goldSphere') sphereNode.addSolid(goldSphere) sphereNode.setFromCollideMask(BitMask32.allOff()) sphereNode.setIntoCollideMask(BitMask32.bit(0)) sphereNp = self.collect.attachNewNode(sphereNode) sphereColHandler = CollisionHandlerQueue() base.cTrav.addCollider(sphereNp, sphereColHandler) def placeChests(self): self.placeCh = render.attachNewNode("Collectible-Placeholder") self.placeCh.setPos(0,0,0) # Add the health items to the placeCol node for i in range(self.chestnum): # Load in the health item model self.collect = loader.loadModel("models/Keg.a2c.cr.egg") self.collect.setPos(0,0,0) self.collect.reparentTo(self.placeCh) self.placeItem(self.collect) # Add spherical collision detection chestSphere = CollisionSphere(0,0,0,1) sphereNode = CollisionNode('chestSphere') sphereNode.addSolid(chestSphere) sphereNode.setFromCollideMask(BitMask32.allOff()) sphereNode.setIntoCollideMask(BitMask32.bit(0)) sphereNp = self.collect.attachNewNode(sphereNode) sphereColHandler = CollisionHandlerQueue() base.cTrav.addCollider(sphereNp, sphereColHandler) def placeRocks(self): self.placeR = render.attachNewNode("Collectible-Placeholder") self.placeR.setPos(0,0,0) # Add the health items to the placeCol node for i in range(self.rocknum): # Load in the health item model self.collect = loader.loadModel("models/smallcactus.egg") self.collect.setScale(0.2) self.collect.setPos(0,0,0) self.collect.reparentTo(self.placeR) self.placeItem(self.collect) # Add spherical collision detection rockSphere = CollisionSphere(0,0,0,1) sphereNode = CollisionNode('rockSphere') sphereNode.addSolid(rockSphere) sphereNode.setFromCollideMask(BitMask32.allOff()) sphereNode.setIntoCollideMask(BitMask32.bit(0)) sphereNp = self.collect.attachNewNode(sphereNode) sphereColHandler = CollisionHandlerQueue() base.cTrav.addCollider(sphereNp, sphereColHandler) #Records the state of the arrow keys def setKey(self, key, value): self.keyMap[key] = value # Makes ralph's health decrease over time # Make ralph's stamina regenerate def staminaReg(self, task): if (self.stamina >= 200): self.stamina = 200 return task.done else: self.stamina += 1 task.setDelay(1) return task.again # Make ralph run def runRalph(self, arg): self.isRunning = arg # Accepts arrow keys to move either the player or the menu cursor, # Also deals with grid checking and collision detection def move(self, task): if self.score < 0: self.die() if self.numObjects == 0: self.endgame() randomnum1 = random.randint(1,1000) randomnum2 = randomnum1 * self.numObjects + self.score if randomnum1 == 1000: result =buttonbox(msg='An odd villager wishes to help you on your quest? Trust him?', title='Alert!', choices=("Yes", "No")) if result == "Yes": if randomnum2 > 20000: msgbox("The villager grants you 4,000 Points!") self.score = self.score + 4000 if randomnum2 < 20000: msgbox("The villager betrays you! He steal 200 points!") self.score = self.score - 200 # save ralph's initial position so that we can restore it, # in case he falls off the map or runs into something. startpos = self.ralph.getPos() # calculate ralph's speed if (self.isRunning and self.stamina > 0): taskMgr.remove("staminaTask") ralphSpeed = 45 self.stamina -= 0.5 else: taskMgr.doMethodLater(5, self.staminaReg, "staminaTask") ralphSpeed = 25 # If a move-key is pressed, move ralph in the specified direction. # and rotate the camera to remain behind ralph if (self.keyMap["left"]!=0): self.ralph.setH(self.ralph.getH() + 100 * globalClock.getDt()) if (self.keyMap["right"]!=0): self.ralph.setH(self.ralph.getH() - 100 * globalClock.getDt()) if (self.keyMap["forward"]!=0): self.ralph.setY(self.ralph, -ralphSpeed * globalClock.getDt()) if (self.keyMap["backward"]!=0): self.ralph.setY(self.ralph, ralphSpeed *globalClock.getDt()) # 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) or (self.keyMap["backward"]!=0)): if self.isMoving is False: self.ralph.loop("run") self.isMoving = True else: if self.isMoving: self.ralph.stop() self.ralph.pose("walk",5) self.isMoving = False # so the following line is unnecessary 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. 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()) #base.camera.setZ(entries[0].getSurfacePoint(render).getZ()+5) #Adds all the items to the map and handles if they get hit. elif (len(entries)>0) and (entries[0].getIntoNode().getName() == "colSphere"): self.collectCollectibles(entries[0]) elif (len(entries)>0) and (entries[0].getIntoNode().getName() == "vaseSphere"): self.collectVase(entries[0]) elif (len(entries)>0) and (entries[0].getIntoNode().getName() == "coinSphere"): self.collectCoins(entries[0]) elif (len(entries)>0) and (entries[0].getIntoNode().getName() == "silverSphere"): self.collectSilver(entries[0]) elif (len(entries)>0) and (entries[0].getIntoNode().getName() == "goldSphere"): self.collectGold(entries[0]) elif (len(entries)>0) and (entries[0].getIntoNode().getName() == "chestSphere"): self.collectChest(entries[0]) elif (len(entries)>0) and (entries[0].getIntoNode().getName() == "rockSphere"): self.deductRocks(entries[0]) else: self.ralph.setPos(startpos) # Keep the camera above the terrain 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"): modZ = entries[0].getSurfacePoint(render).getZ() base.camera.setZ(20.0+modZ+(modZ-self.ralph.getZ())) self.floater.setPos(self.ralph.getPos()) self.floater.setZ(self.ralph.getZ()+2.0) base.camera.lookAt(self.floater) self.displayStamina() return task.cont #If the user collects all items and/or ends the game through Escape. def endgame(self): # end all running tasks taskMgr.remove("moveTask") taskMgr.remove("healthTask") # Open database connection and inserts data. conn = MySQLdb.connect("sql5.freemysqlhosting.net","sql5106009","DFxbmhVkvG","sql5106009") cursor = conn.cursor() cursor.execute("INSERT INTO scores (score, username) VALUES (%s, %s)", (self.score, name)) conn.commit() time.sleep(5) #Error without this... #Some text self.label = DirectLabel(text="End Game!", scale=.05, pos=(0,0,0.2)) self.entry = DirectEntry(text="", scale=.05, initialText="", numLines=1, focus=1, pos=(-0.25,0,0)) #Display high score self.highscore = OkDialog(dialogName="highscoreDialog", text="Your High Score:\n\nName: " + name + "Score: " + str(self.score), command=sys.exit()) # Restart or End? def die(self): # end all running tasks taskMgr.remove("moveTask") taskMgr.remove("healthTask") # Open database connection conn = MySQLdb.connect("sql5.freemysqlhosting.net","sql5106009","DFxbmhVkvG","sql5106009") cursor = conn.cursor() cursor.execute("INSERT INTO scores (score, username) VALUES (%s, %s)", (self.score, name)) conn.commit() time.sleep(5) self.label = DirectLabel(text="Game over!", scale=.05, pos=(0,0,0.2)) self.entry = DirectEntry(text="", scale=.05, initialText="", numLines=1, focus=1, pos=(-0.25,0,0)) #Display high score self.highscore = OkDialog(dialogName="highscoreDialog", text="Your High Score:\n\nName: " + name + " " + "Score: " + str(self.score), command=self.showDialog) def showDialog(self, arg): # cleanup highscore dialog self.highscore.cleanup() # display restart or exit dialog self.dialog = YesNoDialog(dialogName="endDialog", text="Would you like to continue?", command=self.endResult) # Handle the dialog result def endResult(self, arg): if (arg): # cleanup the dialog box self.dialog.cleanup() # restart the game self.restart() else: sys.exit()
class World(DirectObject): def skyBoxLoad(self): self.spaceSkyBox = load_model('skybox1.egg') self.spaceSkyBox.setScale(150) self.spaceSkyBox.setLightOff() self.spaceSkyBox.reparentTo(render) self.spaceSkyBox.setPos(0,0,-200) self.spaceSkyBox.setHpr(0,0,0) def loadEnviron(self): self.environ = load_model("secondWorld.egg") self.environ.reparentTo(render) self.environ.setPos(0,0,0) def loadPokemon(self): self.pikachu = load_model("pikachu.egg") self.pikachu.reparentTo(render) self.pikachu.setScale(1) # self.pikachu.setPos(0,0,1) # self.pikachu.place() self.Groudon = load_model("Groudon.egg") self.Groudon.reparentTo(render) self.Groudon.setPos(-50,0,0) # self.Groudon.place() def loadRalph(self): # Create the main character, Ralph basePath = r"../google_drive/ball/data/models/" ralphStartPos = self.environ.find("**/start_point").getPos() self.ralph = Actor(basePath+"ralph",{"run":basePath+"ralph-run", "walk":basePath+"ralph-walk"}) self.ralph.reparentTo(render) self.ralph.setScale(.2) self.ralph.setPos(ralphStartPos) self.ralph.hide() def loadMusic(self, name="palette.mp3"): bgmusic = load_bgmusic(name) bgmusic.play() def keyControl(self): self.accept("escape", sys.exit) 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("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("w",self.setKey,["upward",1]) self.accept("w-up",self.setKey,["upward",0]) self.accept("s",self.setKey,["downward",1]) self.accept("s-up",self.setKey,["downward",0]) def displayInformation(self): self.title = addTitle("My Pokemon - Roam Mode") self.inst1 = addInstructions(0.95, "[ESC]: Quit") self.inst2 = addInstructions(0.90, "[Arrow Keys]: Move") self.inst4 = addInstructions(0.85, "[w]: look up") self.inst4 = addInstructions(0.80, "[s]: look down") def __init__(self): self.keyMap = {"left":0, "right":0, "forward":0,"backward":0, "upward":0, "downward":0, "leftward":0,"rightward":0, "cam-left":0, "cam-right":0} # base.win.setClearColor(Vec4(0,0,0,1)) self.above = 3.0 # load sky box self.skyBoxLoad() # load environment self.loadEnviron() # load pokemon self.loadPokemon() # load ralph self.loadRalph() # load music self.loadMusic() self.displayInformation() self.keyControl() # 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) taskMgr.add(self.move,"moveTask") taskMgr.add(self.setAbove,"setAbove") # Game state variables self.isMoving = False # Set up the camera base.disableMouse() base.camera.setPos(self.ralph.getX(),self.ralph.getY(),2) self.cTrav = CollisionTraverser() 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() self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler) 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 = base.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler) # 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) # 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)) def setAbove(self,task): if self.keyMap["upward"] == 1: self.above += 0.1 if self.keyMap["downward"] == 1: self.above -= 0.1 return task.cont #Records the state of the arrow keys def setKey(self, key, value): 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): # save ralph's initial position so that we can restore it, # in case he falls off the map or runs into something. startpos = self.ralph.getPos() # If a move-key is pressed, move ralph in the specified direction. if (self.keyMap["left"]!=0): self.ralph.setH(self.ralph.getH() + 113 * globalClock.getDt()) base.camera.setX(base.camera, +20 * globalClock.getDt()) if (self.keyMap["right"]!=0): self.ralph.setH(self.ralph.getH() - 113 * globalClock.getDt()) base.camera.setX(base.camera, -20 * globalClock.getDt()) if (self.keyMap["forward"]!=0): self.ralph.setY(self.ralph, -75 * globalClock.getDt()) if (self.keyMap["backward"] != 0): pass #self.ralph.setY(self.ralph, 75 * globalClock.getDt()) # 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):# or (self.keyMap["backward"]!=0): if self.isMoving is False: #self.ralph.loop("run") self.isMoving = True else: if self.isMoving: #self.ralph.stop() #self.ralph.pose("walk",5) self.isMoving = False # If the camera is too far from ralph, move it closer. # If the camera is too close to ralph, move it farther. camvec = self.ralph.getPos() - base.camera.getPos() camvec.setZ(0) camdist = camvec.length() camvec.normalize() if (camdist > 10.0): base.camera.setPos(base.camera.getPos() + camvec*(camdist-10)) camdist = 10.0 if (camdist < 5.0): base.camera.setPos(base.camera.getPos() - camvec*(5-camdist)) 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.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) # Keep the camera at one foot above the terrain, # or two feet above ralph, 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"): base.camera.setZ(entries[0].getSurfacePoint(render).getZ()+1.0) if (base.camera.getZ() < self.ralph.getZ() + 2.0): base.camera.setZ(self.ralph.getZ() + 2.0) # The camera should look in ralph's direction, # but it should also try to stay horizontal, so look at # a floater which hovers above ralph's head. self.floater.setPos(self.ralph.getPos()) self.floater.setZ(self.ralph.getZ() + self.above)#self.above) base.camera.lookAt(self.floater) return task.cont
class World(DirectObject): def __init__(self): self.keyMap = {"left":0, "right":0, "forward":0, "cam-left":0, "cam-right":0} base.win.setClearColor(Vec4(0,0,0,1)) # Post the instructions self.title = addTitle("Panda3D Tutorial: Roaming Ralph (Walking on Uneven Terrain)") self.inst1 = addInstructions(0.95, "[ESC]: Quit") self.inst2 = addInstructions(0.90, "[Left Arrow]: Rotate Ralph Left") self.inst3 = addInstructions(0.85, "[Right Arrow]: Rotate Ralph Right") self.inst4 = addInstructions(0.80, "[Up Arrow]: Run Ralph Forward") self.inst6 = addInstructions(0.70, "[A]: Rotate Camera Left") self.inst7 = addInstructions(0.65, "[S]: Rotate Camera Right") # 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.environ = loader.loadModel("models/world") self.environ.reparentTo(render) self.environ.setPos(0,0,0) # Create the main character, Ralph ralphStartPos = self.environ.find("**/start_point").getPos() #self.addRalph(ralphStartPos) # 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 self.accept("escape", sys.exit) 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]) 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]) taskMgr.add(self.move,"moveTask") # Game state variables self.isMoving = False # Set up the camera 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. # 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) # 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)) # Add some text ''' bk_text = "This is a test" textObject = OnscreenText(text = bk_text, pos = (0.95,-0.35), scale = 0.07,fg=(1,0.5,0.5,1),align=TextNode.ACenter,mayChange=1) ''' #MS: Adds a Roaming Ralph def addRalph(self, pos): ralphStartPos = pos self.ralph = Actor("models/ralph", {"run":"models/ralph-run", "walk":"models/ralph-walk"}) self.ralph.reparentTo(render) self.ralph.setScale(.2) self.ralph.setPos(ralphStartPos) self.cTrav = CollisionTraverser() 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() self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler) 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 = base.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler) #Records the state of the arrow keys def setKey(self, key, value): 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): # If the camera-left key is pressed, move camera left. # If the camera-right key is pressed, move camera right. base.camera.lookAt(self.ralph) if (self.keyMap["cam-left"]!=0): base.camera.setX(base.camera, -20 * globalClock.getDt()) if (self.keyMap["cam-right"]!=0): base.camera.setX(base.camera, +20 * globalClock.getDt()) # save ralph's initial position so that we can restore it, # in case he falls off the map or runs into something. startpos = self.ralph.getPos() # If a move-key is pressed, move ralph in the specified direction. if (self.keyMap["left"]!=0): self.ralph.setH(self.ralph.getH() + 300 * globalClock.getDt()) if (self.keyMap["right"]!=0): self.ralph.setH(self.ralph.getH() - 300 * globalClock.getDt()) if (self.keyMap["forward"]!=0): self.ralph.setY(self.ralph, -25 * globalClock.getDt()) # 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.ralph.loop("run") self.isMoving = True else: if self.isMoving: self.ralph.stop() self.ralph.pose("walk",5) self.isMoving = False # If the camera is too far from ralph, move it closer. # If the camera is too close to ralph, move it farther. camvec = self.ralph.getPos() - base.camera.getPos() camvec.setZ(0) camdist = camvec.length() camvec.normalize() if (camdist > 10.0): base.camera.setPos(base.camera.getPos() + camvec*(camdist-10)) camdist = 10.0 if (camdist < 5.0): base.camera.setPos(base.camera.getPos() - camvec*(5-camdist)) 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.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) # Keep the camera at one foot above the terrain, # or two feet above ralph, 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"): base.camera.setZ(entries[0].getSurfacePoint(render).getZ()+1.0) if (base.camera.getZ() < self.ralph.getZ() + 2.0): base.camera.setZ(self.ralph.getZ() + 2.0) # The camera should look in ralph's direction, # but it should also try to stay horizontal, so look at # a floater which hovers above ralph's head. self.floater.setPos(self.ralph.getPos()) self.floater.setZ(self.ralph.getZ() + 2.0) base.camera.lookAt(self.floater) return task.cont
class RoamingRalphDemo(ShowBase): def __init__(self): # Set up the window, camera, etc. ShowBase.__init__(self) # Set the background color to black self.win.setClearColor((0, 0, 0, 1)) # This is used to store which keys are currently pressed. self.keyMap = { "left": 0, "right": 0, "forward": 0, "cam-left": 0, "cam-right": 0 } # Post the instructions self.title = addTitle( "Panda3D Tutorial: Roaming Ralph (Walking on Uneven Terrain)") self.inst1 = addInstructions(0.06, "[ESC]: Quit") self.inst2 = addInstructions(0.12, "[Left Arrow]: Rotate Ralph Left") self.inst3 = addInstructions(0.18, "[Right Arrow]: Rotate Ralph Right") self.inst4 = addInstructions(0.24, "[Up Arrow]: Run Ralph Forward") self.inst6 = addInstructions(0.30, "[A]: Rotate Camera Left") self.inst7 = addInstructions(0.36, "[S]: Rotate Camera Right") # 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.environ = loader.loadModel("models/world") self.environ.reparentTo(render) # Create the main character, Ralph ralphStartPos = self.environ.find("**/start_point").getPos() self.ralph = Actor("models/ralph", { "run": "models/ralph-run", "walk": "models/ralph-walk" }) self.ralph.reparentTo(render) self.ralph.setScale(.2) self.ralph.setPos(ralphStartPos + (0, 0, 0.5)) # Create a floater object, which floats 2 units above ralph. We # use this as a target for the camera to look at. self.floater = NodePath(PandaNode("floater")) self.floater.reparentTo(self.ralph) self.floater.setZ(2.0) # Accept the control keys for movement and rotation self.accept("escape", sys.exit) self.accept("arrow_left", self.setKey, ["left", True]) self.accept("arrow_right", self.setKey, ["right", True]) self.accept("arrow_up", self.setKey, ["forward", True]) self.accept("a", self.setKey, ["cam-left", True]) self.accept("s", self.setKey, ["cam-right", True]) self.accept("arrow_left-up", self.setKey, ["left", False]) self.accept("arrow_right-up", self.setKey, ["right", False]) self.accept("arrow_up-up", self.setKey, ["forward", False]) self.accept("a-up", self.setKey, ["cam-left", False]) self.accept("s-up", self.setKey, ["cam-right", False]) taskMgr.add(self.move, "moveTask") # Game state variables self.isMoving = False # Set up the camera self.disableMouse() self.camera.setPos(self.ralph.getX(), self.ralph.getY() + 10, 2) # 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.cTrav = CollisionTraverser() self.ralphGroundRay = CollisionRay() self.ralphGroundRay.setOrigin(0, 0, 9) self.ralphGroundRay.setDirection(0, 0, -1) self.ralphGroundCol = CollisionNode('ralphRay') self.ralphGroundCol.addSolid(self.ralphGroundRay) self.ralphGroundCol.setFromCollideMask(CollideMask.bit(0)) self.ralphGroundCol.setIntoCollideMask(CollideMask.allOff()) self.ralphGroundColNp = self.ralph.attachNewNode(self.ralphGroundCol) self.ralphGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler) self.camGroundRay = CollisionRay() self.camGroundRay.setOrigin(0, 0, 9) self.camGroundRay.setDirection(0, 0, -1) self.camGroundCol = CollisionNode('camRay') self.camGroundCol.addSolid(self.camGroundRay) self.camGroundCol.setFromCollideMask(CollideMask.bit(0)) self.camGroundCol.setIntoCollideMask(CollideMask.allOff()) self.camGroundColNp = self.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler) # 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) # Create some lighting ambientLight = AmbientLight("ambientLight") ambientLight.setColor((.3, .3, .3, 1)) directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection((-5, -5, -5)) directionalLight.setColor((1, 1, 1, 1)) directionalLight.setSpecularColor((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 # Accepts arrow keys to move either the player or the menu cursor, # Also deals with grid checking and collision detection def move(self, task): # Get the time that elapsed since last frame. We multiply this with # the desired speed in order to find out with which distance to move # in order to achieve that desired speed. dt = globalClock.getDt() # If the camera-left key is pressed, move camera left. # If the camera-right key is pressed, move camera right. if self.keyMap["cam-left"]: self.camera.setX(self.camera, -20 * dt) if self.keyMap["cam-right"]: self.camera.setX(self.camera, +20 * dt) # save ralph's initial position so that we can restore it, # in case he falls off the map or runs into something. startpos = self.ralph.getPos() # If a move-key is pressed, move ralph in the specified direction. if self.keyMap["left"]: self.ralph.setH(self.ralph.getH() + 300 * dt) if self.keyMap["right"]: self.ralph.setH(self.ralph.getH() - 300 * dt) if self.keyMap["forward"]: self.ralph.setY(self.ralph, -25 * dt) # If ralph is moving, loop the run animation. # If he is standing still, stop the animation. if self.keyMap["forward"] or self.keyMap["left"] or self.keyMap[ "right"]: if self.isMoving is False: self.ralph.loop("run") self.isMoving = True else: if self.isMoving: self.ralph.stop() self.ralph.pose("walk", 5) self.isMoving = False # If the camera is too far from ralph, move it closer. # If the camera is too close to ralph, move it farther. camvec = self.ralph.getPos() - self.camera.getPos() camvec.setZ(0) camdist = camvec.length() camvec.normalize() if camdist > 10.0: self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10)) camdist = 10.0 if camdist < 5.0: self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist)) camdist = 5.0 # Normally, we would have to call traverse() to check for collisions. # However, the class ShowBase that we inherit from has a task to do # this for us, if we assign a CollisionTraverser to self.cTrav. #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 = list(self.ralphGroundHandler.getEntries()) entries.sort(key=lambda x: 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) # Keep the camera at one foot above the terrain, # or two feet above ralph, whichever is greater. entries = list(self.camGroundHandler.getEntries()) entries.sort(key=lambda x: x.getSurfacePoint(render).getZ()) if len(entries) > 0 and entries[0].getIntoNode().getName( ) == "terrain": self.camera.setZ(entries[0].getSurfacePoint(render).getZ() + 1.0) if self.camera.getZ() < self.ralph.getZ() + 2.0: self.camera.setZ(self.ralph.getZ() + 2.0) # The camera should look in ralph's direction, # but it should also try to stay horizontal, so look at # a floater which hovers above ralph's head. self.camera.lookAt(self.floater) return task.cont
class DistributedPartyJukeboxActivityBase(DistributedPartyActivity): __module__ = __name__ notify = directNotify.newCategory('DistributedPartyJukeboxActivityBase') def __init__(self, cr, actId, phaseToMusicData): DistributedPartyActivity.__init__(self, cr, actId, ActivityTypes.Continuous) self.phaseToMusicData = phaseToMusicData self.jukebox = None self.gui = None self.tunes = [] self.music = None self.currentSongData = None self.localQueuedSongInfo = None self.localQueuedSongListItem = None return def generateInit(self): self.gui = JukeboxGui(self.phaseToMusicData) def load(self): DistributedPartyActivity.load(self) self.jukebox = Actor( 'phase_13/models/parties/jukebox_model', {'dance': 'phase_13/models/parties/jukebox_dance'}) self.jukebox.reparentTo(self.root) self.collNode = CollisionNode(self.getCollisionName()) self.collNode.setCollideMask(ToontownGlobals.CameraBitmask | ToontownGlobals.WallBitmask) collTube = CollisionTube(0, 0, 0, 0.0, 0.0, 4.25, 2.25) collTube.setTangible(1) self.collNode.addSolid(collTube) self.collNodePath = self.jukebox.attachNewNode(self.collNode) self.sign.setPos(-5.0, 0, 0) self.activate() def unload(self): DistributedPartyActivity.unload(self) self.gui.unload() if self.music is not None: self.music.stop() self.jukebox.stop() self.jukebox.delete() self.jukebox = None self.ignoreAll() return def getCollisionName(self): return self.uniqueName('jukeboxCollision') def activate(self): self.accept('enter' + self.getCollisionName(), self.__handleEnterCollision) def __handleEnterCollision(self, collisionEntry): if base.cr.playGame.getPlace().fsm.getCurrentState().getName( ) == 'walk': base.cr.playGame.getPlace().fsm.request('activity') self.d_toonJoinRequest() def joinRequestDenied(self, reason): DistributedPartyActivity.joinRequestDenied(self, reason) self.showMessage(TTLocalizer.PartyJukeboxOccupied) def handleToonJoined(self, toonId): toon = base.cr.doId2do.get(toonId) if toon: self.jukebox.lookAt(base.cr.doId2do[toonId]) self.jukebox.setHpr(self.jukebox.getH() + 180.0, 0, 0) if toonId == base.localAvatar.doId: self.__localUseJukebox() def handleToonExited(self, toonId): if toonId == base.localAvatar.doId and self.gui.isLoaded(): self.__deactivateGui() def handleToonDisabled(self, toonId): self.notify.warning('handleToonDisabled no implementation yet') def __localUseJukebox(self): base.localAvatar.disableAvatarControls() base.localAvatar.stopPosHprBroadcast() self.__activateGui() self.accept(JukeboxGui.CLOSE_EVENT, self.__handleGuiClose) taskMgr.doMethodLater(0.5, self.__localToonWillExitTask, self.uniqueName('toonWillExitJukeboxOnTimeout'), extraArgs=None) self.accept(JukeboxGui.ADD_SONG_CLICK_EVENT, self.__handleQueueSong) if self.isUserHost(): self.accept(JukeboxGui.MOVE_TO_TOP_CLICK_EVENT, self.__handleMoveSongToTop) return def __localToonWillExitTask(self, task): self.localToonExiting() return Task.done def __activateGui(self): self.gui.enable(timer=JUKEBOX_TIMEOUT) self.gui.disableAddSongButton() if self.currentSongData is not None: self.gui.setSongCurrentlyPlaying(self.currentSongData[0], self.currentSongData[1]) self.d_queuedSongsRequest() return def __deactivateGui(self): self.ignore(JukeboxGui.CLOSE_EVENT) self.ignore(JukeboxGui.SONG_SELECT_EVENT) self.ignore(JukeboxGui.MOVE_TO_TOP_CLICK_EVENT) base.cr.playGame.getPlace().setState('walk') base.localAvatar.startPosHprBroadcast() base.localAvatar.enableAvatarControls() self.gui.unload() self.__localClearQueuedSong() def isUserHost(self): return self.party.partyInfo.hostId == base.localAvatar.doId def d_queuedSongsRequest(self): self.sendUpdate('queuedSongsRequest') def queuedSongsResponse(self, songInfoList, index): if self.gui.isLoaded(): for i in range(len(songInfoList)): songInfo = songInfoList[i] self.__addSongToQueue(songInfo, isLocalQueue=index >= 0 and i == index) self.gui.enableAddSongButton() def __handleGuiClose(self): self.__deactivateGui() self.d_toonExitDemand() def __handleQueueSong(self, name, values): self.d_setNextSong(values[0], values[1]) def d_setNextSong(self, phase, filename): self.sendUpdate('setNextSong', [(phase, filename)]) def setSongInQueue(self, songInfo): if self.gui.isLoaded(): phase = sanitizePhase(songInfo[0]) filename = songInfo[1] data = self.getMusicData(phase, filename) if data: if self.localQueuedSongListItem is not None: self.localQueuedSongListItem['text'] = data[0] else: self.__addSongToQueue(songInfo, isLocalQueue=True) return def __addSongToQueue(self, songInfo, isLocalQueue=False): if isLocalQueue: isHost = self.isUserHost() data = self.getMusicData(sanitizePhase(songInfo[0]), songInfo[1]) if data: listItem = self.gui.addSongToQueue(data[0], highlight=isLocalQueue, moveToTopButton=isHost) self.localQueuedSongInfo = isLocalQueue and songInfo self.localQueuedSongListItem = listItem def __localClearQueuedSong(self): self.localQueuedSongInfo = None self.localQueuedSongListItem = None return def __play(self, phase, filename, length): self.music = base.loadMusic((MUSIC_PATH + '%s') % (phase, filename)) if self.music: if self.__checkPartyValidity() and hasattr( base.cr.playGame.getPlace().loader, 'music') and base.cr.playGame.getPlace().loader.music: base.cr.playGame.getPlace().loader.music.stop() base.resetMusic.play() self.music.setTime(0.0) self.music.setLoopCount(getMusicRepeatTimes(length)) self.music.play() jukeboxAnimControl = self.jukebox.getAnimControl('dance') if not jukeboxAnimControl.isPlaying(): self.jukebox.loop('dance') self.currentSongData = (phase, filename) def __stop(self): self.jukebox.stop() self.currentSongData = None if self.music: self.music.stop() if self.gui.isLoaded(): self.gui.clearSongCurrentlyPlaying() return def setSongPlaying(self, songInfo, toonId): phase = sanitizePhase(songInfo[0]) filename = songInfo[1] if not filename: self.__stop() return data = self.getMusicData(phase, filename) if data: self.__play(phase, filename, data[1]) self.setSignNote(data[0]) if self.gui.isLoaded(): item = self.gui.popSongFromQueue() self.gui.setSongCurrentlyPlaying(phase, filename) if item == self.localQueuedSongListItem: self.__localClearQueuedSong() if toonId == localAvatar.doId: localAvatar.setSystemMessage(0, TTLocalizer.PartyJukeboxNowPlaying) def __handleMoveSongToTop(self): if self.isUserHost() and self.localQueuedSongListItem is not None: self.d_moveHostSongToTopRequest() return def d_moveHostSongToTopRequest(self): self.notify.debug('d_moveHostSongToTopRequest') self.sendUpdate('moveHostSongToTopRequest') def moveHostSongToTop(self): self.notify.debug('moveHostSongToTop') if self.gui.isLoaded(): self.gui.pushQueuedItemToTop(self.localQueuedSongListItem) def getMusicData(self, phase, filename): data = [] phase = sanitizePhase(phase) phase = self.phaseToMusicData.get(phase) if phase: data = phase.get(filename, []) return data def __checkPartyValidity(self): if hasattr(base.cr.playGame, 'getPlace') and base.cr.playGame.getPlace() and hasattr( base.cr.playGame.getPlace(), 'loader') and base.cr.playGame.getPlace().loader: return True else: return False
class RoamingRalphDemo(ShowBase): def __init__(self): # Set up the window, camera, etc. ShowBase.__init__(self) base.render.setAttrib(LightRampAttrib.makeHdr0()) # Configure depth pre-pass prepass_pass = lionrender.DepthScenePass() # Configure scene pass scene_fb_props = FrameBufferProperties() scene_fb_props.set_rgb_color(True) scene_fb_props.set_rgba_bits(8, 8, 8, 0) scene_fb_props.set_depth_bits(32) scene_pass = lionrender.ScenePass( frame_buffer_properties=scene_fb_props, clear_color=LColor(0.53, 0.80, 0.92, 1), share_depth_with=prepass_pass) scene_pass.node_path.set_depth_write(False) # Configure post processing filter_pass = lionrender.FilterPass(fragment_path='shaders/fsq.frag') filter_pass.node_path.set_shader_input('inputTexture', scene_pass.output) # Enable FXAA fxaa_pass = lionrender.FxaaFilterPass() fxaa_pass.node_path.set_shader_input('inputTexture', filter_pass.output) # Output result fxaa_pass.output_to(render2d) # This is used to store which keys are currently pressed. self.keyMap = { "left": 0, "right": 0, "forward": 0, "backward": 0, "cam-left": 0, "cam-right": 0, } # Post the instructions self.title = addTitle( "Panda3D Tutorial: Roaming Ralph (Walking on Uneven Terrain)") self.inst1 = addInstructions(0.06, "[ESC]: Quit") self.inst2 = addInstructions(0.12, "[Left Arrow]: Rotate Ralph Left") self.inst3 = addInstructions(0.18, "[Right Arrow]: Rotate Ralph Right") self.inst4 = addInstructions(0.24, "[Up Arrow]: Run Ralph Forward") self.inst5 = addInstructions(0.30, "[Down Arrow]: Walk Ralph Backward") self.inst6 = addInstructions(0.36, "[A]: Rotate Camera Left") self.inst7 = addInstructions(0.42, "[S]: Rotate Camera Right") # 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.environ = loader.loadModel("models/world") self.environ.reparentTo(render) # We do not have a skybox, so we will just use a sky blue background color self.setBackgroundColor(0.53, 0.80, 0.92, 1) # Create the main character, Ralph ralphStartPos = self.environ.find("**/start_point").getPos() self.ralph = Actor("models/ralph", { "run": "models/ralph-run", "walk": "models/ralph-walk" }) self.ralph.reparentTo(render) self.ralph.setScale(.2) self.ralph.setPos(ralphStartPos + (0, 0, 1.5)) # Create a floater object, which floats 2 units above ralph. We # use this as a target for the camera to look at. self.floater = NodePath(PandaNode("floater")) self.floater.reparentTo(self.ralph) self.floater.setZ(2.0) # Accept the control keys for movement and rotation self.accept("escape", sys.exit) self.accept("arrow_left", self.setKey, ["left", True]) self.accept("arrow_right", self.setKey, ["right", True]) self.accept("arrow_up", self.setKey, ["forward", True]) self.accept("arrow_down", self.setKey, ["backward", True]) self.accept("a", self.setKey, ["cam-left", True]) self.accept("s", self.setKey, ["cam-right", True]) self.accept("arrow_left-up", self.setKey, ["left", False]) self.accept("arrow_right-up", self.setKey, ["right", False]) self.accept("arrow_up-up", self.setKey, ["forward", False]) self.accept("arrow_down-up", self.setKey, ["backward", False]) self.accept("a-up", self.setKey, ["cam-left", False]) self.accept("s-up", self.setKey, ["cam-right", False]) self.accept("v", self.toggleCards) taskMgr.add(self.move, "moveTask") # Set up the camera self.disableMouse() self.camera.setPos(self.ralph.getX(), self.ralph.getY() + 10, 2) self.cTrav = CollisionTraverser() # Use a CollisionHandlerPusher to handle collisions between Ralph and # the environment. Ralph is added as a "from" object which will be # "pushed" out of the environment if he walks into obstacles. # # Ralph is composed of two spheres, one around the torso and one # around the head. They are slightly oversized since we want Ralph to # keep some distance from obstacles. self.ralphCol = CollisionNode('ralph') self.ralphCol.addSolid(CollisionSphere(center=(0, 0, 2), radius=1.5)) self.ralphCol.addSolid( CollisionSphere(center=(0, -0.25, 4), radius=1.5)) self.ralphCol.setFromCollideMask(CollideMask.bit(0)) self.ralphCol.setIntoCollideMask(CollideMask.allOff()) self.ralphColNp = self.ralph.attachNewNode(self.ralphCol) self.ralphPusher = CollisionHandlerPusher() self.ralphPusher.horizontal = True # Note that we need to add ralph both to the pusher and to the # traverser; the pusher needs to know which node to push back when a # collision occurs! self.ralphPusher.addCollider(self.ralphColNp, self.ralph) self.cTrav.addCollider(self.ralphColNp, self.ralphPusher) # 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. self.ralphGroundRay = CollisionRay() self.ralphGroundRay.setOrigin(0, 0, 9) self.ralphGroundRay.setDirection(0, 0, -1) self.ralphGroundCol = CollisionNode('ralphRay') self.ralphGroundCol.addSolid(self.ralphGroundRay) self.ralphGroundCol.setFromCollideMask(CollideMask.bit(0)) self.ralphGroundCol.setIntoCollideMask(CollideMask.allOff()) self.ralphGroundColNp = self.ralph.attachNewNode(self.ralphGroundCol) self.ralphGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler) self.camGroundRay = CollisionRay() self.camGroundRay.setOrigin(0, 0, 9) self.camGroundRay.setDirection(0, 0, -1) self.camGroundCol = CollisionNode('camRay') self.camGroundCol.addSolid(self.camGroundRay) self.camGroundCol.setFromCollideMask(CollideMask.bit(0)) self.camGroundCol.setIntoCollideMask(CollideMask.allOff()) self.camGroundColNp = self.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler) # Uncomment this line to see the collision rays #self.ralphColNp.show() #self.camGroundColNp.show() # Uncomment this line to show a visual representation of the # collisions occuring #self.cTrav.showCollisions(render) # Create some lighting ambientLight = AmbientLight("ambientLight") ambientLight.setColor((.3, .3, .3, 1)) directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection((-5, -5, -5)) directionalLight.setColor((1, 1, 1, 1)) directionalLight.setSpecularColor((1, 1, 1, 1)) render.setLight(render.attachNewNode(ambientLight)) render.setLight(render.attachNewNode(directionalLight)) # Clean up texture attributes for texture in self.render.find_all_textures(): texture.set_format(Texture.F_srgb) # Records the state of the arrow keys def setKey(self, key, value): 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): # Get the time that elapsed since last frame. We multiply this with # the desired speed in order to find out with which distance to move # in order to achieve that desired speed. dt = globalClock.getDt() # If the camera-left key is pressed, move camera left. # If the camera-right key is pressed, move camera right. if self.keyMap["cam-left"]: self.camera.setX(self.camera, -20 * dt) if self.keyMap["cam-right"]: self.camera.setX(self.camera, +20 * dt) # If a move-key is pressed, move ralph in the specified direction. if self.keyMap["left"]: self.ralph.setH(self.ralph.getH() + 300 * dt) if self.keyMap["right"]: self.ralph.setH(self.ralph.getH() - 300 * dt) if self.keyMap["forward"]: self.ralph.setY(self.ralph, -20 * dt) if self.keyMap["backward"]: self.ralph.setY(self.ralph, +10 * dt) # If ralph is moving, loop the run animation. # If he is standing still, stop the animation. currentAnim = self.ralph.getCurrentAnim() if self.keyMap["forward"]: if currentAnim != "run": self.ralph.loop("run") elif self.keyMap["backward"]: # Play the walk animation backwards. if currentAnim != "walk": self.ralph.loop("walk") self.ralph.setPlayRate(-1.0, "walk") elif self.keyMap["left"] or self.keyMap["right"]: if currentAnim != "walk": self.ralph.loop("walk") self.ralph.setPlayRate(1.0, "walk") else: if currentAnim is not None: self.ralph.stop() self.ralph.pose("walk", 5) self.isMoving = False # If the camera is too far from ralph, move it closer. # If the camera is too close to ralph, move it farther. camvec = self.ralph.getPos() - self.camera.getPos() camvec.setZ(0) camdist = camvec.length() camvec.normalize() if camdist > 10.0: self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10)) camdist = 10.0 if camdist < 5.0: self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist)) camdist = 5.0 # Normally, we would have to call traverse() to check for collisions. # However, the class ShowBase that we inherit from has a task to do # this for us, if we assign a CollisionTraverser to self.cTrav. #self.cTrav.traverse(render) # Adjust ralph's Z coordinate. If ralph's ray hit terrain, # update his Z entries = list(self.ralphGroundHandler.entries) entries.sort(key=lambda x: x.getSurfacePoint(render).getZ()) for entry in entries: if entry.getIntoNode().getName() == "terrain": self.ralph.setZ(entry.getSurfacePoint(render).getZ()) # Keep the camera at one unit above the terrain, # or two units above ralph, whichever is greater. entries = list(self.camGroundHandler.entries) entries.sort(key=lambda x: x.getSurfacePoint(render).getZ()) for entry in entries: if entry.getIntoNode().getName() == "terrain": self.camera.setZ(entry.getSurfacePoint(render).getZ() + 1.5) if self.camera.getZ() < self.ralph.getZ() + 2.0: self.camera.setZ(self.ralph.getZ() + 2.0) # The camera should look in ralph's direction, # but it should also try to stay horizontal, so look at # a floater which hovers above ralph's head. self.camera.lookAt(self.floater) return task.cont def toggleCards(self): self.bufferViewer.toggleEnable()
class World(DirectObject): def __init__(self): #create Queue to hold the incoming chat #request the heartbeat so that the caht interface is being refreshed in order to get the message from other player self.keyMap = { "left": 0, "right": 0, "forward": 0, "cam-left": 0, "cam-right": 0, "charge": 0 } base.win.setClearColor(Vec4(0, 0, 0, 1)) self.cManager = ConnectionManager() self.cManager.startConnection() #------------------------------ #Chat Chat(self.cManager) #send dummy login info of the particular client #send first chat info #--------------------------------------- self.userName = username dummy_login = { 'user_id': self.userName, 'factionId': faction, 'password': '******' } self.cManager.sendRequest(Constants.RAND_STRING, dummy_login) chat = { 'userName': self.userName, #username 'message': '-------Login------' } self.cManager.sendRequest(Constants.CMSG_CHAT, chat) #-------------------------------------- #self.minimap = OnscreenImage(image="images/minimap.png", scale=(0.2,1,0.2), pos=(-1.1,0,0.8)) #frame = DirectFrame(text="Resource Bar", scale=0.001) resource_bar = DirectWaitBar(text="", value=35, range=100, pos=(0, 0, 0.9), barColor=(255, 255, 0, 1), frameSize=(-0.3, 0.3, 0, 0.03)) cp_bar = DirectWaitBar(text="", value=70, range=100, pos=(1.0, 0, 0.9), barColor=(0, 0, 255, 1), frameSize=(-0.3, 0.3, 0, 0.03), frameColor=(255, 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.environ = loader.loadModel("models/world") self.environ.reparentTo(render) self.environ.setPos(0, 0, 0) # Create the main character, Ralph ralphStartPos = self.environ.find("**/start_point").getPos() self.ralph = Actor("models/ralph", { "run": "models/ralph-run", "walk": "models/ralph-walk" }) self.ralph.reparentTo(render) self.ralph.setScale(.2) self.ralph.setPos(ralphStartPos) nameplate = TextNode('textNode username_' + str(self.userName)) nameplate.setText(self.userName) npNodePath = self.ralph.attachNewNode(nameplate) npNodePath.setScale(0.8) npNodePath.setBillboardPointEye() #npNodePath.setPos(1.0,0,6.0) npNodePath.setZ(6.5) bar = DirectWaitBar(value=100, scale=1.0) bar.setColor(255, 0, 0) #bar.setBarRelief() bar.setZ(6.0) bar.setBillboardPointEye() bar.reparentTo(self.ralph) # 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 self.accept("escape", sys.exit) 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]) 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]) self.accept("c", self.setKey, ["charge", 1]) self.accept("c-up", self.setKey, ["charge", 0]) taskMgr.add(self.move, "moveTask") # Game state variables self.isMoving = False # Set up the camera base.disableMouse() base.camera.setPos(self.ralph.getX(), self.ralph.getY() + 10, 2) # 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.cTrav = CollisionTraverser() 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() self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler) 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 = base.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler) # 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) # 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 # Accepts arrow keys to move either the player or the menu cursor, # Also deals with grid checking and collision detection def move(self, task): # If the camera-left key is pressed, move camera left. # If the camera-right key is pressed, move camera right. base.camera.lookAt(self.ralph) if (self.keyMap["cam-left"] != 0): base.camera.setX(base.camera, -20 * globalClock.getDt()) if (self.keyMap["cam-right"] != 0): base.camera.setX(base.camera, +20 * globalClock.getDt()) # save ralph's initial position so that we can restore it, # in case he falls off the map or runs into something. startpos = self.ralph.getPos() # If a move-key is pressed, move ralph in the specified direction. if (self.keyMap["left"] != 0): self.ralph.setH(self.ralph.getH() + 300 * globalClock.getDt()) if (self.keyMap["right"] != 0): self.ralph.setH(self.ralph.getH() - 300 * globalClock.getDt()) if (self.keyMap["forward"] != 0): self.ralph.setY(self.ralph, -25 * globalClock.getDt()) if (self.keyMap["charge"] != 0): self.ralph.setY(self.ralph, -250 * globalClock.getDt()) #ribbon = Ribbon(self.ralph, Vec4(1,1,1,1), 3, 10, 0.3) #ribbon.getRoot().setZ(2.0) # If ralph is moving, loop the run animation. # If he is standing still, stop the animation. if (self.keyMap["forward"] != 0) or (self.keyMap["charge"] != 0) or ( self.keyMap["left"] != 0) or (self.keyMap["right"] != 0): if self.isMoving is False: self.ralph.loop("run") self.isMoving = True else: if self.isMoving: self.ralph.stop() self.ralph.pose("walk", 5) self.isMoving = False # If the camera is too far from ralph, move it closer. # If the camera is too close to ralph, move it farther. camvec = self.ralph.getPos() - base.camera.getPos() camvec.setZ(0) camdist = camvec.length() camvec.normalize() if (camdist > 10.0): base.camera.setPos(base.camera.getPos() + camvec * (camdist - 10)) camdist = 10.0 if (camdist < 5.0): base.camera.setPos(base.camera.getPos() - camvec * (5 - camdist)) 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.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) # Keep the camera at one foot above the terrain, # or two feet above ralph, 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"): base.camera.setZ(entries[0].getSurfacePoint(render).getZ() + 1.0) if (base.camera.getZ() < self.ralph.getZ() + 2.0): base.camera.setZ(self.ralph.getZ() + 2.0) # The camera should look in ralph's direction, # but it should also try to stay horizontal, so look at # a floater which hovers above ralph's head. self.floater.setPos(self.ralph.getPos()) self.floater.setZ(self.ralph.getZ() + 2.0) base.camera.lookAt(self.floater) return task.cont
class World(ShowBase): def __init__(self): # Load the default configuration.prc. This is recommended, as it # contains some important panda options loadPrcFile("../../Config/configuration.prc") ShowBase.__init__(self) # Create a new pipeline instance self.renderPipeline = RenderingPipeline(self) # Set the base path for the pipeline. This is required as we are in # a subdirectory self.renderPipeline.getMountManager().setBasePath("../../") # Also set the write path self.renderPipeline.getMountManager().setWritePath("../../Temp/") # Load the default settings self.renderPipeline.loadSettings("../../Config/pipeline.ini") # Now create the pipeline self.renderPipeline.create() # Add a directional light dPos = Vec3(40, 40, 15) dirLight = DirectionalLight() dirLight.setPos(dPos * 1000000.0) dirLight.setShadowMapResolution(1024) dirLight.setCastsShadows(True) dirLight.setColor(Vec3(8)) self.renderPipeline.addLight(dirLight) self.renderPipeline.setScatteringSource(dirLight) self.dirLight = dirLight self.keyMap = { "left": 0, "right": 0, "forward": 0, "cam-left": 0, "cam-right": 0} base.win.setClearColor(Vec4(0, 0, 0, 1)) # Post the instructions self.title = addTitle( "Panda3D Tutorial: Roaming Ralph (Walking on Uneven Terrain)") self.inst1 = addInstructions(0.95, "[ESC]: Quit") self.inst2 = addInstructions(0.90, "[Left Arrow]: Rotate Ralph Left") self.inst3 = addInstructions(0.85, "[Right Arrow]: Rotate Ralph Right") self.inst4 = addInstructions(0.80, "[Up Arrow]: Run Ralph Forward") self.inst6 = addInstructions(0.70, "[A]: Rotate Camera Left") self.inst7 = addInstructions(0.65, "[S]: Rotate Camera Right") # 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.environ = loader.loadModel("models/world") self.environ.reparentTo(render) self.environ.setPos(0, 0, 0) self.environ.find("**/wall").removeNode() # Create the main character, Ralph ralphStartPos = self.environ.find("**/start_point").getPos() self.ralph = Actor("models/ralph", {"run": "models/ralph-run", "walk": "models/ralph-walk"}) self.ralph.reparentTo(render) self.ralph.setScale(.2) self.ralph.setPos(ralphStartPos) self.renderPipeline.setEffect(self.ralph, "Effects/Default/Default.effect", { "dynamic": True }) # 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 self.accept("escape", sys.exit) 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]) 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]) # NOTICE: It is important that your update tasks have a lower priority # than -10000 taskMgr.add(self.move, "moveTask", priority=-20000) self.accept("r", self.reloadShader) # Game state variables self.isMoving = False # Set up the camera base.disableMouse() base.camera.setPos(self.ralph.getX(), self.ralph.getY() + 10, 1.2) # 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.cTrav = CollisionTraverser() 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() self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler) 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 = base.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler) # 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) # Create some ocean self.water = ProjectedWaterGrid(self.renderPipeline) self.water.setWaterLevel(-4.0) # Create the skybox self.skybox = self.renderPipeline.getDefaultSkybox() self.skybox.reparentTo(render) self.prepareSRGB(render) self.reloadShader() self.renderPipeline.onSceneInitialized() # Add demo slider to move the sun position if self.renderPipeline.settings.displayOnscreenDebugger: self.renderPipeline.guiManager.demoSlider.node[ "command"] = self.setSunPos self.renderPipeline.guiManager.demoSlider.node[ "value"] = 50 def setSunPos(self): rawValue = self.renderPipeline.guiManager.demoSlider.node["value"] dPos = Vec3(100, 100, rawValue - 20) self.dirLight.setPos(dPos * 100000000.0) def reloadShader(self): self.renderPipeline.reloadShaders() # Records the state of the arrow keys def setKey(self, key, value): self.keyMap[key] = value def prepareSRGB(self, np): """ Sets the correct texture format for all textures found in <np> """ for tex in np.findAllTextures(): baseFormat = tex.getFormat() if baseFormat == Texture.FRgb: tex.setFormat(Texture.FSrgb) elif baseFormat == Texture.FRgba: tex.setFormat(Texture.FSrgbAlpha) else: print "Unkown texture format:", baseFormat print "\tTexture:", tex # tex.setMinfilter(Texture.FTLinearMipmapLinear) # tex.setMagfilter(Texture.FTLinear) tex.setAnisotropicDegree(16) # Accepts arrow keys to move either the player or the menu cursor, # Also deals with grid checking and collision detection def move(self, task): # If the camera-left key is pressed, move camera left. # If the camera-right key is pressed, move camera right. base.camera.lookAt(self.ralph) if (self.keyMap["cam-left"] != 0): base.camera.setX(base.camera, -20 * globalClock.getDt()) if (self.keyMap["cam-right"] != 0): base.camera.setX(base.camera, +20 * globalClock.getDt()) # save ralph's initial position so that we can restore it, # in case he falls off the map or runs into something. startpos = self.ralph.getPos() # If a move-key is pressed, move ralph in the specified direction. if (self.keyMap["left"] != 0): self.ralph.setH(self.ralph.getH() + 300 * globalClock.getDt()) if (self.keyMap["right"] != 0): self.ralph.setH(self.ralph.getH() - 300 * globalClock.getDt()) if (self.keyMap["forward"] != 0): self.ralph.setY(self.ralph, -25 * globalClock.getDt()) # 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.ralph.loop("run") self.isMoving = True else: if self.isMoving: self.ralph.stop() self.ralph.pose("walk", 5) self.isMoving = False # If the camera is too far from ralph, move it closer. # If the camera is too close to ralph, move it farther. camvec = self.ralph.getPos() - base.camera.getPos() camvec.setZ(0) camdist = camvec.length() camvec.normalize() if (camdist > 7.0): base.camera.setPos(base.camera.getPos() + camvec * (camdist - 7)) camdist = 7.0 if (camdist < 5.0): base.camera.setPos(base.camera.getPos() - camvec * (5 - camdist)) 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.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) # Keep the camera at one foot above the terrain, # or two feet above ralph, 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"): base.camera.setZ(entries[0].getSurfacePoint(render).getZ() + 1.0) if (base.camera.getZ() < self.ralph.getZ() + 2.5): base.camera.setZ(self.ralph.getZ() + 2.5) # The camera should look in ralph's direction, # but it should also try to stay horizontal, so look at # a floater which hovers above ralph's head. self.floater.setPos(self.ralph.getPos()) self.floater.setZ(self.ralph.getZ() + 2.0) base.camera.lookAt(self.floater) return task.cont
class RoamingRalphDemo(ShowBase): def __init__(self): # Setup window size, title and so on load_prc_file_data( "", """ win-size 1600 900 window-title Render Pipeline - Roaming Ralph Demo """) if alt: ShowBase.__init__(self) self.render_pipeline = render_pipeline self.render_pipeline.create(self) else: # ------ Begin of render pipeline code (else case) ------ # Insert the pipeline path to the system path, this is required to be # able to import the pipeline classes #pipeline_path = "../../" # Just a special case for my development setup, so I don't accidentally # commit a wrong path. You can remove this in your own programs. #if not os.path.isfile(os.path.join(pipeline_path, "setup.py")): pipeline_path = "../tobsprRenderPipeline" sys.path.insert(0, pipeline_path) from rpcore import RenderPipeline, SpotLight self.render_pipeline = RenderPipeline() self.render_pipeline.create(self) # ------ End of render pipeline code, thats it! ------ # Set time of day self.render_pipeline.daytime_mgr.time = "7:40" # Use a special effect for rendering the scene, this is because the # roaming ralph model has no normals or valid materials self.render_pipeline.set_effect( render, "roaming_ralph_pipeline_scene-effect.yaml", {}, sort=250) self.keyMap = { "left": 0, "right": 0, "forward": 0, "backward": 0, "cam-left": 0, "cam-right": 0 } self.speed = 1.0 base.win.setClearColor(Vec4(0, 0, 0, 1)) # Post the instructions self.inst1 = addInstructions(0.95, "[ESC] Quit") self.inst4 = addInstructions(0.90, "[W] Run Ralph Forward") self.inst4 = addInstructions(0.85, "[S] Run Ralph Backward") self.inst2 = addInstructions(0.80, "[A] Rotate Ralph Left") self.inst3 = addInstructions(0.75, "[D] Rotate Ralph Right") self.inst6 = addInstructions(0.70, "[Left Arrow] Rotate Camera Left") self.inst7 = addInstructions(0.65, "[Right Arrow] Rotate Camera Right") # 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.environ = loader.loadModel( "roaming_ralph_pipeline_resources/world") self.environ.reparentTo(render) self.environ.setPos(0, 0, 0) # Remove wall nodes self.environ.find("**/wall").remove_node() # Create the main character, Ralph self.ralph = Actor( "roaming_ralph_pipeline_resources/ralph", { "run": "roaming_ralph_pipeline_resources/ralph-run", "walk": "roaming_ralph_pipeline_resources/ralph-walk" }) self.ralph.reparentTo(render) self.ralph.setScale(.2) self.ralph.setPos(Vec3(-110.9, 29.4, 1.8)) # 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 self.accept("escape", sys.exit) self.accept("a", self.setKey, ["left", 1]) self.accept("d", self.setKey, ["right", 1]) self.accept("w", self.setKey, ["forward", 1]) self.accept("s", self.setKey, ["backward", 1]) self.accept("arrow_left", self.setKey, ["cam-left", 1]) self.accept("arrow_right", self.setKey, ["cam-right", 1]) self.accept("a-up", self.setKey, ["left", 0]) self.accept("d-up", self.setKey, ["right", 0]) self.accept("w-up", self.setKey, ["forward", 0]) self.accept("s-up", self.setKey, ["backward", 0]) self.accept("arrow_left-up", self.setKey, ["cam-left", 0]) self.accept("arrow_right-up", self.setKey, ["cam-right", 0]) self.accept("=", self.adjustSpeed, [0.25]) self.accept("+", self.adjustSpeed, [0.25]) self.accept("-", self.adjustSpeed, [-0.25]) taskMgr.add(self.move, "moveTask") # Game state variables self.isMoving = False # Set up the camera base.disableMouse() base.camera.setPos(self.ralph.getX() + 10, self.ralph.getY() + 10, 2) base.camLens.setFov(80) # 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.cTrav = CollisionTraverser() 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() self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler) 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 = base.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler) # 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) # 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 # Adjust movement speed def adjustSpeed(self, delta): newSpeed = self.speed + delta if 0 <= newSpeed <= 3: self.speed = newSpeed # Accepts arrow keys to move either the player or the menu cursor, # Also deals with grid checking and collision detection def move(self, task): # If the camera-left key is pressed, move camera left. # If the camera-right key is pressed, move camera right. base.camera.lookAt(self.ralph) if (self.keyMap["cam-left"] != 0): base.camera.setX(base.camera, +20 * globalClock.getDt()) if (self.keyMap["cam-right"] != 0): base.camera.setX(base.camera, -20 * globalClock.getDt()) # save ralph's initial position so that we can restore it, # in case he falls off the map or runs into something. startpos = self.ralph.getPos() # If a move-key is pressed, move ralph in the specified direction. if (self.keyMap["left"] != 0): self.ralph.setH(self.ralph.getH() + 300 * globalClock.getDt()) elif (self.keyMap["right"] != 0): self.ralph.setH(self.ralph.getH() - 300 * globalClock.getDt()) if (self.keyMap["forward"] != 0): self.ralph.setY(self.ralph, -25 * self.speed * globalClock.getDt()) elif (self.keyMap["backward"] != 0): self.ralph.setY(self.ralph, 25 * self.speed * globalClock.getDt()) # If ralph is moving, loop the run animation. # If he is standing still, stop the animation. if (self.keyMap["forward"]!=0) or (self.keyMap["backward"]!=0) or \ (self.keyMap["left"]!=0) or (self.keyMap["right"]!=0): if self.isMoving is False: self.ralph.loop("run") self.isMoving = True else: if self.isMoving: self.ralph.stop() self.ralph.pose("walk", 5) self.isMoving = False # If the camera is too far from ralph, move it closer. # If the camera is too close to ralph, move it farther. camvec = self.ralph.getPos() - base.camera.getPos() camvec.setZ(0) camdist = camvec.length() camvec.normalize() if (camdist > 10.0): base.camera.setPos(base.camera.getPos() + camvec * (camdist - 10)) camdist = 10.0 if (camdist < 5.0): base.camera.setPos(base.camera.getPos() - camvec * (5 - camdist)) 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.ralphGroundHandler.getNumEntries()): entry = self.ralphGroundHandler.getEntry(i) entries.append(entry) if (len(entries) > 0) and (entries[0].getIntoNode().getName() == "terrain"): self.ralph.setZ(entries[0].getSurfacePoint(render).getZ()) else: self.ralph.setPos(startpos) # Keep the camera at one foot above the terrain, # or two feet above ralph, whichever is greater. entries = [] for i in range(self.camGroundHandler.getNumEntries()): entry = self.camGroundHandler.getEntry(i) entries.append(entry) if (len(entries) > 0) and (entries[0].getIntoNode().getName() == "terrain"): base.camera.setZ(entries[0].getSurfacePoint(render).getZ() + 1.0) if (base.camera.getZ() < self.ralph.getZ() + 2.0): base.camera.setZ(self.ralph.getZ() + 2.0) # The camera should look in ralph's direction, # but it should also try to stay horizontal, so look at # a floater which hovers above ralph's head. self.floater.setPos(self.ralph.getPos()) self.floater.setZ(self.ralph.getZ() + 2.0) base.camera.lookAt(self.floater) return task.cont
class PartyCog(FSM): notify = directNotify.newCategory("PartyCog") HpTextGenerator = TextNode("HpTextGenerator") hpText = None height = 7 def __init__(self, parentNode, id, bounceSpeed=3, bounceHeight=1, rotateSpeed=1, heightShift=1, xMoveSpeed=0, xMoveDistance=0, bounceOffset=0): self.id = id FSM.__init__(self, "PartyCogFSM-%d" % self.id) self.showFacingStatus = False self.xMoveSpeed = xMoveSpeed self.xMoveDistance = xMoveDistance self.heightShift = heightShift self.bounceSpeed = bounceSpeed self.bounceHeight = bounceHeight self.rotateSpeed = rotateSpeed self.parentNode = parentNode self.bounceOffset = bounceOffset self.hitInterval = None self.kaboomTrack = None self.resetRollIval = None self.netTimeSentToStartByHit = 0 self.load() self.request("Down") def load(self): self.root = NodePath("PartyCog-%d" % self.id) self.root.reparentTo(self.parentNode) path = "phase_13/models/parties/cogPinata_" self.actor = Actor( path + "actor", { "idle": path + "idle_anim", "down": path + "down_anim", "up": path + "up_anim", "bodyHitBack": path + "bodyHitBack_anim", "bodyHitFront": path + "bodyHitFront_anim", "headHitBack": path + "headHitBack_anim", "headHitFront": path + "headHitFront_anim", }) self.actor.reparentTo(self.root) self.temp_transform = Mat4() self.head_locator = self.actor.attachNewNode("temphead") self.bodyColl = CollisionTube(0, 0, 1, 0, 0, 5.75, 0.75) self.bodyColl.setTangible(1) self.bodyCollNode = CollisionNode("PartyCog-%d-Body-Collision" % self.id) self.bodyCollNode.setCollideMask(ToontownGlobals.PieBitmask) self.bodyCollNode.addSolid(self.bodyColl) self.bodyCollNodePath = self.root.attachNewNode(self.bodyCollNode) self.headColl = CollisionTube(0, 0, 3, 0, 0, 3.0, 1.5) self.headColl.setTangible(1) self.headCollNode = CollisionNode("PartyCog-%d-Head-Collision" % self.id) self.headCollNode.setCollideMask(ToontownGlobals.PieBitmask) self.headCollNode.addSolid(self.headColl) self.headCollNodePath = self.root.attachNewNode(self.headCollNode) # Cog's Left Arm self.arm1Coll = CollisionSphere(1.65, 0, 3.95, 1.0) self.arm1Coll.setTangible(1) self.arm1CollNode = CollisionNode("PartyCog-%d-Arm1-Collision" % self.id) self.arm1CollNode.setCollideMask(ToontownGlobals.PieBitmask) self.arm1CollNode.addSolid(self.arm1Coll) self.arm1CollNodePath = self.root.attachNewNode(self.arm1CollNode) # Cog's Right Arm self.arm2Coll = CollisionSphere(-1.65, 0, 3.45, 1.0) self.arm2Coll.setTangible(1) self.arm2CollNode = CollisionNode("PartyCog-%d-Arm2-Collision" % self.id) self.arm2CollNode.setCollideMask(ToontownGlobals.PieBitmask) self.arm2CollNode.addSolid(self.arm2Coll) self.arm2CollNodePath = self.root.attachNewNode(self.arm2CollNode) splatName = 'splat-creampie' self.splat = globalPropPool.getProp(splatName) self.splat.setBillboardPointEye() self.splatType = globalPropPool.getPropType(splatName) self.pieHitSound = globalBattleSoundCache.getSound( 'AA_wholepie_only.mp3') self.upSound = globalBattleSoundCache.getSound('AV_jump_to_side.mp3') self.hole = loader.loadModel("phase_13/models/parties/cogPinataHole") self.hole.setTransparency(True) self.hole.setP(-90.0) self.hole.setScale(3) self.hole.setBin("ground", 3) self.hole.reparentTo(self.parentNode) def unload(self): self.request("Off") self.clearHitInterval() if self.hole is not None: self.hole.removeNode() self.hole = None if self.actor is not None: self.actor.cleanup() self.actor.removeNode() self.actor = None if self.root is not None: self.root.removeNode() self.root = None if self.kaboomTrack is not None and self.kaboomTrack.isPlaying(): self.kaboomTrack.finish() self.kaboomTrack = None if self.resetRollIval is not None and self.resetRollIval.isPlaying(): self.resetRollIval.finish() self.resetRollIval = None if self.hitInterval is not None and self.hitInterval.isPlaying(): self.hitInterval.finish() self.hitInterval = None del self.upSound del self.pieHitSound #=============================================================================== # FSM States #=============================================================================== def enterStatic(self): pass def exitStatic(self): pass def enterActive(self, startTime): self.root.setR(0.0) updateTask = Task.Task(self.updateTask) updateTask.startTime = startTime taskMgr.add(updateTask, "PartyCog.update-%d" % self.id) def exitActive(self): taskMgr.remove("PartyCog.update-%d" % self.id) taskMgr.remove("PartyCog.bounceTask-%d" % self.id) self.clearHitInterval() self.resetRollIval = self.root.hprInterval(0.5, Point3( self.root.getH(), 0.0, 0.0), blendType="easeInOut") self.resetRollIval.start() self.actor.stop() def enterDown(self): if self.oldState == "Off": self.actor.pose("down", self.actor.getNumFrames("down") - 1) return self.clearHitInterval() startScale = self.hole.getScale() endScale = Point3(5, 5, 5) self.hitInterval = Sequence( LerpFunc(self.setAlongSpline, duration=1.0, fromData=self.currentT, toData=0.0), LerpScaleInterval(self.hole, duration=0.175, scale=endScale, startScale=startScale, blendType="easeIn"), Parallel( SoundInterval(self.upSound, volume=0.6, node=self.actor, cutOff=PartyGlobals.PARTY_COG_CUTOFF), ActorInterval(self.actor, "down", loop=0), ), LerpScaleInterval(self.hole, duration=0.175, scale=Point3(3, 3, 3), startScale=endScale, blendType="easeOut"), ) self.hitInterval.start() def exitDown(self): self.root.setR(0.0) self.root.setH(0.0) self.targetDistance = 0.0 self.targetFacing = 0.0 self.currentT = 0.0 self.setAlongSpline(0.0) self.clearHitInterval() startScale = self.hole.getScale() endScale = Point3(5, 5, 5) self.hitInterval = Sequence( LerpScaleInterval(self.hole, duration=0.175, scale=endScale, startScale=startScale, blendType="easeIn"), Parallel( SoundInterval(self.upSound, volume=0.6, node=self.actor, cutOff=PartyGlobals.PARTY_COG_CUTOFF), ActorInterval(self.actor, "up", loop=0), ), Func(self.actor.loop, "idle"), LerpScaleInterval(self.hole, duration=0.175, scale=Point3(3, 3, 3), startScale=endScale, blendType="easeOut"), ) self.hitInterval.start() def filterDown(self, request, args): if request == "Down": return None else: return self.defaultFilter(request, args) #------------------------------------------------------------------------------ def setEndPoints(self, start, end, amplitude=1.7): self.sinAmplitude = amplitude self.sinPeriod = (end.getX() - start.getX()) / 2 self.sinDisplacement = start.getY() self.startPoint = start self.endPoint = end self.currentT = 0.0 self.targetDistance = 0.0 self.currentFacing = 0.0 self.targetFacing = 0.0 self.setAlongSpline(self.currentT) self.hole.setPos(self.root.getPos()) self.hole.setZ(0.02) def rockBackAndForth(self, task): t = task.startTime + task.time angle = math.sin(t) * 20.0 self.root.setR(angle) # if self.id == 0: # print angle return task.cont def updateDistance(self, distance): self.targetDistance = clamp(distance, -1.0, 1.0) def updateTask(self, task): self.rockBackAndForth(task) if self.targetDistance > self.currentT: self.currentT += min(0.01, self.targetDistance - self.currentT) self.setAlongSpline(self.currentT) elif self.targetDistance < self.currentT: self.currentT += max(-0.01, self.targetDistance - self.currentT) self.setAlongSpline(self.currentT) if self.currentT < 0.0: self.targetFacing = -90.0 elif self.currentT > 0.0: self.targetFacing = 90.0 else: self.targetFacing = 0.0 if self.targetFacing > self.currentFacing: self.currentFacing += min(10, self.targetFacing - self.currentFacing) elif self.targetFacing < self.currentFacing: self.currentFacing += max(-10, self.targetFacing - self.currentFacing) self.root.setH(self.currentFacing) return task.cont def setAlongSpline(self, t): t = t + 1.0 dist = (self.endPoint.getX() - self.startPoint.getX()) / 2.0 x = self.startPoint.getX() + t * dist y = self.startPoint.getY() - math.sin( t * 2 * math.pi) * self.sinAmplitude self.root.setPos(x, y, 0) def startBounce(self): taskMgr.add(self.bounce, "PartyCog.bounceTask-%d" % self.id) def bounce(self, task): #self.root.setH(self.root.getH() - self.rotateSpeed) self.root.setZ((math.sin((self.bounceOffset + task.time) * self.bounceSpeed) * self.bounceHeight) + self.heightShift) return task.cont def setPos(self, position): self.root.setPos(position) def respondToPieHit(self, timestamp, position, hot=False, direction=1.0): """The toon hit us, react appropriately.""" assert (self.notify.debugStateCall(self)) if self.netTimeSentToStartByHit < timestamp: self.__showSplat(position, direction, hot) if self.netTimeSentToStartByHit < timestamp: self.netTimeSentToStartByHit = timestamp else: #self.notify.debug('localStamp = %s, lastLocalTimeStampFromAI=%s, ignoring respondToPieHit' % (localStamp, self.lastLocalTimeStampFromAI)) self.notify.debug( 'respondToPieHit self.netTimeSentToStartByHit = %s' % self.netTimeSentToStartByHit) def clearHitInterval(self): if self.hitInterval is not None and self.hitInterval.isPlaying(): self.hitInterval.clearToInitial() def __showSplat(self, position, direction, hot=False): """Show the splat graphic and sound.""" if self.kaboomTrack is not None and self.kaboomTrack.isPlaying(): self.kaboomTrack.finish() self.clearHitInterval() splatName = 'splat-creampie' self.splat = globalPropPool.getProp(splatName) self.splat.setBillboardPointEye() self.splat.reparentTo(render) self.splat.setPos(self.root, position) self.splat.setAlphaScale(1.0) if not direction == 1.0: #self.splat.setColorScale(Vec4(0.0, 0.0, 50.0, 1.0)) self.splat.setColorScale(PartyGlobals.CogActivitySplatColors[0]) if self.currentFacing > 0.0: facing = "HitFront" else: facing = "HitBack" else: self.splat.setColorScale(PartyGlobals.CogActivitySplatColors[1]) #self.splat.setColorScale(Vec4(1.0, 0.6, 0.08, 1.0)) if self.currentFacing > 0.0: facing = "HitBack" else: facing = "HitFront" if hot: targetscale = 0.75 part = "head" else: targetscale = 0.5 part = "body" def setSplatAlpha(amount): self.splat.setAlphaScale(amount) self.hitInterval = Sequence( ActorInterval(self.actor, part + facing, loop=0), Func(self.actor.loop, "idle"), ) self.hitInterval.start() self.kaboomTrack = Parallel( SoundInterval(self.pieHitSound, volume=1.0, node=self.actor, cutOff=PartyGlobals.PARTY_COG_CUTOFF), Sequence( Func(self.splat.showThrough), Parallel( Sequence( LerpScaleInterval(self.splat, duration=0.175, scale=targetscale, startScale=Point3(0.1, 0.1, 0.1), blendType="easeOut"), Wait(0.175), ), Sequence( Wait(0.1), LerpFunc( setSplatAlpha, duration=1.0, #0.4, fromData=1.0, toData=0.0, blendType="easeOut"))), Func(self.splat.cleanup), Func(self.splat.removeNode), )) self.kaboomTrack.start() def showHitScore(self, number, scale=1): """ Shows the hit score. Borrowed from otp.avatar.DistributedAvatar.showHpText """ if number <= 0: return # Get rid of the number if it is already there. if self.hpText: self.hideHitScore() # Set the font self.HpTextGenerator.setFont(ToontownGlobals.getSignFont()) # Show both negative and positive signs if number < 0: self.HpTextGenerator.setText(str(number)) else: self.HpTextGenerator.setText("+" + str(number)) # No shadow self.HpTextGenerator.clearShadow() # Center the number self.HpTextGenerator.setAlign(TextNode.ACenter) # Red, always #if number < 0: r = 1 #0.9 g = 1 #0 b = 0 a = 1 self.HpTextGenerator.setTextColor(r, g, b, a) self.hpTextNode = self.HpTextGenerator.generate() # Put the hpText over the head of the avatar self.hpText = render.attachNewNode(self.hpTextNode) self.hpText.setScale(scale) # Make sure it is a billboard self.hpText.setBillboardPointEye() # Render it after other things in the scene. self.hpText.setBin('fixed', 100) # Initial position ... Center of the body... the "tan tien" self.hpText.setPos(self.root, 0, 0, self.height / 2) # Black magic from the early days of Panda3D, later replaced by a Sequence seq = Task.sequence( # Fly the number out of the character self.hpText.lerpPos(Point3( self.root.getX(render), self.root.getY(render), self.root.getZ(render) + self.height + 1.0), 0.25, blendType='easeOut'), Task.pause(0.25), # Fade the number self.hpText.lerpColor(Vec4(r, g, b, a), Vec4(r, g, b, 0), 0.1), # Get rid of the number Task.Task(self.__hideHitScoreTask)) taskMgr.add(seq, "PartyCogHpText" + str(self.id)) def __hideHitScoreTask(self, task): self.hideHitScore() return Task.done def hideHitScore(self): if self.hpText: taskMgr.remove("PartyCogHpText" + str(self.id)) self.hpText.removeNode() self.hpText = None def getHeadLocation(self): (self.actor.getJoints(jointName="head")[0]).getNetTransform( self.temp_transform) self.head_locator.setMat(self.temp_transform) #print self.head_locator.getZ() return self.head_locator.getZ(self.root)
class Hero(DirectObject, MovableObject): def __init__(self, pos=(0, 0, 0), scale=1, parent=None): DirectObject.__init__(self) MovableObject.__init__(self) # 英雄属性 self._maxHP = defaultHeroHP self._HP = defaultHeroHP self._attackPower = defaultHeroAttackPower self._attackSpeed = defaultHeroAttackSpeed self.isMoving = False self._moveSpeed = defaultHeroMoveSpeed self.mousePos = (0, 0, 0) self.leapAttackTime = -1 #英雄被击闪烁 self.invincible = False #是否无敌 self.changeTime = -1 #下次变换形态时间 self.recoveryTime = -1 #恢复正常的时间 self.isHide = False ########## set model size hero self.bullet = SphereBullet( ) #(intoMask = CollideMask.bit(DefaultMonsterMaskVal)) if not self.bullet.model.isEmpty(): self.bullet.model.removeNode() self.attackMode = "Common" self.lastAttackTime = 0 # to enable shoutting at the beginning self.position = pos self.initAttackMethod = self.attack #'model_dierguanBOSS',{ # # 英雄模型和相应动画 self.model = Actor( HeroModelPath + "model_mainChara", { "Walk": HeroModelPath + "anim_mainChara_running_attack", #"Attack": HeroModelPath + "anim_mainChara_standing", "Hit": HeroModelPath + "anim_mainChara_standing", "Die": HeroModelPath + "anim_mainChara_standing" }) if parent == None: self.model.reparentTo(base.render) else: self.model.reparentTo(parent) self.model.setPos(self.position) self.lastPos = self.position self.scale = scale self.model.setScale(scale) self.model.hide() # 设置碰撞检测 self.colliderName = "hero" characterSphere = CollisionSphere(0, 0, 2, 1) characterColNode = CollisionNode(self.colliderName) characterColNode.addSolid(characterSphere) characterColNode.setFromCollideMask( CollideMask.bit(DefaultHeroMaskVal) ^ CollideMask.bit(defaultHeroInMonsterMaskVal)) # print characterColNode.getFromCollideMask() self.colliderNodePath = self.model.attachNewNode(characterColNode) #self.colliderNodePath.show() #将对象添加到nodepath中 用于在碰撞事件处理中获取对象 self.colliderNodePath.setPythonTag("Hero", self) base.cTrav.addCollider(self.colliderNodePath, base.cHandler) #用于处理英雄与墙壁的碰撞 characterSphere2 = CollisionSphere(0, 0, 2, 1) characterColNode2 = CollisionNode(self.colliderName) characterColNode2.addSolid(characterSphere2) self.colliderNodePath2 = self.model.attachNewNode(characterColNode2) self.modelGroundHandler = CollisionHandlerQueue() base.cTrav.addCollider(self.colliderNodePath2, self.modelGroundHandler) # #用于支持英雄与怪物的物理碰撞 characterSphere3 = CollisionSphere(0, 0, 2, 1) characterColNode3 = CollisionNode(self.colliderName) characterColNode3.addSolid(characterSphere3) self.colliderNodePath3 = self.model.attachNewNode(characterColNode3) base.cPusher.addCollider(self.colliderNodePath3, self.model) #用于支持鼠标控制英雄的朝向---------------- self.angle = 0 self.pickerName = 'mouseRay' self.pickerNode = CollisionNode(self.pickerName) self.pickerNP = camera.attachNewNode(self.pickerNode) self.pickerNode.setFromCollideMask(CollideMask.bit(5)) self.pickerNode.setIntoCollideMask(CollideMask.allOff()) self.pickerRay = CollisionRay() self.pickerNode.addSolid(self.pickerRay) #self.pickerNP.show() base.cTrav.addCollider(self.pickerNP, base.cHandler) self.pickedName = 'mousePlane' self.pickedNode = CollisionNode(self.pickedName) self.pickedNP = render.attachNewNode(self.pickedNode) self.pickedNode.setFromCollideMask(CollideMask.allOff()) self.pickedNode.setIntoCollideMask(CollideMask.bit(5)) self.pickedPlane = CollisionPlane( LPlane(LVector3f(0, 0, 1), LPoint3f(0, 0, 2))) self.pickedNode.addSolid(self.pickedPlane) #self.pickedNP.show() #------------------------------------ #加载英雄的各种音效 self.sounds["GetItem"] = loader.loadSfx(HeroSoundPath + "getItem.wav") self.sounds["Die"] = loader.loadSfx(HeroSoundPath + "robot_death.wav") self.sounds["Attack"] = loader.loadSfx(HeroSoundPath + "bullet_shooting.wav") #键位字典 self.keyMap = { "left": 0, "right": 0, "forward": 0, "back": 0, "fire": 0 } self._initAccept() def _initAccept(self): againEvent = '{}-again-{}' self.accept(againEvent.format(self.pickerName, self.pickedName), self._accept_ray_into_plane) def _accept_ray_into_plane(self, entry): pos = entry.getSurfacePoint(render) self.mousePos = LPoint3(pos[0], pos[1], pos[2]) x, y = pos.get_x() - self.model.getPos().get_x(), pos.get_y( ) - self.model.getPos().get_y() angle = math.atan2(y, x) angle = angle * 180 / math.pi + 90 self.angle = angle # maxHP @property def maxHP(self): return self._maxHP @maxHP.setter def maxHP(self, value): if value > defaultHeroMaxHPMax: value = defaultHeroMaxHPMax self._maxHP = value # HP @property def HP(self): return self._HP @HP.setter def HP(self, value): if value > self._maxHP: value = self._maxHP self._HP = value # attackPower @property def attackPower(self): return self._attackPower @attackPower.setter def attackPower(self, value): if value > defaultHeroAttackPowerMax: value = defaultHeroAttackPowerMax self._attackPower = value # attackSpeed @property def attackSpeed(self): return self._attackSpeed @attackSpeed.setter def attackSpeed(self, value): if value > defaultHeroAttackSpeedMax: value = defaultHeroAttackSpeedMax self._attackSpeed = value # moveSpeed @property def moveSpeed(self): return self._moveSpeed @moveSpeed.setter def moveSpeed(self, value): if value > defaultHeroMoveSpeedMax: value = defaultHeroMoveSpeedMax self._moveSpeed = value def setPos(self, pos): self.position = pos self.model.setPos(pos) def setScale(self, scale): self.scale = scale self.model.setScale(scale) def setEnemy(self, enemy): if isinstance(enemy, Monster): #inEvent = "{}-into-{}".format(enemy.colliderName,self.colliderName ) inEvent = "{}-into-{}".format(self.colliderName, enemy.colliderName) self.accept(inEvent, self.underAttack) if isinstance(enemy, Bullet): inEvent = "{}-into-{}".format(self.colliderName, enemy.colliderName) base.cHandler.addInPattern(inEvent) enemy.accept(inEvent, enemy.action) def move(self): dt = base.globalClock.getDt() x = self.model.getX() y = self.model.getY() dis = self._moveSpeed * dt #控制移动 if self.keyMap['forward']: y += dis if self.keyMap['back']: y -= dis if self.keyMap['left']: x -= dis if self.keyMap['right']: x += dis if x == self.model.getX() and y == self.model.getY(): if self.isMoving: self.model.stop() self.model.pose("walk", 0) self.isMoving = False elif not self.isMoving: self.model.loop('Walk') self.isMoving = True self.model.setX(x) self.model.setY(y) # 控制面朝向 self.updateDirection() #是否与房间(墙壁)碰撞 base.cTrav.traverse(base.render) entries = list(self.modelGroundHandler.getEntries()) entries.sort(key=lambda x: x.getSurfacePoint(base.render).getZ()) backup = False for entry in entries: if entry.getIntoNode().getName() == "room": backup = True break if backup: self.model.setPos(self.lastPos) else: self.lastPos = self.model.getPos() #base.camera.setPos(self.model.getX(), self.model.getY()+20, 20) #base.camera.lookAt(self.model) def updateDirection(self): self.model.setH(self.angle) def updateRay(self): ''' 在主循环中更新 人物朝向控制射线的方向 ''' if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY()) def attack(self, taskTime): ''' taskTime 无效参数,可以重新赋值 ''' angle = self.angle # 是否过了攻击冷却期 currTime = time.time() split = currTime - self.lastAttackTime if standarHitRate * 1.0 / self.attackSpeed > split: return # 更新上一次攻击的时间 self.lastAttackTime = currTime # 播放攻击动画 self.model.play("Attack") # 播放攻击音效 self.sounds["Attack"].play() # 子弹位置 pos = self.model.getPos() bullet = self.bullet.copy() #SphereBullet()#copy.deepcopy(self.bullet) bullet.model.reparentTo(render) bullet.setPos(pos) bullet.setZ(2) # bullet.getZ() + # 子弹生命周期(消亡的时间) bullet.setExpires(currTime + bullet.bulletLife) #bullet.bulletLife # 子弹飞行方向 bullet.setAngle(angle) # 子弹伤害值 ( 子弹本身伤害值 + 英雄攻击力 ) bullet.damage += self.attackPower bullet.model.show() # 注册子弹 base.messenger.send("bullet-create", [bullet]) def leapAttack(self, pos, size, speed): if self.leapAttackTime > time.time(): return self.leapAttackTime = time.time() + 2 bullet = LeapBullet(pos, DefaultMonsterMaskVal, size, speed) base.messenger.send("bullet-create", [bullet]) def update(self): self.updateInvincible() self.updateRay() self.move() self.updateDirection() if self.keyMap["fire"]: self.attack(time.time) self.keyMap["fire"] = False def updateInvincible(self): #处理无敌状态 if self.recoveryTime > time.time(): self.invincible = True if self.changeTime < time.time(): if self.isHide: self.isHide = False self.model.show() self.changeTime = time.time() + 0.2 else: self.isHide = True self.model.hide() self.changeTime = time.time() + 0.2 else: self.model.show() self.invincible = False def underAttack(self, val=defaultHeroHitByMonsterDamageVal): if self.invincible == True: return self.model.play("Hit") self.decreaseHP(val) self.recoveryTime = time.time() + 1.5 def decreaseHP(self, val): self.HP -= val if self.HP < 0: self.HP = 0 base.messenger.send("hero-HPChange", [self.HP]) if self.HP == 0: if Debug: return self.die() def increaseHP(self, val): self.HP += val if self.HP > self.maxHP: self.HP = self.maxHP base.messenger.send("hero-HPChange", [self.HP]) def increaseMaxHP(self, val): self.maxHP += val base.messenger.send("hero-maxHPChange", [self.maxHP]) def die(self): self.doMethodLater(self.model.getDuration("Die"), self.destroy, "hero-die") self.model.play("Die") self.sounds["Die"].play() # 防止继续移动 旋转 self.ignoreAll() base.taskMgr.remove("hero-Loop") def destroy(self, task): base.messenger.send("hero-die") @staticmethod def ToDict(hero): dict = {} dict["maxHP"] = hero.maxHP dict["HP"] = hero.HP dict["attackPower"] = hero.attackPower dict["attackSpeed"] = hero.attackSpeed dict["moveSpeed"] = hero._moveSpeed dict["bullet"] = hero.bullet.ToDict(hero.bullet) dict["pos"] = [hero.position[0], hero.position[1], hero.position[2]] dict["scale"] = hero.scale dict["attackMode"] = hero.attackMode return dict @staticmethod def ToHero(dict): hero = Hero() hero.maxHP = dict["maxHP"] hero.HP = dict["HP"] hero.attackPower = dict["attackPower"] hero.attackSpeed = dict["attackSpeed"] hero.setPos(LVecBase3f(dict["pos"][0], dict['pos'][1], dict['pos'][2])) hero.setScale(dict["scale"]) hero._moveSpeed = dict["moveSpeed"] hero.attackMode = dict["attackMode"] hero.bullet = BulletFactory.getBullet(dict["bullet"], hero) return hero def reInit(self, dict, renew=False): self.maxHP = dict["maxHP"] self.HP = dict["HP"] self.attackPower = dict["attackPower"] self.attackSpeed = dict["attackSpeed"] self._moveSpeed = dict["moveSpeed"] self.attackMode = dict["attackMode"] self.bullet = BulletFactory.getBullet(dict["bullet"], self) self.setPos(LVecBase3f(dict["pos"][0], dict['pos'][1], dict['pos'][2])) self.setScale(dict["scale"]) if renew: self.attack = self.initAttackMethod self._initAccept()
class RoamingRalphDemo(ShowBase): def __init__(self): # Set up the window, camera, etc. ShowBase.__init__(self) # Set the background color to black self.win.setClearColor((0, 0, 0, 1)) # This is used to store which keys are currently pressed. self.keyMap = { "left": 0, "right": 0, "forward": 0, "cam-left": 0, "cam-right": 0} # Post the instructions self.title = addTitle( "Panda3D Tutorial: Roaming Ralph (Walking on Uneven Terrain)") self.inst1 = addInstructions(0.06, "[ESC]: Quit") self.inst2 = addInstructions(0.12, "[Left Arrow]: Rotate Ralph Left") self.inst3 = addInstructions(0.18, "[Right Arrow]: Rotate Ralph Right") self.inst4 = addInstructions(0.24, "[Up Arrow]: Run Ralph Forward") self.inst6 = addInstructions(0.30, "[A]: Rotate Camera Left") self.inst7 = addInstructions(0.36, "[S]: Rotate Camera Right") self.dirText = addInstructions(0.42, "pos") self.anglesText = addInstructions(0.48, "angle") # 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.environ = loader.loadModel("models/world") #self.environ.reparentTo(render) self.createArm() # Create the main character, Ralph #ralphStartPos = self.environ.find("**/start_point").getPos() self.ralph = Actor("models/ralph", {"run": "models/ralph-run", "walk": "models/ralph-walk"}) self.ralph.reparentTo(render) self.ralph.setScale(.2) #self.ralph.setPos(ralphStartPos + (0, 0, 0.5)) # Create a floater object, which floats 2 units above ralph. We # use this as a target for the camera to look at. self.floater = NodePath(PandaNode("floater")) self.floater.reparentTo(self.ralph) self.floater.setZ(2.0) # Accept the control keys for movement and rotation self.accept("escape", self.exitButton) self.accept("arrow_left", self.setKey, ["left", True]) self.accept("arrow_right", self.setKey, ["right", True]) self.accept("arrow_up", self.setKey, ["forward", True]) self.accept("a", self.setKey, ["cam-left", True]) self.accept("s", self.setKey, ["cam-right", True]) self.accept("arrow_left-up", self.setKey, ["left", False]) self.accept("arrow_right-up", self.setKey, ["right", False]) self.accept("arrow_up-up", self.setKey, ["forward", False]) self.accept("a-up", self.setKey, ["cam-left", False]) self.accept("s-up", self.setKey, ["cam-right", False]) taskMgr.add(self.move, "moveTask") # Game state variables self.isMoving = False # Set up the camera self.disableMouse() self.camera.setPos(15, 0, 3)#self.ralph.getX(), self.ralph.getY() + 10, 2) self.camera.setHpr(90, -5, 0) # 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.cTrav = CollisionTraverser() self.ralphGroundRay = CollisionRay() self.ralphGroundRay.setOrigin(0, 0, 9) self.ralphGroundRay.setDirection(0, 0, -1) self.ralphGroundCol = CollisionNode('ralphRay') self.ralphGroundCol.addSolid(self.ralphGroundRay) self.ralphGroundCol.setFromCollideMask(CollideMask.bit(0)) self.ralphGroundCol.setIntoCollideMask(CollideMask.allOff()) self.ralphGroundColNp = self.ralph.attachNewNode(self.ralphGroundCol) self.ralphGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler) self.camGroundRay = CollisionRay() self.camGroundRay.setOrigin(0, 0, 9) self.camGroundRay.setDirection(0, 0, -1) self.camGroundCol = CollisionNode('camRay') self.camGroundCol.addSolid(self.camGroundRay) self.camGroundCol.setFromCollideMask(CollideMask.bit(0)) self.camGroundCol.setIntoCollideMask(CollideMask.allOff()) self.camGroundColNp = self.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler) # 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) # Create some lighting ambientLight = AmbientLight("ambientLight") ambientLight.setColor((.3, .3, .3, 1)) directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection((-5, -5, -5)) directionalLight.setColor((1, 1, 1, 1)) directionalLight.setSpecularColor((1, 1, 1, 1)) render.setLight(render.attachNewNode(ambientLight)) render.setLight(render.attachNewNode(directionalLight)) def exitButton(self): servos.exit() __import__('sys').exit() def createArm(self): self.robotarm = Actor("models/robotarm") self.robotarm.reparentTo(render) self.robotarm.setPos(0,0,0) self.robotarm.setScale(.2) self.jointForearm = self.robotarm.controlJoint(None, "modelRoot", "forearm") self.jointBase = self.robotarm.controlJoint(None, "modelRoot", "base") taskMgr.add(self.monitorArm, "robot arm") inc = 15 self.accept("i", self.setForearm, [inc]) self.accept("u", self.setForearm, [-inc]) self.accept("j", self.setBase, [inc]) self.accept("k", self.setBase, [-inc]) def monitorArm(self, task): def clamp1(x): return min(1, max(-1, x)) direction = self.ralph.get_pos() - self.robotarm.get_pos() direction.z += 1 direction.normalize() # camera starts facing along x dec = math.asin(direction.x) cosdec = math.cos(dec) if cosdec > 1e-05: ra = math.asin(clamp1(direction.z / cosdec)) ra2 = math.acos(clamp1(direction.y / cosdec)) else: ra = ra2 = math.pi/2#float('nan') #print(cosdec, direction) #print(dec, ra, ra2, cosdec) if direction.z < 0: if ra2 < math.pi/2: ra2 = 0 else: ra2 = math.pi self.jointForearm.setH(-dec * 180/math.pi) self.jointBase.setP(ra2 * 180/math.pi) self.dirText.setText(str(direction)) self.anglesText.setText(str((dec, ra, ra2, cosdec))) a = self.jointForearm.getH() / 90.0 * 300 + 512 b = self.jointBase.getP() / 90.0 * 300 + 212 #print(a, b) baseID = 9 servos.setAngle({baseID:int(round(b)), (baseID+1):int(round(a))}) return task.again def monitorArmServos(self, task): baseID = 9 a = self.jointForearm.getH() / 90.0 * 300 + 512 b = self.jointBase.getP() / 90.0 * 300 + 212 #print(a, b) servos.setAngle({baseID:int(round(a)), (baseID+1):int(round(b))}) # frac = task.time - int(task.time) # if frac > .9 and frac < .99: #print(self.jointForearm.getH(), self.jointBase.getP()) return task.again def setForearm(self, inc): #self.jointForearm.setH(random.random()*180-90) self.jointForearm.setH(self.jointForearm.getH() + inc) def setBase(self, inc): #self.jointBase.setP(random.random()*180) self.jointBase.setP(self.jointBase.getP() + inc) # Records the state of the arrow keys def setKey(self, key, value): 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): # Get the time that elapsed since last frame. We multiply this with # the desired speed in order to find out with which distance to move # in order to achieve that desired speed. dt = globalClock.getDt() # If the camera-left key is pressed, move camera left. # If the camera-right key is pressed, move camera right. if self.keyMap["cam-left"]: self.camera.setX(self.camera, -20 * dt) if self.keyMap["cam-right"]: self.camera.setX(self.camera, +20 * dt) # save ralph's initial position so that we can restore it, # in case he falls off the map or runs into something. startpos = self.ralph.getPos() # If a move-key is pressed, move ralph in the specified direction. if self.keyMap["left"]: self.ralph.setH(self.ralph.getH() + 300 * dt) if self.keyMap["right"]: self.ralph.setH(self.ralph.getH() - 300 * dt) if self.keyMap["forward"]: self.ralph.setY(self.ralph, -25 * dt) # If ralph is moving, loop the run animation. # If he is standing still, stop the animation. if self.keyMap["forward"] or self.keyMap["left"] or self.keyMap["right"]: if self.isMoving is False: self.ralph.loop("run") self.isMoving = True else: if self.isMoving: self.ralph.stop() self.ralph.pose("walk", 5) self.isMoving = False # If the camera is too far from ralph, move it closer. # If the camera is too close to ralph, move it farther. """camvec = self.ralph.getPos() - self.camera.getPos() camvec.setZ(0) camdist = camvec.length() camvec.normalize() if camdist > 10.0: self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10)) camdist = 10.0 if camdist < 5.0: self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist)) camdist = 5.0 # Normally, we would have to call traverse() to check for collisions. # However, the class ShowBase that we inherit from has a task to do # this for us, if we assign a CollisionTraverser to self.cTrav. #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 = list(self.ralphGroundHandler.getEntries()) entries.sort(key=lambda x: 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) # Keep the camera at one foot above the terrain, # or two feet above ralph, whichever is greater. entries = list(self.camGroundHandler.getEntries()) entries.sort(key=lambda x: x.getSurfacePoint(render).getZ()) if len(entries) > 0 and entries[0].getIntoNode().getName() == "terrain": self.camera.setZ(entries[0].getSurfacePoint(render).getZ() + 1.0) if self.camera.getZ() < self.ralph.getZ() + 2.0: self.camera.setZ(self.ralph.getZ() + 2.0) # The camera should look in ralph's direction, # but it should also try to stay horizontal, so look at # a floater which hovers above ralph's head. self.camera.lookAt(self.floater)""" return task.cont
class ClusterHowitzer: """Cluster bombs launcher locomotive upgrade. Args: loc_model (panda3d.core.NodePath): The locomotive model. """ def __init__(self, loc_model): self._is_loading = False self.is_up = False self._coors = [None, None, None, None] self._sights = [] self._explosions = [] self._ground_holes = [] self._smokes = [] self._bombs = [] self._explosion_snds = [] self._train_mod = loc_model self._model = Actor(address("cluster_bomb_launcher")) self._model.reparentTo(loc_model) for _ in range(4): sight = loader.loadModel(address("grenade_sight")) # noqa: F82 sight.reparentTo(loc_model) sight.hide() self._sights.append(sight) explosion = ParticleEffect() explosion.loadConfig("effects/grenade_explode.ptf") self._explosions.append(explosion) smoke = ParticleEffect() smoke.loadConfig("effects/bomb_smoke1.ptf") self._smokes.append(smoke) snd = loader.loadSfx("sounds/combat/bomb_explosion1.ogg") # noqa: F821 snd.setVolume(random.uniform(0.1, 0.15)) snd.setPlayRate(random.uniform(0.8, 1)) self._explosion_snds.append(snd) hole = loader.loadModel(address("ground_hole")) # noqa: F821 hole.reparentTo(loc_model) hole.setTransparency(TransparencyAttrib.MAlpha) hole.hide() self._ground_holes.append(hole) self._load_snd = loader.loadSfx("sounds/combat/howitzer_load.ogg") # noqa: F821 self._load_snd.setPlayRate(0.8) base.accept("3", self.change_state) # noqa: F82 def _change_mode(self, task): """Change the launcher mode: aiming or idle.""" if self.is_up: self._end_aiming() else: taskMgr.doMethodLater(0.05, self._show_sights, "show_sights") # noqa: F82 base.common_ctrl.deselect() # noqa: F82 base.accept("mouse1", self._shot) # noqa: F821 self.is_up = not self.is_up self._is_loading = False return task.done def _show_sights(self, task): """Show four aiming sights.""" self._move_sights() for sight in self._sights: sight.show() taskMgr.doMethodLater(1, self._move_sights, "move_cluster_sights") # noqa: F82 return task.done def _end_aiming(self): """End aiming mode, hide sights.""" for sight in self._sights: sight.hide() taskMgr.remove("move_cluster_sights") # noqa: F82 base.common_ctrl.set_mouse_events() # noqa: F82 def _shot(self): """Make a cluster howitzer shot.""" self.change_state() base.ignore("3") # noqa: F82 rocket = loader.loadModel(address("cluster_rocket")) # noqa: F82 rocket.reparentTo(self._model) rocket.setPos(0, -0.325, 0.3) rocket.setP(20) smoke = ParticleEffect() smoke.loadConfig("effects/smoke_tail.ptf") smoke.start(rocket, render) # noqa: F821 hiss_snd = base.sound_mgr.loadSfx("sounds/rocket_fly.ogg") # noqa: F821 base.sound_mgr.attachSoundToObject(hiss_snd, rocket) # noqa: F821 hiss_snd.play() open_snd = base.sound_mgr.loadSfx("sounds/cluster_open.ogg") # noqa: F821 base.sound_mgr.attachSoundToObject(open_snd, rocket) # noqa: F821 Sequence( Parallel( LerpPosInterval(rocket, 2, (0, 1.8, 3)), LerpHprInterval(rocket, 2, (0, 80, 0)), ), SoundInterval(open_snd), Func(self._clear_rocket, rocket, smoke, hiss_snd), Func(self._bombs_down), ).start() taskMgr.doMethodLater( # noqa: F82 45, base.accept, # noqa: F82 "unblock_cluster_launcher", extraArgs=["3", self.change_state], ) base.train.make_shot("Cluster Howitzer") # noqa: F82 def _bombs_down(self): """Move bombs down to the ground and do explosion.""" move_par = Parallel() for num in range(4): bomb = loader.loadModel(address("hand_bomb1")) # noqa: F82 bomb.reparentTo(self._train_mod) bomb.setPos(*self._coors[num], 2) bomb.setScale(2) smoke = ParticleEffect() smoke.loadConfig("effects/smoke_tail.ptf") smoke.start(bomb, render) # noqa: F821 self._bombs.append((bomb, smoke)) move_par.append( LerpPosInterval( bomb, random.uniform(0.45, 0.7), (*self._coors[num], 0) ), ) Sequence( move_par, Func(self._clear_grenades), Func(self._explode_grenades), ).start() def _clear_grenades(self): """Delete bomb models.""" smokes = [] for bomb, smoke in self._bombs: bomb.removeNode() smoke.softStop() smokes.append(smoke) self._bombs.clear() taskMgr.doMethodLater( # noqa: F821 2, self._clear_bomb_trails, "clear_bomb_trails", extraArgs=[smokes], appendTask=True, ) def _clear_bomb_trails(self, smokes, task): """Clear bomb smoke trail effects. Args: smokes (list): List of smoke effects. """ for smoke in smokes: smoke.disable() return task.done def _do_grenade_damage(self, event): """Event which is called by a grenade explosion. The method do damage to the enemy units, which were in the grenade explosion area. """ base.world.enemy.active_units[ # noqa: F821 event.getFromNodePath().getName() ].get_damage(50) def _explode_grenades(self): """Organize grenades explosion effects and damaging.""" col_nps = [] for num, coor in enumerate(self._coors): col_node = CollisionNode("grenade_explosion{}".format(num)) col_node.setFromCollideMask(NO_MASK) col_node.setIntoCollideMask(SHOT_RANGE_MASK) col_node.addSolid(CollisionSphere(0, 0, 0, 0.096)) col_np = self._model.attachNewNode(col_node) col_np.setPos(*coor, 0.1) col_nps.append(col_np) base.accept( # noqa: F821 "into-grenade_explosion{}".format(num), self._do_grenade_damage ) self._explosions[num].setPos(*coor, 0.1) self._explosions[num].start(self._model, render) # noqa: F82 self._explosions[num].softStart() self._smokes[num].setPos(*coor, 0.1) self._smokes[num].start(self._model, render) # noqa: F82 self._smokes[num].softStart() taskMgr.doMethodLater( # noqa: F82 random.uniform(0, 0.5), self._explosion_snds[num].play, "play_explosion_snd", extraArgs=[], ) self._ground_holes[num].setPos(*coor, 0.05) self._ground_holes[num].wrtReparentTo( base.world.current_block.rails_mod # noqa: F82 ) self._ground_holes[num].show() taskMgr.doMethodLater( # noqa: F821 1, self._grenade_explosions_stop, "stop_grenade_explosions" ) taskMgr.doMethodLater( # noqa: F821 2.5, self._grenade_smokes_stop, "stop_grenade_smokes" ) taskMgr.doMethodLater( # noqa: F821 0.1, self._clear_grenade_solids, "clear_grenade_solid", extraArgs=[col_nps] ) taskMgr.doMethodLater( # noqa: F821 4, self._return_hole_sprites, "hide_ground_hole", ) def _return_hole_sprites(self, task): """Return groun hole sprites to the howitzer model.""" for hole in self._ground_holes: hole.hide() hole.reparentTo(self._train_mod) return task.done def _grenade_explosions_stop(self, task): """Stop grenade explosion effects.""" for explosion in self._explosions: explosion.softStop() return task.done def _grenade_smokes_stop(self, task): """Stop explosion smoke effects.""" for smoke in self._smokes: smoke.softStop() return task.done def _clear_grenade_solids(self, col_nps): """Delete explosion solids, which are dealing the damage to enemies. Args: col_nps (list): List of collision solids. """ for col_np in col_nps: col_np.removeNode() def _clear_rocket(self, rocket, smoke, hiss_snd): """Clear the cluster rocket model and its effects. Args: rocket (panda3d.core.NodePath): The rocket model. smoke (direct.particles.ParticleEffect.ParticleEffect): The rocket smoke tail effect. hiss_snd (panda3d.core.AudioSound): The rocket hiss sound. """ hiss_snd.stop() base.sound_mgr.detach_sound(hiss_snd) # noqa: F82 smoke.disable() rocket.removeNode() def _move_sights(self, task=None): """Randomly periodically move aiming sights within shoot-range.""" for ind, sight in enumerate(self._sights): x = random.uniform(*random.choice(((-1.1, -0.15), (1.1, 0.15)))) y = random.uniform(-0.11, 0.5) self._coors[ind] = (x, y) sight.setPos(x, y, 0.01) if task: return task.again def change_state(self): """Change the launcher mode.""" if not base.world.is_on_et or self._is_loading: # noqa: F82 return base.train.disable_enabled_weapon(self) # noqa: F821 self._is_loading = True self._model.setPlayRate(-4 if self.is_up else 4, "gun_up") self._model.play("gun_up") if not self.is_up: self._load_snd.play() taskMgr.doMethodLater( # noqa: F82 0.2, self._change_mode, "cluster_bomb_launcher_aim" )
class Item(DirectObject, object): ''' 道具类的虚基类 ''' num = 0 # use to identify item collition node def __init__(self, itemName): super(Item, self).__init__() self.number = Item.num self.itemName = itemName Item.num += 1 def initModel(self, pos, scale, player, buffState, parent=None): ''' 初始化道具模型和设置碰撞检测 #pos 道具模型的放置位置 (世界坐标系) #scale 模型缩放比例 #player 英雄实例 ''' # 加载并设置模型 try: modelName = ModelPath + "model_" + self.itemName self.item = Actor(modelName, {'revolve': modelName}) self.item.loop('revolve') except Exception: self.item = Actor() self.item.setScale(0.3) self.item.setPos(pos) self.item.setScale(scale) if parent == None: self.item.reparentTo(base.render) else: self.item.reparentTo(parent) # 设置碰撞检测 collisionSphere = CollisionSphere(0, 0, 0, 1) self.collisionNodeName = "{}CollisionNode{}".format( self.itemName, self.number) itemColNode = CollisionNode(self.collisionNodeName) itemColNode.addSolid(collisionSphere) itemColNode.setIntoCollideMask(CollideMask.bit(DefaultHeroMaskVal)) itemColNode.setFromCollideMask(CollideMask.allOff()) self.itemCollision = self.item.attachNewNode(itemColNode) self.itemCollision.setPythonTag("Item", self) ##显示包围体 用于粗略模拟道具盒 # self.itemCollision.show() base.cTrav.addCollider(self.itemCollision, base.cHandler) inEvent = "{}-into-{}".format(player.colliderName, self.collisionNodeName) self.accept(inEvent, self.action) buffState.accept(inEvent, buffState.addBuff) @print_func_time def action(self, entry): ''' 碰撞处理事件 将道具效果应用到英雄对象 不同类型道具有不同实现方式 ''' #print self.itemName,self.collisionNodeName player = entry.getFromNodePath().getPythonTag("Hero") player.sounds["GetItem"].play() @print_func_time def _destroy(self): ''' 道具使用后立即销毁 ''' self.ignoreAll() if not self.item.isEmpty(): self.item.cleanup() self.item.removeNode()
class Usuario(object): ''' Usuario ''' def __init__(self): self.habilitado = False self.estaMovendo = False self.estaRodando = False self.timeIniMover = 0 self.timeIniRodar = 0 self.keyMap = { TECLA_esquerda: EVENT_up, TECLA_direita: EVENT_up, TECLA_frente: EVENT_up, TECLA_traz: EVENT_up } self.login = None self.senha = None self.nick = None self.vida_real = None self.vida_total = None self.mana_real = None self.mana_total = None self.forca = None self.velocidade = None self.velocidade_atack = None self.key = None self.addr = None self.login = None pandaFileModelo = get_path_modelo("ralph") self.__modelo = Actor(pandaFileModelo) self.__modelo.reparentTo(render) self.__modelo.setScale(SCALE_MODELOS) modeloStartPos = vinerWorld.mapa.modelo.find("**/start_point").getPos() self.set_pos(modeloStartPos) self.__setup_collision() def get_x(self): return self.__modelo.getX() def get_y(self): return self.__modelo.getY() def get_z(self): return self.__modelo.getZ() def get_h(self): return self.__modelo.getH() def get_pos(self): return self.__modelo.getPos() def set_x(self, x): self.__modelo.setX(x) def set_y(self, y): self.__modelo.setY(y) def set_z(self, z): self.__modelo.setZ(z) def set_h(self, h): self.__modelo.setH(h) def set_pos(self, pos): self.__modelo.setPos(pos) def get_dados(self): return [ self.key, self.nick, self.vida_real, self.vida_total, self.mana_real, self.mana_total, self.forca, self.velocidade, self.velocidade_atack, self.get_x(), self.get_y(), self.get_z(), self.get_h(), ] def stop_task_movimentacao(self): taskMgr.remove(self.key) def inicia_task_movimentacao(self): if self.key != "": taskMgr.add(self.__task_movimentacao, self.key, sort=1) def __setup_collision(self): #Colisao self.ralphGroundRay = CollisionRay() self.ralphGroundRay.setOrigin(0, 0, 5) 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.__modelo.attachNewNode( self.ralphGroundCol) self.ralphGroundHandler = CollisionHandlerQueue() base.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler) #Colisao def __task_movimentacao(self, task): dt = globalClock.getDt() startpos = self.__modelo.getPos() #rodar usuario if self.keyMap[TECLA_esquerda] == EVENT_down and self.keyMap[ TECLA_direita] == EVENT_up: if time.time() < self.timeIniRodar + 4: self.estaRodando = True self.__modelo.setH(self.__modelo, ((self.velocidade * 5) * dt)) else: h = self.get_h() vinerOnline.envia_pacote_todos( 1, ACAO_CLIENT_rodar, [self.key, TECLA_esquerda, EVENT_up, h]) self.estaRodando = False self.keyMap[TECLA_esquerda] = EVENT_up elif self.keyMap[TECLA_direita] == EVENT_down and self.keyMap[ TECLA_esquerda] == EVENT_up: if time.time() < self.timeIniRodar + 4: self.estaRodando = True self.__modelo.setH(self.__modelo, ((self.velocidade * 5) * dt) * -1) else: h = self.get_h() vinerOnline.envia_pacote_todos( 1, ACAO_CLIENT_rodar, [self.key, TECLA_direita, EVENT_up, h]) self.estaRodando = False self.keyMap[TECLA_direita] = EVENT_up elif self.estaRodando: self.estaRodando = False #rodar usuario #mover usuario if self.keyMap[TECLA_frente] == EVENT_down and self.keyMap[ TECLA_traz] == EVENT_up: if time.time() < self.timeIniMover + 4: self.estaMovendo = True self.__modelo.setY(self.__modelo, ((self.velocidade * 2) * dt) * -1) else: x = self.get_x() y = self.get_y() z = self.get_z() vinerOnline.envia_pacote_todos( 1, ACAO_CLIENT_mover, [self.key, TECLA_frente, EVENT_up, x, y, z]) self.estaMovendo = False self.keyMap[TECLA_frente] = EVENT_up elif self.keyMap[TECLA_traz] == EVENT_down and self.keyMap[ TECLA_frente] == EVENT_up: if time.time() < self.timeIniMover + 4: self.estaMovendo = True self.__modelo.setY(self.__modelo, (self.velocidade * dt)) else: x = self.get_x() y = self.get_y() z = self.get_z() vinerOnline.envia_pacote_todos( 1, ACAO_CLIENT_mover, [self.key, TECLA_traz, EVENT_up, x, y, z]) self.estaMovendo = False self.keyMap[TECLA_traz] = EVENT_up elif self.estaMovendo: self.estaMovendo = False #mover usuario #se esta moventdo trata colisao if self.estaMovendo: base.cTrav.traverse(render) if self.ralphGroundHandler.getNumEntries() == 1: entry = self.ralphGroundHandler.getEntry(0) if entry.getIntoNode().getName() == "terrain": self.__modelo.setZ(entry.getSurfacePoint(render).getZ()) else: self.__modelo.setPos(startpos) #se esta moventdo trata colisao return task.cont
class RoamingRalphDemo(CosmoniumBase): def get_local_position(self): return base.camera.get_pos() def create_terrain_appearance(self): self.terrain_appearance.set_shadow(self.shadow_caster) def create_terrain_heightmap(self): self.heightmap = PatchedHeightmap('heightmap', self.noise_size, self.height_scale, self.size, self.size, True, ShaderHeightmapPatchFactory(self.noise)) def create_terrain_biome(self): self.biome = PatchedHeightmap('biome', self.biome_size, 1.0, self.size, self.size, False, ShaderHeightmapPatchFactory(self.biome_noise)) def create_terrain_shader(self): # control4 = HeightColorMap('colormap', # [ # ColormapLayer(0.00, top=LRGBColor(0, 0.1, 0.24)), # ColormapLayer(0.40, top=LRGBColor(0, 0.1, 0.24)), # ColormapLayer(0.49, top=LRGBColor(0, 0.6, 0.6)), # ColormapLayer(0.50, bottom=LRGBColor(0.9, 0.8, 0.6), top=LRGBColor(0.5, 0.4, 0.3)), # ColormapLayer(0.80, top=LRGBColor(0.2, 0.3, 0.1)), # ColormapLayer(0.90, top=LRGBColor(0.7, 0.6, 0.4)), # ColormapLayer(1.00, bottom=LRGBColor(1, 1, 1), top=LRGBColor(1, 1, 1)), # ]) appearance = DetailMap(self.terrain_control, self.heightmap, create_normals=True) data_source = [HeightmapDataSource(self.heightmap, PatchedGpuTextureSource, filtering=HeightmapDataSource.F_none), HeightmapDataSource(self.biome, PatchedGpuTextureSource, filtering=HeightmapDataSource.F_none), TextureDictionaryDataSource(self.terrain_appearance, TextureDictionaryDataSource.F_hash)] if settings.allow_tesselation: tesselation_control = ConstantTesselationControl(invert_v=False) else: tesselation_control = None if self.fog is not None: after_effects = [Fog(**self.fog)] else: after_effects = None self.terrain_shader = BasicShader(appearance=appearance, tesselation_control=tesselation_control, geometry_control=DisplacementGeometryControl(self.heightmap), data_source=data_source, after_effects=after_effects) def create_tile(self, x, y): self.terrain_shape.add_root_patch(x, y) def create_terrain(self): self.tile_factory = TileFactory(self.tile_density, self.size, self.has_water, self.water) self.terrain_shape = TiledShape(self.tile_factory, self.size, self.max_lod, lod_control=VertexSizeMaxDistancePatchLodControl(self.max_distance, self.max_vertex_size)) self.create_terrain_heightmap() self.create_terrain_biome() self.create_terrain_appearance() self.create_terrain_shader() self.terrain = HeightmapSurface( 'surface', 0, self.terrain_shape, self.heightmap, self.biome, self.terrain_appearance, self.terrain_shader, self.size, clickable=False, average=True) self.terrain.set_parent(self) self.terrain.create_instance() def toggle_water(self): if not self.has_water: return self.water.visible = not self.water.visible self.terrain_shape.check_settings() def get_height(self, position): height = self.terrain.get_height(position) if self.has_water and self.water.visible and height < self.water.level: height = self.water.level return height #Used by populator def get_height_patch(self, patch, u, v): height = self.terrain.get_height_patch(patch, u, v) if self.has_water and self.water.visible and height < self.water.level: height = self.water.level return height def skybox_init(self): skynode = base.cam.attachNewNode('skybox') self.skybox = loader.loadModel('ralph-data/models/rgbCube') self.skybox.reparentTo(skynode) self.skybox.setTextureOff(1) self.skybox.setShaderOff(1) self.skybox.setTwoSided(True) # make big enough to cover whole terrain, else there'll be problems with the water reflections self.skybox.setScale(1.5* self.size) self.skybox.setBin('background', 1) self.skybox.setDepthWrite(False) self.skybox.setDepthTest(False) self.skybox.setLightOff(1) self.skybox.setShaderOff(1) self.skybox.setFogOff(1) #self.skybox.setColor(.55, .65, .95, 1.0) self.skybox_color = LColor(pow(0.5, 1/2.2), pow(0.6, 1/2.2), pow(0.7, 1/2.2), 1.0) self.skybox.setColor(self.skybox_color) def objects_density_for_patch(self, patch): scale = 1 << patch.lod return int(self.objects_density / scale + 1.0) def create_populator(self): if settings.allow_instancing: TerrainPopulator = GpuTerrainPopulator else: TerrainPopulator = CpuTerrainPopulator self.rock_collection = TerrainPopulator(RockFactory(self), self.objects_density_for_patch, self.objects_density, RandomObjectPlacer(self)) self.tree_collection = TerrainPopulator(TreeFactory(self), self.objects_density_for_patch, self.objects_density, RandomObjectPlacer(self)) self.object_collection = MultiTerrainPopulator() self.object_collection.add_populator(self.rock_collection) self.object_collection.add_populator(self.tree_collection) def set_light_angle(self, angle): self.light_angle = angle self.light_quat.setFromAxisAngleRad(angle * pi / 180, LVector3.forward()) self.light_dir = self.light_quat.xform(LVector3.up()) cosA = self.light_dir.dot(LVector3.up()) self.vector_to_star = self.light_dir if self.shadow_caster is not None: self.shadow_caster.set_direction(-self.light_dir) if self.directionalLight is not None: self.directionalLight.setDirection(-self.light_dir) if cosA >= 0: coef = sqrt(cosA) self.light_color = (1, coef, coef, 1) self.directionalLight.setColor(self.light_color) self.skybox.setColor(self.skybox_color * cosA) else: self.light_color = (1, 0, 0, 1) self.directionalLight.setColor(self.light_color) self.skybox.setColor(self.skybox_color * 0) self.update() def update(self): self.object_collection.update_instance() self.terrain.update_instance(None, None) def apply_instance(self, instance): pass def create_instance_delayed(self): pass def get_apparent_radius(self): return 0 def get_name(self): return "terrain" def is_emissive(self): return False def __init__(self): CosmoniumBase.__init__(self) config = RalphConfigParser() (self.noise, self.biome_noise, self.terrain_control, self.terrain_appearance, self.water, self.fog) = config.load_and_parse('ralph-data/ralph.yaml') self.tile_density = 64 self.default_size = 128 self.max_vertex_size = 64 self.max_lod = 10 self.size = 128 * 8 self.max_distance = 1.001 * self.size * sqrt(2) self.noise_size = 512 self.biome_size = 128 self.noise_scale = 0.5 * self.size / self.default_size self.objects_density = int(25 * (1.0 * self.size / self.default_size) * (1.0 * self.size / self.default_size)) self.objects_density = 250 self.height_scale = 100 * 5.0 self.has_water = True self.fullscreen = False self.shadow_caster = None self.light_angle = None self.light_dir = LVector3.up() self.vector_to_star = self.light_dir self.light_quat = LQuaternion() self.light_color = (1.0, 1.0, 1.0, 1.0) self.directionalLight = None self.shadow_size = self.default_size / 8 self.shadow_box_length = self.height_scale self.observer = RalphCamera(self.cam, self.camLens) self.observer.init() self.distance_to_obs = float('inf') self.height_under = 0.0 self.scene_position = LVector3() self.scene_scale_factor = 1 self.scene_orientation = LQuaternion() #Size of an edge seen from 4 units above self.edge_apparent_size = (1.0 * self.size / self.tile_density) / (4.0 * self.observer.pixel_size) print("Apparent size:", self.edge_apparent_size) self.win.setClearColor((135.0/255, 206.0/255, 235.0/255, 1)) # This is used to store which keys are currently pressed. self.keyMap = { "left": 0, "right": 0, "forward": 0, "backward": 0, "cam-left": 0, "cam-right": 0, "cam-up": 0, "cam-down": 0, "sun-left": 0, "sun-right": 0, "turbo": 0} # Set up the environment # # Create some lighting self.vector_to_obs = base.cam.get_pos() self.vector_to_obs.normalize() if True: self.shadow_caster = ShadowCaster(1024) self.shadow_caster.create() self.shadow_caster.set_lens(self.shadow_size, -self.shadow_box_length / 2.0, self.shadow_box_length / 2.0, -self.light_dir) self.shadow_caster.set_pos(self.light_dir * self.shadow_box_length / 2.0) self.shadow_caster.bias = 0.1 else: self.shadow_caster = None self.ambientLight = AmbientLight("ambientLight") self.ambientLight.setColor((settings.global_ambient, settings.global_ambient, settings.global_ambient, 1)) self.directionalLight = DirectionalLight("directionalLight") self.directionalLight.setDirection(-self.light_dir) self.directionalLight.setColor(self.light_color) self.directionalLight.setSpecularColor(self.light_color) render.setLight(render.attachNewNode(self.ambientLight)) render.setLight(render.attachNewNode(self.directionalLight)) render.setShaderAuto() base.setFrameRateMeter(True) self.create_terrain() self.create_populator() self.terrain_shape.set_populator(self.object_collection) self.create_tile(0, 0) self.skybox_init() self.set_light_angle(45) # Create the main character, Ralph ralphStartPos = LPoint3() self.ralph = Actor("ralph-data/models/ralph", {"run": "ralph-data/models/ralph-run", "walk": "ralph-data/models/ralph-walk"}) self.ralph.reparentTo(render) self.ralph.setScale(.2) self.ralph.setPos(ralphStartPos + (0, 0, 0.5)) self.ralph_shape = InstanceShape(self.ralph) self.ralph_shape.parent = self self.ralph_shape.set_owner(self) self.ralph_shape.create_instance() self.ralph_appearance = ModelAppearance(self.ralph) self.ralph_appearance.set_shadow(self.shadow_caster) self.ralph_shader = BasicShader() self.ralph_appearance.bake() self.ralph_appearance.apply(self.ralph_shape, self.ralph_shader) self.ralph_shader.apply(self.ralph_shape, self.ralph_appearance) self.ralph_shader.update(self.ralph_shape, self.ralph_appearance) # Create a floater object, which floats 2 units above ralph. We # use this as a target for the camera to look at. self.floater = NodePath(PandaNode("floater")) self.floater.reparentTo(self.ralph) self.floater.setZ(2.0) # Accept the control keys for movement and rotation self.accept("escape", sys.exit) self.accept("control-q", sys.exit) self.accept("arrow_left", self.setKey, ["left", True]) self.accept("arrow_right", self.setKey, ["right", True]) self.accept("arrow_up", self.setKey, ["forward", True]) self.accept("arrow_down", self.setKey, ["backward", True]) self.accept("shift", self.setKey, ["turbo", True]) self.accept("a", self.setKey, ["cam-left", True], direct=True) self.accept("s", self.setKey, ["cam-right", True], direct=True) self.accept("u", self.setKey, ["cam-up", True], direct=True) self.accept("u-up", self.setKey, ["cam-up", False]) self.accept("d", self.setKey, ["cam-down", True], direct=True) self.accept("d-up", self.setKey, ["cam-down", False]) self.accept("o", self.setKey, ["sun-left", True], direct=True) self.accept("o-up", self.setKey, ["sun-left", False]) self.accept("p", self.setKey, ["sun-right", True], direct=True) self.accept("p-up", self.setKey, ["sun-right", False]) self.accept("arrow_left-up", self.setKey, ["left", False]) self.accept("arrow_right-up", self.setKey, ["right", False]) self.accept("arrow_up-up", self.setKey, ["forward", False]) self.accept("arrow_down-up", self.setKey, ["backward", False]) self.accept("shift-up", self.setKey, ["turbo", False]) self.accept("a-up", self.setKey, ["cam-left", False]) self.accept("s-up", self.setKey, ["cam-right", False]) self.accept("w", self.toggle_water) self.accept("h", self.print_debug) self.accept("f2", self.connect_pstats) self.accept("f3", self.toggle_filled_wireframe) self.accept("shift-f3", self.toggle_wireframe) self.accept("f5", self.bufferViewer.toggleEnable) self.accept("f8", self.terrain_shape.dump_tree) self.accept('alt-enter', self.toggle_fullscreen) taskMgr.add(self.move, "moveTask") # Game state variables self.isMoving = False # Set up the camera self.camera.setPos(self.ralph.getX(), self.ralph.getY() + 10, 2) self.camera_height = 2.0 render.set_shader_input("camera", self.camera.get_pos()) self.cTrav = CollisionTraverser() self.ralphGroundRay = CollisionRay() self.ralphGroundRay.setOrigin(0, 0, 9) self.ralphGroundRay.setDirection(0, 0, -1) self.ralphGroundCol = CollisionNode('ralphRay') self.ralphGroundCol.addSolid(self.ralphGroundRay) self.ralphGroundCol.setFromCollideMask(CollideMask.bit(0)) self.ralphGroundCol.setIntoCollideMask(CollideMask.allOff()) self.ralphGroundColNp = self.ralph.attachNewNode(self.ralphGroundCol) self.ralphGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler) # Uncomment this line to see the collision rays #self.ralphGroundColNp.show() # Uncomment this line to show a visual representation of the # collisions occuring #self.cTrav.showCollisions(render) #self.terrain_shape.test_lod(LPoint3d(*self.ralph.getPos()), self.distance_to_obs, self.pixel_size, self.terrain_appearance) #self.terrain_shape.update_lod(LPoint3d(*self.ralph.getPos()), self.distance_to_obs, self.pixel_size, self.terrain_appearance) #self.terrain.shape_updated() self.terrain.update_instance(LPoint3d(*self.ralph.getPos()), None) # Records the state of the arrow keys def setKey(self, key, value): 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): # Get the time that elapsed since last frame. We multiply this with # the desired speed in order to find out with which distance to move # in order to achieve that desired speed. dt = globalClock.getDt() # If the camera-left key is pressed, move camera left. # If the camera-right key is pressed, move camera right. if self.keyMap["cam-left"]: self.camera.setX(self.camera, -20 * dt) if self.keyMap["cam-right"]: self.camera.setX(self.camera, +20 * dt) if self.keyMap["cam-up"]: self.camera_height *= (1 + 2 * dt) if self.keyMap["cam-down"]: self.camera_height *= (1 - 2 * dt) if self.camera_height < 1.0: self.camera_height = 1.0 if self.keyMap["sun-left"]: self.set_light_angle(self.light_angle + 30 * dt) if self.keyMap["sun-right"]: self.set_light_angle(self.light_angle - 30 * dt) # save ralph's initial position so that we can restore it, # in case he falls off the map or runs into something. startpos = self.ralph.getPos() # If a move-key is pressed, move ralph in the specified direction. delta = 25 if self.keyMap["turbo"]: delta *= 10 if self.keyMap["left"]: self.ralph.setH(self.ralph.getH() + 300 * dt) if self.keyMap["right"]: self.ralph.setH(self.ralph.getH() - 300 * dt) if self.keyMap["forward"]: self.ralph.setY(self.ralph, -delta * dt) if self.keyMap["backward"]: self.ralph.setY(self.ralph, delta * dt) #self.limit_pos(self.ralph) # If ralph is moving, loop the run animation. # If he is standing still, stop the animation. if self.keyMap["forward"] or self.keyMap["backward"] or self.keyMap["left"] or self.keyMap["right"]: if self.isMoving is False: self.ralph.loop("run") self.isMoving = True else: if self.isMoving: self.ralph.stop() self.ralph.pose("walk", 5) self.isMoving = False # If the camera is too far from ralph, move it closer. # If the camera is too close to ralph, move it farther. camvec = self.ralph.getPos() - self.camera.getPos() camvec.setZ(0) camdist = camvec.length() camvec.normalize() if camdist > 10.0: self.camera.setPos(self.camera.getPos() + camvec * (camdist - 10)) camdist = 10.0 if camdist < 5.0: self.camera.setPos(self.camera.getPos() - camvec * (5 - camdist)) camdist = 5.0 # Normally, we would have to call traverse() to check for collisions. # However, the class ShowBase that we inherit from has a task to do # this for us, if we assign a CollisionTraverser to self.cTrav. self.cTrav.traverse(render) if False: # Adjust ralph's Z coordinate. If ralph's ray hit anything, put # him back where he was last frame. entries = list(self.ralphGroundHandler.getEntries()) entries.sort(key=lambda x: x.getSurfacePoint(render).getZ()) if len(entries) > 0: self.ralph.setPos(startpos) ralph_height = self.get_height(self.ralph.getPos()) self.ralph.setZ(ralph_height) # Keep the camera at one foot above the terrain, # or two feet above ralph, whichever is greater. camera_height = self.get_height(self.camera.getPos()) + 1.0 if camera_height < ralph_height + self.camera_height: self.camera.setZ(ralph_height + self.camera_height) else: self.camera.setZ(camera_height) #self.limit_pos(self.camera) # The camera should look in ralph's direction, # but it should also try to stay horizontal, so look at # a floater which hovers above ralph's head. self.camera.lookAt(self.floater) #self.shadow_caster.set_pos(self.ralph.get_pos()) self.shadow_caster.set_pos(self.ralph.get_pos() - camvec * camdist + camvec * self.shadow_size / 2) render.set_shader_input("camera", self.camera.get_pos()) self.vector_to_obs = base.cam.get_pos() self.vector_to_obs.normalize() if self.isMoving: #self.terrain_shape.test_lod(LPoint3d(*self.ralph.getPos()), self.distance_to_obs, self.pixel_size, self.terrain_appearance) pass#self.terrain_shape.update_lod(LPoint3d(*self.ralph.getPos()), self.distance_to_obs, self.pixel_size, self.terrain_appearance) self.object_collection.update_instance() self.terrain.update_instance(LPoint3d(*self.ralph.getPos()), None) return task.cont def print_debug(self): print("Height:", self.get_height(self.ralph.getPos()), self.terrain.get_height(self.ralph.getPos())) print("Ralph:", self.ralph.get_pos()) print("Camera:", base.camera.get_pos())
class FPS(object, DirectObject): def __init__(self): self.winXhalf = base.win.getXSize() / 2 self.winYhalf = base.win.getYSize() / 2 winprops = WindowProperties() winprops.setCursorHidden(True) base.win.requestProperties(winprops) self.model = loader.loadModel('models/Guns/45.x') self.model.reparentTo(base.camera) self.model.setPos(USP45_POS) self.model.setHpr(USP45_HPR) self.model.setScale(PISTOL_SCALE) self.gun = 1 self.initSound() self.initCollision() self.loadLevel() self.initPlayer() self.setupMouseCollision() self.loadCrosshairs() self.loadRalph() def initSound(self): self.deathSnd = base.loader.loadSfx("models/sounds/and.ogg") self.spawnSnd = base.loader.loadSfx("models/sounds/faster.ogg") self.fireSnd = base.loader.loadSfx("models/sounds/rifle.ogg") def loadCrosshairs(self): self.crosshairs = OnscreenImage(image='models/crosshair.png', pos=base.win.getPointer(0)) self.crosshairs.setTransparency(TransparencyAttrib.MAlpha) self.crosshairs.setScale(.04, .04, .04) def initCollision(self): #initialize traverser base.cTrav = CollisionTraverser() base.cTrav.setRespectPrevTransform(True) base.cTrav.showCollisions(render) self.mPicker = CollisionTraverser() self.mPicker.showCollisions(render) self.mCQue = CollisionHandlerQueue() # base.cTrav.showCollisions(render) #initialize pusher self.pusher = CollisionHandlerPusher() # collision bits self.groundCollBit = BitMask32.bit(0) self.collBitOff = BitMask32.allOff() self.zombieColBitFrom = BitMask32.bit(2) self.zombieColBitInto = BitMask32.bit(2) self.zombieColBitOff = BitMask32.allOff() def loadLevel(self): self.level = loader.loadModel('models/world') self.level.reparentTo(render) self.level.setPos(0, 0, 0) self.level.setColor(1, 1, 1, .5) self.level.setCollideMask(self.groundCollBit) self.box = loader.loadModel("models/box") self.box.reparentTo(render) self.box.setPos(-29.83, 0, 0) self.box.setScale(1) self.box.setCollideMask(self.groundCollBit) self.box1 = loader.loadModel("models/box") self.box1.reparentTo(render) self.box1.setPos(-51.14, -17.90, 0) self.box1.setScale(1) self.box1.setCollideMask(self.groundCollBit) def loadRalph(self): ralphStartPos = Vec3(-98.64, -20.60, 0) self.ralph = Actor("models/ralph", { "run": "models/ralph-run", "walk": "models/ralph-walk" }) self.ralph.reparentTo(render) self.ralph.setPos(ralphStartPos) self.ralph.setScale(.3) self.ralphLife = 10 ralphaiStartPos = Vec3(-50, 20, 0) self.ralphai = Actor("models/ralph", { "run": "models/ralph-run", "walk": "models/ralph-walk" }) self.cTrav = CollisionTraverser() 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() self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler) self.ralphHeadSphere = CollisionSphere(0, -.2, 4.5, .7) self.ralphHeadCol = CollisionNode('ralphHeadColSphere') self.ralphHeadCol.addSolid(self.ralphHeadSphere) self.ralphHeadCol.setFromCollideMask(self.zombieColBitFrom) self.ralphHeadCol.setIntoCollideMask(self.zombieColBitInto) self.ralphHeadColNp = self.ralph.attachNewNode(self.ralphHeadCol) self.mPicker.addCollider(self.ralphHeadColNp, self.mCQue) self.ralphBodySphere = CollisionSphere(0, -.2, 2, 1) self.ralphBodyCol = CollisionNode('ralphBodyColSphere') self.ralphBodyCol.addSolid(self.ralphBodySphere) self.ralphBodyCol.setFromCollideMask(self.zombieColBitFrom) self.ralphBodyCol.setIntoCollideMask(self.zombieColBitInto) self.ralphBodyColNp = self.ralph.attachNewNode(self.ralphBodyCol) self.mPicker.addCollider(self.ralphBodyColNp, self.mCQue) self.ralphHeadColNp.show() self.ralphBodyColNp.show() base.taskMgr.doMethodLater(.7, self.spawnSound, "spawnSound") self.isMoving = False self.setAI() def spawnSound(self, task): self.spawnSnd.play() return task.done def Scar(self): self.model.removeNode() self.model = loader.loadModel('models/Guns/SCAR.x') self.model.reparentTo(base.camera) self.model.setPos(SCAR_POS) self.model.setHpr(SCAR_HPR) self.model.setScale(RIFLE_SCALE) self.gun = 4 def M4(self): self.model.removeNode() self.model = loader.loadModel('models/Guns/M4.x') self.model.reparentTo(base.camera) self.model.setPos(M4_POS) self.model.setHpr(M4_HPR) self.model.setScale(RIFLE_SCALE) self.gun = 3 def Shotgun(self): self.model.removeNode() self.model = loader.loadModel('models/Guns/Shotgun.x') self.model.reparentTo(base.camera) self.model.setPos(SHOTGUN_POS) self.model.setHpr(SHOTGUN_HPR) self.model.setScale(RIFLE_SCALE) self.gun = 2 def Pistol(self): self.model.removeNode() self.model = loader.loadModel('models/Guns/45.x') self.model.reparentTo(base.camera) self.model.setPos(USP45_POS) self.model.setHpr(USP45_HPR) self.model.setScale(PISTOL_SCALE) self.gun = 1 def setupMouseCollision(self): self.mRay = CollisionRay() self.mRayNode = CollisionNode('pickRay') self.mRayNode.addSolid(self.mRay) self.mRayNode.setFromCollideMask(self.zombieColBitFrom) self.mRayNode.setIntoCollideMask(self.zombieColBitOff) self.mPickNp = base.camera.attachNewNode(self.mRayNode) self.mPicker.addCollider(self.mPickNp, self.mCQue) self.mPickNp.show() def initPlayer(self): #load man self.man = render.attachNewNode( 'man') # keep this node scaled to identity self.man.setPos(0, 0, 10) # camera base.camera.reparentTo(self.man) base.camera.setPos(0, 0, 1.7) base.camLens.setNearFar(.1, 1000) base.disableMouse() #create a collsion solid around the man manC = self.man.attachCollisionSphere('manSphere', 0, 0, 1, .4, self.groundCollBit, self.collBitOff) self.pusher.addCollider(manC, self.man) base.cTrav.addCollider(manC, self.pusher) speed = 4 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 self.jump = 0 taskMgr.add(self.move, 'move-task') self.jumping = LerpFunc(Functor(self.__setattr__, "jump"), duration=.5, fromData=.4, toData=0) self.accept("escape", sys.exit) self.accept("space", self.startJump) 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]) self.accept("wheel_up", self.nextWeapon) self.accept("wheel_down", self.prevWeapon) self.accept("1", self.Pistol) self.accept("2", self.Shotgun) self.accept("3", self.M4) self.accept("4", self.Scar) self.accept('mouse1', self.onMouseTask) #add mouse collision to our world self.setupMouseCollision() self.manGroundColNp = self.man.attachCollisionRay( 'manRay', 0, 0, .6, 0, 0, -1, self.groundCollBit, self.collBitOff) self.manGroundHandler = CollisionHandlerGravity() self.manGroundHandler.addCollider(self.manGroundColNp, self.man) base.cTrav.addCollider(self.manGroundColNp, self.manGroundHandler) def nextWeapon(self): if self.gun == 1: self.Shotgun() elif self.gun == 2: self.M4() elif self.gun == 3: self.Scar() elif self.gun == 4: self.Pistol() def prevWeapon(self): if self.gun == 1: self.Scar() elif self.gun == 2: self.Pistol() elif self.gun == 3: self.Shotgun() elif self.gun == 4: self.M4() def startJump(self): if self.manGroundHandler.isOnGround(): self.jumping.start() 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.man.setH(self.man, (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 # horisontal moveVec.setZ(self.jump) # vertical self.man.setFluidPos(self.man, moveVec) # jump damping if self.jump > 0: self.jump = clampScalar(0, 1, self.jump * .9) return task.cont def onMouseTask(self): mpos = base.mouseWatcherNode.getMouse() self.mRay.setDirection(render.getRelativeVector(camera, Vec3(0, 1, 0))) self.mRay.setFromLens(base.camNode, mpos.getX(), mpos.getY()) self.mPicker.traverse(render) self.fireSnd.play() entries = [] for i in range(self.mCQue.getNumEntries()): entry = self.mCQue.getEntry(i) print entry entries.append(entry) if (len(entries) > 0) and (entries[0].getIntoNode().getName() == 'terrain'): print 'terrain' entries = [] for i in range(self.mCQue.getNumEntries()): entry = self.mCQue.getEntry(i) print entry entries.append(entry) if (len(entries) > 0) and (entries[0].getIntoNode().getName() == 'ralphHeadColSphere'): self.ralphLife -= 10 base.taskMgr.doMethodLater(.3, self.deathSound, "deathSound") entries = [] for i in range(self.mCQue.getNumEntries()): entry = self.mCQue.getEntry(i) print entry entries.append(entry) if (len(entries) > 0) and (entries[0].getIntoNode().getName() == 'ralphBodyColSphere'): self.ralphLife -= 5 if self.ralphLife < 5: base.taskMgr.doMethodLater(.3, self.deathSound, "deathSound") if self.ralphLife <= 0: self.ralph.cleanup() self.ralphai.cleanup() self.loadRalph() def deathSound(self, task): self.deathSnd.play() return task.done def setAI(self): #Creating AI World self.AIworld = AIWorld(render) self.AIchar = AICharacter("ralph", self.ralph, 130, 0.05, 25) self.AIworld.addAiChar(self.AIchar) self.AIbehaviors = self.AIchar.getAiBehaviors() self.AIbehaviors.initPathFind("models/navmesh.csv") self.setMove() #AI World update taskMgr.add(self.AIUpdate, "AIUpdate") def setMove(self): self.AIbehaviors.addStaticObstacle(self.box) self.AIbehaviors.addStaticObstacle(self.box1) self.AIbehaviors.pathFindTo(self.man) self.ralph.loop("run") #to update the AIWorld def AIUpdate(self, task): self.AIworld.update() self.ralphMove() return Task.cont def ralphMove(self): startpos = self.ralph.getPos() # Now check for collisions. self.cTrav.traverse(render) 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) self.ralph.setP(0) return Task.cont
class Player: STATE_IDLE = "Idle" STATE_WALK = "Walk" STATE_RUN = "Run" STATE_JUMP = "Jump" STATE_RUNJUMP = "RunJump" STATE_FALL = "Fall" STATE_DUCK = "Duck" STATE_UN_DUCK = "UnDuck" STATE_FLOAT = "Float" STATE_SWIM = "Swim" SUB_STATE_GRAB = "Grab" JUMP_ACCEL = 3.5 FALL_ACCEL = -9.81 TERRAIN_NONE = 0 TERRAIN_GROUND = 1 TERRAIN_WATER = 2 TERRAIN_AIR = 3 DUCK_FRAME_COUNT = 0 DUCK_FRAME_MID = 0 SUNK_CUTOFF = -0.9 def __init__(self, base): self.base = base self.keyState = { "WalkFw": False, "WalkBw": False, "Run": False, "RotateL": False, "RotateR": False, "Jump": False, "Duck": False } self.isKeyDown = self.base.mouseWatcherNode.isButtonDown self.state = Player.STATE_IDLE self.sub_state = None self.walkDir = 0 self.rotationDir = 0 self.zVelocity = 0 self.zOffset = None self.jumpHeight = None self.terrainZone = Player.TERRAIN_NONE self.terrainSurfZ = None self.waterDepth = 0 self.collidedObjects = list() # actor anims = { "idle": "models/player-idle", "walk": "models/player-walk", "run": "models/player-run", "jump": "models/player-jump", "duck": "models/player-duck", "float": "models/player-float", "swim": "models/player-swim", "grab": "models/player-grab" } self.actor = Actor("models/player", anims) self.actor.reparentTo(self.base.render) self.actor.setH(200) log.debug("actor tight bounds is %s" % str(self.actor.getTightBounds())) # animation info Player.DUCK_FRAME_COUNT = self.actor.getNumFrames("duck") Player.DUCK_FRAME_MID = int(Player.DUCK_FRAME_COUNT / 2) # camara point self.camNode = NodePath("camNode") self.camNode.reparentTo(self.actor) self.camNode.setPos(0, 0, 1) # collision # ray collRay = CollisionRay(0, 0, 1.5, 0, 0, -1) collRayN = CollisionNode("playerCollRay") collRayN.addSolid(collRay) collRayN.setFromCollideMask(1) collRayN.setIntoCollideMask(CollideMask.allOff()) collRayNP = self.actor.attachNewNode(collRayN) self.collQRay = CollisionHandlerQueue() self.base.cTrav.addCollider(collRayNP, self.collQRay) # sphere mask 2 collSphere2 = CollisionSphere(0, 0, 0.5, 0.25) collSphere2N = CollisionNode("playerCollSphere2") collSphere2N.addSolid(collSphere2) collSphere2N.setFromCollideMask(2) collSphere2N.setIntoCollideMask(CollideMask.allOff()) self.collSphere2NP = self.actor.attachNewNode(collSphere2N) self.collPSphere = CollisionHandlerPusher() self.collPSphere.addCollider(self.collSphere2NP, self.actor) self.base.cTrav.addCollider(self.collSphere2NP, self.collPSphere) # key events self.base.accept("i", self.dump_info) # task self.base.taskMgr.add(self.update, "playerUpdateTask") def defineKeys(self): for k in self.keyState.keys(): self.keyState[k] = False if self.isKeyDown(KeyboardButton.up()): self.keyState["WalkFw"] = True if self.isKeyDown(KeyboardButton.down()): self.keyState["WalkBw"] = True if self.isKeyDown(KeyboardButton.left()): self.keyState["RotateL"] = True if self.isKeyDown(KeyboardButton.right()): self.keyState["RotateR"] = True if self.isKeyDown(KeyboardButton.shift()): self.keyState["Run"] = True if self.isKeyDown(KeyboardButton.space()): self.keyState["Jump"] = True if self.isKeyDown(KeyboardButton.asciiKey("d")): self.keyState["Duck"] = True def defineState(self): # newState = self.state # keys states ks = self.keyState # state force if self.zOffset > 0.2 and self.state != Player.STATE_FALL: newState = Player.STATE_FALL # from Idle -> Walk, Jump if self.state == Player.STATE_IDLE: # Walk if ks["WalkFw"] or ks["WalkBw"] or ks["RotateL"] or ks["RotateR"]: newState = Player.STATE_WALK elif ks["Jump"]: newState = Player.STATE_JUMP elif ks["Duck"]: newState = Player.STATE_DUCK # from Walk, Run -> Walk, Run, Idle; from Run -> Jump elif self.state == Player.STATE_WALK or self.state == Player.STATE_RUN: if ks["Run"] and self.state != Player.STATE_RUN and self.terrainZone != Player.TERRAIN_WATER: newState = Player.STATE_RUN elif not ks["Run"] and self.state == Player.STATE_RUN: newState = Player.STATE_WALK if ks["WalkFw"]: self.walkDir = -1 elif ks["WalkBw"]: self.walkDir = 1 elif not ks["WalkFw"] and not ks["WalkBw"]: self.walkDir = 0 if ks["RotateL"]: self.rotationDir = 1 elif ks["RotateR"]: self.rotationDir = -1 elif not ks["RotateL"] and not ks["RotateR"]: self.rotationDir = 0 if ks["Jump"]: newState = Player.STATE_RUNJUMP if self.walkDir == 0 and self.rotationDir == 0: newState = Player.STATE_IDLE # from Jump -> Fall elif self.state == Player.STATE_JUMP or self.state == Player.STATE_RUNJUMP: if self.zVelocity > 0: newState = Player.STATE_FALL # from Fall -> Idle elif self.state == Player.STATE_FALL: if self.zOffset <= 0: newState = Player.STATE_IDLE self.jumpHeight = None self.zVelocity = 0 self.walkDir = 0 # from Duck -> UnDuck elif self.state == Player.STATE_DUCK: if not ks["Duck"]: newState = Player.STATE_UN_DUCK # from UnDuck -> Idle elif self.state == Player.STATE_UN_DUCK: if not self.actor.getCurrentAnim() == "duck": newState = Player.STATE_IDLE return newState def processState(self, dt): # terrain sdjustment if self.zOffset <= 0.2 and not self.state == Player.STATE_FALL: self.actor.setZ(self.terrainSurfZ) # idle if self.state == Player.STATE_IDLE: self.collSphere2NP.setZ(0) # walk if self.walkDir != 0: if self.zVelocity == 0: speed = 3.6 if self.state == Player.STATE_RUN else 2.4 else: speed = 3.2 if self.terrainZone == Player.TERRAIN_WATER: speed *= 0.5 self.actor.setY(self.actor, speed * self.walkDir * dt) if self.rotationDir != 0: self.actor.setH(self.actor.getH() + 3.5 * self.rotationDir) # jump if self.state == Player.STATE_JUMP or self.state == Player.STATE_RUNJUMP: self.zVelocity = Player.JUMP_ACCEL log.debug("jump start at v=%f" % self.zVelocity) if self.state == Player.STATE_RUNJUMP: self.walkDir = -1 # fall if self.state == Player.STATE_FALL: dZ = self.zVelocity * dt dV = Player.FALL_ACCEL * dt curZ = self.actor.getZ() newZ = curZ + dZ if self.jumpHeight == None and newZ < curZ: self.jumpHeight = self.zOffset log.debug("jump height=%f" % self.jumpHeight) log.debug( "falling... dt=%(dt)f getZ=%(getZ)f v=%(v)f dZ=%(dZ)f newZ=%(newZ)f dV=%(dV)f zOffset=%(zOff)f" % { "dt": dt, "getZ": self.actor.getZ(), "v": self.zVelocity, "dZ": dZ, "newZ": newZ, "dV": dV, "zOff": self.zOffset }) if newZ < self.terrainSurfZ: newZ = self.terrainSurfZ self.actor.setZ(newZ) self.zVelocity += dV # duck if self.state == Player.STATE_DUCK: if self.actor.getCurrentAnim() == "duck": collSphrZ = (self.actor.getCurrentFrame("duck") / Player.DUCK_FRAME_MID) * 0.25 self.collSphere2NP.setZ(-collSphrZ) def processTerrainRelation( self): # -> [terrainZone, terrainSurfZ, zOffset, waterDepth] collEntries = self.collQRay.getEntries() newZone = None # if len(collEntries) == 0: #log.error("out of terrain, pos=%s"%str(self.actor.getPos())) newZone = Player.TERRAIN_NONE if newZone != self.terrainZone: self.onTerrainZoneChanged(Player.TERRAIN_NONE) self.terrainZone = newZone return Player.TERRAIN_NONE, 0, 0, 0 # newZone = Player.TERRAIN_NONE gndZ, wtrZ = -1000, -1000 waterDepth = 0 for entry in collEntries: eName = entry.getIntoNodePath().getName() eZ = entry.getSurfacePoint(self.base.render).getZ() if eName.startswith("Water"): wtrZ = eZ if wtrZ > gndZ: newZone = Player.TERRAIN_WATER else: if eZ > gndZ: gndZ = eZ if gndZ > wtrZ: newZone = Player.TERRAIN_GROUND if newZone == Player.TERRAIN_WATER: waterDepth = gndZ - wtrZ #log.debug("water depth is %f"%waterDepth) zOffset = self.actor.getZ() - gndZ return newZone, gndZ, zOffset, waterDepth def onTerrainZoneChanged(self, zone): log.debug("terrain zone chaged to: %i" % zone) def onStateChanged(self, newState): curState = self.state log.debug("state change %s -> %s" % (str(curState), str(newState))) #self.actor.stop() if newState == Player.STATE_IDLE: self.actor.loop("idle") elif newState == Player.STATE_WALK: self.actor.setPlayRate(4.0, "walk") self.actor.loop("walk") elif newState == Player.STATE_RUN: self.actor.loop("run") elif newState == Player.STATE_JUMP or newState == Player.STATE_RUNJUMP: self.actor.setPlayRate(1.4, "jump") self.actor.play("jump", fromFrame=20, toFrame=59) elif newState == Player.STATE_DUCK: self.actor.play("duck", fromFrame=0, toFrame=Player.DUCK_FRAME_MID) elif newState == Player.STATE_UN_DUCK: initFrame = Player.DUCK_FRAME_MID if self.actor.getCurrentAnim() == "duck": initFrame = Player.DUCK_FRAME_COUNT - self.actor.getCurrentFrame( "duck") self.actor.stop() self.actor.play("duck", fromFrame=initFrame, toFrame=Player.DUCK_FRAME_COUNT) def updateCollidedObjectsList(self): pass def update(self, task): # clock dt = self.base.taskMgr.globalClock.getDt() # keys self.defineKeys() # terrain relation newZone, self.terrainSurfZ, self.zOffset, self.waterDepth = self.processTerrainRelation( ) if newZone != self.terrainZone: self.terrainZone = newZone self.onTerrainZoneChanged(self.terrainZone) # obstacles relation self.updateCollidedObjectsList() # state newState = self.defineState() if self.state != newState: self.onStateChanged(newState) self.state = newState self.processState(dt) # move return task.cont def dump_info(self): info = "position: %s\n" % str(self.actor.getPos()) info += "hpr: %s\n" % str(self.actor.getHpr()) info += "state: %s; sub_state: %s\n" % (str( self.state), str(self.sub_state)) info += "terrainZone: %s\n" % str(self.terrainZone) info += "terrainSurfZ: %s\n" % str(self.terrainSurfZ) info += "zOffset: %s\n" % str(self.zOffset) log.info("*INFO:\n%s" % info)
class thirdPerson(DirectObject): def __init__(self, parserClass, mainClass, mapLoaderClass, modelLoaderClass): self.switchState = False # self.t = Timer() self.keyMap = {"left": 0, "right": 0, "forward": 0, "backward": 0} self.ralph = Actor( "data/models/units/ralph/ralph", {"run": "data/models/units/ralph/ralph-run", "walk": "data/models/units/ralph/ralph-walk"}, ) self.ralph.reparentTo(render) # self.ralph.setPos(42, 30, 0) self.ralph.setPos(6, 10, 0) self.ralph.setScale(0.1) self.accept("escape", sys.exit) self.accept("arrow_left", self.setKey, ["left", 1]) self.accept("arrow_left-up", self.setKey, ["left", 0]) self.accept("arrow_right", self.setKey, ["right", 1]) self.accept("arrow_right-up", self.setKey, ["right", 0]) self.accept("arrow_up", self.setKey, ["forward", 1]) self.accept("arrow_up-up", self.setKey, ["forward", 0]) self.accept("arrow_down", self.setKey, ["backward", 1]) self.accept("arrow_down-up", self.setKey, ["backward", 0]) self.isMoving = False self.cTrav = CollisionTraverser() 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() self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler) # self.ralphGroundCol.show() base.cam.reparentTo(self.ralph) base.cam.setPos(0, 9, 7) self.floater2 = NodePath(PandaNode("floater2")) self.floater2.reparentTo(self.ralph) self.floater2.setZ(self.floater2.getZ() + 6) base.cam.lookAt(self.floater2) # 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) self.floater = NodePath(PandaNode("floater")) self.floater.reparentTo(render) taskMgr.add(self.move, "movingTask", extraArgs=[mainClass, parserClass, mapLoaderClass, modelLoaderClass]) # Records the state of the arrow keys def setKey(self, key, value): self.keyMap[key] = value def move(self, mainClass, parserClass, mapLoaderClass, modelLoaderClass): # Get the time elapsed since last frame. We need this # for framerate-independent movement. elapsed = globalClock.getDt() # save ralph's initial position so that we can restore it, # in case he falls off the map or runs into something. startpos = self.ralph.getPos() # If a move-key is pressed, move ralph in the specified direction. if self.keyMap["left"] != 0: self.ralph.setH(self.ralph.getH() + elapsed * 300) if self.keyMap["right"] != 0: self.ralph.setH(self.ralph.getH() - elapsed * 300) if self.keyMap["forward"] != 0: self.ralph.setY(self.ralph, -(elapsed * 50)) # 25)) if self.keyMap["backward"] != 0: self.ralph.setY(self.ralph, +(elapsed * 20)) if (self.keyMap["forward"] != 0) or (self.keyMap["left"] != 0) or (self.keyMap["right"] != 0): if self.isMoving is False: self.ralph.loop("run") self.isMoving = True elif self.keyMap["backward"] != 0: if self.isMoving is False: self.ralph.stop() self.ralph.pose("walk", 5) self.isMoving = False else: if self.isMoving: self.ralph.stop() self.ralph.pose("walk", 5) self.isMoving = False # 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.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()[0:4] == "tile"): self.ralph.setZ(entries[0].getSurfacePoint(render).getZ()) elif (len(entries) > 0) and (entries[0].getIntoNode().getName()[0:5] == "solid"): self.ralph.setPos(startpos) x = int( entries[0] .getIntoNode() .getName()[len(entries[0].getIntoNode().getName()) - 6 : len(entries[0].getIntoNode().getName()) - 4] ) y = int(entries[0].getIntoNode().getName()[len(entries[0].getIntoNode().getName()) - 2 :]) if mapLoaderClass.tileArray[y][x].drillTime != None: mainClass.changeTile(mapLoaderClass.tileArray[y][x], 0, parserClass, modelLoaderClass, mapLoaderClass) else: self.ralph.setPos(startpos) self.ralph.setP(0) return Task.cont
class World(ShowBase): def skyBoxLoad(self): self.spaceSkyBox = load_model('skybox1.egg') self.spaceSkyBox.setScale(150) self.spaceSkyBox.setLightOff() self.spaceSkyBox.reparentTo(render) self.spaceSkyBox.setPos(0,0,-200) self.spaceSkyBox.setHpr(0,0,0) def loadEnviron(self): self.environ = load_model("secondWorld.egg") self.environ.reparentTo(render) self.environ.setPos(0,0,0) def Hooh(self): """ hooh """ self.hoohActor = Actor("anim2hooh.egg", {"wing":"anim-Anim0.egg"}) self.hoohActor.reparentTo(render) self.hoohActor.loop("wing") self.hoohActor.setPos(self.ralphStartPos[0], self.ralphStartPos[1]+100, self.ralphStartPos[2]+100) self.hoohActor.setPlayRate(4.0,"wing") self.hoohActor.setHpr(180,90,0) start = Point3(self.ralphStartPos[0], self.ralphStartPos[1]+95, self.ralphStartPos[2]+100) end = Point3(self.ralphStartPos[0], self.ralphStartPos[1]-100, self.ralphStartPos[2]+100) turnHpr1 = Point3(180,90,0) turnHpr2 = Point3(0,90,0) hoohPosInt1 = self.hoohActor.posInterval(5.0, start, startPos = end) hoohPosInt2 = self.hoohActor.posInterval(5.0, end, startPos = start) hoohHprInt1 = self.hoohActor.hprInterval(1.0, turnHpr2, startHpr=turnHpr1) hoohHprInt2 = self.hoohActor.hprInterval(1.0, turnHpr1, startHpr=turnHpr2) self.hoohFly = Sequence(hoohPosInt1, hoohHprInt1, hoohPosInt2, hoohHprInt2, name="hoohFly") self.hoohFly.loop() def gold(self, task): _GOLD_PARTICLES.setPos(self.hoohActor.getPos()) return task.cont def loadPokemon(self): """ Pikachu """ self.pikachu = load_model("pikachu.egg") self.pikachu.reparentTo(render) self.pikachu.setPos(_PIKACHU_POS) self.pikachu.setHpr(_PIKACHU_HPR) """ Groudon """ self.Groudon = load_model("Groudon.egg") self.Groudon.reparentTo(render) self.Groudon.setPos(_GROUDON_POS) self.Groudon.setHpr(_GROUDON_HPR) """ Bulbasaur """ self.bulbasaur = load_model("bulbasaur.egg") self.bulbasaur.reparentTo(render) self.bulbasaur.setPos(_BULBASAUR_POS) self.bulbasaur.setHpr(_BULBASAUR_HPR) """ hooh """ self.Hooh() """ Pichu """ self.pichu = load_model("pichu.egg") self.pichu.reparentTo(render) self.pichu.setPos(_PICHU_POS) self.pichu.setHpr(_PICHU_HPR) """ Charmander """ self.charmander = load_model("char.egg") self.charmander.reparentTo(render) self.charmander.setPos(_CHARMANDER_POS) self.charmander.setHpr(_CHARMANDER_HPR) """ charizard """ self.charizard = load_model("charizard.egg") self.charizard.reparentTo(render) self.charizard.setPos(_CHARIZARD_POS) self.charizard.setHpr(_CHARIZARD_HPR) """ blastoise """ self.blastoise = load_model("blastoise.egg") self.blastoise.reparentTo(render) self.blastoise.setPos(_BLASTOISE_POS) self.blastoise.setHpr(_BLASTOISE_HPR) """ Squirtle """ self.squirtle = load_model("squirtle.egg") self.squirtle.reparentTo(render) self.squirtle.setPos(_SQUIRTLE_POS) self.squirtle.setHpr(_SQUIRTLE_HPR) """ Dragonite """ self.dragonite = load_model("dragonite.egg") self.dragonite.reparentTo(render) self.dragonite.setPos(_DRAGONITE_POS) self.dragonite.setHpr(_DRAGONITE_HPR) _FLAME.setPos(_FLAME_POS) _FLAME.setScale(0.1) _FLAME.start(parent=render, renderParent=render) """ venusaur """ self.venusaur = load_model("venusaur.egg") self.venusaur.reparentTo(render) self.venusaur.setPos(_VENUSAUR_POS) self.venusaur.setHpr(_VENUSAUR_HPR) def loadRalph(self): # Create the main character, Ralph basePath = r"../google_drive/ball/data/models/" self.ralphStartPos = self.environ.find("**/start_point").getPos() self.ralph = Actor(basePath+"ralph",{"run":basePath+"ralph-run", "walk":basePath+"ralph-walk"}) self.ralph.reparentTo(render) self.ralph.setScale(.2) self.ralph.setPos(self.ralphStartPos) self.ralph.hide() def loadNextMusic(self, task): # random load background music if (self.music.status()!=self.music.PLAYING): # not playing self.musicCounter += 1 index = self.musicCounter % len(_BGMUSIC) self.music = load_bgmusic(_BGMUSIC[index]) self.music.play() return task.cont def keyControl(self): self.accept("escape", sys.exit) 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("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("w",self.setKey,["upward",1]) self.accept("w-up",self.setKey,["upward",0]) self.accept("s",self.setKey,["downward",1]) self.accept("s-up",self.setKey,["downward",0]) self.accept("t", self.toggleMusic) self.accept("u", self.changeVolume, ['u']) self.accept("d", self.changeVolume, ['d']) self.accept("h", self.hideInstructions) def changeVolume(self, direction): if direction == 'u' and self.volume < 1: self.volume += 0.05 else: # direction == 'd' if self.volume > 0: self.volume -= 0.05 self.music.setVolume(self.volume) def toggleMusic(self): self.music.stop() self.musicCounter += 1 # increment the counter by index = self.musicCounter % len(_BGMUSIC) self.music = load_bgmusic(_BGMUSIC[index]) self.music.play() def displayInformation(self): self.title = addTitle("My Pokemon - Roam Mode") self.inst1 = addInstructions(0.95, "[ESC]: Quit") self.inst2 = addInstructions(0.90, "[Arrow Keys]: Move") self.inst3 = addInstructions(0.85, "[w]: look up") self.inst4 = addInstructions(0.80, "[s]: look down") self.inst5 = addInstructions(0.75, "[t]: toggle next song") self.inst6 = addInstructions(0.70, "[u]: volume up") self.inst7 = addInstructions(0.65, "[d]: volume down") self.inst8 = addInstructions(0.60, "[h]: hide/show instructions") self.insts = [self.title, self.inst1, self.inst2, self.inst3, self.inst4, self.inst5, self.inst6, self.inst7, self.inst8] def hideInstructions(self): if self.instStatus == "show": self.instStatus = "hide" groupHide(self.insts) else: # instructions are hidden self.instStatus = "show" groupShow(self.insts) def __init__(self): base.enableParticles() self.keyMap = {"left":0, "right":0, "forward":0,"backward":0, "upward":0, "downward":0, "leftward":0,"rightward":0, "cam-left":0, "cam-right":0} _GOLD_PARTICLES.start(parent=render, renderParent=render) _GOLD_PARTICLES.setScale(200) self.instStatus = "show" self.musicCounter = 0 self.music = load_bgmusic(_BGMUSIC[0]) # self.music.play() self.volume = 0 self.music.setVolume(self.volume) base.win.setClearColor(Vec4(0,0,0,1)) self.above = 3.0 # load environment self.loadEnviron() # load ralph self.loadRalph() # load sky box self.skyBoxLoad() # load pokemon self.loadPokemon() self.displayInformation() self.keyControl() # 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) taskMgr.add(self.move,"moveTask") taskMgr.add(self.setAbove,"setAbove") taskMgr.add(self.loadNextMusic, "loadRandomMusic") taskMgr.add(self.gold, "gold") # Game state variables self.isMoving = False # Set up the camera base.disableMouse() base.camera.setPos(self.ralph.getX(),self.ralph.getY(),2) self.cTrav = CollisionTraverser() 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() self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler) 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 = base.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler) # 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) # 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)) def setAbove(self,task): if self.keyMap["upward"] == 1: self.above += 0.1 if self.keyMap["downward"] == 1: self.above -= 0.1 return task.cont #Records the state of the arrow keys def setKey(self, key, value): 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): # save ralph's initial position so that we can restore it, # in case he falls off the map or runs into something. startpos = self.ralph.getPos() # If a move-key is pressed, move ralph in the specified direction. if (self.keyMap["left"]!=0): self.ralph.setH(self.ralph.getH() + 113 * globalClock.getDt()) base.camera.setX(base.camera, +20 * globalClock.getDt()) if (self.keyMap["right"]!=0): self.ralph.setH(self.ralph.getH() - 113 * globalClock.getDt()) base.camera.setX(base.camera, -20 * globalClock.getDt()) if (self.keyMap["forward"]!=0): self.ralph.setY(self.ralph, -75 * globalClock.getDt()) if (self.keyMap["backward"] != 0): pass #self.ralph.setY(self.ralph, 75 * globalClock.getDt()) # 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):# or (self.keyMap["backward"]!=0): if self.isMoving is False: #self.ralph.loop("run") self.isMoving = True else: if self.isMoving: #self.ralph.stop() #self.ralph.pose("walk",5) self.isMoving = False # If the camera is too far from ralph, move it closer. # If the camera is too close to ralph, move it farther. camvec = self.ralph.getPos() - base.camera.getPos() camvec.setZ(0) camdist = camvec.length() camvec.normalize() if (camdist > 10.0): base.camera.setPos(base.camera.getPos() + camvec*(camdist-10)) camdist = 10.0 if (camdist < 5.0): base.camera.setPos(base.camera.getPos() - camvec*(5-camdist)) 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.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) # Keep the camera at one foot above the terrain, # or two feet above ralph, 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"): base.camera.setZ(entries[0].getSurfacePoint(render).getZ()+1.0) if (base.camera.getZ() < self.ralph.getZ() + 2.0): base.camera.setZ(self.ralph.getZ() + 2.0) # The camera should look in ralph's direction, # but it should also try to stay horizontal, so look at # a floater which hovers above ralph's head. self.floater.setPos(self.ralph.getPos()) self.floater.setZ(self.ralph.getZ() + self.above)#self.above) base.camera.lookAt(self.floater) return task.cont
class MyPanda: count = 0 def __init__(self, tempworld): self.isWalk = False self.jumpState = False self.currentTime = 0 self.idleTime = 0 self.pandaPosIntervalX = 0 self.pandaPaceX = None self.pandaPace = None self.mySequence = None MyPanda.count += 1 self.myInterval1 = 0 self.myInterval2 = 0 self.myInterval3 = 0 self.myInterval4 = 0 self.pandaPosInterval1 = 0 self.id = MyPanda.count self.world = tempworld self.pandaNode=render.attachNewNode('pandaNode') self.actor=Actor("models/panda-model", {"walk": "models/panda-walk4"}) self.actor.reparentTo(self.pandaNode) cPos = int(self.id) * 20 self.actor.setPos(cPos,0,0) self.actor.setScale(0.002, 0.002, 0.002) # Create a collsion node for this object. self.cNode = CollisionNode('panda') # Attach a collision sphere solid to the collision node. self.cNode.addSolid(CollisionSphere(2, 0, 400, 500)) # Attach the collision node to the object's model. self.frowneyC = self.actor.attachNewNode(self.cNode) #self.frowneyC.show() base.cTrav.addCollider(self.frowneyC, self.world.pusher) self.world.pusher.addCollider(self.frowneyC, self.actor, base.drive.node()) self.setJumpSequence() def setJumpSequence(self): self.myInterval1 = self.actor.posInterval(0.3, Point3(self.actor.getX(), self.actor.getY(), 0)) self.myInterval2 = self.actor.posInterval(0.3, Point3(self.actor.getX(), self.actor.getY(), 1)) self.myInterval3 = self.actor.posInterval(0.2, Point3(self.actor.getX(), self.actor.getY(), 1)) self.myInterval4 = self.actor.posInterval(0.1, Point3(self.actor.getX(), self.actor.getY(), 0)) self.mySequence = Sequence(self.myInterval1, self.myInterval2, self.myInterval3, self.myInterval4) def getActor(self): return self.actor def timerTask(self, task): self.currentTime = int(task.time) return Task.cont def jumpPanda (self, task): if(int(self.currentTime) - int(self.idleTime) > 20 and self.jumpState == False and self.getDist() > 20): self.setJumpSequence() self.jumpState = True print "Jump" self.mySequence.start() self.mySequence.loop() return Task.cont def getDist(self): distanceVector = self.world.mainChar.getPos()-self.actor.getPos() dist = distanceVector.length() return dist def getId(self): return self.id def walkSequence(self): if self.isWalk == False: self.actor.play("walk") self.actor.loop("walk") self.isWalk = True self.actor.setPos(self.actor, 0, 5, 0) self.pandaMovement = self.pandaNode.hprInterval(10.0,Point3(0,0,0),startHpr=Point3(self.actor.getX(),self.actor.getY(),0)) def pandaWalk(self, task): if(self.getDist() < 15 and self.getDist() > 3.5): self.idleTime = self.currentTime #Look at Ralph self.actor.find('**/+GeomNode').setH(180) self.actor.lookAt(self.world.mainChar) if self.jumpState == True: print "Stop Jump" self.jumpState = False #self.idleTime = self.currentTime self.mySequence.pause() self.actor.setPos(self.actor.getX(), self.actor.getY(), 0) print "Start Walk" self.walkSequence() if self.getDist() < 15 and self.actor.getZ() != 0: self.actor.setPos(self.actor.getX(), self.actor.getY(), 0) return Task.cont def pandaStop(self, task): if (self.getDist() > 15 or self.getDist() < 3.5) and self.isWalk: print "Stop Walk" self.isWalk = False self.actor.stop() return Task.cont
class Usuario(object): """ Usuario """ def __init__(self, dadosUsuario, principal=False): self.key = dadosUsuario["key"] self.nick = dadosUsuario["nick"] self.vida_real = float(dadosUsuario["vida_real"]) self.vida_total = float(dadosUsuario["vida_total"]) self.mana_real = float(dadosUsuario["mana_real"]) self.mana_total = float(dadosUsuario["mana_total"]) self.forca = float(dadosUsuario["forca"]) self.velocidade = float(dadosUsuario["velocidade"]) self.velocidade_atack = float(dadosUsuario["velocidade_atack"]) self.estaMovendo = False self.estaRodando = False self.__task_name = "Task Usuario - " + self.key self.keyMap = {TECLA_esquerda: EVENT_up, TECLA_direita: EVENT_up, TECLA_frente: EVENT_up, TECLA_traz: EVENT_up} pandaFileModelo = get_path_modelo("ralph") pandaFileAnimacaoRun = get_path_animacao("ralph-run") pandaFileAnimacaoWalk = get_path_animacao("ralph-walk") self.modelo = Actor(pandaFileModelo, {"run": pandaFileAnimacaoRun, "walk": pandaFileAnimacaoWalk}) self.modelo.reparentTo(render) self.modelo.setScale(SCALE_MODELOS) self.set_pos((float(dadosUsuario["x"]), float(dadosUsuario["y"]), float(dadosUsuario["z"]))) self.set_h(float(dadosUsuario["h"])) if not principal: self.text = Text( parent=self.modelo, pos=(0, 0, 5.5), scale=0.5, align="center", cor=COR_VERDE, text=self.nick ) self.text.billboardEffect() self.__setup_collision() taskMgr.add(self.__task_movimentacao, self.__task_name, sort=1) def get_x(self): return self.modelo.getX() def get_y(self): return self.modelo.getY() def get_z(self): return self.modelo.getZ() def get_h(self): return self.modelo.getH() def get_pos(self): return self.modelo.getPos() def set_x(self, x): self.modelo.setX(x) def set_y(self, y): self.modelo.setY(y) def set_z(self, z): self.modelo.setZ(z) def set_h(self, h): self.modelo.setH(h) def set_pos(self, pos): self.modelo.setPos(pos) def delete(self): taskMgr.remove(self.__task_name) self.modelo.delete() def __setup_collision(self): # Colisao self.cTrav = CollisionTraverser("usuarioTraverser") self.ralphGroundRay = CollisionRay() self.ralphGroundRay.setOrigin(0, 0, 5) 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.modelo.attachNewNode(self.ralphGroundCol) self.ralphGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler) # self.ralphGroundColNp.show() # self.cTrav.showCollisions(render) # Colisao def __task_movimentacao(self, task): dt = globalClock.getDt() startpos = self.modelo.getPos() # movimentos usuario modelo if self.keyMap[TECLA_esquerda] == EVENT_down and self.keyMap[TECLA_direita] == EVENT_up: self.modelo.setH(self.modelo, ((self.velocidade * 5) * dt)) if not self.estaRodando: self.estaRodando = True elif self.keyMap[TECLA_direita] == EVENT_down and self.keyMap[TECLA_esquerda] == EVENT_up: self.modelo.setH(self.modelo, ((self.velocidade * 5) * dt) * -1) if not self.estaRodando: self.estaRodando = True elif self.estaRodando: self.estaRodando = False if self.keyMap[TECLA_frente] == EVENT_down and self.keyMap[TECLA_traz] == EVENT_up: self.modelo.setY(self.modelo, ((self.velocidade * 2) * dt) * -1) if self.estaMovendo is False: self.modelo.loop("run") self.estaMovendo = True elif self.keyMap[TECLA_traz] == EVENT_down and self.keyMap[TECLA_frente] == EVENT_up: self.modelo.setY(self.modelo, (self.velocidade * dt)) if self.estaMovendo is False: self.modelo.loop("walk") self.estaMovendo = True elif self.estaMovendo: self.modelo.stop() self.modelo.pose("walk", 5) self.estaMovendo = False # movimentos usuario modelo if self.estaMovendo: self.cTrav.traverse(render) if self.ralphGroundHandler.getNumEntries() == 1: entry = self.ralphGroundHandler.getEntry(0) if entry.getIntoNode().getName() == "terrain": self.modelo.setZ(entry.getSurfacePoint(render).getZ()) else: self.modelo.setPos(startpos) return task.cont
class Player(DirectObject): def __init__(self): self._keymap = { 'forward' : 0, 'reverse' : 0, 'right' : 0, 'left' : 0, } self._camera_pos = (0, -40, 5) self._cam_min_dist = 10 self._dir = 0 self._coll_dist = 10 self._coll_dist_h = 3 self._scale = .5 self._fixed_camera = False self._load_models() self._load_sounds() self._load_lights() self._configure_camera() self._setup_actions() self._setup_tasks() self._setup_collisions() self.health = 100 self.font = loader.loadFont(os.path.join("fonts", "arial.ttf")) self.bk_text= "Health " self.textObject = OnscreenText(text=self.bk_text+str(self.health), font=self.font, pos = (-1, -.95), scale=0.1, fg=(1, 1, 1, 1), mayChange=1) self.win = False def _load_models(self): self._model = Actor(os.path.join("models", "player")) self._model.reparentTo(render) self._model.setPos(206.277, -94.9225, 5) self._model.setScale(self._scale) self._floater = NodePath(PandaNode("floater")) self._floater.reparentTo(render) self._floater.setPos(self._model.getPos()) self._skybox = loader.loadModel(os.path.join("models", "sky")) self._skybox.reparentTo(render) self._skybox.setPos(0,0,3) def _load_sounds(self): self._sound_toggle = loader.loadSfx(os.path.join("sounds", "headlight-toggle.mp3")) self._sound_snowmobile = loader.loadSfx(os.path.join("sounds", "snowmobile-running.mp3")) def _load_lights(self): self._headlight = Spotlight('player-headlight') self._headlight.setColor((1, 1, 1, 1)) self._headlight.setLens(PerspectiveLens()) self._headlight.getLens().setFov(30, 15) self._headlight.setAttenuation(Vec3(1, 0, 0)) self._headlight.setExponent(.5) self._headlight_path = self._model.attachNewNode(self._headlight) self._headlight_path.setPos(0, 0, 0) self._headlight_path.setHpr(0, 0, 0) render.setLight(self._headlight_path) self._skybox.setLightOff() self._headlight_on = True self._skylight = AmbientLight('skylight') self._skylight.setColor((.5,.5,.5,1)) self._skylight_path = render.attachNewNode(self._skylight) self._skybox.setLight(self._skylight_path) def _configure_camera(self): camera.reparentTo(self._floater) camera.setPos(self._camera_pos[0], self._camera_pos[1], self._camera_pos[2]) camera.lookAt(self._floater) def _setup_actions(self): self.accept("arrow_up", self._set_key, ["forward", 1]) self.accept("arrow_up-up", self._set_key, ["forward", 0]) self.accept("arrow_down", self._set_key, ["reverse", 1]) self.accept("arrow_down-up", self._set_key, ["reverse", 0]) self.accept("arrow_left", self._set_key, ["left", 1]) self.accept("arrow_left-up", self._set_key, ["left", 0]) self.accept("arrow_right", self._set_key, ["right", 1]) self.accept("arrow_right-up", self._set_key, ["right", 0]) self.accept('f',self._toggle_headlight) self.accept('space',self._toggle_camera) def _toggle_headlight(self): if self._headlight_on: render.clearLight(self._headlight_path) self._sound_toggle.play() self._headlight_on = False else: render.setLight(self._headlight_path) self._skybox.setLightOff() self._skybox.setLight(self._skylight_path) self._sound_toggle.play() self._headlight_on = True def _toggle_camera(self): if self._fixed_camera: self._fixed_camera = False else: self._fixed_camera = True def _setup_tasks(self): self._prev_move_time = 0 taskMgr.add(self._task_move, "player-task-move") def _setup_collisions(self): self._coll_trav = CollisionTraverser() # Front collision self._gnd_handler_front = CollisionHandlerQueue() self._gnd_ray_front = CollisionRay() self._gnd_ray_front.setOrigin(0, self._coll_dist, 20) self._gnd_ray_front.setDirection(0, 0, -1) self._gnd_coll_front = CollisionNode('collision-ground-front') self._gnd_coll_front.addSolid(self._gnd_ray_front) self._gnd_coll_front.setFromCollideMask(BitMask32.bit(0)) self._gnd_coll_front.setIntoCollideMask(BitMask32.allOff()) self._gnd_coll_path_front = self._model.attachNewNode(self._gnd_coll_front) #self._gnd_coll_path_front.show() self._coll_trav.addCollider(self._gnd_coll_path_front, self._gnd_handler_front) # Back collision self._gnd_handler_back = CollisionHandlerQueue() self._gnd_ray_back = CollisionRay() self._gnd_ray_back.setOrigin(0, -self._coll_dist, 20) self._gnd_ray_back.setDirection(0, 0, -1) self._gnd_coll_back = CollisionNode('collision-ground-back') self._gnd_coll_back.addSolid(self._gnd_ray_back) self._gnd_coll_back.setFromCollideMask(BitMask32.bit(0)) self._gnd_coll_back.setIntoCollideMask(BitMask32.allOff()) self._gnd_coll_path_back = self._model.attachNewNode(self._gnd_coll_back) #self._gnd_coll_path_back.show() self._coll_trav.addCollider(self._gnd_coll_path_back, self._gnd_handler_back) # Left collision self._gnd_handler_left = CollisionHandlerQueue() self._gnd_ray_left = CollisionRay() self._gnd_ray_left.setOrigin(-self._coll_dist_h, 0, 20) self._gnd_ray_left.setDirection(0, 0, -1) self._gnd_coll_left = CollisionNode('collision-ground-left') self._gnd_coll_left.addSolid(self._gnd_ray_left) self._gnd_coll_left.setFromCollideMask(BitMask32.bit(0)) self._gnd_coll_left.setIntoCollideMask(BitMask32.allOff()) self._gnd_coll_path_left = self._model.attachNewNode(self._gnd_coll_left) #self._gnd_coll_path_left.show() self._coll_trav.addCollider(self._gnd_coll_path_left, self._gnd_handler_left) # Right collision self._gnd_handler_right = CollisionHandlerQueue() self._gnd_ray_right = CollisionRay() self._gnd_ray_right.setOrigin(self._coll_dist_h, 0, 20) self._gnd_ray_right.setDirection(0, 0, -1) self._gnd_coll_right = CollisionNode('collision-ground-right') self._gnd_coll_right.addSolid(self._gnd_ray_right) self._gnd_coll_right.setFromCollideMask(BitMask32.bit(0)) self._gnd_coll_right.setIntoCollideMask(BitMask32.allOff()) self._gnd_coll_path_right = self._model.attachNewNode(self._gnd_coll_right) #self._gnd_coll_path_right.show() self._coll_trav.addCollider(self._gnd_coll_path_right, self._gnd_handler_right) # Camera collision self._gnd_handler_cam = CollisionHandlerQueue() self._gnd_ray_cam = CollisionRay() self._gnd_ray_cam.setOrigin(camera.getX(), camera.getY(), 20) self._gnd_ray_cam.setDirection(0, 0, -1) self._gnd_coll_cam = CollisionNode('collision-ground-cam') self._gnd_coll_cam.addSolid(self._gnd_ray_cam) self._gnd_coll_cam.setFromCollideMask(BitMask32.bit(0)) self._gnd_coll_cam.setIntoCollideMask(BitMask32.allOff()) self._gnd_coll_path_cam = self._floater.attachNewNode(self._gnd_coll_cam) #self._gnd_coll_path_cam.show() self._coll_trav.addCollider(self._gnd_coll_path_cam, self._gnd_handler_cam) # Enemy sight target self._sphere_handler = CollisionHandlerQueue() self._sphere = CollisionSphere(0, 0, 0, 10) self._coll_sphere = CollisionNode('collision-player-sphere') self._coll_sphere.addSolid(self._sphere) self._coll_sphere.setFromCollideMask(BitMask32.bit(0)) self._coll_sphere.setIntoCollideMask(BitMask32.bit(5)) self._coll_sphere_path = self._model.attachNewNode(self._coll_sphere) #self._coll_sphere_path.show() self._coll_trav.addCollider(self._coll_sphere_path, self._sphere_handler) # Inner sphere collision self._inner_sphere_handler = CollisionHandlerQueue() self._inner_sphere = CollisionSphere(0, 0, 0, 10) self._coll_inner_sphere = CollisionNode('collision-player-sphere-inner') self._coll_inner_sphere.addSolid(self._inner_sphere) self._coll_inner_sphere.setFromCollideMask(BitMask32.bit(7)) self._coll_inner_sphere.setIntoCollideMask(BitMask32.bit(7)) self._coll_inner_sphere_path = self._model.attachNewNode(self._coll_inner_sphere) #self._coll_inner_sphere_path.show() self._coll_trav.addCollider(self._coll_inner_sphere_path, self._inner_sphere_handler) def _set_key(self, key, value): self._keymap[key] = value def _task_move(self, task): for i in range(self._inner_sphere_handler.getNumEntries()): if self._inner_sphere_handler.getEntry(i).getIntoNode().getName()=='collision-with-player': self.health -= .5 et = task.time - self._prev_move_time rotation_rate = 100 walk_rate = 50 cam_rate = .5 cam_turn = 10 # Get current values rotation = self._model.getH() pos_x = self._model.getX() pos_y = self._model.getY() pos = self._model.getPos() # Rotate the player dr = et * rotation_rate rotation += self._keymap['left'] * dr rotation -= self._keymap['right'] * dr # Move the player rotation_rad = deg2Rad(rotation) dx = et * walk_rate * -math.sin(rotation_rad) dy = et * walk_rate * math.cos(rotation_rad) pos_x += self._keymap['forward'] * dx pos_y += self._keymap['forward'] * dy pos_x -= self._keymap['reverse'] * dx pos_y -= self._keymap['reverse'] * dy if self._sound_snowmobile.status() == 1: if self._keymap['forward'] == 1 or self._keymap['reverse'] == 1 or self._keymap['left'] == 1 or self._keymap['right'] == 1: self._sound_snowmobile.play() self._sound_snowmobile.setLoop(True) elif self._sound_snowmobile.status() == 2: if self._keymap['forward'] == 0 and self._keymap['reverse'] == 0 and self._keymap['left'] == 0 and self._keymap['right'] == 0: self._sound_snowmobile.stop() # Save back to the model self._model.setH(rotation) self._model.setX(pos_x) self._model.setY(pos_y) self._coll_trav.traverse(render) entries_front = [] entries_back = [] entries_left = [] entries_right = [] for i in range(self._gnd_handler_front.getNumEntries()): entries_front.append(self._gnd_handler_front.getEntry(i)) for i in range(self._gnd_handler_back.getNumEntries()): entries_back.append(self._gnd_handler_back.getEntry(i)) for i in range(self._gnd_handler_left.getNumEntries()): entries_left.append(self._gnd_handler_left.getEntry(i)) for i in range(self._gnd_handler_right.getNumEntries()): entries_right.append(self._gnd_handler_right.getEntry(i)) entries_all = entries_front + entries_back + entries_left + entries_right srt = lambda x, y: cmp(y.getSurfacePoint(render).getZ(), x.getSurfacePoint(render).getZ()) entries_front.sort(srt) entries_back.sort(srt) entries_left.sort(srt) entries_right.sort(srt) if entries_all: is_valid = lambda x: x and x[0].getIntoNode().getName().find('terrain') != -1 if is_valid(entries_front) and is_valid(entries_back) and is_valid(entries_left) and is_valid(entries_right): f = entries_front[0].getSurfacePoint(render).getZ() b = entries_back[0].getSurfacePoint(render).getZ() l = entries_left[0].getSurfacePoint(render).getZ() r = entries_right[0].getSurfacePoint(render).getZ() z = (f + b) / 2 if abs(z - self._model.getZ()) > 5: self._model.setPos(pos) else: self._model.setZ(z) self._model.setP(rad2Deg(math.atan2(f - z, self._coll_dist * self._scale))) self._model.setR(rad2Deg(math.atan2(l - z, self._coll_dist_h * self._scale))) else: self._model.setPos(pos) self._floater.setPos(self._model.getPos()) self._floater.setH(self._model.getH()) entries_cam = [] for i in range(self._gnd_handler_cam.getNumEntries()): entries_cam.append(self._gnd_handler_cam.getEntry(i)) entries_cam = filter(lambda x: x.getIntoNode().getName().find('terrain') != -1, entries_cam) entries_cam.sort(srt) cam_z = self._camera_pos[2] if entries_cam and self._fixed_camera: cam_z = max(cam_z, entries_cam[0].getSurfacePoint(render).getZ() + self._cam_min_dist) ival = None if self._keymap['left']: self._dir = -1 ival = camera.posHprInterval(cam_rate, (-cam_turn, camera.getY(), cam_z), (-cam_turn, camera.getP(), camera.getR())) elif self._keymap['right']: self._dir = 1 ival = camera.posHprInterval(cam_rate, (cam_turn, camera.getY(), cam_z), (cam_turn, camera.getP(), camera.getR())) else: self._dir = 0 ival = camera.posHprInterval(cam_rate / 2, (0, camera.getY(), cam_z), (0, camera.getP(), camera.getR())) if ival: ival.start() camera.lookAt(self._floater) self._gnd_ray_cam.setOrigin(camera.getX(), camera.getY(), 20) self._prev_move_time = task.time if self.health >= 0: self.textObject.setText(self.bk_text+str(self.health)) if self.health <= 0 and self.win == False: c = OnscreenImage(parent=render2d, image=os.path.join("models", "titlescreen.png")) lose = OnscreenText(text="You Lose!", font=self.font, pos = (0, 0.7), scale=0.2, fg=(1, 1, 1, 1), mayChange=0) return Task.cont
class PartyCog(FSM): notify = directNotify.newCategory('PartyCog') HpTextGenerator = TextNode('HpTextGenerator') hpText = None height = 7 def __init__(self, parentNode, id, bounceSpeed=3, bounceHeight=1, rotateSpeed=1, heightShift=1, xMoveSpeed=0, xMoveDistance=0, bounceOffset=0): self.id = id FSM.__init__(self, 'PartyCogFSM-%d' % self.id) self.showFacingStatus = False self.xMoveSpeed = xMoveSpeed self.xMoveDistance = xMoveDistance self.heightShift = heightShift self.bounceSpeed = bounceSpeed self.bounceHeight = bounceHeight self.rotateSpeed = rotateSpeed self.parentNode = parentNode self.bounceOffset = bounceOffset self.hitInterval = None self.kaboomTrack = None self.resetRollIval = None self.netTimeSentToStartByHit = 0 self.load() self.request('Down') return def load(self): self.root = NodePath('PartyCog-%d' % self.id) self.root.reparentTo(self.parentNode) path = 'phase_13/models/parties/cogPinata_' self.actor = Actor( path + 'actor', { 'idle': path + 'idle_anim', 'down': path + 'down_anim', 'up': path + 'up_anim', 'bodyHitBack': path + 'bodyHitBack_anim', 'bodyHitFront': path + 'bodyHitFront_anim', 'headHitBack': path + 'headHitBack_anim', 'headHitFront': path + 'headHitFront_anim' }) self.actor.reparentTo(self.root) self.temp_transform = Mat4() self.head_locator = self.actor.attachNewNode('temphead') self.bodyColl = CollisionTube(0, 0, 1, 0, 0, 5.75, 0.75) self.bodyColl.setTangible(1) self.bodyCollNode = CollisionNode('PartyCog-%d-Body-Collision' % self.id) self.bodyCollNode.setCollideMask(ToontownGlobals.PieBitmask) self.bodyCollNode.addSolid(self.bodyColl) self.bodyCollNodePath = self.root.attachNewNode(self.bodyCollNode) self.headColl = CollisionTube(0, 0, 3, 0, 0, 3.0, 1.5) self.headColl.setTangible(1) self.headCollNode = CollisionNode('PartyCog-%d-Head-Collision' % self.id) self.headCollNode.setCollideMask(ToontownGlobals.PieBitmask) self.headCollNode.addSolid(self.headColl) self.headCollNodePath = self.root.attachNewNode(self.headCollNode) self.arm1Coll = CollisionSphere(1.65, 0, 3.95, 1.0) self.arm1Coll.setTangible(1) self.arm1CollNode = CollisionNode('PartyCog-%d-Arm1-Collision' % self.id) self.arm1CollNode.setCollideMask(ToontownGlobals.PieBitmask) self.arm1CollNode.addSolid(self.arm1Coll) self.arm1CollNodePath = self.root.attachNewNode(self.arm1CollNode) self.arm2Coll = CollisionSphere(-1.65, 0, 3.45, 1.0) self.arm2Coll.setTangible(1) self.arm2CollNode = CollisionNode('PartyCog-%d-Arm2-Collision' % self.id) self.arm2CollNode.setCollideMask(ToontownGlobals.PieBitmask) self.arm2CollNode.addSolid(self.arm2Coll) self.arm2CollNodePath = self.root.attachNewNode(self.arm2CollNode) splatName = 'splat-creampie' self.splat = globalPropPool.getProp(splatName) self.splat.setBillboardPointEye() self.splatType = globalPropPool.getPropType(splatName) self.pieHitSound = globalBattleSoundCache.getSound( 'AA_wholepie_only.ogg') self.upSound = globalBattleSoundCache.getSound('AV_jump_to_side.ogg') self.hole = loader.loadModel('phase_13/models/parties/cogPinataHole') self.hole.setTransparency(True) self.hole.setP(-90.0) self.hole.setScale(3) self.hole.setBin('ground', 3) self.hole.reparentTo(self.parentNode) def unload(self): self.request('Off') self.clearHitInterval() if self.hole is not None: self.hole.removeNode() self.hole = None if self.actor is not None: self.actor.cleanup() self.actor.removeNode() self.actor = None if self.root is not None: self.root.removeNode() self.root = None if self.kaboomTrack is not None and self.kaboomTrack.isPlaying(): self.kaboomTrack.finish() self.kaboomTrack = None if self.resetRollIval is not None and self.resetRollIval.isPlaying(): self.resetRollIval.finish() self.resetRollIval = None if self.hitInterval is not None and self.hitInterval.isPlaying(): self.hitInterval.finish() self.hitInterval = None del self.upSound del self.pieHitSound return def enterStatic(self): pass def exitStatic(self): pass def enterActive(self, startTime): self.root.setR(0.0) updateTask = Task.Task(self.updateTask) updateTask.startTime = startTime taskMgr.add(updateTask, 'PartyCog.update-%d' % self.id) def exitActive(self): taskMgr.remove('PartyCog.update-%d' % self.id) taskMgr.remove('PartyCog.bounceTask-%d' % self.id) self.clearHitInterval() self.resetRollIval = self.root.hprInterval(0.5, Point3( self.root.getH(), 0.0, 0.0), blendType='easeInOut') self.resetRollIval.start() self.actor.stop() def enterDown(self): if self.oldState == 'Off': downAnimControl = self.actor.getAnimControl('down') self.actor.pose('down', downAnimControl.getNumFrames() - 1) return self.clearHitInterval() startScale = self.hole.getScale() endScale = Point3(5, 5, 5) self.hitInterval = Sequence( LerpFunc(self.setAlongSpline, duration=1.0, fromData=self.currentT, toData=0.0), LerpScaleInterval(self.hole, duration=0.175, scale=endScale, startScale=startScale, blendType='easeIn'), Parallel( SoundInterval(self.upSound, volume=0.6, node=self.actor, cutOff=PartyGlobals.PARTY_COG_CUTOFF), ActorInterval(self.actor, 'down', loop=0)), LerpScaleInterval(self.hole, duration=0.175, scale=Point3(3, 3, 3), startScale=endScale, blendType='easeOut')) self.hitInterval.start() def exitDown(self): self.root.setR(0.0) self.root.setH(0.0) self.targetDistance = 0.0 self.targetFacing = 0.0 self.currentT = 0.0 self.setAlongSpline(0.0) self.clearHitInterval() startScale = self.hole.getScale() endScale = Point3(5, 5, 5) self.hitInterval = Sequence( LerpScaleInterval(self.hole, duration=0.175, scale=endScale, startScale=startScale, blendType='easeIn'), Parallel( SoundInterval(self.upSound, volume=0.6, node=self.actor, cutOff=PartyGlobals.PARTY_COG_CUTOFF), ActorInterval(self.actor, 'up', loop=0)), Func(self.actor.loop, 'idle'), LerpScaleInterval(self.hole, duration=0.175, scale=Point3(3, 3, 3), startScale=endScale, blendType='easeOut')) self.hitInterval.start() def filterDown(self, request, args): if request == 'Down': return None else: return self.defaultFilter(request, args) return None def setEndPoints(self, start, end, amplitude=1.7): self.sinAmplitude = amplitude self.sinPeriod = (end.getX() - start.getX()) / 2 self.sinDisplacement = start.getY() self.startPoint = start self.endPoint = end self.currentT = 0.0 self.targetDistance = 0.0 self.currentFacing = 0.0 self.targetFacing = 0.0 self.setAlongSpline(self.currentT) self.hole.setPos(self.root.getPos()) self.hole.setZ(0.02) def rockBackAndForth(self, task): t = task.startTime + task.time angle = math.sin(t) * 20.0 self.root.setR(angle) return task.cont def updateDistance(self, distance): self.targetDistance = clamp(distance, -1.0, 1.0) def updateTask(self, task): self.rockBackAndForth(task) if self.targetDistance > self.currentT: self.currentT += min(0.01, self.targetDistance - self.currentT) self.setAlongSpline(self.currentT) elif self.targetDistance < self.currentT: self.currentT += max(-0.01, self.targetDistance - self.currentT) self.setAlongSpline(self.currentT) if self.currentT < 0.0: self.targetFacing = -90.0 elif self.currentT > 0.0: self.targetFacing = 90.0 else: self.targetFacing = 0.0 if self.targetFacing > self.currentFacing: self.currentFacing += min(10, self.targetFacing - self.currentFacing) elif self.targetFacing < self.currentFacing: self.currentFacing += max(-10, self.targetFacing - self.currentFacing) self.root.setH(self.currentFacing) return task.cont def setAlongSpline(self, t): t = t + 1.0 dist = (self.endPoint.getX() - self.startPoint.getX()) / 2.0 x = self.startPoint.getX() + t * dist y = self.startPoint.getY() - math.sin( t * 2 * math.pi) * self.sinAmplitude self.root.setPos(x, y, 0) def startBounce(self): taskMgr.add(self.bounce, 'PartyCog.bounceTask-%d' % self.id) def bounce(self, task): self.root.setZ( math.sin((self.bounceOffset + task.time) * self.bounceSpeed) * self.bounceHeight + self.heightShift) return task.cont def setPos(self, position): self.root.setPos(position) def respondToPieHit(self, timestamp, position, hot=False, direction=1.0): if self.netTimeSentToStartByHit < timestamp: self.__showSplat(position, direction, hot) if self.netTimeSentToStartByHit < timestamp: self.netTimeSentToStartByHit = timestamp else: self.notify.debug( 'respondToPieHit self.netTimeSentToStartByHit = %s' % self.netTimeSentToStartByHit) def clearHitInterval(self): if self.hitInterval is not None and self.hitInterval.isPlaying(): self.hitInterval.clearToInitial() return def __showSplat(self, position, direction, hot=False): if self.kaboomTrack is not None and self.kaboomTrack.isPlaying(): self.kaboomTrack.finish() self.clearHitInterval() splatName = 'splat-creampie' self.splat = globalPropPool.getProp(splatName) self.splat.setBillboardPointEye() self.splat.reparentTo(render) self.splat.setPos(self.root, position) self.splat.setAlphaScale(1.0) if not direction == 1.0: self.splat.setColorScale(PartyGlobals.CogActivitySplatColors[0]) if self.currentFacing > 0.0: facing = 'HitFront' else: facing = 'HitBack' else: self.splat.setColorScale(PartyGlobals.CogActivitySplatColors[1]) if self.currentFacing > 0.0: facing = 'HitBack' else: facing = 'HitFront' if hot: targetscale = 0.75 part = 'head' else: targetscale = 0.5 part = 'body' def setSplatAlpha(amount): self.splat.setAlphaScale(amount) self.hitInterval = Sequence( ActorInterval(self.actor, part + facing, loop=0), Func(self.actor.loop, 'idle')) self.hitInterval.start() self.kaboomTrack = Parallel( SoundInterval(self.pieHitSound, volume=1.0, node=self.actor, cutOff=PartyGlobals.PARTY_COG_CUTOFF), Sequence( Func(self.splat.showThrough), Parallel( Sequence( LerpScaleInterval(self.splat, duration=0.175, scale=targetscale, startScale=Point3(0.1, 0.1, 0.1), blendType='easeOut'), Wait(0.175)), Sequence( Wait(0.1), LerpFunc(setSplatAlpha, duration=1.0, fromData=1.0, toData=0.0, blendType='easeOut'))), Func(self.splat.cleanup), Func(self.splat.removeNode))) self.kaboomTrack.start() return def showHitScore(self, number, scale=1): if number <= 0: return if self.hpText: self.hideHitScore() self.HpTextGenerator.setFont(ToontownGlobals.getSignFont()) if number < 0: self.HpTextGenerator.setText(str(number)) else: self.HpTextGenerator.setText('+' + str(number)) self.HpTextGenerator.clearShadow() self.HpTextGenerator.setAlign(TextNode.ACenter) r = 1 g = 1 b = 0 a = 1 self.HpTextGenerator.setTextColor(r, g, b, a) self.hpTextNode = self.HpTextGenerator.generate() self.hpText = render.attachNewNode(self.hpTextNode) self.hpText.setScale(scale) self.hpText.setBillboardPointEye() self.hpText.setBin('fixed', 100) self.hpText.setPos(self.root, 0, 0, self.height / 2) seq = Task.sequence( self.hpText.lerpPos(Point3( self.root.getX(render), self.root.getY(render), self.root.getZ(render) + self.height + 1.0), 0.25, blendType='easeOut'), Task.pause(0.25), self.hpText.lerpColor(Vec4(r, g, b, a), Vec4(r, g, b, 0), 0.1), Task.Task(self.__hideHitScoreTask)) taskMgr.add(seq, 'PartyCogHpText' + str(self.id)) def __hideHitScoreTask(self, task): self.hideHitScore() return Task.done def hideHitScore(self): if self.hpText: taskMgr.remove('PartyCogHpText' + str(self.id)) self.hpText.removeNode() self.hpText = None return def getHeadLocation(self): self.actor.getJoints(jointName='head')[0].getNetTransform( self.temp_transform) self.head_locator.setMat(self.temp_transform) return self.head_locator.getZ(self.root)
class Game(ShowBase): def __init__(self): ShowBase.__init__(self) self.disableMouse() properties = WindowProperties() properties.setSize(1000, 750) self.win.requestProperties(properties) ambientLight = AmbientLight("ambient light") ambientLight.setColor(Vec4(0.2, 0.2, 0.2, 1)) self.ambientLightNodePath = render.attachNewNode(ambientLight) render.setLight(self.ambientLightNodePath) mainLight = DirectionalLight("main light") self.mainLightNodePath = render.attachNewNode(mainLight) # Turn it around by 45 degrees, and tilt it down by 45 degrees self.mainLightNodePath.setHpr(45, -45, 0) render.setLight(self.mainLightNodePath) render.setShaderAuto() self.environment = loader.loadModel("Models/Misc/environment") self.environment.reparentTo(render) self.tempActor = Actor("Models/PandaChan/act_p3d_chan", {"walk" : "Models/PandaChan/a_p3d_chan_run"}) self.tempActor.getChild(0).setH(180) self.tempActor.reparentTo(render) self.tempActor.setPos(0, 2, 0) self.tempActor.loop("walk") self.camera.setPos(0, 0, 32) self.camera.setP(-90) self.keyMap = { "up" : False, "down" : False, "left" : False, "right" : False, "shoot" : False } self.accept("w", self.updateKeyMap, ["up", True]) self.accept("w-up", self.updateKeyMap, ["up", False]) self.accept("s", self.updateKeyMap, ["down", True]) self.accept("s-up", self.updateKeyMap, ["down", False]) self.accept("a", self.updateKeyMap, ["left", True]) self.accept("a-up", self.updateKeyMap, ["left", False]) self.accept("d", self.updateKeyMap, ["right", True]) self.accept("d-up", self.updateKeyMap, ["right", False]) self.accept("mouse1", self.updateKeyMap, ["shoot", True]) self.accept("mouse1-up", self.updateKeyMap, ["shoot", False]) self.updateTask = taskMgr.add(self.update, "update") # Panda should now automatically update that traverser! self.cTrav = CollisionTraverser() self.pusher = CollisionHandlerPusher() # prevents nominated solid objects from intersecting other solid objects. colliderNode = CollisionNode("player") # Add a collision-sphere centred on (0, 0, 0), and with a radius of 0.3 colliderNode.addSolid(CollisionSphere(0, 0, 0, 0.4)) collider = self.tempActor.attachNewNode(colliderNode) collider.show() # The pusher wants a collider, and a NodePath that # should be moved by that collider's collisions. # In this case, we want our player-Actor to be moved. base.pusher.addCollider(collider, self.tempActor) # The traverser wants a collider, and a handler # that responds to that collider's collisions base.cTrav.addCollider(collider, self.pusher) self.pusher.setHorizontal(True) # Tubes are defined by their start-points, end-points, and radius. # In this first case, the tube goes from (-8, 0, 0) to (8, 0, 0), # and has a radius of 0.2. wallSolid = CollisionTube(-8.0, 0, 0, 8.0, 0, 0, 0.2) wallNode = CollisionNode("wall") wallNode.addSolid(wallSolid) wall = render.attachNewNode(wallNode) wall.setY(8.0) wallSolid = CollisionTube(-8.0, 0, 0, 8.0, 0, 0, 0.2) wallNode = CollisionNode("wall") wallNode.addSolid(wallSolid) wall = render.attachNewNode(wallNode) wall.setY(-8.0) wallSolid = CollisionTube(0, -8.0, 0, 0, 8.0, 0, 0.2) wallNode = CollisionNode("wall") wallNode.addSolid(wallSolid) wall = render.attachNewNode(wallNode) wall.setX(8.0) wallSolid = CollisionTube(0, -8.0, 0, 0, 8.0, 0, 0.2) wallNode = CollisionNode("wall") wallNode.addSolid(wallSolid) wall = render.attachNewNode(wallNode) wall.setX(-8.0) def updateKeyMap(self, controlName, controlState): self.keyMap[controlName] = controlState print (controlName, "set to", controlState) def update(self, task): # Get the amount of time since the last update dt = globalClock.getDt() # If any movement keys are pressed, use the above time # to calculate how far to move the character, and apply that. if self.keyMap["up"]: self.tempActor.setPos(self.tempActor.getPos() + Vec3(0, 5.0*dt, 0)) if self.keyMap["down"]: self.tempActor.setPos(self.tempActor.getPos() + Vec3(0, -5.0*dt, 0)) if self.keyMap["left"]: self.tempActor.setPos(self.tempActor.getPos() + Vec3(-5.0*dt, 0, 0)) if self.keyMap["right"]: self.tempActor.setPos(self.tempActor.getPos() + Vec3(5.0*dt, 0, 0)) if self.keyMap["shoot"]: print ("Zap!") return Task.cont
class GameObject(): def __init__(self, pos, modelName, modelAnims, maxHealth, maxSpeed, colliderName): self.actor = Actor(modelName, modelAnims) self.actor.reparentTo(render) self.actor.setPos(pos) self.maxHealth = maxHealth self.health = maxHealth self.maxSpeed = maxSpeed self.velocity = Vec3(0, 0, 0) self.acceleration = 300.0 self.walking = False colliderNode = CollisionNode(colliderName) colliderNode.addSolid(CollisionSphere(0, 0, 0, 0.3)) self.collider = self.actor.attachNewNode(colliderNode) self.collider.setPythonTag("owner", self) def update(self, dt): # If we're going faster than our maximum speed, # set the velocity-vector's length to that maximum speed = self.velocity.length() if speed > self.maxSpeed: self.velocity.normalize() self.velocity *= self.maxSpeed speed = self.maxSpeed # If we're walking, don't worry about friction. # Otherwise, use friction to slow us down. if not self.walking: frictionVal = FRICTION*dt if frictionVal > speed: self.velocity.set(0, 0, 0) else: frictionVec = -self.velocity frictionVec.normalize() frictionVec *= frictionVal self.velocity += frictionVec # Move the character, using our velocity and # the time since the last update. self.actor.setPos(self.actor.getPos() + self.velocity*dt) def alterHealth(self, dHealth): self.health += dHealth if self.health > self.maxHealth: self.health = self.maxHealth # Remove various nodes, and clear the Python-tag--see below! def cleanup(self): if self.collider is not None and not self.collider.isEmpty(): self.collider.clearPythonTag("owner") base.cTrav.removeCollider(self.collider) base.pusher.removeCollider(self.collider) if self.actor is not None: self.actor.cleanup() self.actor.removeNode() self.actor = None self.collider = None
class PartyCog(FSM): notify = directNotify.newCategory('PartyCog') HpTextGenerator = TextNode('HpTextGenerator') hpText = None height = 7 def __init__(self, parentNode, id, bounceSpeed = 3, bounceHeight = 1, rotateSpeed = 1, heightShift = 1, xMoveSpeed = 0, xMoveDistance = 0, bounceOffset = 0): self.id = id FSM.__init__(self, 'PartyCogFSM-%d' % self.id) self.showFacingStatus = False self.xMoveSpeed = xMoveSpeed self.xMoveDistance = xMoveDistance self.heightShift = heightShift self.bounceSpeed = bounceSpeed self.bounceHeight = bounceHeight self.rotateSpeed = rotateSpeed self.parentNode = parentNode self.bounceOffset = bounceOffset self.hitInterval = None self.kaboomTrack = None self.resetRollIval = None self.netTimeSentToStartByHit = 0 self.load() self.request('Down') return def load(self): self.root = NodePath('PartyCog-%d' % self.id) self.root.reparentTo(self.parentNode) path = 'phase_13/models/parties/cogPinata_' self.actor = Actor(path + 'actor', {'idle': path + 'idle_anim', 'down': path + 'down_anim', 'up': path + 'up_anim', 'bodyHitBack': path + 'bodyHitBack_anim', 'bodyHitFront': path + 'bodyHitFront_anim', 'headHitBack': path + 'headHitBack_anim', 'headHitFront': path + 'headHitFront_anim'}) self.actor.reparentTo(self.root) self.temp_transform = Mat4() self.head_locator = self.actor.attachNewNode('temphead') self.bodyColl = CollisionTube(0, 0, 1, 0, 0, 5.75, 0.75) self.bodyColl.setTangible(1) self.bodyCollNode = CollisionNode('PartyCog-%d-Body-Collision' % self.id) self.bodyCollNode.setCollideMask(ToontownGlobals.PieBitmask) self.bodyCollNode.addSolid(self.bodyColl) self.bodyCollNodePath = self.root.attachNewNode(self.bodyCollNode) self.headColl = CollisionTube(0, 0, 3, 0, 0, 3.0, 1.5) self.headColl.setTangible(1) self.headCollNode = CollisionNode('PartyCog-%d-Head-Collision' % self.id) self.headCollNode.setCollideMask(ToontownGlobals.PieBitmask) self.headCollNode.addSolid(self.headColl) self.headCollNodePath = self.root.attachNewNode(self.headCollNode) self.arm1Coll = CollisionSphere(1.65, 0, 3.95, 1.0) self.arm1Coll.setTangible(1) self.arm1CollNode = CollisionNode('PartyCog-%d-Arm1-Collision' % self.id) self.arm1CollNode.setCollideMask(ToontownGlobals.PieBitmask) self.arm1CollNode.addSolid(self.arm1Coll) self.arm1CollNodePath = self.root.attachNewNode(self.arm1CollNode) self.arm2Coll = CollisionSphere(-1.65, 0, 3.45, 1.0) self.arm2Coll.setTangible(1) self.arm2CollNode = CollisionNode('PartyCog-%d-Arm2-Collision' % self.id) self.arm2CollNode.setCollideMask(ToontownGlobals.PieBitmask) self.arm2CollNode.addSolid(self.arm2Coll) self.arm2CollNodePath = self.root.attachNewNode(self.arm2CollNode) splatName = 'splat-creampie' self.splat = globalPropPool.getProp(splatName) self.splat.setBillboardPointEye() self.splatType = globalPropPool.getPropType(splatName) self.pieHitSound = globalBattleSoundCache.getSound('AA_wholepie_only.ogg') self.upSound = globalBattleSoundCache.getSound('AV_jump_to_side.ogg') self.hole = loader.loadModel('phase_13/models/parties/cogPinataHole') self.hole.setTransparency(True) self.hole.setP(-90.0) self.hole.setScale(3) self.hole.setBin('ground', 3) self.hole.reparentTo(self.parentNode) def unload(self): self.request('Off') self.clearHitInterval() if self.hole is not None: self.hole.removeNode() self.hole = None if self.actor is not None: self.actor.cleanup() self.actor.removeNode() self.actor = None if self.root is not None: self.root.removeNode() self.root = None if self.kaboomTrack is not None and self.kaboomTrack.isPlaying(): self.kaboomTrack.finish() self.kaboomTrack = None if self.resetRollIval is not None and self.resetRollIval.isPlaying(): self.resetRollIval.finish() self.resetRollIval = None if self.hitInterval is not None and self.hitInterval.isPlaying(): self.hitInterval.finish() self.hitInterval = None del self.upSound del self.pieHitSound return def enterStatic(self): pass def exitStatic(self): pass def enterActive(self, startTime): self.root.setR(0.0) updateTask = Task.Task(self.updateTask) updateTask.startTime = startTime taskMgr.add(updateTask, 'PartyCog.update-%d' % self.id) def exitActive(self): taskMgr.remove('PartyCog.update-%d' % self.id) taskMgr.remove('PartyCog.bounceTask-%d' % self.id) self.clearHitInterval() self.resetRollIval = self.root.hprInterval(0.5, Point3(self.root.getH(), 0.0, 0.0), blendType='easeInOut') self.resetRollIval.start() self.actor.stop() def enterDown(self): if self.oldState == 'Off': downAnimControl = self.actor.getAnimControl('down') self.actor.pose('down', downAnimControl.getNumFrames() - 1) return self.clearHitInterval() startScale = self.hole.getScale() endScale = Point3(5, 5, 5) self.hitInterval = Sequence(LerpFunc(self.setAlongSpline, duration=1.0, fromData=self.currentT, toData=0.0), LerpScaleInterval(self.hole, duration=0.175, scale=endScale, startScale=startScale, blendType='easeIn'), Parallel(SoundInterval(self.upSound, volume=0.6, node=self.actor, cutOff=PartyGlobals.PARTY_COG_CUTOFF), ActorInterval(self.actor, 'down', loop=0)), LerpScaleInterval(self.hole, duration=0.175, scale=Point3(3, 3, 3), startScale=endScale, blendType='easeOut')) self.hitInterval.start() def exitDown(self): self.root.setR(0.0) self.root.setH(0.0) self.targetDistance = 0.0 self.targetFacing = 0.0 self.currentT = 0.0 self.setAlongSpline(0.0) self.clearHitInterval() startScale = self.hole.getScale() endScale = Point3(5, 5, 5) self.hitInterval = Sequence(LerpScaleInterval(self.hole, duration=0.175, scale=endScale, startScale=startScale, blendType='easeIn'), Parallel(SoundInterval(self.upSound, volume=0.6, node=self.actor, cutOff=PartyGlobals.PARTY_COG_CUTOFF), ActorInterval(self.actor, 'up', loop=0)), Func(self.actor.loop, 'idle'), LerpScaleInterval(self.hole, duration=0.175, scale=Point3(3, 3, 3), startScale=endScale, blendType='easeOut')) self.hitInterval.start() def filterDown(self, request, args): if request == 'Down': return None else: return self.defaultFilter(request, args) return None def setEndPoints(self, start, end, amplitude = 1.7): self.sinAmplitude = amplitude self.sinPeriod = (end.getX() - start.getX()) / 2 self.sinDisplacement = start.getY() self.startPoint = start self.endPoint = end self.currentT = 0.0 self.targetDistance = 0.0 self.currentFacing = 0.0 self.targetFacing = 0.0 self.setAlongSpline(self.currentT) self.hole.setPos(self.root.getPos()) self.hole.setZ(0.02) def rockBackAndForth(self, task): t = task.startTime + task.time angle = math.sin(t) * 20.0 self.root.setR(angle) return task.cont def updateDistance(self, distance): self.targetDistance = clamp(distance, -1.0, 1.0) def updateTask(self, task): self.rockBackAndForth(task) if self.targetDistance > self.currentT: self.currentT += min(0.01, self.targetDistance - self.currentT) self.setAlongSpline(self.currentT) elif self.targetDistance < self.currentT: self.currentT += max(-0.01, self.targetDistance - self.currentT) self.setAlongSpline(self.currentT) if self.currentT < 0.0: self.targetFacing = -90.0 elif self.currentT > 0.0: self.targetFacing = 90.0 else: self.targetFacing = 0.0 if self.targetFacing > self.currentFacing: self.currentFacing += min(10, self.targetFacing - self.currentFacing) elif self.targetFacing < self.currentFacing: self.currentFacing += max(-10, self.targetFacing - self.currentFacing) self.root.setH(self.currentFacing) return task.cont def setAlongSpline(self, t): t = t + 1.0 dist = (self.endPoint.getX() - self.startPoint.getX()) / 2.0 x = self.startPoint.getX() + t * dist y = self.startPoint.getY() - math.sin(t * 2 * math.pi) * self.sinAmplitude self.root.setPos(x, y, 0) def startBounce(self): taskMgr.add(self.bounce, 'PartyCog.bounceTask-%d' % self.id) def bounce(self, task): self.root.setZ(math.sin((self.bounceOffset + task.time) * self.bounceSpeed) * self.bounceHeight + self.heightShift) return task.cont def setPos(self, position): self.root.setPos(position) def respondToPieHit(self, timestamp, position, hot = False, direction = 1.0): if self.netTimeSentToStartByHit < timestamp: self.__showSplat(position, direction, hot) if self.netTimeSentToStartByHit < timestamp: self.netTimeSentToStartByHit = timestamp else: self.notify.debug('respondToPieHit self.netTimeSentToStartByHit = %s' % self.netTimeSentToStartByHit) def clearHitInterval(self): if self.hitInterval is not None and self.hitInterval.isPlaying(): self.hitInterval.clearToInitial() return def __showSplat(self, position, direction, hot = False): if self.kaboomTrack is not None and self.kaboomTrack.isPlaying(): self.kaboomTrack.finish() self.clearHitInterval() splatName = 'splat-creampie' self.splat = globalPropPool.getProp(splatName) self.splat.setBillboardPointEye() self.splat.reparentTo(render) self.splat.setPos(self.root, position) self.splat.setAlphaScale(1.0) if not direction == 1.0: self.splat.setColorScale(PartyGlobals.CogActivitySplatColors[0]) if self.currentFacing > 0.0: facing = 'HitFront' else: facing = 'HitBack' else: self.splat.setColorScale(PartyGlobals.CogActivitySplatColors[1]) if self.currentFacing > 0.0: facing = 'HitBack' else: facing = 'HitFront' if hot: targetscale = 0.75 part = 'head' else: targetscale = 0.5 part = 'body' def setSplatAlpha(amount): self.splat.setAlphaScale(amount) self.hitInterval = Sequence(ActorInterval(self.actor, part + facing, loop=0), Func(self.actor.loop, 'idle')) self.hitInterval.start() self.kaboomTrack = Parallel(SoundInterval(self.pieHitSound, volume=1.0, node=self.actor, cutOff=PartyGlobals.PARTY_COG_CUTOFF), Sequence(Func(self.splat.showThrough), Parallel(Sequence(LerpScaleInterval(self.splat, duration=0.175, scale=targetscale, startScale=Point3(0.1, 0.1, 0.1), blendType='easeOut'), Wait(0.175)), Sequence(Wait(0.1), LerpFunc(setSplatAlpha, duration=1.0, fromData=1.0, toData=0.0, blendType='easeOut'))), Func(self.splat.cleanup), Func(self.splat.removeNode))) self.kaboomTrack.start() return def showHitScore(self, number, scale = 1): if number <= 0: return if self.hpText: self.hideHitScore() self.HpTextGenerator.setFont(ToontownGlobals.getSignFont()) if number < 0: self.HpTextGenerator.setText(str(number)) else: self.HpTextGenerator.setText('+' + str(number)) self.HpTextGenerator.clearShadow() self.HpTextGenerator.setAlign(TextNode.ACenter) r = 1 g = 1 b = 0 a = 1 self.HpTextGenerator.setTextColor(r, g, b, a) self.hpTextNode = self.HpTextGenerator.generate() self.hpText = render.attachNewNode(self.hpTextNode) self.hpText.setScale(scale) self.hpText.setBillboardPointEye() self.hpText.setBin('fixed', 100) self.hpText.setPos(self.root, 0, 0, self.height / 2) seq = Sequence(self.hpText.posInterval(0.25, Point3(self.root.getX(render), self.root.getY(render), self.root.getZ(render) + self.height + 1.0), blendType='easeOut'), Wait(0.25), self.hpText.colorInterval(0.1, Vec4(r, g, b, 0)), Func(self.__hideHitScore)) seq.start() def hideHitScore(self): if self.hpText: taskMgr.remove('PartyCogHpText' + str(self.id)) self.hpText.removeNode() self.hpText = None return def getHeadLocation(self): self.actor.getJoints(jointName='head')[0].getNetTransform(self.temp_transform) self.head_locator.setMat(self.temp_transform) return self.head_locator.getZ(self.root)
class DistributedPartyJukeboxActivityBase(DistributedPartyActivity): notify = directNotify.newCategory("DistributedPartyJukeboxActivityBase") def __init__(self, cr, actId, phaseToMusicData): DistributedPartyActivity.__init__(self, cr, actId, ActivityTypes.Continuous) self.phaseToMusicData = phaseToMusicData self.jukebox = None self.gui = None self.tunes = [] self.music = None self.currentSongData = None self.localQueuedSongInfo = None self.localQueuedSongListItem = None return def generateInit(self): self.gui = JukeboxGui(self.phaseToMusicData) def load(self): DistributedPartyActivity.load(self) self.jukebox = Actor( "phase_13/models/parties/jukebox_model", {"dance": "phase_13/models/parties/jukebox_dance"} ) self.jukebox.reparentTo(self.root) self.jukebox.loop("dance", fromFrame=0, toFrame=48) self.collNode = CollisionNode(self.getCollisionName()) self.collNode.setCollideMask(ToontownGlobals.CameraBitmask | ToontownGlobals.WallBitmask) collTube = CollisionTube(0, 0, 0, 0.0, 0.0, 4.25, 2.25) collTube.setTangible(1) self.collNode.addSolid(collTube) self.collNodePath = self.jukebox.attachNewNode(self.collNode) self.sign.setPos(-5.0, 0, 0) self.activate() def unload(self): DistributedPartyActivity.unload(self) self.gui.unload() if self.music is not None: self.music.stop() self.jukebox.stop() self.jukebox.delete() self.jukebox = None self.ignoreAll() return def getCollisionName(self): return self.uniqueName("jukeboxCollision") def activate(self): self.accept("enter" + self.getCollisionName(), self.__handleEnterCollision) def __handleEnterCollision(self, collisionEntry): if base.cr.playGame.getPlace().fsm.getCurrentState().getName() == "walk": base.cr.playGame.getPlace().fsm.request("activity") self.d_toonJoinRequest() def joinRequestDenied(self, reason): DistributedPartyActivity.joinRequestDenied(self, reason) self.showMessage(TTLocalizer.PartyJukeboxOccupied) def handleToonJoined(self, toonId): toon = base.cr.doId2do.get(toonId) if toon: self.jukebox.lookAt(base.cr.doId2do[toonId]) self.jukebox.setHpr(self.jukebox.getH() + 180.0, 0, 0) if toonId == base.localAvatar.doId: self.__localUseJukebox() def handleToonExited(self, toonId): if toonId == base.localAvatar.doId and self.gui.isLoaded(): self.__deactivateGui() def handleToonDisabled(self, toonId): self.notify.warning("handleToonDisabled no implementation yet") def __localUseJukebox(self): base.localAvatar.disableAvatarControls() base.localAvatar.stopPosHprBroadcast() self.__activateGui() self.accept(JukeboxGui.CLOSE_EVENT, self.__handleGuiClose) taskMgr.doMethodLater( 0.5, self.__localToonWillExitTask, self.uniqueName("toonWillExitJukeboxOnTimeout"), extraArgs=None ) self.accept(JukeboxGui.ADD_SONG_CLICK_EVENT, self.__handleQueueSong) if self.isUserHost(): self.accept(JukeboxGui.MOVE_TO_TOP_CLICK_EVENT, self.__handleMoveSongToTop) return def __localToonWillExitTask(self, task): self.localToonExiting() return Task.done def __activateGui(self): self.gui.enable(timer=JUKEBOX_TIMEOUT) self.gui.disableAddSongButton() if self.currentSongData is not None: self.gui.setSongCurrentlyPlaying(self.currentSongData[0], self.currentSongData[1]) self.d_queuedSongsRequest() return def __deactivateGui(self): self.ignore(JukeboxGui.CLOSE_EVENT) self.ignore(JukeboxGui.SONG_SELECT_EVENT) self.ignore(JukeboxGui.MOVE_TO_TOP_CLICK_EVENT) base.cr.playGame.getPlace().setState("walk") base.localAvatar.startPosHprBroadcast() base.localAvatar.enableAvatarControls() self.gui.unload() self.__localClearQueuedSong() def isUserHost(self): return self.party.partyInfo.hostId == base.localAvatar.doId def d_queuedSongsRequest(self): self.sendUpdate("queuedSongsRequest") def queuedSongsResponse(self, songInfoList, index): if self.gui.isLoaded(): for i in range(len(songInfoList)): songInfo = songInfoList[i] self.__addSongToQueue(songInfo, isLocalQueue=index >= 0 and i == index) self.gui.enableAddSongButton() def __handleGuiClose(self): self.__deactivateGui() self.d_toonExitDemand() def __handleQueueSong(self, name, values): self.d_setNextSong(values[0], values[1]) def d_setNextSong(self, phase, filename): self.sendUpdate("setNextSong", [(phase, filename)]) def setSongInQueue(self, songInfo): if self.gui.isLoaded(): phase = sanitizePhase(songInfo[0]) filename = songInfo[1] data = self.getMusicData(phase, filename) if data: if self.localQueuedSongListItem is not None: self.localQueuedSongListItem["text"] = data[0] else: self.__addSongToQueue(songInfo, isLocalQueue=True) return def __addSongToQueue(self, songInfo, isLocalQueue=False): isHost = isLocalQueue and self.isUserHost() data = self.getMusicData(sanitizePhase(songInfo[0]), songInfo[1]) if data: listItem = self.gui.addSongToQueue(data[0], highlight=isLocalQueue, moveToTopButton=isHost) if isLocalQueue: self.localQueuedSongInfo = songInfo self.localQueuedSongListItem = listItem def __localClearQueuedSong(self): self.localQueuedSongInfo = None self.localQueuedSongListItem = None return def __play(self, phase, filename, length): self.music = base.loadMusic((MUSIC_PATH + "%s") % (phase, filename)) if self.music: if ( self.__checkPartyValidity() and hasattr(base.cr.playGame.getPlace().loader, "music") and base.cr.playGame.getPlace().loader.music ): base.cr.playGame.getPlace().loader.music.stop() self.music.setTime(0.0) self.music.setLoopCount(getMusicRepeatTimes(length)) self.music.play() self.currentSongData = (phase, filename) def __stop(self): self.currentSongData = None if self.music: self.music.stop() if self.gui.isLoaded(): self.gui.clearSongCurrentlyPlaying() return def setSongPlaying(self, songInfo, toonId): phase = sanitizePhase(songInfo[0]) filename = songInfo[1] if not filename: self.__stop() return data = self.getMusicData(phase, filename) if data: self.__play(phase, filename, data[1]) self.setSignNote(data[0]) if self.gui.isLoaded(): item = self.gui.popSongFromQueue() self.gui.setSongCurrentlyPlaying(phase, filename) if item == self.localQueuedSongListItem: self.__localClearQueuedSong() if toonId == localAvatar.doId: localAvatar.setSystemMessage(0, TTLocalizer.PartyJukeboxNowPlaying) def __handleMoveSongToTop(self): if self.isUserHost() and self.localQueuedSongListItem is not None: self.d_moveHostSongToTopRequest() return def d_moveHostSongToTopRequest(self): self.notify.debug("d_moveHostSongToTopRequest") self.sendUpdate("moveHostSongToTopRequest") def moveHostSongToTop(self): self.notify.debug("moveHostSongToTop") if self.gui.isLoaded(): self.gui.pushQueuedItemToTop(self.localQueuedSongListItem) def getMusicData(self, phase, filename): data = [] phase = sanitizePhase(phase) phase = self.phaseToMusicData.get(phase) if phase: data = phase.get(filename, []) return data def __checkPartyValidity(self): if ( hasattr(base.cr.playGame, "getPlace") and base.cr.playGame.getPlace() and hasattr(base.cr.playGame.getPlace(), "loader") and base.cr.playGame.getPlace().loader ): return True else: return False
class World(DirectObject): def __init__(self): #create Queue to hold the incoming chat #request the heartbeat so that the caht interface is being refreshed in order to get the message from other player self.keyMap = {"left":0, "right":0, "forward":0, "cam-left":0, "cam-right":0, "charge":0} base.win.setClearColor(Vec4(0,0,0,1)) self.cManager = ConnectionManager() self.cManager.startConnection() #------------------------------ #Chat Chat(self.cManager) #send dummy login info of the particular client #send first chat info #--------------------------------------- self.userName = username dummy_login ={'user_id' : self.userName, 'factionId': faction, 'password': '******'} self.cManager.sendRequest(Constants.RAND_STRING, dummy_login) chat = { 'userName' : self.userName, #username 'message' : '-------Login------' } self.cManager.sendRequest(Constants.CMSG_CHAT, chat) #-------------------------------------- #self.minimap = OnscreenImage(image="images/minimap.png", scale=(0.2,1,0.2), pos=(-1.1,0,0.8)) #frame = DirectFrame(text="Resource Bar", scale=0.001) resource_bar = DirectWaitBar(text="", value=35, range=100, pos=(0,0,0.9), barColor=(255,255,0,1), frameSize=(-0.3,0.3,0,0.03)) cp_bar = DirectWaitBar(text="", value=70, range=100, pos=(1.0,0,0.9), barColor=(0,0,255,1), frameSize=(-0.3,0.3,0,0.03), frameColor=(255,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.environ = loader.loadModel("models/world") self.environ.reparentTo(render) self.environ.setPos(0,0,0) # Create the main character, Ralph ralphStartPos = self.environ.find("**/start_point").getPos() self.ralph = Actor("models/ralph", {"run":"models/ralph-run", "walk":"models/ralph-walk"}) self.ralph.reparentTo(render) self.ralph.setScale(.2) self.ralph.setPos(ralphStartPos) nameplate = TextNode('textNode username_' + str(self.userName)) nameplate.setText(self.userName) npNodePath = self.ralph.attachNewNode(nameplate) npNodePath.setScale(0.8) npNodePath.setBillboardPointEye() #npNodePath.setPos(1.0,0,6.0) npNodePath.setZ(6.5) bar = DirectWaitBar(value=100, scale=1.0) bar.setColor(255,0,0) #bar.setBarRelief() bar.setZ(6.0) bar.setBillboardPointEye() bar.reparentTo(self.ralph) # 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 self.accept("escape", sys.exit) 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]) 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]) self.accept("c", self.setKey, ["charge",1]) self.accept("c-up", self.setKey, ["charge",0]) taskMgr.add(self.move,"moveTask") # Game state variables self.isMoving = False # Set up the camera base.disableMouse() base.camera.setPos(self.ralph.getX(),self.ralph.getY()+10,2) # 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.cTrav = CollisionTraverser() 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() self.cTrav.addCollider(self.ralphGroundColNp, self.ralphGroundHandler) 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 = base.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler) # 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) # 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 # Accepts arrow keys to move either the player or the menu cursor, # Also deals with grid checking and collision detection def move(self, task): # If the camera-left key is pressed, move camera left. # If the camera-right key is pressed, move camera right. base.camera.lookAt(self.ralph) if (self.keyMap["cam-left"]!=0): base.camera.setX(base.camera, -20 * globalClock.getDt()) if (self.keyMap["cam-right"]!=0): base.camera.setX(base.camera, +20 * globalClock.getDt()) # save ralph's initial position so that we can restore it, # in case he falls off the map or runs into something. startpos = self.ralph.getPos() # If a move-key is pressed, move ralph in the specified direction. if (self.keyMap["left"]!=0): self.ralph.setH(self.ralph.getH() + 300 * globalClock.getDt()) if (self.keyMap["right"]!=0): self.ralph.setH(self.ralph.getH() - 300 * globalClock.getDt()) if (self.keyMap["forward"]!=0): self.ralph.setY(self.ralph, -25 * globalClock.getDt()) if (self.keyMap["charge"]!=0): self.ralph.setY(self.ralph, -250 * globalClock.getDt()) #ribbon = Ribbon(self.ralph, Vec4(1,1,1,1), 3, 10, 0.3) #ribbon.getRoot().setZ(2.0) # If ralph is moving, loop the run animation. # If he is standing still, stop the animation. if (self.keyMap["forward"]!=0) or (self.keyMap["charge"]!=0) or (self.keyMap["left"]!=0) or (self.keyMap["right"]!=0): if self.isMoving is False: self.ralph.loop("run") self.isMoving = True else: if self.isMoving: self.ralph.stop() self.ralph.pose("walk",5) self.isMoving = False # If the camera is too far from ralph, move it closer. # If the camera is too close to ralph, move it farther. camvec = self.ralph.getPos() - base.camera.getPos() camvec.setZ(0) camdist = camvec.length() camvec.normalize() if (camdist > 10.0): base.camera.setPos(base.camera.getPos() + camvec*(camdist-10)) camdist = 10.0 if (camdist < 5.0): base.camera.setPos(base.camera.getPos() - camvec*(5-camdist)) 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.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) # Keep the camera at one foot above the terrain, # or two feet above ralph, 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"): base.camera.setZ(entries[0].getSurfacePoint(render).getZ()+1.0) if (base.camera.getZ() < self.ralph.getZ() + 2.0): base.camera.setZ(self.ralph.getZ() + 2.0) # The camera should look in ralph's direction, # but it should also try to stay horizontal, so look at # a floater which hovers above ralph's head. self.floater.setPos(self.ralph.getPos()) self.floater.setZ(self.ralph.getZ() + 2.0) base.camera.lookAt(self.floater) return task.cont