def _add_side_walk2bullet(self, lane_start, lane_end, middle, radius=0.0, direction=0): length = norm(lane_end[0] - lane_start[0], lane_end[1] - lane_start[1]) body_node = BulletRigidBodyNode(BodyName.Side_walk) body_node.setActive(False) body_node.setKinematic(False) body_node.setStatic(True) side_np = self.side_walk_node_path.attachNewNode(body_node) shape = BulletBoxShape(Vec3(1 / 2, 1 / 2, 1 / 2)) body_node.addShape(shape) body_node.setIntoCollideMask(BitMask32.bit(Block.LANE_LINE_COLLISION_MASK)) self.dynamic_nodes.append(body_node) if radius == 0: factor = 1 else: if direction == 1: factor = (1 - self.SIDE_WALK_LINE_DIST / radius) else: factor = (1 + self.SIDE_WALK_WIDTH / radius) * (1 + self.SIDE_WALK_LINE_DIST / radius) direction_v = lane_end - lane_start vertical_v = (-direction_v[1], direction_v[0]) / numpy.linalg.norm(direction_v) middle += vertical_v * (self.SIDE_WALK_WIDTH / 2 + self.SIDE_WALK_LINE_DIST) side_np.setPos(panda_position(middle, 0)) theta = -numpy.arctan2(direction_v[1], direction_v[0]) side_np.setQuat(LQuaternionf(numpy.cos(theta / 2), 0, 0, numpy.sin(theta / 2))) side_np.setScale( length * factor, self.SIDE_WALK_WIDTH, self.SIDE_WALK_THICKNESS * (1 + 0.1 * numpy.random.rand()) ) if self.render: side_np.setTexture(self.ts_color, self.side_texture) self.side_walk.instanceTo(side_np)
def _initAgents(self): # Load agents for agent in self.scene.scene.findAllMatches('**/agents/agent*'): transform = TransformState.makeIdentity() if self.agentMode == 'capsule': shape = BulletCapsuleShape( self.agentRadius, self.agentHeight - 2 * self.agentRadius) elif self.agentMode == 'sphere': shape = BulletCapsuleShape(self.agentRadius, 2 * self.agentRadius) # XXX: use BulletCharacterControllerNode class, which already handles local transform? node = BulletRigidBodyNode('physics') node.setMass(self.agentMass) node.setStatic(False) node.setFriction(self.defaultMaterialFriction) node.setRestitution(self.defaultMaterialRestitution) node.addShape(shape) self.bulletWorld.attach(node) # Constrain the agent to have fixed position on the Z-axis node.setLinearFactor(Vec3(1.0, 1.0, 0.0)) # Constrain the agent not to be affected by rotations node.setAngularFactor(Vec3(0.0, 0.0, 0.0)) node.setIntoCollideMask(BitMask32.allOn()) node.setDeactivationEnabled(True) # Enable continuous collision detection (CCD) node.setCcdMotionThreshold(1e-7) node.setCcdSweptSphereRadius(0.50) if node.isStatic(): agent.setTag('physics-mode', 'static') else: agent.setTag('physics-mode', 'dynamic') # Attach the physic-related node to the scene graph physicsNp = NodePath(node) physicsNp.setTransform(transform) # Reparent all child nodes below the new physic node for child in agent.getChildren(): child.reparentTo(physicsNp) physicsNp.reparentTo(agent) # NOTE: we need this to update the transform state of the internal bullet node physicsNp.node().setTransformDirty() # Validation assert np.allclose( mat4ToNumpyArray(physicsNp.getNetTransform().getMat()), mat4ToNumpyArray(agent.getNetTransform().getMat()), atol=1e-6)
def _initLayoutModels(self): # Load layout objects as meshes for model in self.scene.scene.findAllMatches('**/layouts/object*/model*'): # NOTE: ignore models that have no geometry defined if model.getTightBounds() is None: logger.warning('Object %s has no geometry defined and will be ignored for physics!' % (str(model))) continue shape, transform = getCollisionShapeFromModel( model, mode='mesh', defaultCentered=False) node = BulletRigidBodyNode('physics') node.setMass(0.0) node.setFriction(self.defaultMaterialFriction) node.setRestitution(self.defaultMaterialRestitution) node.setStatic(True) node.addShape(shape) node.setDeactivationEnabled(True) node.setIntoCollideMask(BitMask32.allOn()) self.bulletWorld.attach(node) # Attach the physic-related node to the scene graph physicsNp = model.getParent().attachNewNode(node) physicsNp.setTransform(transform) if node.isStatic(): model.getParent().setTag('physics-mode', 'static') else: model.getParent().setTag('physics-mode', 'dynamic') # Reparent render and acoustics nodes (if any) below the new physic node # XXX: should be less error prone to just reparent all children # (except the hidden model) renderNp = model.getParent().find('**/render') if not renderNp.isEmpty(): renderNp.reparentTo(physicsNp) acousticsNp = model.getParent().find('**/acoustics') if not acousticsNp.isEmpty(): acousticsNp.reparentTo(physicsNp) semanticsNp = model.getParent().find('**/semantics') if not semanticsNp.isEmpty(): semanticsNp.reparentTo(physicsNp) # NOTE: we need this to update the transform state of the internal # bullet node physicsNp.node().setTransformDirty() # Validation assert np.allclose(mat4ToNumpyArray(physicsNp.getNetTransform().getMat()), mat4ToNumpyArray(model.getNetTransform().getMat()), atol=1e-6)
def load(self): SafeZoneLoader.SafeZoneLoader.load(self, False) self.geom.find('**/ground_center').setBin('ground', 18) self.geom.find('**/ground_sidewalk').setBin('ground', 18) self.geom.find('**/ground').setBin('ground', 18) self.geom.find('**/ground_center_coll').setCollideMask( CIGlobals.FloorGroup) self.geom.find('**/ground_sidewalk_coll').setCollideMask( CIGlobals.FloorGroup) self.geom.find('**/ground_coll').setCollideMask(CIGlobals.FloorGroup) for tree in self.geom.findAllMatches('**/prop_green_tree_*_DNARoot'): tree.wrtReparentTo(hidden) # Make corrected collisions tree.find("**/+BulletRigidBodyNode").removeNode() capsule = BulletCapsuleShape(2.0, 6.0, ZUp) bnode = BulletRigidBodyNode("tree_collision") bnode.addShape(capsule, TransformState.makePos((0, 0, 3.0))) bnode.setKinematic(True) bnode.setIntoCollideMask(CIGlobals.WallGroup) tree.attachNewNode(bnode) self.trees.append(tree) newShadow = loader.loadModel( "phase_3/models/props/drop_shadow.bam") newShadow.reparentTo(tree) newShadow.setScale(1.5) newShadow.setBillboardAxis(2) newShadow.setColor(0, 0, 0, 0.5, 1) #tree.clearModelNodes() #tree.flattenStrong() # Fix bank door trigger bank = self.geom.find('**/*toon_landmark_TT_bank_DNARoot') doorTrigger = bank.find('**/door_trigger*') doorTrigger.setY(doorTrigger.getY() - 1.0) #self.telescope = Actor(self.geom.find('**/*animated_prop_HQTelescopeAnimatedProp*'), copy = 0) #{'chan': 'phase_3.5/models/props/HQ_telescope-chan.bam'}, copy=0) #self.telescope.reparentTo(self.geom.find('**/tb20:toon_landmark_hqTT_DNARoot')) #self.telescope.setPos(1, 0.46, 0) #self.geom.setMaterialOff() water = self.geom.find("**/pond_water") water.removeNode() self.doFlatten()
def _add_chassis(self, pg_physics_world: PGPhysicsWorld): para = self.get_config() chassis = BulletRigidBodyNode(BodyName.Ego_vehicle_top) chassis.setIntoCollideMask(BitMask32.bit(self.COLLISION_MASK)) chassis_shape = BulletBoxShape( Vec3(para[Parameter.vehicle_width] / 2, para[Parameter.vehicle_length] / 2, para[Parameter.vehicle_height] / 2)) ts = TransformState.makePos( Vec3(0, 0, para[Parameter.chassis_height] * 2)) chassis.addShape(chassis_shape, ts) heading = np.deg2rad(-para[Parameter.heading] - 90) chassis.setMass(para[Parameter.mass]) self.chassis_np = self.node_path.attachNewNode(chassis) # not random born now self.chassis_np.setPos(Vec3(*self.born_place, 1)) self.chassis_np.setQuat( LQuaternionf(np.cos(heading / 2), 0, 0, np.sin(heading / 2))) chassis.setDeactivationEnabled(False) chassis.notifyCollisions(True) # advance collision check self.pg_world.physics_world.dynamic_world.setContactAddedCallback( PythonCallbackObject(self._collision_check)) self.dynamic_nodes.append(chassis) chassis_beneath = BulletGhostNode(BodyName.Ego_vehicle) chassis_beneath.setIntoCollideMask(BitMask32.bit(self.COLLISION_MASK)) chassis_beneath.addShape(chassis_shape) self.chassis_beneath_np = self.chassis_np.attachNewNode( chassis_beneath) self.dynamic_nodes.append(chassis_beneath) self.system = BulletVehicle(pg_physics_world.dynamic_world, chassis) self.system.setCoordinateSystem(ZUp) self.dynamic_nodes.append( self.system ) # detach chassis will also detach system, so a waring will generate self.LENGTH = para[Parameter.vehicle_length] self.WIDTH = para[Parameter.vehicle_width] if self.render: model_path = 'models/ferra/scene.gltf' self.chassis_vis = self.loader.loadModel( AssetLoader.file_path(model_path)) self.chassis_vis.setZ(para[Parameter.vehicle_vis_z]) self.chassis_vis.setY(para[Parameter.vehicle_vis_y]) self.chassis_vis.setH(para[Parameter.vehicle_vis_h]) self.chassis_vis.set_scale(para[Parameter.vehicle_vis_scale]) self.chassis_vis.reparentTo(self.chassis_np)
def __init__(self): super(Terrain, self).__init__(random_seed=0) shape = BulletPlaneShape(Vec3(0, 0, 1), 0) node = BulletRigidBodyNode(BodyName.Ground) node.setFriction(.9) node.addShape(shape) node.setIntoCollideMask(self.COLLISION_MASK) self.dynamic_nodes.append(node) self.origin.attachNewNode(node) if self.render: self.origin.hide(CamMask.MiniMap | CamMask.Shadow | CamMask.DepthCam | CamMask.ScreenshotCam) # self.terrain_normal = self.loader.loadTexture( # AssetLoader.file_path( "textures", "grass2", "normal.jpg") # ) self.terrain_texture = self.loader.loadTexture( AssetLoader.file_path("textures", "ground.png")) self.terrain_texture.setWrapU(Texture.WM_repeat) self.terrain_texture.setWrapV(Texture.WM_repeat) self.ts_color = TextureStage("color") self.ts_normal = TextureStage("normal") self.ts_normal.set_mode(TextureStage.M_normal) self.origin.setPos(0, 0, self.HEIGHT) cm = CardMaker('card') scale = 20000 cm.setUvRange((0, 0), (scale / 10, scale / 10)) card = self.origin.attachNewNode(cm.generate()) # scale = 1 if self.use_hollow else 20000 card.set_scale(scale) card.setPos(-scale / 2, -scale / 2, -0.1) card.setZ(-.05) card.setTexture(self.ts_color, self.terrain_texture) # card.setTexture(self.ts_normal, self.terrain_normal) self.terrain_texture.setMinfilter( SamplerState.FT_linear_mipmap_linear) self.terrain_texture.setAnisotropicDegree(8) card.setQuat( LQuaternionf(math.cos(-math.pi / 4), math.sin(-math.pi / 4), 0, 0))
class DistributedRestockBarrel(DistributedEntity, DistributedNode): notify = directNotify.newCategory('DistributedRestockBarrel') def __init__(self, cr): DistributedEntity.__init__(self, cr) DistributedNode.__init__(self, cr) NodePath.__init__(self, 'restock_barrel') self.grabSfx = None self.rejectSfx = None self.grabSoundPath = 'phase_4/audio/sfx/SZ_DD_treasure.ogg' self.rejectSoundPath = 'phase_4/audio/sfx/ring_miss.ogg' self.animTrack = None self.barrelScale = 0.5 self.radius = 1.5 self.height = 4.275 self.playSoundForRemoteToons = 1 self.barrel = None self.gagNode = None self.gagModel = None # Collision nodes self.collSphere = None self.collNode = None self.collNodePath = None def load(self): DistributedEntity.load(self) self.setPos(self.cEntity.getOrigin()) self.setHpr(self.cEntity.getAngles()) def announceGenerate(self): DistributedEntity.announceGenerate(self) DistributedNode.announceGenerate(self) self.build() # Build collisions self.collSphere = BulletCylinderShape(self.radius, self.height, ZUp) self.collNode = BulletRigidBodyNode(self.uniqueName('barrelSphere')) self.collNode.setKinematic(True) self.collNode.addShape(self.collSphere, TransformState.makePos(Point3(0, 0, self.height / 2))) self.collNode.setIntoCollideMask(WallGroup) self.collNodePath = self.attachNewNode(self.collNode) base.physicsWorld.attach(self.collNodePath.node()) self.accept('enter' + self.collNodePath.getName(), self.__handleCollision) self.reparentTo(render) def disable(self): DistributedEntity.disable(self) DistributedNode.disable(self) self.ignoreAll() if self.animTrack: self.animTrack.pause() self.animTrack = None return def delete(self): self.gagNode.removeNode() self.barrel.removeNode() base.physicsWorld.remove(self.collNode) self.collNodePath.removeNode() del self.barrel del self.gagNode del self.grabSfx del self.rejectSfx del self.grabSoundPath del self.rejectSoundPath del self.animTrack del self.barrelScale del self.radius del self.height del self.playSoundForRemoteToons del self.gagModel del self.collNode del self.collNodePath del self.collSphere DistributedNode.delete(self) DistributedEntity.delete(self) def setLabel(self, labelId): if labelId == 0: self.gagModel = loader.loadModel('phase_4/models/props/icecream.bam') self.gagModel.reparentTo(self.gagNode) self.gagModel.find('**/p1_2').clearBillboard() self.gagModel.setScale(0.6) self.gagModel.setPos(0, -0.1, -0.1 - 0.6) elif labelId == 1: purchaseModels = loader.loadModel('phase_4/models/gui/purchase_gui.bam') self.gagModel = purchaseModels.find('**/Jar') self.gagModel.reparentTo(self.gagNode) self.gagModel.setScale(3.0) self.gagModel.setPos(0, -0.1, 0) purchaseModels.removeNode() elif labelId < 1000: gagId = labelId - 2 iconName = GagGlobals.InventoryIconByName.get(self.cr.attackMgr.getAttackName(gagId)) invModel = loader.loadModel('phase_3.5/models/gui/inventory_icons.bam').find('**/%s' % iconName) if invModel: self.gagModel = invModel self.gagModel.reparentTo(self.gagNode) self.gagModel.setScale(13.0) self.gagModel.setPos(0, -0.1, 0) else: self.notify.warning('Failed to find gag label %s.' % (str(labelId))) else: # Provided a hood id, the restock barrel will select the model of the # treasure for that playground and use it as the label. hoodName = ZoneUtil.ZoneId2Hood.get(labelId) modelPath = 'phase_4/models/props/icecream.bam' if hoodName is ZoneUtil.DonaldsDreamland: modelPath = 'phase_8/models/props/zzz_treasure.bam' elif hoodName is ZoneUtil.TheBrrrgh: modelPath = 'phase_8/models/props/snowflake_treasure.bam' elif hoodName is ZoneUtil.MinniesMelodyland: modelPath = 'phase_6/models/props/music_treasure.bam' elif hoodName is ZoneUtil.DaisyGardens: modelPath = 'phase_8/models/props/flower_treasure.bam' elif hoodName is ZoneUtil.DonaldsDock: modelPath = 'phase_6/models/props/starfish_treasure.bam' self.gagModel = loader.loadModel(modelPath) self.gagModel.reparentTo(self.gagNode) self.gagModel.find('**/p1_2').clearBillboard() self.gagModel.setScale(0.6) self.gagModel.setPos(0, -0.1, -0.7) def __handleCollision(self, _ = None): self.sendUpdate('requestGrab', []) def setGrab(self, avId): local = (avId == base.localAvatar.getDoId()) if local: self.ignore(self.uniqueName('enterbarrelSphere')) self.barrel.setColorScale(0.5, 0.5, 0.5, 1) if self.playSoundForRemoteToons or local: base.playSfx(self.grabSfx) if self.animTrack: self.animTrack.finish() self.animTrack = None self.animTrack = Sequence( LerpScaleInterval(self.barrel, 0.2, 1.1 * self.barrelScale, blendType='easeInOut'), LerpScaleInterval(self.barrel, 0.2, self.barrelScale, blendType='easeInOut'), Func(self.reset), name=self.uniqueName('animTrack')) self.animTrack.start() def setReject(self): base.playSfx(self.rejectSfx) self.notify.warning('Pickup rejected.') def build(self): self.grabSfx = base.audio3d.loadSfx(self.grabSoundPath) self.rejectSfx = base.audio3d.loadSfx(self.rejectSoundPath) base.audio3d.attachSoundToObject(self.grabSfx, self) base.audio3d.attachSoundToObject(self.rejectSfx, self) self.barrel = loader.loadModel('phase_4/models/cogHQ/gagTank.bam') self.barrel.setScale(self.barrelScale) self.barrel.reparentTo(self) self.barrel.setH(180) # Set the label background color. lblBg = self.barrel.find('**/gagLabelDCS') lblBg.setColor(0.15, 0.15, 0.1) self.gagNode = self.barrel.attachNewNode('gagNode') self.gagNode.setPosHpr(0.0, -2.62, 4.0, 0, 0, 0) self.gagNode.setColorScale(0.7, 0.7, 0.6, 1) def reset(self): self.barrel.setScale(self.barrelScale) self.accept(self.uniqueName('enterbarrelSphere'), self.__handleCollision)
def _initObjects(self): # Load objects for model in self.scene.scene.findAllMatches( '**/objects/object*/model*'): modelId = model.getParent().getTag('model-id') # XXX: we could create BulletGhostNode instance for non-collidable objects, but we would need to filter out the collisions later on if not modelId in self.openedDoorModelIds: shape, transform = getCollisionShapeFromModel( model, self.objectMode, defaultCentered=True) node = BulletRigidBodyNode('physics') node.addShape(shape) node.setFriction(self.defaultMaterialFriction) node.setRestitution(self.defaultMaterialRestitution) node.setIntoCollideMask(BitMask32.allOn()) node.setDeactivationEnabled(True) if self.suncgDatasetRoot is not None: # Check if it is a movable object category = self.modelCatMapping.getCoarseGrainedCategoryForModelId( modelId) if category in self.movableObjectCategories: # Estimate mass of object based on volumetric data and default material density objVoxFilename = os.path.join(self.suncgDatasetRoot, 'object_vox', 'object_vox_data', modelId, modelId + '.binvox') voxelData = ObjectVoxelData.fromFile(objVoxFilename) mass = Panda3dBulletPhysics.defaultDensity * voxelData.getFilledVolume( ) node.setMass(mass) else: node.setMass(0.0) node.setStatic(True) else: node.setMass(0.0) node.setStatic(True) if node.isStatic(): model.getParent().setTag('physics-mode', 'static') else: model.getParent().setTag('physics-mode', 'dynamic') # Attach the physic-related node to the scene graph physicsNp = model.getParent().attachNewNode(node) physicsNp.setTransform(transform) # Reparent render and acoustics nodes (if any) below the new physic node #XXX: should be less error prone to just reparent all children (except the hidden model) renderNp = model.getParent().find('**/render') if not renderNp.isEmpty(): renderNp.reparentTo(physicsNp) acousticsNp = model.getParent().find('**/acoustics') if not acousticsNp.isEmpty(): acousticsNp.reparentTo(physicsNp) # NOTE: we need this to update the transform state of the internal bullet node node.setTransformDirty() # NOTE: we need to add the node to the bullet engine only after setting all attributes self.bulletWorld.attach(node) # Validation assert np.allclose( mat4ToNumpyArray(physicsNp.getNetTransform().getMat()), mat4ToNumpyArray( model.getParent().getNetTransform().getMat()), atol=1e-6) else: logger.debug('Object %s ignored from physics' % (modelId))
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 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