class HLodDynamicObject(NodePath): def __init__(self, name, scene, visibleLODsDict={"eggfileName":("maxFar","minNear")}, collisionEgg=None, x0=0, y0=0, z0=0, parent=None, margin=0.02, mass=0, directRender=True, convex=True): self.name = name self.scene = scene NodePath.__init__(self,LODNode(name+"_LODNode")) ###LOD### for k in visibleLODsDict.keys(): v=base.loader.loadModel(k) v.reparentTo(self) self.node().addSwitch(visibleLODsDict[k][0],visibleLODsDict[k][1]) ######### self.body = BulletRigidBodyNode(self.name + "_RigidBody") self.attachNewNode(self.body) if collisionEgg != None: m = self.scene.Base.loader.loadModel(collisionEgg) if convex: sTuple = modelToConvex(m) else: sTuple = modelToShape(m) sTuple[0].setMargin(margin) self.body.addShape(sTuple[0], sTuple[1]) self.body.setMass(mass) self.body.setPythonTag("name", self.name + "_RigidBody") self.scene.world.attachRigidBody(self.body) self.setPos(x0, y0, z0) if directRender: self.reparentTo(self.scene.Base.render) elif parent != None: self.reparentTo(parent)
def setupPhysics(self, radius=None, height=None): if not radius: radius = self.getWidth() if not height: height = self.getHeight() self.notify.debug("setupPhysics(r{0}, h{1}) hitboxData: {2}".format( radius, height, self.hitboxData)) # When the height is passed into BulletCapsuleShape, it's # talking about the height only of the cylinder part. # But what we want is the height of the entire capsule. #height -= (radius * 2) # The middle of the capsule is the origin by default. Push the capsule shape up # so the very bottom of the capsule is the origin. zOfs = (height / 2.0) + radius capsule = BulletCapsuleShape(radius, height) bodyNode = BulletRigidBodyNode('avatarBodyNode') bodyNode.addShape(capsule, TransformState.makePos(Point3(0, 0, zOfs))) bodyNode.setKinematic(True) bodyNode.setPythonTag("avatar", self) BasePhysicsObject.setupPhysics(self, bodyNode, True) self.stopWaterCheck()
def build_node_path(self, parent_node_path, bullet_world): land_geom = self.__build_land_mesh() ocean_geom = self.__build_ocean_mesh() land_mesh = BulletTriangleMesh() land_mesh.addGeom(land_geom) land_shape = BulletTriangleMeshShape(land_mesh, dynamic=False) ocean_shape = BulletSphereShape(self.__radius) land_bullet_node = BulletRigidBodyNode('land collider') land_bullet_node.addShape(land_shape) bullet_world.attachRigidBody(land_bullet_node) land_bullet_node_path = parent_node_path.attachNewNode( land_bullet_node) ocean_bullet_node = BulletGhostNode('ocean collider') ocean_bullet_node.addShape(ocean_shape) bullet_world.attachGhost(ocean_bullet_node) ocean_bullet_node_path = land_bullet_node_path.attachNewNode( ocean_bullet_node) land_node = GeomNode('land') land_node.addGeom(land_geom) land_node_path = land_bullet_node_path.attachNewNode(land_node) ocean_node = GeomNode('ocean') ocean_node.addGeom(ocean_geom) ocean_node_path = ocean_bullet_node_path.attachNewNode(ocean_node) ocean_node_path.setTransparency(TransparencyAttrib.MAlpha) self.__node_path = land_bullet_node_path land_bullet_node.setPythonTag('planet', self) return land_bullet_node_path
def __init__(self, node_name, lane: AbstractLane, lane_index=(str, str, int)): """ Using ray cast to query the lane information :param node_name: node_name :param lane: CircularLane or StraightLane :param lane_index: Lane index """ BulletRigidBodyNode.__init__(self, node_name) BulletRigidBodyNode.setPythonTag(self, BodyName.Lane, self) self.info = lane self.index = lane_index
def __init__(self, body_name: str, base_vehicle): BulletRigidBodyNode.__init__(self, body_name) BulletRigidBodyNode.setPythonTag(self, body_name, self) # mutual reference here self._base_vehicle = base_vehicle self.crash_vehicle = False self.crash_object = False self.crash_sidewalk = False # lane line detection self.on_yellow_continuous_line = False self.on_white_continuous_line = False self.on_broken_line = False
class HDynamicObject(NodePath): #Only rigid body def __init__(self, name, scene, visibleEgg, collisionEgg=None, x0=0, y0=0, z0=0, parent=None, margin=0.02, mass=0, directRender=True, convex=True): self.name = name self.scene = scene NodePath.__init__(self, self.scene.loadEgg(visibleEgg)) self.body = BulletRigidBodyNode(self.name + "_RigidBody") self.attachNewNode(self.body) if collisionEgg != None: m = self.scene.Base.loader.loadModel(collisionEgg) if convex: sTuple = modelToConvex(m) else: sTuple = modelToShape(m) sTuple[0].setMargin(margin) self.body.addShape(sTuple[0], sTuple[1]) self.body.setMass(mass) self.body.setPythonTag("name", self.name + "_RigidBody") self.scene.world.attachRigidBody(self.body) self.setPos(x0, y0, z0) if directRender: self.reparentTo(self.scene.Base.render) elif parent != None: self.reparentTo(parent)
class Flame(Entity): """ The thing that comes out the end of the thing you hold """ animspeed = 0.1 depth = 20 playerWidth = 3 speed = 20 def __init__(self, world, pos, hpr): super(Flame, self).__init__() self.shape = BulletBoxShape(Vec3(0.1,0.05,0.05)) self.bnode = BulletRigidBodyNode() self.bnode.setMass(1.0) self.bnode.addShape(self.shape) self.np = utilities.app.render.attachNewNode(self.bnode) self.world =world self.anim = list() self.anim.append(utilities.loadObject("flame1", depth=0)) self.anim.append(utilities.loadObject("flame2", depth=0)) self.anim.append(utilities.loadObject("flame3", depth=0)) world.bw.attachRigidBody(self.bnode) self.curspr = 0 self.obj = self.anim[self.curspr] self.obj.show() self.livetime = 0 self.delta = 0 self.pos = pos self.pos.y = Flame.depth #self.pos.z -= 0.2 self.hpr = hpr self.vel = Point2() self.vel.x = cos(world.player.angle)*Flame.speed self.vel.y = sin(world.player.angle)*Flame.speed tv = Vec3(self.vel.x, 0, self.vel.y) # this makes the shot miss the target if the player has any velocity tv += world.player.bnode.getLinearVelocity() self.bnode.setLinearVelocity(tv) tv.normalize() # initial position of RB and draw plane self.np.setHpr(hpr) self.np.setPos(pos+tv/2) self.bnode.setAngularFactor(Vec3(0,0,0)) self.bnode.setLinearFactor(Vec3(1,0,1)) self.bnode.setGravity(Vec3(0,0,0)) self.bnode.setCcdMotionThreshold(1e-7) self.bnode.setCcdSweptSphereRadius(0.10) self.bnode.notifyCollisions(True) self.bnode.setIntoCollideMask(BitMask32.bit(1)) self.bnode.setPythonTag("Entity", self) self.noCollideFrames = 4 for a in self.anim: a.hide() a.reparentTo(self.np) a.setScale(0.25, 1, 0.25) a.setPos(0, -0.1,0) def update(self, timer): #animation self.delta += timer self.livetime += timer if self.noCollideFrames == 0: self.bnode.setIntoCollideMask(BitMask32.allOn()) if self.noCollideFrames > -1: self.noCollideFrames -= 1 if self.delta > Flame.animspeed: self.delta = 0 self.obj.hide() self.curspr += 1 if self.curspr > len(self.anim)-1: self.curspr = 0 self.obj = self.anim[self.curspr] self.obj.show()
class Player(Entity): walkspeed = 50 damping = 0.9 topspeed = 15 leftMove = False rightMove = False jumpToggle = False crouchToggle = False def __init__(self, world): super(Player, self).__init__() self.obj = utilities.loadObject("player", depth=20) self.world = world self.health = 100 self.inventory = dict() self.depth = self.obj.getPos().y self.location = Point2(0,0) self.velocity = Vec3(0) self.pt = 0.0 self.shape = BulletBoxShape(Vec3(0.3, 1.0, 0.49)) self.bnode = BulletRigidBodyNode('Box') self.bnode.setMass(1.0) self.bnode.setAngularVelocity(Vec3(0)) self.bnode.setAngularFactor(Vec3(0)) self.bnode.addShape(self.shape) self.bnode.setLinearDamping(0.95) self.bnode.setLinearSleepThreshold(0) world.bw.attachRigidBody(self.bnode) self.bnode.setPythonTag("Entity", self) self.bnode.setIntoCollideMask(BitMask32.bit(0)) self.node = utilities.app.render.attachNewNode(self.bnode) self.node.setPos(self.obj.getPos()) self.obj.setPos(0,0,0) self.obj.setScale(1) self.obj.reparentTo(self.node) self.node.setPos(self.location.x, self.depth, self.location.y) def initialise(self): self.inventory["LightLaser"] = LightLaser(self.world, self) self.inventory["Blowtorch"] = Blowtorch(self.world, self) self.inventory["Grenade"] = Grenade(self.world, self) for i in self.inventory: self.inventory[i].initialise() self.currentItem = self.inventory["Blowtorch"] self.currentItem.equip() self.armNode = self.obj.attachNewNode("arm") self.armNode.setPos(0.20,0,0.08) self.arm = utilities.loadObject("arm", scaleX = 0.5,scaleY = 0.5, depth = -0.2) self.arm.reparentTo(self.armNode) def activate(self): self.currentItem.activate() def update(self, timer): self.velocity = self.bnode.getLinearVelocity() if (self.leftMove): self.bnode.applyCentralForce(Vec3(-Player.walkspeed,0,0)) if (self.rightMove): self.bnode.applyCentralForce(Vec3(Player.walkspeed,0,0)) if (self.jumpToggle): self.bnode.applyCentralForce(Vec3(0,0,Player.walkspeed)) if (self.crouchToggle): self.bnode.applyCentralForce(Vec3(0,0,-Player.walkspeed)) if (self.velocity.x < -self.topspeed): self.velocity.x = -self.topspeed if (self.velocity.x > self.topspeed): self.velocity.x = self.topspeed mouse = utilities.app.mousePos # extrude test near = Point3() far = Point3() utilities.app.camLens.extrude(mouse, near, far) camp = utilities.app.camera.getPos() near *= 20 # player depth if near.x != 0: angle = atan2(near.z + camp.z - self.node.getPos().z, near.x + camp.x - self.node.getPos().x) #angle = atan2(near.z, near.x) else: angle = 90 self.angle = angle # set current item to point at cursor self.currentItem.update(timer) # move the camera so the player is centred horizontally, # but keep the camera steady vertically utilities.app.camera.setPos(self.node.getPos().x, 0, self.node.getPos().z) #move arm into correct position. gunLength = 2.0 self.gunVector = Point2(cos(angle)*gunLength - self.armNode.getX()*5, sin(angle)*gunLength - self.armNode.getZ()*2) armAngle = atan2(self.gunVector.y, self.gunVector.x) self.arm.setHpr(self.armNode, 0, 0, -1 * degrees(armAngle)) def moveLeft(self, switch): self.leftMove = switch #self.bnode.applyCentralForce(Vec3(-500,0,0)) def moveRight(self, switch): self.rightMove = switch #self.bnode.applyCentralForce(Vec3(500,0,0)) def jump(self, switch): self.jumpToggle = switch def crouch(self, switch): self.crouchToggle = switch
class Flame(Entity): """ The thing that comes out the end of the thing you hold """ animspeed = 0.1 depth = 20 playerWidth = 3 speed = 30 maxlife = 10 damage = 30 def __init__(self, world, pos, hpr): super(Flame, self).__init__() self.shape = BulletBoxShape(Vec3(0.1, 0.05, 0.05)) self.bnode = BulletRigidBodyNode() self.bnode.setMass(0.00001) self.bnode.addShape(self.shape) self.np = utilities.app.render.attachNewNode(self.bnode) self.remove = False self.world = world self.anim = list() self.anim.append(utilities.loadObject("flame1", depth=0)) self.anim.append(utilities.loadObject("flame2", depth=0)) self.anim.append(utilities.loadObject("flame3", depth=0)) world.bw.attachRigidBody(self.bnode) self.curspr = 0 self.livetime = 0 self.delta = 0 self.pos = pos self.pos.y = Flame.depth self.hpr = hpr self.vel = Point2() self.vel.x = cos(world.player.angle) * Flame.speed self.vel.y = sin(world.player.angle) * Flame.speed tv = Vec3(self.vel.x, 0, self.vel.y) # this makes the shot miss the target if the player has any velocity tv += world.player.bnode.getLinearVelocity() self.bnode.setLinearVelocity(tv) tv.normalize() # initial position of RB and draw plane self.np.setHpr(hpr) self.np.setPos(pos + tv / 2) self.bnode.setAngularFactor(Vec3(0, 0, 0)) self.bnode.setLinearFactor(Vec3(1, 0, 1)) self.bnode.setGravity(Vec3(0, 0, 0)) #self.bnode.setCcdMotionThreshold(1e-7) #self.bnode.setCcdSweptSphereRadius(0.50) self.bnode.notifyCollisions(True) self.bnode.setIntoCollideMask(BitMask32.bit(1)) self.bnode.setPythonTag("Entity", self) self.noCollideFrames = 4 for a in self.anim: a.hide() a.reparentTo(self.np) a.setScale(0.25, 1, 0.25) a.setPos(0, -0.1, 0) self.obj = self.anim[self.curspr] self.obj.show() self.bnode.setPythonTag("entity", self) def update(self, timer): #animation self.delta += timer self.livetime += timer if self.remove: self.obj.hide() return if self.noCollideFrames == 0: self.bnode.setIntoCollideMask(BitMask32.allOn()) if self.noCollideFrames > -1: self.noCollideFrames -= 1 if self.delta > Flame.animspeed: self.delta = 0 self.obj.hide() self.curspr += 1 if self.curspr > len(self.anim) - 1: self.curspr = 0 self.obj = self.anim[self.curspr] self.obj.show() if self.livetime > Flame.maxlife: self.remove = True def hitby(self, index, projectile): return def destroy(self): self.remove = True self.obj.hide() for model in self.anim: model.remove() self.world.bw.removeRigidBody(self.bnode) def removeOnHit(self): self.remove = True
class Chunk(Entity): chunkmass = 5.0 def __init__(self, world, blocks, pos, hpr=Point3(0,0,0), diff = Vec3(0,0,0), angVel = Vec3(0,0,0), linVel = Vec3(0,0,0)): super(Chunk, self).__init__() self.mass = len(blocks)*Chunk.chunkmass self.world = world self.blocks = blocks self.bnode = BulletRigidBodyNode() self.bnode.setMass(self.mass) self.bnode.setAngularFactor(Vec3(0,1,0)) self.bnode.setLinearSleepThreshold(20) self.bnode.setAngularSleepThreshold(20) self.bnode.setAngularVelocity(angVel) self.bnode.setLinearVelocity(linVel) self.np = utilities.app.render.attachNewNode(self.bnode) self.np.setPos(pos.x,20,pos.y) self.np.setHpr(hpr) self.np.setPos(self.np, diff) self.bnode.setPythonTag("entity", self) self.inScope = False # culling not done yet # centre the blocks around the np and add their shapes in. self.minMax() cog = Point2((self.minX+self.maxX) / 2.0, (self.minY+self.maxY) / 2.0) for block in blocks: block.rebuild(self, cog) world.bw.attachRigidBody(self.bnode) self.hitlist = dict() def update(self, timer): for index in self.hitlist: # returns true if the wall is destroyed by the hit if self.blocks[index].hitby(self.hitlist[index]): self.blocks[index].destroy() self.rebuild(index) self.hitlist.clear() if self.playerDistance() > 40.0: self.bnode.setAngularSleepThreshold(1) self.bnode.setLinearSleepThreshold(1) else: self.bnode.setAngularSleepThreshold(0) self.bnode.setLinearSleepThreshold(0) def playerDistance(self): sp = self.np.getPos() pp = self.world.player.node.getPos() distance = hypot(sp.x - pp.x, sp.z - pp.z) return distance # remove an element and rebuild # TODO add another method for removing multiple # blocks in a single go def rebuild(self, index): deadblock = self.blocks[index] out = list() for block in self.blocks: for edge in block.edges: if edge == deadblock: block.edges.remove(edge) for block in deadblock.edges: chunk = list() self.searchBlock(block, chunk, deadblock) out.append(chunk) #out is a list of lists of populated blocks #remove duplicate chunks results = list() for chunk in out: chunk.sort(compareBlock) if not chunk in results and len(chunk) > 0: results.append(chunk) for result in results: self.minMax(result) #diff = Point2((self.minX+self.maxX) / 2.0, (self.minY+self.maxY) / 2.0) diff = Vec3((self.minX+self.maxX) / 2.0, 0, (self.minY+self.maxY) / 2.0) p = self.np.getPos() pos = Point2(p.x, p.z) h = self.np.getHpr() self.world.entities.append(Chunk(self.world, result, pos, h, diff, self.bnode.getAngularVelocity(), self.bnode.getLinearVelocity())) self.destroyNow() self.remove = True def searchBlock(self, block, lst, deleted): if block in lst: return else: lst.append(block) for newblock in block.edges: self.searchBlock(newblock, lst, deleted) def minMax(self, blocks=None): if blocks == None: blocks = self.blocks self.minX = blocks[0].pos.x self.minY = blocks[0].pos.y self.maxX = blocks[0].pos.x self.maxY = blocks[0].pos.y for point in blocks: self.minX = min(point.pos.x, self.minX) self.minY = min(point.pos.y, self.minY) self.maxX = max(point.pos.x, self.maxX) self.maxY = max(point.pos.y, self.maxY) # Need to clear the bulletrigidbody immediately # so that the phys object isn't present during next sim phase # which occurs before cleanup normally. Otherwise shit will # fly everywhere since two things are inside each other def destroyNow(self): self.world.bw.removeRigidBody(self.bnode) return # since this is handled earlier nothing happens def destroy(self): return def hitby(self, projectile, index): self.hitlist[index] = projectile
class Chunk(Entity): chunkmass = 5.0 def __init__(self, world, blocks, pos, hpr=Point3(0, 0, 0), diff=Vec3(0, 0, 0), angVel=Vec3(0, 0, 0), linVel=Vec3(0, 0, 0)): super(Chunk, self).__init__() self.mass = len(blocks) * Chunk.chunkmass self.world = world self.blocks = blocks self.bnode = BulletRigidBodyNode() self.bnode.setMass(self.mass) self.bnode.setAngularFactor(Vec3(0, 1, 0)) self.bnode.setLinearSleepThreshold(20) self.bnode.setAngularSleepThreshold(20) self.bnode.setAngularVelocity(angVel) self.bnode.setLinearVelocity(linVel) self.np = utilities.app.render.attachNewNode(self.bnode) self.np.setPos(pos.x, 20, pos.y) self.np.setHpr(hpr) self.np.setPos(self.np, diff) self.bnode.setPythonTag("entity", self) self.inScope = False # culling not done yet # centre the blocks around the np and add their shapes in. self.minMax() cog = Point2((self.minX + self.maxX) / 2.0, (self.minY + self.maxY) / 2.0) for block in blocks: block.rebuild(self, cog) world.bw.attachRigidBody(self.bnode) self.hitlist = dict() def update(self, timer): for index in self.hitlist: # returns true if the wall is destroyed by the hit if self.blocks[index].hitby(self.hitlist[index]): self.blocks[index].destroy() self.rebuild(index) self.hitlist.clear() if self.playerDistance() > 40.0: self.bnode.setAngularSleepThreshold(1) self.bnode.setLinearSleepThreshold(1) else: self.bnode.setAngularSleepThreshold(0) self.bnode.setLinearSleepThreshold(0) def playerDistance(self): sp = self.np.getPos() pp = self.world.player.node.getPos() distance = hypot(sp.x - pp.x, sp.z - pp.z) return distance # remove an element and rebuild # TODO add another method for removing multiple # blocks in a single go def rebuild(self, index): deadblock = self.blocks[index] out = list() for block in self.blocks: for edge in block.edges: if edge == deadblock: block.edges.remove(edge) for block in deadblock.edges: chunk = list() self.searchBlock(block, chunk, deadblock) out.append(chunk) #out is a list of lists of populated blocks #remove duplicate chunks results = list() for chunk in out: chunk.sort(compareBlock) if not chunk in results and len(chunk) > 0: results.append(chunk) for result in results: self.minMax(result) #diff = Point2((self.minX+self.maxX) / 2.0, (self.minY+self.maxY) / 2.0) diff = Vec3((self.minX + self.maxX) / 2.0, 0, (self.minY + self.maxY) / 2.0) p = self.np.getPos() pos = Point2(p.x, p.z) h = self.np.getHpr() self.world.entities.append( Chunk(self.world, result, pos, h, diff, self.bnode.getAngularVelocity(), self.bnode.getLinearVelocity())) self.destroyNow() self.remove = True def searchBlock(self, block, lst, deleted): if block in lst: return else: lst.append(block) for newblock in block.edges: self.searchBlock(newblock, lst, deleted) def minMax(self, blocks=None): if blocks == None: blocks = self.blocks self.minX = blocks[0].pos.x self.minY = blocks[0].pos.y self.maxX = blocks[0].pos.x self.maxY = blocks[0].pos.y for point in blocks: self.minX = min(point.pos.x, self.minX) self.minY = min(point.pos.y, self.minY) self.maxX = max(point.pos.x, self.maxX) self.maxY = max(point.pos.y, self.maxY) # Need to clear the bulletrigidbody immediately # so that the phys object isn't present during next sim phase # which occurs before cleanup normally. Otherwise shit will # fly everywhere since two things are inside each other def destroyNow(self): self.world.bw.removeRigidBody(self.bnode) return # since this is handled earlier nothing happens def destroy(self): return def hitby(self, projectile, index): self.hitlist[index] = projectile
def __init__(self, object_body_name: str): BulletRigidBodyNode.__init__(self, object_body_name) BulletRigidBodyNode.setPythonTag(self, object_body_name, self) self.crashed = False
class Player(Entity): walkspeed = 5 damping = 0.9 topspeed = 15 leftMove = False rightMove = False jumpToggle = False crouchToggle = False def __init__(self, world): super(Player, self).__init__() self.obj = utilities.loadObject("tdplayer", depth=20) self.world = world self.health = 100 self.inventory = list() self.depth = self.obj.getPos().y self.location = Point2(10,0) self.velocity = Vec3(0) self.shape = BulletBoxShape(Vec3(0.3, 1.0, 0.49)) self.bnode = BulletRigidBodyNode('Box') self.bnode.setMass(0.1) self.bnode.setAngularVelocity(Vec3(0)) self.bnode.setAngularFactor(Vec3(0)) self.bnode.addShape(self.shape) self.bnode.setLinearDamping(0.95) self.bnode.setLinearSleepThreshold(0) world.bw.attachRigidBody(self.bnode) self.bnode.setPythonTag("entity", self) self.bnode.setIntoCollideMask(BitMask32.bit(0)) self.node = utilities.app.render.attachNewNode(self.bnode) self.node.setPos(self.obj.getPos()) self.obj.setPos(0,0,0) self.obj.setScale(1) self.obj.reparentTo(self.node) self.node.setPos(self.location.x, self.depth, self.location.y) def initialise(self): self.inventory.append(LightLaser(self.world, self)) self.inventory.append(Blowtorch(self.world, self)) #self.inventory["Grenade"] = Grenade(self.world, self) for item in self.inventory: item.initialise() self.currentItemIndex = 1 self.currentItem = self.inventory[self.currentItemIndex] self.currentItem.equip() def activate(self): self.currentItem.activate() def update(self, timer): self.velocity = self.bnode.getLinearVelocity() if (self.leftMove): self.bnode.applyCentralForce(Vec3(-Player.walkspeed,0,0)) if (self.rightMove): self.bnode.applyCentralForce(Vec3(Player.walkspeed,0,0)) if (self.jumpToggle): self.bnode.applyCentralForce(Vec3(0,0,Player.walkspeed)) if (self.crouchToggle): self.bnode.applyCentralForce(Vec3(0,0,-Player.walkspeed)) if (self.velocity.x < -self.topspeed): self.velocity.x = -self.topspeed if (self.velocity.x > self.topspeed): self.velocity.x = self.topspeed mouse = utilities.app.mousePos # extrude test near = Point3() far = Point3() utilities.app.camLens.extrude(mouse, near, far) camp = utilities.app.camera.getPos() near *= 20 # player depth if near.x != 0: angle = atan2(near.z + camp.z - self.node.getPos().z, near.x + camp.x - self.node.getPos().x) #angle = atan2(near.z, near.x) else: angle = 90 self.angle = angle # set current item to point at cursor self.currentItem.update(timer) # move the camera so the player is centred horizontally, # but keep the camera steady vertically utilities.app.camera.setPos(self.node.getPos().x, 0, self.node.getPos().z) self.obj.setHpr(0, 0, -1 * degrees(angle)) self.location.x = self.node.getPos().x self.location.y = self.node.getPos().z def moveLeft(self, switch): self.leftMove = switch def moveRight(self, switch): self.rightMove = switch def jump(self, switch): self.jumpToggle = switch def crouch(self, switch): self.crouchToggle = switch def scrollItem(self, number): self.currentItem.unequip() self.currentItemIndex = self.currentItemIndex + number if self.currentItemIndex < 0: self.currentItemIndex = len(self.inventory) - 1 if self.currentItemIndex > len(self.inventory) - 1: self.currentItemIndex = 0 self.currentItem = self.inventory[self.currentItemIndex] self.currentItem.equip() def selectItem(self, number): if (number - 1 < len(self.inventory) and number - 1 >= 0): self.currentItem.unequip() self.currentItemIndex = number - 1 self.currentItem = self.inventory[self.currentItemIndex] self.currentItem.equip() def hitby(self, projectile, index): self.health -= projectile.damage if (self.health < 0): self.obj.setColor(1,0,0,1) return True greyscale = 0.3 + (0.01 * self.health) self.obj.setColor(greyscale, greyscale,greyscale,greyscale) return False
class Catcher(Enemy): damage = 25 def __init__(self, location, player, cmap, world): super(Catcher, self).__init__(location) self.player = player self.cmap = cmap self.obj = utilities.loadObject("robot", depth=20) self.world = world self.health = 100 self.depth = self.obj.getPos().y self.location = location self.velocity = Vec3(0) self.shape = BulletBoxShape(Vec3(0.5, 1.0, 0.5)) self.bnode = BulletRigidBodyNode('Box') self.bnode.setMass(0.1) self.bnode.setAngularVelocity(Vec3(0)) self.bnode.setAngularFactor(Vec3(0)) self.bnode.addShape(self.shape) self.bnode.setLinearDamping(0.75) self.bnode.setLinearSleepThreshold(0) world.bw.attachRigidBody(self.bnode) self.bnode.setPythonTag("entity", self) self.bnode.setIntoCollideMask(BitMask32.bit(0)) self.node = utilities.app.render.attachNewNode(self.bnode) self.node.setPos(self.obj.getPos()) self.obj.setPos(0,0,0) self.obj.setScale(1) self.obj.reparentTo(self.node) self.node.setPos(self.location.x, self.depth, self.location.y) def update(self, time): self.location = Point2(self.node.getPos().x - self.player.location.x, self.node.getPos().z - self.player.location.y) if self.location.x > 20 or self.location.x < -20: return if self.location.y > 20 or self.location.y < -20: return path = findPath(Point2(self.location + Point2(20,20)), Point2(20,20), self.world.cmap) if len(path) > 1: move = path[1] - self.location self.bnode.applyCentralForce(Vec3(move.x-20,0,move.y-20)) def hitby(self, projectile, index): self.health -= projectile.damage if (self.health < 0): self.remove = True greyscale = 0.3 + (0.01 * self.health) self.obj.setColor(1, greyscale,greyscale,1) return False def removeOnHit(self): return def destroy(self): self.obj.hide() self.world.bw.removeRigidBody(self.bnode)
class Catcher(Enemy): damage = 25 def __init__(self, location, player, cmap, world): super(Catcher, self).__init__(location) self.player = player self.cmap = cmap self.obj = utilities.loadObject("robot", depth=20) self.world = world self.health = 100 self.depth = self.obj.getPos().y self.location = location self.velocity = Vec3(0) self.shape = BulletBoxShape(Vec3(0.5, 1.0, 0.5)) self.bnode = BulletRigidBodyNode('Box') self.bnode.setMass(0.1) self.bnode.setAngularVelocity(Vec3(0)) self.bnode.setAngularFactor(Vec3(0)) self.bnode.addShape(self.shape) self.bnode.setLinearDamping(0.75) self.bnode.setLinearSleepThreshold(0) world.bw.attachRigidBody(self.bnode) self.bnode.setPythonTag("entity", self) self.bnode.setIntoCollideMask(BitMask32.bit(0)) self.node = utilities.app.render.attachNewNode(self.bnode) self.node.setPos(self.obj.getPos()) self.obj.setPos(0, 0, 0) self.obj.setScale(1) self.obj.reparentTo(self.node) self.node.setPos(self.location.x, self.depth, self.location.y) def update(self, time): self.location = Point2(self.node.getPos().x - self.player.location.x, self.node.getPos().z - self.player.location.y) if self.location.x > 20 or self.location.x < -20: return if self.location.y > 20 or self.location.y < -20: return path = findPath(Point2(self.location + Point2(20, 20)), Point2(20, 20), self.world.cmap) if len(path) > 1: move = path[1] - self.location self.bnode.applyCentralForce(Vec3(move.x - 20, 0, move.y - 20)) def hitby(self, projectile, index): self.health -= projectile.damage if (self.health < 0): self.remove = True greyscale = 0.3 + (0.01 * self.health) self.obj.setColor(1, greyscale, greyscale, 1) return False def removeOnHit(self): return def destroy(self): self.obj.hide() self.world.bw.removeRigidBody(self.bnode)
class Player(Entity): walkspeed = 5 damping = 0.9 topspeed = 15 leftMove = False rightMove = False jumpToggle = False crouchToggle = False def __init__(self, world): super(Player, self).__init__() self.obj = utilities.loadObject("tdplayer", depth=20) self.world = world self.health = 100 self.inventory = list() self.depth = self.obj.getPos().y self.location = Point2(10, 0) self.velocity = Vec3(0) self.shape = BulletBoxShape(Vec3(0.3, 1.0, 0.49)) self.bnode = BulletRigidBodyNode('Box') self.bnode.setMass(0.1) self.bnode.setAngularVelocity(Vec3(0)) self.bnode.setAngularFactor(Vec3(0)) self.bnode.addShape(self.shape) self.bnode.setLinearDamping(0.95) self.bnode.setLinearSleepThreshold(0) world.bw.attachRigidBody(self.bnode) self.bnode.setPythonTag("entity", self) self.bnode.setIntoCollideMask(BitMask32.bit(0)) self.node = utilities.app.render.attachNewNode(self.bnode) self.node.setPos(self.obj.getPos()) self.obj.setPos(0, 0, 0) self.obj.setScale(1) self.obj.reparentTo(self.node) self.node.setPos(self.location.x, self.depth, self.location.y) def initialise(self): self.inventory.append(LightLaser(self.world, self)) self.inventory.append(Blowtorch(self.world, self)) #self.inventory["Grenade"] = Grenade(self.world, self) for item in self.inventory: item.initialise() self.currentItemIndex = 1 self.currentItem = self.inventory[self.currentItemIndex] self.currentItem.equip() def activate(self): self.currentItem.activate() def update(self, timer): self.velocity = self.bnode.getLinearVelocity() if (self.leftMove): self.bnode.applyCentralForce(Vec3(-Player.walkspeed, 0, 0)) if (self.rightMove): self.bnode.applyCentralForce(Vec3(Player.walkspeed, 0, 0)) if (self.jumpToggle): self.bnode.applyCentralForce(Vec3(0, 0, Player.walkspeed)) if (self.crouchToggle): self.bnode.applyCentralForce(Vec3(0, 0, -Player.walkspeed)) if (self.velocity.x < -self.topspeed): self.velocity.x = -self.topspeed if (self.velocity.x > self.topspeed): self.velocity.x = self.topspeed mouse = utilities.app.mousePos # extrude test near = Point3() far = Point3() utilities.app.camLens.extrude(mouse, near, far) camp = utilities.app.camera.getPos() near *= 20 # player depth if near.x != 0: angle = atan2(near.z + camp.z - self.node.getPos().z, near.x + camp.x - self.node.getPos().x) #angle = atan2(near.z, near.x) else: angle = 90 self.angle = angle # set current item to point at cursor self.currentItem.update(timer) # move the camera so the player is centred horizontally, # but keep the camera steady vertically utilities.app.camera.setPos(self.node.getPos().x, 0, self.node.getPos().z) self.obj.setHpr(0, 0, -1 * degrees(angle)) self.location.x = self.node.getPos().x self.location.y = self.node.getPos().z def moveLeft(self, switch): self.leftMove = switch def moveRight(self, switch): self.rightMove = switch def jump(self, switch): self.jumpToggle = switch def crouch(self, switch): self.crouchToggle = switch def scrollItem(self, number): self.currentItem.unequip() self.currentItemIndex = self.currentItemIndex + number if self.currentItemIndex < 0: self.currentItemIndex = len(self.inventory) - 1 if self.currentItemIndex > len(self.inventory) - 1: self.currentItemIndex = 0 self.currentItem = self.inventory[self.currentItemIndex] self.currentItem.equip() def selectItem(self, number): if (number - 1 < len(self.inventory) and number - 1 >= 0): self.currentItem.unequip() self.currentItemIndex = number - 1 self.currentItem = self.inventory[self.currentItemIndex] self.currentItem.equip() def hitby(self, projectile, index): self.health -= projectile.damage if (self.health < 0): self.obj.setColor(1, 0, 0, 1) return True greyscale = 0.3 + (0.01 * self.health) self.obj.setColor(greyscale, greyscale, greyscale, greyscale) return False