UNPKG

matrix-engine

Version:

basic_timeline improved, VT func setup vide html element id with name arg.- DISABLE RAYCAST DEBUG TEST [2.3.3] Fix for GUI win desktop [2.3.0] DestrucMesh solution & loading convex objs for physics BASIC, SpriteAnimation CPU/texture solution added, Improv

345 lines (326 loc) 12.4 kB
/** * @Author Nikola Lukic * @Description Matrix Engine Api Example. * Test new feature for objLoader * Loading obj file - single textures - UV mapping from blender done * Detecting groups with special name prefix/sufix `COLLIDER` * * If you wanna real FPShooter multiplayer example goto: * https://github.com/zlatnaspirala/matrix-engine-starter */ import * as CANNON from 'cannon'; import App from "../program/manifest"; import {meMapLoader} from '../lib/map-loader'; import {map} from "./maps/map2"; import {ENUMERATORS, isMobile} from '../lib/utility'; export var runThis = world => { canvas.style.cursor = 'none'; App.camera.FirstPersonController = true; // matrixEngine.Events.camera.fly = true; App.camera.speedAmp = 0.2;//ori 0.02 matrixEngine.Events.camera.yPos = 10; App.camera.yawRateOnEdge = 3; //ori 3 App.camera.yawRate = 3; // 1 // Load Physics world. let gravityVector = [0, 0, -29.82]; let physics = world.loadPhysics(gravityVector); // Add ground - mass == 0 makes the body static var groundBody = new CANNON.Body({ mass: 0, position: new CANNON.Vec3(0, -15, -2) }); var groundShape = new CANNON.Plane(); groundBody.addShape(groundShape); groundBody._name = 'floor'; physics.world.addBody(groundBody); // Matrix engine visual scene object var tex = { source: ["res/images/old-tex/floor.gif"], mix_operation: "multiply", }; world.Add("squareTex", 1, "FLOOR_STATIC", tex); App.scene.FLOOR_STATIC.geometry.setScaleByX(500); App.scene.FLOOR_STATIC.geometry.setScaleByY(500); App.scene.FLOOR_STATIC.position.SetY(-2); App.scene.FLOOR_STATIC.position.SetZ(-15); App.scene.FLOOR_STATIC.rotation.rotx = 90; App.scene.FLOOR_STATIC.geometry.setTexCoordScaleFactor(40); const createObjSequence = (objName) => { let preventDoubleJump = null; function onLoadObj(meshes) { for(let key in meshes) { matrixEngine.objLoader.initMeshBuffers(world.GL.gl, meshes[key]); } var textuteImageSamplers2 = { source: ["res/bvh-skeletal-base/swat-guy/gun2.png"], mix_operation: "multiply" }; var animArg = { id: objName, meshList: meshes, currentAni: 0, animations: { active: 'walk', walk: { from: 0, to: 20, speed: 3 } } }; // WEAPON world.Add("obj", 1, objName, textuteImageSamplers2, meshes['player']); App.scene.player.position.setPosition(0.5, -0.7, -3); App.scene.player.isHUD = true; // Fix object orientation - this can be fixed also in blender. matrixEngine.Events.camera.yaw = 0; // Not in use but can be used function bodiesAreInContact(bodyA, bodyB) { for(var i = 0;i < world.contacts.length;i++) { var c = world.contacts[i]; if((c.bi === bodyA && c.bj === bodyB) || (c.bi === bodyB && c.bj === bodyA)) { return true; } } return false; } // Add collision cube to the local player. world.Add("cube", 0.2, "playerCollisonBox"); var collisionBox = new CANNON.Body({ mass: 7, linearDamping: 0.01, position: new CANNON.Vec3(-50, 24, 0), shape: new CANNON.Box(new CANNON.Vec3(1.75, 1.75, 2)) }); // This is custom param added. collisionBox._name = 'collisionBox'; physics.world.addBody(collisionBox); App.scene.playerCollisonBox.physics.currentBody = collisionBox; App.scene.playerCollisonBox.physics.enabled = true; App.scene.playerCollisonBox.physics.currentBody.fixedRotation = true; App.scene.playerCollisonBox.physics.currentBody.updateMassProperties(); App.scene.playerCollisonBox.geometry.setScale(0.02); App.scene.playerCollisonBox.glBlend.blendEnabled = true; App.scene.playerCollisonBox.glBlend.blendParamSrc = ENUMERATORS.glBlend.param[0]; App.scene.playerCollisonBox.glBlend.blendParamDest = ENUMERATORS.glBlend.param[0]; App.scene.playerCollisonBox.visible = false; // Test custom flag for collide moment App.scene.playerCollisonBox.iamInCollideRegime = false; // simple logic but also not perfect App.scene.playerCollisonBox.pingpong = true; collisionBox.addEventListener("collide", function(e) { // const contactNormal = new CANNON.Vec3(); // var relativeVelocity = e.contact.getImpactVelocityAlongNormal(); // console.log("playerCollisonBox collide with", e); preventDoubleJump = null; if(e.contact.bj._name == 'floor' || e.contact.bi._name == 'floor') { preventDoubleJump = null; return; } if(e.contact.bi._name == 'damage') { console.log("Trigger damage!"); //. 4x fix App.scene.player.energy.value -= (0.25 - (App.scene.player.items.armor ? App.scene.player.items.armor.preventDamage : 0)); App.scene.player.updateEnergy(App.scene.player.energy.value); } if(e.contact.bj._name == 'item-armor' || e.contact.bi._name == 'item-armor') { console.log("Trigger armor:", e.contact); // Make some enery restore App.scene.player.energy.value += 0.25; App.scene.player.updateEnergy(App.scene.player.energy.value); App.scene.player.items.armor = { preventDamage: 0.15 } if(App.scene['armor']) { App.scene['armor'].physics.enabled = false; App.scene['armor'].isHUD = true; App.scene.armor.position.setPosition(1.2, 1.1, -3); App.scene.armor.mesh.setScale(0.1) // Can be destroyed also App.scene['armor'].selfDestroy(1) } if(e.body._name == 'item-armor') { console.log("Trigger armor collect!"); physics.world.removeBody(e.body); } } }); // Mobile support if(isMobile() == true) { byId('mobSpace').addEventListener('touchstart', (e) => { // Jump if(preventDoubleJump == null) { preventDoubleJump = setTimeout(() => { App.scene.playerCollisonBox.physics.currentBody.mass = 1; App.scene.playerCollisonBox.physics.currentBody.velocity.set(0, 0, 25); // preventDoubleJump = null; for ever }, 250); } }) } else { // Matrix-engine key event DESKTOP addEventListener('hit.keyDown', (e) => { // Jump if(e.detail.keyCode == 32) { if(preventDoubleJump == null) { preventDoubleJump = setTimeout(() => { console.log('JUMP: ', e.detail.keyCode); App.scene.playerCollisonBox.physics.currentBody.mass = 1; App.scene.playerCollisonBox.physics.currentBody.velocity.set(0, 0, 25); // preventDoubleJump = null; for ever }, 250); } } }) } var handlerTimeout = null, handlerTimeout2 = null; var playerUpdater = { sendRotEvery: 5, sendRotValue: 0, UPDATE: () => { var detPitch; var limit = 2; if(matrixEngine.Events.camera.pitch < limit && matrixEngine.Events.camera.pitch > -limit) { detPitch = matrixEngine.Events.camera.pitch * 2; } else if(matrixEngine.Events.camera.pitch > limit) { detPitch = limit * 2; } else if(matrixEngine.Events.camera.pitch < -(limit + 2)) { detPitch = -(limit + 2) * 2; } handlerTimeout = null; // Make more stable situation App.scene.playerCollisonBox.physics.currentBody.mass = 10; App.scene.playerCollisonBox.physics.currentBody.quaternion.setFromEuler(0, 0, 0); // Cannonjs object set Switched Z - Y if(App.scene.playerCollisonBox.pingpong == true) { matrixEngine.Events.camera.xPos = App.scene.playerCollisonBox.physics.currentBody.position.x; matrixEngine.Events.camera.zPos = App.scene.playerCollisonBox.physics.currentBody.position.y; matrixEngine.Events.camera.yPos = App.scene.playerCollisonBox.physics.currentBody.position.z; App.scene.playerCollisonBox.pingpong = false; } else { handlerTimeout2 = 0; App.scene.playerCollisonBox. physics.currentBody.position.set( matrixEngine.Events.camera.xPos, matrixEngine.Events.camera.zPos, matrixEngine.Events.camera.yPos); App.scene.playerCollisonBox.pingpong = true; } // Player Look if(playerUpdater.sendRotValue > playerUpdater.sendRotEvery /*&& matrixEngine.Engine.net.connection != null*/) { if(typeof App.scene.playerCollisonBox === undefined) {return;} if(App.scene.playerCollisonBox.position.nameUniq == App.scene.playerCollisonBox.position.netObjId) { // console.log('NOT READY - MOBILE ALREADY IN SCENE MOMENT BUG') return; } // matrixEngine.Engine.net.connection.send({ // netRot: {y: matrixEngine.Events.camera.yaw + 180}, // netObjId: App.scene.playerCollisonBox.position.netObjId, // }) playerUpdater.sendRotValue = 0; } playerUpdater.sendRotValue++; } }; App.updateBeforeDraw.push(playerUpdater); // Player Energy status App.scene.player.energy = {}; // Collector for items App.scene.player.items = {}; for(let key in App.scene.player.meshList) { App.scene.player.meshList[key].setScale(1.85); } // Target scene object var texTarget = { source: [ "res/bvh-skeletal-base/swat-guy/target.png", "res/bvh-skeletal-base/swat-guy/target.png" ], mix_operation: "multiply", }; world.Add("squareTex", 0.25, 'FPSTarget', texTarget); App.scene.FPSTarget.position.setPosition(0, 0, -4); App.scene.FPSTarget.glBlend.blendEnabled = true; App.scene.FPSTarget.glBlend.blendParamSrc = matrixEngine.utility.ENUMERATORS.glBlend.param[4]; App.scene.FPSTarget.glBlend.blendParamDest = matrixEngine.utility.ENUMERATORS.glBlend.param[4]; App.scene.FPSTarget.isHUD = true; App.scene.FPSTarget.geometry.setScale(0.1); // Energy active bar - Custom generic textures. Micro Drawing. // Example for arg shema square for now only. var options = { squareShema: [8, 8], pixels: new Uint8Array(8 * 8 * 4) }; // options.pixels.fill(0); App.scene.player.energy.value = 8; App.scene.player.updateEnergy = function(v) { this.energy.value = v; var t = App.scene.energyBar.preparePixelsTex(App.scene.energyBar.specialValue); App.scene.energyBar.textures.pop() App.scene.energyBar.textures.push(App.scene.energyBar.createPixelsTex(t)); if(this.energy.value <= 0) { notify.error("YOU DIE...") } }; function preparePixelsTex(options) { var I = 0, R = 0, G = 0, B = 0, localCounter = 0; for(var funny = 0;funny < 8 * 8 * 4;funny += 4) { if(localCounter > 7) { localCounter = 0; } if(localCounter < App.scene.player.energy.value) { I = 128; if(App.scene.player.energy.value < 3) { R = 255; G = 0; B = 0; I = 0; } else if(App.scene.player.energy.value > 2 && App.scene.player.energy.value < 5) { R = 255; G = 255; B = 0; } else { R = 0; G = 255; B = 0; } } else { I = 0; R = 0; G = 0; B = 0; } options.pixels[funny] = R; options.pixels[funny + 1] = G; options.pixels[funny + 2] = B; options.pixels[funny + 3] = 0; localCounter++; } return options; } var tex2 = { source: ["res/images/hud/energy-bar.png", "res/images/hud/energy-bar.png"], mix_operation: "multiply", }; world.Add("squareTex", 1, 'energyBar', tex2); App.scene.energyBar.glBlend.blendEnabled = true; App.scene.energyBar.glBlend.blendParamSrc = matrixEngine.utility.ENUMERATORS.glBlend.param[5]; App.scene.energyBar.glBlend.blendParamDest = matrixEngine.utility.ENUMERATORS.glBlend.param[5]; App.scene.energyBar.isHUD = true; // App.scene.energy.visible = false; App.scene.energyBar.position.setPosition(0, 1.1, -3); App.scene.energyBar.geometry.setScaleByX(1) App.scene.energyBar.geometry.setScaleByY(0.05) App.scene.energyBar.preparePixelsTex = preparePixelsTex; options = preparePixelsTex(options); App.scene.energyBar.textures.push(App.scene.energyBar.createPixelsTex(options)); App.scene.energyBar.specialValue = options; } matrixEngine.objLoader.downloadMeshes({player: "res/bvh-skeletal-base/swat-guy/gun2.obj"}, onLoadObj ); }; createObjSequence('player') meMapLoader.load(map, physics); }