사용자:Senouis/백괴포트리스/게임 플레이: 두 판 사이의 차이
< 사용자:Senouis | 백괴포트리스
리버티게임>Senouis (새 문서: {{PluginX|script=사용자:Senouis/자바스크립트/plugin1.js|creator=Senouis|name=백괴포트리스 1.0}}) |
imported>Senouis 잔글 (Senouis님이 백괴포트리스/게임 플레이 문서를 사용자:Senouis/백괴포트리스/게임 플레이 문서로 이동했습니다: 보존 요청에 대해 발전소에서 동의하는 의견이 나와 일단 보존을 위한 이동으로 처리) |
(차이 없음)
|
2023년 5월 5일 (금) 18:35 기준 최신판
//--------------------------------------------------------------------------------------------- // UncycloEngine 1 by Epic Ungames, 2019-2020 //--------------------------------------------------------------------------------------------- //----------------------------------mapinfo and object definition------------------------------ // Objects must also be defined in server-side javascript function GameRule(RedClock, BlueClock, initialstate) { this.state = initialstate; // 0: game ceased, 1: game setup, 2: game on!, 3: round end this.RedClock = RedClock; this.BlueClock = BlueClock; this.currentdominating = 0; // 0: neutral, 1: red, 2:blue this.reddominatingprogress = 0; this.bluedominatingprogress = 0; } let redteamnum = 0; let blueteamnum = 0; function GameObject (pos, size, direction, team, collidetype, flag, health = 100) { // pos: array[x, y], size: array(cube)[x, y]/integer(cylinder), direction: integer(degree) this.pos = pos; this.size = size; this.rotation = [0, 0 ,0]; this.direction = direction; // define camera angle this.height = 0; this.scale = [1, 1, 1]; this.collidetype = collidetype; // 0: statical cubic(no direction), 1: cylinder this.flag = flag; // free flag this.team = team; // team : integer(0: not defined, 1: Red Yangachi, 2: Blue Yingeo, 3: Neutral) this.state = 0; // state depends on type of Game Object(0 is usually initial state) this.healthpoint = health; this.maxhealthpoint = health; this.canbedamaged = false; this.cameraMatrix = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; this.cameraAngleRadians = 0; this.updateCameraAngle = (event, value) => { this.cameraAngleRadians = degToRad(value); }; this.updatePosition = (index, value)=> { switch (index) { case 0: this.pos[0] = value; break; case 2: this.pos[1] = value; break; case 1: this.height = value; break; default: break; } }; this.vertexlist = [ // wall 1 2*pos[0], 32, 2*pos[1], 2*pos[0], -32, 2*pos[1], 2*pos[0], -32, 2*pos[1] + 2*size[1], 2*pos[0], 32, 2*pos[1], 2*pos[0], -32, 2*pos[1] + 2*size[1], 2*pos[0], 32, 2*pos[1] + 2*size[1], // wall 2 2*pos[0]+ 2*size[0], 32, 2*pos[1], 2*pos[0]+ 2*size[0], -32, 2*pos[1] + 2*size[1], 2*pos[0]+ 2*size[0], -32, 2*pos[1], 2*pos[0]+ 2*size[0], 32, 2*pos[1], 2*pos[0]+ 2*size[0], 32, 2*pos[1] + 2*size[1], 2*pos[0]+ 2*size[0], -32, 2*pos[1] + 2*size[1], // wall 3 2*pos[0], 32, 2*pos[1], 2*pos[0]+ 2*size[0], -32, 2*pos[1], 2*pos[0], -32, 2*pos[1], 2*pos[0], 32, 2*pos[1], 2*pos[0]+ 2*size[0], 32, 2*pos[1], 2*pos[0]+ 2*size[0], -32, 2*pos[1], // wall 4 2*pos[0], 32, 2*pos[1] + 2*size[1], 2*pos[0], -32, 2*pos[1] + 2*size[1], 2*pos[0]+ 2*size[0], -32, 2*pos[1] + 2*size[1], 2*pos[0], 32, 2*pos[1] + 2*size[1], 2*pos[0]+ 2*size[0], -32, 2*pos[1] + 2*size[1], 2*pos[0]+ 2*size[0], 32, 2*pos[1] + 2*size[1] ]; this.updateRotation = (index, value) => { var angleInDegrees = value; var angleInRadians = (angleInDegree % 360) * Math.PI / 180; this.rotation[index] = angleInRadians; }; this.updatescale = (index, value) =>{ this.scale[index] = value; }; this.GetCenterPosition = () => { if (this.collidetype === 0) { return [this.pos[0] + this.size[0] /2, this.pos[1] + this.size[1] / 2]; } else { return [this.pos[0] + this.size, this.pos[1] + this.size]; } }; this.SetCenterPosition = (position) => { if (this.collidetype === 0) { this.pos = [position[0] -this.size[0] /2, position[1] -this.size[1] / 2]; } else { this.pos = [position[0] -this.size, position[1] - this.size]; } }; this.IsColliding = (target) => { if (this.collidetype === 0 && target.collidetype === 0) { // cube vs cube if (this.GetCenterPosition()[0] + this.size[0]/2 >= target.GetCenterPosition()[0] - target.size[0]/2 && this.GetCenterPosition()[0] - this.size[0]/2 <= target.GetCenterPosition()[0] + target.size[0]/2 && this.GetCenterPosition()[1] + this.size[1]/2 >= target.GetCenterPosition()[1] - target.size[1]/2 && this.GetCenterPosition()[1] - this.size[1]/2 <= target.GetCenterPosition()[1] + target.size[1]/2) return true; else return false; } else if (this.collidetype === 0 && target.collidetype === 1) { if (target.GetCenterPosition()[0] + target.size >= this.GetCenterPosition()[0] - this.size[0] / 2 && target.GetCenterPosition()[0] - target.size <= this.GetCenterPosition()[0] + this.size[0] / 2) { // horizontal collision if (target.GetCenterPosition()[1] >= this.GetCenterPosition()[1] - this.size[1]/2 - target.size && target.GetCenterPosition()[1] <= this.GetCenterPosition()[1] + this.size[1]/2 + target.size ) return true; } if (target.GetCenterPosition()[1] + target.size >= this.GetCenterPosition()[1] - this.size[1] /2 && target.GetCenterPosition()[1] - target.size <= this.GetCenterPosition()[1] + this.size[1] /2) { // vertical collision if (target.GetCenterPosition()[0]+ target.size >= this.GetCenterPosition()[0] - this.size[0]/2 && target.GetCenterPosition()[0] - target.size <= this.GetCenterPosition()[0] + this.size[0] /2) { return true; } } // corner collision let equation1 = (target.GetCenterPosition()[0]-(this.GetCenterPosition()[0] - this.size[0] / 2)) * (target.GetCenterPosition()[0]-(this.GetCenterPosition()[0]- this.size[0] / 2))+ (target.GetCenterPosition()[1]-(this.GetCenterPosition()[1]- this.size[1] / 2)) * (target.GetCenterPosition()[1]-(this.GetCenterPosition()[1]- this.size[1] / 2)); let equation2 = (target.GetCenterPosition()[0]-(this.GetCenterPosition()[0] - this.size[0] / 2)) * (target.GetCenterPosition()[0]-(this.GetCenterPosition()[0]- this.size[0] / 2))+ (target.GetCenterPosition()[1]-(this.GetCenterPosition()[1]+this.size[1]/2)) * (target.GetCenterPosition()[1]-(this.GetCenterPosition()[1]+this.size[1]/2)); let equation3 = (target.GetCenterPosition()[0]-(this.GetCenterPosition()[0]+this.size[0]/2)) * (target.GetCenterPosition()[0]-(this.GetCenterPosition()[0]+this.size[0]/2))+ (target.GetCenterPosition()[1]-(this.GetCenterPosition()[1]- this.size[1] / 2)) * (target.GetCenterPosition()[1]-(this.GetCenterPosition()[1]- this.size[1] / 2)); let equation4 = (target.GetCenterPosition()[0]-this.GetCenterPosition()[0]-this.size[0]/2) * (target.GetCenterPosition()[0]-this.GetCenterPosition()[0]-this.size[0]/2)+ (target.GetCenterPosition()[1]-this.GetCenterPosition()[1]-this.size[1]/2) * (target.GetCenterPosition()[1]-this.GetCenterPosition()[1]-this.size[1]/2); if (equation1 <= target.size* target.size || equation2 <= target.size* target.size || equation3 <= target.size* target.size || equation4 <= target.size* target.size) { return true; } else { return false; } } else if (this.collidetype === 1 && target.collidetype === 0) { if (this.GetCenterPosition()[0] + this.size >= target.GetCenterPosition()[0] - target.size[0] / 2 && this.GetCenterPosition()[0] - this.size <= target.GetCenterPosition()[0] + target.size[0]/2) { // horizontal collision if (this.GetCenterPosition()[1] + this.size>= target.GetCenterPosition()[1] - target.size[1] / 2 && this.GetCenterPosition()[1] - this.size <= target.GetCenterPosition()[1] + target.size[1]/2 ) return true; } if (this.GetCenterPosition()[1] + this.size >= target.GetCenterPosition()[1] - target.size[1] / 2 && this.GetCenterPosition()[1] - this.size <= target.GetCenterPosition()[1] + target.size[1]/2 ) { // vertical collision if (this.GetCenterPosition()[0] + this.size>= target.GetCenterPosition()[0] - target.size[0] / 2 && this.GetCenterPosition()[0]- this.size <= target.GetCenterPosition()[0] + target.size[0] /2) { return true; } } // corner collision let equation1 = (this.GetCenterPosition()[0]-(target.GetCenterPosition()[0]+target.size[0]/2)) * (this.GetCenterPosition()[0]-(target.GetCenterPosition()[0]+target.size[0]/2))+ (this.GetCenterPosition()[1]-(target.GetCenterPosition()[1]+target.size[1]/2)) * (this.GetCenterPosition()[1]-(target.GetCenterPosition()[1]+target.size[1]/2)); let equation2 = (this.GetCenterPosition()[0]-(target.GetCenterPosition()[0] - target.size[0] / 2)) * (this.GetCenterPosition()[0]-(target.GetCenterPosition()[0]- target.size[0] / 2))+ (this.GetCenterPosition()[1]-(target.GetCenterPosition()[1]+target.size[1]/2)) * (this.GetCenterPosition()[1]-(target.GetCenterPosition()[1]+target.size[1]/2)); let equation3 = (this.GetCenterPosition()[0]-(target.GetCenterPosition()[0]+target.size[0]/2)) * (this.GetCenterPosition()[0]-(target.GetCenterPosition()[0]+target.size[0]/2))+ (this.GetCenterPosition()[1]-(target.GetCenterPosition()[1] - target.size[1] / 2)) * (this.GetCenterPosition()[1]-(target.GetCenterPosition()[1] - target.size[1] / 2)); let equation4 = (this.GetCenterPosition()[0]-(target.GetCenterPosition()[0] - target.size[0] / 2)) * (this.GetCenterPosition()[0]-(target.GetCenterPosition()[0] - target.size[0] / 2))+ (this.GetCenterPosition()[1]-(target.GetCenterPosition()[1]- target.size[1] / 2)) * (this.GetCenterPosition()[1]-(target.GetCenterPosition()[1]- target.size[1] / 2)); if (equation1 <= this.size* this.size || equation2 <= this.size* this.size || equation3 <= this.size* this.size || equation4 <= this.size* this.size) { return true; } else { return false; } } else { // cylinder vs cylinder if ((this.GetCenterPosition()[0] - target.GetCenterPosition()[0])*(this.GetCenterPosition()[0] - target.GetCenterPosition()[0]) + (this.GetCenterPosition()[1] - target.GetCenterPosition()[1])*(this.GetCenterPosition()[1] - target.GetCenterPosition()[1]) <= (this.size + target.size) * (this.size + target.size)) return true; else return false; } return false; // this could not be happened }; } function Projectile(pos, size, direction, team, shooter, imgsrc, type = 0) { GameObject.call(this, pos, size, direction, team, 1, 0, 1); this.movespeed = 4; this.shooter = shooter; this.imgsrc = imgsrc; this.visible = false; this.type = type; this.cameraMatrix = m4.lookAt([this.GetCenterPosition()[0],0,this.GetCenterPosition()[1]],[this.GetCenterPosition()[0]+Math.cos(this.direction), 0, this.GetCenterPosition()[1]+Math.sin(this.direction)], up ); this.vertexlist = [ ]; } Projectile.prototype = Object.create(GameObject.prototype); Projectile.prototype.constructor = Projectile; const MAX_PROJECTILE_PER_PLAYER = 100; const MAX_PROJECTILE_NUMBER = 100 * MAX_PROJECTILE_PER_PLAYER; let projectilelist = []; function Explosion(pos, size, type = 0) { GameObject.call(this, pos, size, 0, 0, 1, 0, 1); this.type = type; this.counter = 0; this.active = true; this.cameraMatrix = m4.lookAt([this.GetCenterPosition()[0],0,this.GetCenterPosition()[1]],[this.GetCenterPosition()[0]+Math.cos(this.direction), 0, this.GetCenterPosition()[1]+Math.sin(this.direction)], up ); this.vertexlist = GeneratePlaneVertex(this.GetCenterPosition(), size * 2, this.cameraMatrix); } Explosion.prototype = Object.create(GameObject.prototype); Explosion.prototype.constructor = Explosion; const MAX_EXPLOSION_NUMBER = 100 * MAX_PROJECTILE_PER_PLAYER; let explosionlist = []; function Player(pos, size, direction, team, health, id = 0, isdead = false, playername = "unknown player", classnum = 0) { GameObject.call(this, pos, size, direction, team, 1, 0, health); this.playername = playername; this.playerID = id; this.movespeed = 1; this.classnumber = classnum; this.canbedamaged = true; this.isdead = isdead; this.deadtimer; this.secondweapon = undefined; // weapon 0 this.firstweapon = undefined; // weapon 1 this.currentweapon = 0; this.ReloadWeapon = () => { console.log("Reloaded"); }; this.FireWeapon = () =>{ console.log("Fired"); }; this.DoSpecialSkill = () => { console.log("Did SpecialSkill"); }; this.ReleaseFire = () => { return; } this.reloadDelaying = false; this.raylist = []; // remember, this only has MAX_RAY_PER_PLAYER number of elements this.moveSomething = () => { let camMatrix = m4.lookAt([this.GetCenterPosition()[0],this.height,this.GetCenterPosition()[1]],[this.GetCenterPosition()[0]+Math.cos(this.direction), 0, this.GetCenterPosition()[1]+Math.sin(this.direction)], up ); let forwardvector = m4.getForward(camMatrix); let rightvector = m4.getRight(camMatrix); if (keystate[0] && keystate[2] || keystate[0] && keystate[3] || keystate[1] && keystate[2] || keystate[1] && keystate[3]) { rightvector[0] *= 0.7071; rightvector[2] *= 0.7071; forwardvector[0] *= 0.7071; forwardvector[2] *= 0.7071; } // remember, the map has reversed axis if (keystate[0]){ // a let freeToMove = true; for (let mapobject of mapinfo.mapobjectlist) { let tempmapobject = new GameObject([mapobject.pos[0] - this.movespeed*rightvector[0], mapobject.pos[1] ], mapobject.size, mapobject.direction, mapobject.team, mapobject.collidetype, mapobject.flag, mapobject.healthpoint); if (tempmapobject.team != this.team && this.IsColliding(tempmapobject)) freeToMove = false; } if (freeToMove){ this.updatePosition(0, this.pos[0] + this.movespeed*rightvector[0]); } freeToMove = true; for (let mapobject of mapinfo.mapobjectlist) { let tempmapobject = new GameObject([mapobject.pos[0], mapobject.pos[1] - this.movespeed*rightvector[2]], mapobject.size, mapobject.direction, mapobject.team, mapobject.collidetype, mapobject.flag, mapobject.healthpoint); if (tempmapobject.team != this.team &&this.IsColliding(tempmapobject)) freeToMove = false; } if (freeToMove){ this.updatePosition(2, this.pos[1] + this.movespeed*rightvector[2]); } ws.send(JSON.stringify({ type:5, id: this.playerID, pos: this.pos, direction: this.direction })); } if (keystate[1]){ //d let freeToMove = true; for (let mapobject of mapinfo.mapobjectlist) { let tempmapobject = new GameObject([mapobject.pos[0] + this.movespeed*rightvector[0], mapobject.pos[1] ], mapobject.size, mapobject.direction, mapobject.team, mapobject.collidetype, mapobject.flag, mapobject.healthpoint); if (tempmapobject.team != this.team &&this.IsColliding(tempmapobject)) freeToMove = false; } if (freeToMove){ this.updatePosition(0, this.pos[0] - this.movespeed*rightvector[0]); } freeToMove = true; for (let mapobject of mapinfo.mapobjectlist) { let tempmapobject = new GameObject([mapobject.pos[0], mapobject.pos[1] + this.movespeed*rightvector[2]], mapobject.size, mapobject.direction, mapobject.team, mapobject.collidetype, mapobject.flag, mapobject.healthpoint); if (tempmapobject.team != this.team &&this.IsColliding(tempmapobject)) freeToMove = false; } if (freeToMove){ this.updatePosition(2, this.pos[1] - this.movespeed*rightvector[2]); } ws.send(JSON.stringify({ type:5, id: this.playerID, pos: this.pos, direction: this.direction })); } if (keystate[2]) { //s let freeToMove = true; for (let mapobject of mapinfo.mapobjectlist) { let tempmapobject = new GameObject([mapobject.pos[0] - this.movespeed*forwardvector[0], mapobject.pos[1] ], mapobject.size, mapobject.direction, mapobject.team, mapobject.collidetype, mapobject.flag, mapobject.healthpoint); if (tempmapobject.team != this.team &&this.IsColliding(tempmapobject)) freeToMove = false; } if (freeToMove){ this.updatePosition(0, this.pos[0] + this.movespeed*forwardvector[0]); } freeToMove = true; for (let mapobject of mapinfo.mapobjectlist) { let tempmapobject = new GameObject([mapobject.pos[0], mapobject.pos[1] - this.movespeed*forwardvector[2]], mapobject.size, mapobject.direction, mapobject.team, mapobject.collidetype, mapobject.flag, mapobject.healthpoint); if (tempmapobject.team != this.team &&this.IsColliding(tempmapobject)) freeToMove = false; } if (freeToMove){ this.updatePosition(2, this.pos[1] + this.movespeed*forwardvector[2]); } ws.send(JSON.stringify({ type:5, id: this.playerID, pos: this.pos, direction: this.direction })); } if (keystate[3]) { // w let freeToMove = true; for (let mapobject of mapinfo.mapobjectlist) { let tempmapobject = new GameObject([mapobject.pos[0] + this.movespeed*forwardvector[0], mapobject.pos[1] ], mapobject.size, mapobject.direction, mapobject.team, mapobject.collidetype, mapobject.flag, mapobject.healthpoint); if (tempmapobject.team != this.team &&this.IsColliding(tempmapobject)) freeToMove = false; } if (freeToMove){ this.updatePosition(0, this.pos[0] -this.movespeed*forwardvector[0]); } freeToMove = true; for (let mapobject of mapinfo.mapobjectlist) { let tempmapobject = new GameObject([mapobject.pos[0], mapobject.pos[1] + this.movespeed*forwardvector[2]], mapobject.size, mapobject.direction, mapobject.team, mapobject.collidetype, mapobject.flag, mapobject.healthpoint); if (tempmapobject.team != this.team &&this.IsColliding(tempmapobject)) freeToMove = false; } if (freeToMove){ this.updatePosition(2, this.pos[1] - this.movespeed*forwardvector[2]); } ws.send(JSON.stringify({ type:5, id: this.playerID, pos: this.pos, direction: this.direction })); } if (keystate[0] || keystate[1] || keystate[2] || keystate[3]) { if ( heightcount >= 0 && heightcount <20) this.updatePosition(1, 0.1* heightcount); else this.updatePosition(1, 2-0.1*heightcount); if (heightcount >= 39) heightcount = 0; else heightcount = heightcount +1; } if (keystate[4] && this.reloadDelaying === false) { // q if (this.currentweapon === 0) { this.secondweapon.isFiring = false; this.currentweapon = 1; } else { this.firstweapon.isFiring = false; this.currentweapon = 0; } ws.send(JSON.stringify({ type:16, id: this.playerID, currentweapon: this.currentweapon })); this.reloadDelaying = true; setTimeout(this.keydelayEnd,400); } if (keystate[5]) { // e } if (keystate[6]) { // r this.ReloadWeapon(); } if (keystate[7]) { // f } } this.keydelayEnd = () => { this.reloadDelaying = false; } this.vertexlist = GeneratePlaneVertex(this.GetCenterPosition(), 32, this.cameraMatrix); } Player.prototype = Object.create(GameObject.prototype); Player.prototype.constructor = Player; let playerlist = []; function Building(pos, size, direction, team, health, id = 0) { Player.call(this, pos, size, direction, team, health, id) } Building.prototype = Object.create(Player.prototype); Building.prototype.constructor = Building; const mapobjectsizeconstant = 32; function MapInfo (text) { // map infomation this.rawmapdata = text; let mapdataarray = this.rawmapdata.split('\n'); let mapsize = mapdataarray[0].split(' '); this.mapheight = parseInt(mapsize[0]); this.mapwidth = parseInt(mapsize[1]); this.mapversion = parseInt(mapsize[2]); this.mapdata = mapdataarray; this.mapwallcounter = 0; this.mapobjectlist = []; this.maphealthkitlist = []; let mapX = 64* this.mapwidth; let mapY = 64* this.mapheight; this.polygons = [ // ground 0, -32, 0, mapX, -32, mapY, mapX, -32, 0, mapX, -32, mapY, 0, -32, 0, 0, -32, mapY, // ceiling 0, 32, 0, mapX, 32, 0, mapX, 32, mapY, mapX, 32, mapY, 0, 32, mapY, 0, 32, 0 // walls ]; this.mapColors = [ // ground and ceiling 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // other wall ]; for (let i = 1; i <= this.mapheight; i++) { for (let j = 0; j < this.mapwidth; j++){ switch (this.mapdata[i][j]) { case 'R': this.RedSpawn = [ mapobjectsizeconstant*j, mapobjectsizeconstant*(i-1)]; break; case 'B': this.BlueSpawn = [ mapobjectsizeconstant*j, mapobjectsizeconstant*(i-1)]; break; case 'W': this.mapobjectlist.push(new GameObject([mapobjectsizeconstant*j, mapobjectsizeconstant*(i-1)], [mapobjectsizeconstant, mapobjectsizeconstant],0, 0, 0, 0)); break; case 'Q': this.mapobjectlist.push(new GameObject([mapobjectsizeconstant*j, mapobjectsizeconstant*(i-1)], [mapobjectsizeconstant, mapobjectsizeconstant],0, 0, 0, 2)); break; case 'A': this.mapobjectlist.push(new GameObject([mapobjectsizeconstant*j, mapobjectsizeconstant*(i-1)], [mapobjectsizeconstant, mapobjectsizeconstant],0, 0, 0, 1)); break; case 'H': this.maphealthkitlist.push(new Healthkit([mapobjectsizeconstant*j + 8, mapobjectsizeconstant*(i-1) +8], 8, this.maphealthkitlist.length)); break; case 'Z': this.mapobjectlist.push(new Door([mapobjectsizeconstant*j, mapobjectsizeconstant*(i-1)], [mapobjectsizeconstant, mapobjectsizeconstant],270, 2)); break; case 'X': this.mapobjectlist.push(new Door([mapobjectsizeconstant*j, mapobjectsizeconstant*(i-1)], [mapobjectsizeconstant, mapobjectsizeconstant],90, 2)); break; case 'C': this.mapobjectlist.push(new Door([mapobjectsizeconstant*j, mapobjectsizeconstant*(i-1)], [mapobjectsizeconstant, mapobjectsizeconstant],180, 2)); break; case 'V': this.mapobjectlist.push(new Door([mapobjectsizeconstant*j, mapobjectsizeconstant*(i-1)], [mapobjectsizeconstant, mapobjectsizeconstant],0, 2)); break; case 'U': this.mapobjectlist.push(new Door([mapobjectsizeconstant*j, mapobjectsizeconstant*(i-1)], [mapobjectsizeconstant, mapobjectsizeconstant],270, 1)); break; case 'I': this.mapobjectlist.push(new Door([mapobjectsizeconstant*j, mapobjectsizeconstant*(i-1)], [mapobjectsizeconstant, mapobjectsizeconstant],90, 1)); break; case 'O': this.mapobjectlist.push(new Door([mapobjectsizeconstant*j, mapobjectsizeconstant*(i-1)], [mapobjectsizeconstant, mapobjectsizeconstant],180, 1)); break; case 'P': this.mapobjectlist.push(new Door([mapobjectsizeconstant*j, mapobjectsizeconstant*(i-1)], [mapobjectsizeconstant, mapobjectsizeconstant],0, 1)); break; default: break; // do nothing } } } for (let object of this.mapobjectlist) { if (object.constructor === GameObject) { this.mapwallcounter += 4; } else if (object.constructor === Door) { this.mapwallcounter += 2; } this.polygons = this.polygons.concat(object.vertexlist); } } function Healthkit(pos, size, id) { GameObject.call(this, pos, size, 0, 0, 1, 1, 0); this.id = id; this.respawntime = 8000; this.isSpawned = true; this.respawntimer = undefined; this.vertexlist = GenerateProjectile(this.GetCenterPosition(), size, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); this.respawn = () => { this.isSpawned = true; return; } } Healthkit.prototype = Object.create(GameObject.prototype); Healthkit.prototype.constructor = Healthkit; function Door(pos, size, direction, team) { GameObject.call(this, pos, size, direction, team, 0, 0, 100000); switch (direction) { case 0: this.vertexlist = [ // wall (right) 2*pos[0] + 2* size[0], 32, 2*pos[1], 2*pos[0] + 2* size[0], -32, 2*pos[1]+2*size[1], 2*pos[0] + 2* size[0], -32, 2*pos[1], 2*pos[0] + 2* size[0], 32, 2*pos[1], 2*pos[0] + 2* size[0], 32, 2*pos[1]+2*size[1], 2*pos[0] + 2* size[0], -32, 2*pos[1]+2*size[1], // wall (left) 2*pos[0] + 2* size[0] - 4, 32, 2*pos[1], 2*pos[0] + 2* size[0] - 4, -32, 2*pos[1], 2*pos[0] + 2* size[0] - 4, -32, 2*pos[1]+2*size[1], 2*pos[0] + 2* size[0] - 4, 32, 2*pos[1], 2*pos[0] + 2* size[0] - 4, -32, 2*pos[1]+2*size[1], 2*pos[0] + 2* size[0] - 4, 32, 2*pos[1]+2*size[1] ]; break; case 90: this.vertexlist = [ // wall (down) 2*pos[0], 32, 2*pos[1]+2*size[1], 2*pos[0], -32, 2*pos[1]+2*size[1], 2*pos[0] + 2* size[0], -32, 2*pos[1]+2*size[1], 2*pos[0], 32, 2*pos[1]+2*size[1], 2*pos[0] + 2* size[0], -32, 2*pos[1]+2*size[1], 2*pos[0] + 2* size[0], 32, 2*pos[1]+2*size[1], // wall (Up) 2*pos[0], 32, 2*pos[1]+2*size[1]-4, 2*pos[0] + 2* size[0], -32, 2*pos[1]+2*size[1]-4, 2*pos[0], -32, 2*pos[1]+2*size[1]-4, 2*pos[0], 32, 2*pos[1]+2*size[1]-4, 2*pos[0] + 2* size[0], 32, 2*pos[1]+2*size[1]-4, 2*pos[0] + 2* size[0], -32, 2*pos[1]+2*size[1]-4 ]; break; case 180: this.vertexlist = [ // wall (left) 2*pos[0], 32, 2*pos[1], 2*pos[0], -32, 2*pos[1], 2*pos[0], -32, 2*pos[1]+2*size[1], 2*pos[0], 32, 2*pos[1], 2*pos[0], -32, 2*pos[1]+2*size[1], 2*pos[0], 32, 2*pos[1]+2*size[1], // wall (right) 2*pos[0] + 4, 32, 2*pos[1], 2*pos[0] + 4, -32, 2*pos[1]+2*size[1], 2*pos[0] + 4, -32, 2*pos[1], 2*pos[0] + 4, 32, 2*pos[1], 2*pos[0] + 4, 32, 2*pos[1]+2*size[1], 2*pos[0] + 4, -32, 2*pos[1]+2*size[1], ]; break; case 270: this.vertexlist = [ // wall (Up) 2*pos[0], 32, 2*pos[1], 2*pos[0] + 2* size[0], -32, 2*pos[1], 2*pos[0], -32, 2*pos[1], 2*pos[0], 32, 2*pos[1], 2*pos[0] + 2* size[0], 32, 2*pos[1], 2*pos[0] + 2* size[0], -32, 2*pos[1], // wall (down) 2*pos[0], 32, 2*pos[1]+4, 2*pos[0], -32, 2*pos[1]+4, 2*pos[0] + 2* size[0], -32, 2*pos[1]+4, 2*pos[0], 32, 2*pos[1]+4, 2*pos[0] + 2* size[0], -32, 2*pos[1]+4, 2*pos[0] + 2* size[0], 32, 2*pos[1]+4 ]; break; default: break; } } Door.prototype = Object.create(GameObject.prototype); Door.prototype.constructor = Door; function AreaEquation(centerpos, firstcornerpos, secondcornerpos) { // 3 dimensional position this.point = centerpos; this.normalvector = m4.cross([centerpos[0]-firstcornerpos[0],centerpos[1]-firstcornerpos[1],centerpos[2]-firstcornerpos[2]], [centerpos[0]-secondcornerpos[0],centerpos[1]-secondcornerpos[1],centerpos[2]-secondcornerpos[2]]); } function LineEquation(startpos, endpos) { // 3 dimensional position this.point = startpos; this.linevector = [endpos[0] - startpos[0],endpos[1] - startpos[1],endpos[2] - startpos[2]]; } function CylinderEquation(center, radius) { this.centerpos = center; this.radius = radius; } const MAX_RAY_PER_PLAYER = 10; const MAX_RAY_NUM = 32 * MAX_RAY_PER_PLAYER; function Ray (startpos, endpos) { this.visible = false; this.startpos = startpos; // array this.endpos = endpos; // array this.collidedobjectsinfo = []; // will contain list of GameObject objects and their penetrated positions this.AddPenetratingObjects = (objectlist) => { for (let object of objectlist){ let lineeq = new LineEquation(this.startpos, this.endpos); if (object.collidetype === 0) { // cubic -> doing collision check 4 times let areaeq1 = new AreaEquation([object.GetCenterPosition()[0]-object.size[0]/2, object.GetCenterPosition()[1],0], [object.GetCenterPosition()[0]-object.size[0]/2, object.GetCenterPosition()[1]-object.size[1]/2,mapobjectsizeconstant/2],[object.GetCenterPosition()[0]-object.size[0]/2, object.GetCenterPosition()[1]-object.size[1]/2,-mapobjectsizeconstant/2]); let resultArray = LineTrace_Sub1(lineeq, areaeq1); if (resultArray.length > 0 && resultArray[1] >= object.GetCenterPosition()[1]-object.size[1]/2 && resultArray[1] <= object.GetCenterPosition()[1]+object.size[1]/2) this.collidedobjectsinfo.push([object, resultArray]); let areaeq2 = new AreaEquation([object.GetCenterPosition()[0], object.GetCenterPosition()[1]-object.size[1]/2,0], [object.GetCenterPosition()[0]-object.size[0]/2, object.GetCenterPosition()[1]-object.size[1]/2,mapobjectsizeconstant/2],[object.GetCenterPosition()[0]-object.size[0]/2, object.GetCenterPosition()[1]-object.size[1]/2,-mapobjectsizeconstant/2]); resultArray = LineTrace_Sub1(lineeq, areaeq2); if (resultArray.length > 0 && resultArray[0] >= object.GetCenterPosition()[0]-object.size[0]/2 && resultArray[0] <= object.GetCenterPosition()[0]+object.size[0]/2) this.collidedobjectsinfo.push([object, resultArray]); let areaeq3 = new AreaEquation([object.GetCenterPosition()[0]+object.size[0]/2, object.GetCenterPosition()[1],0], [object.GetCenterPosition()[0]+object.size[0]/2, object.GetCenterPosition()[1]+object.size[1]/2,mapobjectsizeconstant/2],[object.GetCenterPosition()[0]+object.size[0]/2, object.GetCenterPosition()[1]+object.size[1]/2,-mapobjectsizeconstant/2]); resultArray = LineTrace_Sub1(lineeq, areaeq3); if (resultArray.length > 0 && resultArray[1] >= object.GetCenterPosition()[1]-object.size[1]/2 && resultArray[1] <= object.GetCenterPosition()[1]+object.size[1]/2) this.collidedobjectsinfo.push([object, resultArray]); let areaeq4 = new AreaEquation([object.GetCenterPosition()[0], object.GetCenterPosition()[1]+object.size[1]/2,0], [object.GetCenterPosition()[0]+object.size[0]/2, object.GetCenterPosition()[1]+object.size[1]/2,mapobjectsizeconstant/2],[object.GetCenterPosition()[0]+object.size[0], object.GetCenterPosition()[1]+object.size[1],-mapobjectsizeconstant/2]); resultArray = LineTrace_Sub1(lineeq, areaeq4); if (resultArray.length > 0 && resultArray[0] >= object.GetCenterPosition()[0]-object.size[0]/2 && resultArray[0] <= object.GetCenterPosition()[0]+object.size[0]/2) this.collidedobjectsinfo.push([object, resultArray]); } else if (object.collidetype === 1){ // cylinder -> only find success/fail let cylindereq = new CylinderEquation(object.GetCenterPosition(), object.size); let hitpoint = LineTrace_Sub2(lineeq, cylindereq); if ((hitpoint[0] - this.startpos[0]) * (hitpoint[0] - this.startpos[0]) + (hitpoint[1] - this.startpos[1]) + (hitpoint[2] - this.startpos[2]) * (hitpoint[2] - this.startpos[2]) < (this.endpos[0] - this.startpos[0]) * (this.endpos[0] - this.startpos[0]) + (this.endpos[1] - this.startpos[1]) * (this.endpos[1] - this.startpos[1]) + (this.endpos[2] - this.startpos[2]) * (this.endpos[2] - this.startpos[2]) ) this.collidedobjectsinfo.push([object, hitpoint]); } } } this.GetClosestCollidedPosition = () => { // only find cube collided position; let collidedposition = this.endpos; for (let objectinfo of this.collidedobjectsinfo) { if (objectinfo.length > 1) { let line1 = new LineEquation(this.startpos, objectinfo[1]); let criterionline = new LineEquation(this.startpos, this.endpos); if (m4.normalize(criterionline.linevector)[0] * m4.normalize(line1.linevector)[0] >0 && GetLineLength(this.startpos, objectinfo[1]) <= GetLineLength(this.startpos, collidedposition)) collidedposition = objectinfo[1]; } } return collidedposition; } this.GetClosestCollidedObject = (rayownerid = -1) => { // only find cube collided position; let collidedposition = this.endpos; let collidedobject = undefined; for (let objectinfo of this.collidedobjectsinfo) { if (objectinfo[0].constructor === Player && objectinfo[0].playerID === rayownerid) continue; if (objectinfo.length > 1) { let line1 = new LineEquation(this.startpos, objectinfo[1]); let criterionline = new LineEquation(this.startpos, this.endpos); if (m4.normalize(criterionline.linevector)[0] * m4.normalize(line1.linevector)[0] >0 && GetLineLength(this.startpos, objectinfo[1]) <= GetLineLength(this.startpos, collidedposition)) { collidedposition = objectinfo[1]; collidedobject = objectinfo[0]; } } } return collidedobject; } this.DrawRay = () => { this.visible = true; setTimeout(this.DrawRay_timeout, 50); return; } this.DrawRay_timeout = () => { this.visible = false; return; } }; // -----------------------------------------------global data------------------------------------------- const up = [0, 1, 0]; // player state let fieldOfViewRadians = degToRad(90); let heightcount = 0; // --------------------------------------------global function ----------------------------------------------- String.format = function() { // The string containing the format items (e.g. "{0}") // will and always has to be the first argument. var theString = arguments[0]; // start with the second argument (i = 1) for (var i = 1; i < arguments.length; i++) { // "gm" = RegEx options for Global search (more than one instance) // and for Multiline search var regEx = new RegExp("\\{" + (i - 1) + "\\}", "gm"); theString = theString.replace(regEx, arguments[i]); } return theString; } function radToDeg(r) { return r * 180 / Math.PI; } function degToRad(d) { return d * Math.PI / 180; } function LineTrace_Sub1(lineeq, areaeq) { if (lineeq.linevector[0] * areaeq.normalvector[0] + lineeq.linevector[1] * areaeq.normalvector[1] === 0) return []; let t = -(areaeq.normalvector[0]*(lineeq.point[0]-areaeq.point[0]) + areaeq.normalvector[1]*(lineeq.point[1]-areaeq.point[1]) + areaeq.normalvector[2]*(lineeq.point[2]-areaeq.point[2])) / (areaeq.normalvector[0]*lineeq.linevector[0] + areaeq.normalvector[1]*lineeq.linevector[1] +areaeq.normalvector[2]*lineeq.linevector[2]); return [lineeq.linevector[0]*t + lineeq.point[0], lineeq.linevector[1]*t + lineeq.point[1],lineeq.linevector[2]*t + lineeq.point[2]]; } function LineTrace_Sub2(lineeq, cylindereq) { let a = lineeq.linevector[0]; let b = lineeq.linevector[1]; let c = cylindereq.centerpos[0] - lineeq.point[0]; let d = cylindereq.centerpos[1] - lineeq.point[1]; let t1 = (a*c + b* d + Math.sqrt( (a*c + b*d) * (a*c + b*d) - (a*a + b*b) * (c*c + d* d - cylindereq.radius * cylindereq.radius) )) / (a*a + b*b); let t2 = (a*c + b* d - Math.sqrt( (a*c + b*d) * (a*c + b*d) - (a*a + b*b) * (c*c + d* d - cylindereq.radius * cylindereq.radius) )) / (a*a + b*b); let dx1 = a * t1; let dy1 = b * t1; let dx2 = a * t2; let dy2 = b * t2; return dx1*dx1+ dy1*dy1 < dx2*dx2 + dy2*dy2 ? [dx1 + lineeq.point[0], dy1 + lineeq.point[1], lineeq.linevector[2]* t1 + lineeq.point[2]] : [dx2 + lineeq.point[0], dy2 + lineeq.point[1], lineeq.linevector[2]* t2 + lineeq.point[2]]; } function GetLineLength(startpos, endpos) { return Math.sqrt((endpos[0] - startpos[0])* (endpos[0] - startpos[0]) + (endpos[1] - startpos[1]) * (endpos[1] - startpos[1]) + (endpos[2] - startpos[2]) * (endpos[2] - startpos[2])); } function createShader(gl, type, source) { var shader = gl.createShader(type); gl.shaderSource(shader, source); gl.compileShader(shader); var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS); if (success) { return shader; } console.log(gl.getShaderInfoLog(shader)); gl.deleteShader(shader); } function createProgram(gl, vertexShader, fragmentShader) { var program = gl.createProgram(); gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); gl.linkProgram(program); var success = gl.getProgramParameter(program, gl.LINK_STATUS); if (success) { return program; } console.log(gl.getProgramInfoLog(program)); gl.deleteProgram(program); } function updateFieldOfView(event, value) { fieldOfViewRadians = degToRad(value); } function GenerateProjectile(pos, size, cameraMatrix) { // pos: [x, y](center), size: integer, cameraMatrix: 4x4 matrix return [ //plane 1 2*pos[0] +size* m4.getForward(cameraMatrix)[0]+size* m4.getRight(cameraMatrix)[0] + size *m4.getUp(cameraMatrix)[0], size* m4.getForward(cameraMatrix)[1]+size* m4.getRight(cameraMatrix)[1] + size *m4.getUp(cameraMatrix)[1], 2*pos[1] +size* m4.getForward(cameraMatrix)[2]+size* m4.getRight(cameraMatrix)[2] + size *m4.getUp(cameraMatrix)[2], 2*pos[0] +size* m4.getForward(cameraMatrix)[0]+size* m4.getRight(cameraMatrix)[0] - size *m4.getUp(cameraMatrix)[0], size* m4.getForward(cameraMatrix)[1]+size* m4.getRight(cameraMatrix)[1] - size *m4.getUp(cameraMatrix)[1], 2*pos[1] +size* m4.getForward(cameraMatrix)[2]+size* m4.getRight(cameraMatrix)[2] - size *m4.getUp(cameraMatrix)[2], 2*pos[0] +size* m4.getForward(cameraMatrix)[0]-size* m4.getRight(cameraMatrix)[0] - size *m4.getUp(cameraMatrix)[0], size* m4.getForward(cameraMatrix)[1]-size* m4.getRight(cameraMatrix)[1] - size *m4.getUp(cameraMatrix)[1], 2*pos[1] +size* m4.getForward(cameraMatrix)[2]-size* m4.getRight(cameraMatrix)[2] - size *m4.getUp(cameraMatrix)[2], 2*pos[0] +size* m4.getForward(cameraMatrix)[0]+size* m4.getRight(cameraMatrix)[0] + size *m4.getUp(cameraMatrix)[0], size* m4.getForward(cameraMatrix)[1]+size* m4.getRight(cameraMatrix)[1] + size *m4.getUp(cameraMatrix)[1], 2*pos[1] +size* m4.getForward(cameraMatrix)[2]+size* m4.getRight(cameraMatrix)[2] + size *m4.getUp(cameraMatrix)[2], 2*pos[0] +size* m4.getForward(cameraMatrix)[0]-size* m4.getRight(cameraMatrix)[0] - size *m4.getUp(cameraMatrix)[0], size* m4.getForward(cameraMatrix)[1]-size* m4.getRight(cameraMatrix)[1] - size *m4.getUp(cameraMatrix)[1], 2*pos[1] +size* m4.getForward(cameraMatrix)[2]-size* m4.getRight(cameraMatrix)[2] - size *m4.getUp(cameraMatrix)[2], 2*pos[0] +size* m4.getForward(cameraMatrix)[0]-size* m4.getRight(cameraMatrix)[0] + size *m4.getUp(cameraMatrix)[0], size* m4.getForward(cameraMatrix)[1]-size* m4.getRight(cameraMatrix)[1] + size *m4.getUp(cameraMatrix)[1], 2*pos[1] +size* m4.getForward(cameraMatrix)[2]-size* m4.getRight(cameraMatrix)[2] + size *m4.getUp(cameraMatrix)[2], //plane 2 2*pos[0] +size* m4.getForward(cameraMatrix)[0]-size* m4.getRight(cameraMatrix)[0] + size *m4.getUp(cameraMatrix)[0], size* m4.getForward(cameraMatrix)[1]-size* m4.getRight(cameraMatrix)[1] + size *m4.getUp(cameraMatrix)[1], 2*pos[1] +size* m4.getForward(cameraMatrix)[2]-size* m4.getRight(cameraMatrix)[2] + size *m4.getUp(cameraMatrix)[2], 2*pos[0] +size* m4.getForward(cameraMatrix)[0]-size* m4.getRight(cameraMatrix)[0] - size *m4.getUp(cameraMatrix)[0], size* m4.getForward(cameraMatrix)[1]-size* m4.getRight(cameraMatrix)[1] - size *m4.getUp(cameraMatrix)[1], 2*pos[1] +size* m4.getForward(cameraMatrix)[2]-size* m4.getRight(cameraMatrix)[2] - size *m4.getUp(cameraMatrix)[2], 2*pos[0] -size* m4.getForward(cameraMatrix)[0]-size* m4.getRight(cameraMatrix)[0] - size *m4.getUp(cameraMatrix)[0], -size* m4.getForward(cameraMatrix)[1]-size* m4.getRight(cameraMatrix)[1] - size *m4.getUp(cameraMatrix)[1], 2*pos[1] -size* m4.getForward(cameraMatrix)[2]-size* m4.getRight(cameraMatrix)[2] - size *m4.getUp(cameraMatrix)[2], 2*pos[0] +size* m4.getForward(cameraMatrix)[0]-size* m4.getRight(cameraMatrix)[0] + size *m4.getUp(cameraMatrix)[0], size* m4.getForward(cameraMatrix)[1]-size* m4.getRight(cameraMatrix)[1] + size *m4.getUp(cameraMatrix)[1], 2*pos[1] +size* m4.getForward(cameraMatrix)[2]-size* m4.getRight(cameraMatrix)[2] + size *m4.getUp(cameraMatrix)[2], 2*pos[0] -size* m4.getForward(cameraMatrix)[0]-size* m4.getRight(cameraMatrix)[0] - size *m4.getUp(cameraMatrix)[0], -size* m4.getForward(cameraMatrix)[1]-size* m4.getRight(cameraMatrix)[1] - size *m4.getUp(cameraMatrix)[1], 2*pos[1] -size* m4.getForward(cameraMatrix)[2]-size* m4.getRight(cameraMatrix)[2] - size *m4.getUp(cameraMatrix)[2], 2*pos[0] -size* m4.getForward(cameraMatrix)[0]-size* m4.getRight(cameraMatrix)[0] + size *m4.getUp(cameraMatrix)[0], -size* m4.getForward(cameraMatrix)[1]-size* m4.getRight(cameraMatrix)[1] + size *m4.getUp(cameraMatrix)[1], 2*pos[1] -size* m4.getForward(cameraMatrix)[2]-size* m4.getRight(cameraMatrix)[2] + size *m4.getUp(cameraMatrix)[2], // plane 3 2*pos[0] -size* m4.getForward(cameraMatrix)[0]-size* m4.getRight(cameraMatrix)[0] + size *m4.getUp(cameraMatrix)[0], -size* m4.getForward(cameraMatrix)[1]-size* m4.getRight(cameraMatrix)[1] + size *m4.getUp(cameraMatrix)[1], 2*pos[1] -size* m4.getForward(cameraMatrix)[2]-size* m4.getRight(cameraMatrix)[2] + size *m4.getUp(cameraMatrix)[2], 2*pos[0] -size* m4.getForward(cameraMatrix)[0]-size* m4.getRight(cameraMatrix)[0] - size *m4.getUp(cameraMatrix)[0], -size* m4.getForward(cameraMatrix)[1]-size* m4.getRight(cameraMatrix)[1] - size *m4.getUp(cameraMatrix)[1], 2*pos[1] -size* m4.getForward(cameraMatrix)[2]-size* m4.getRight(cameraMatrix)[2] - size *m4.getUp(cameraMatrix)[2], 2*pos[0] -size* m4.getForward(cameraMatrix)[0]+size* m4.getRight(cameraMatrix)[0] - size *m4.getUp(cameraMatrix)[0], -size* m4.getForward(cameraMatrix)[1]+size* m4.getRight(cameraMatrix)[1] - size *m4.getUp(cameraMatrix)[1], 2*pos[1] -size* m4.getForward(cameraMatrix)[2]+size* m4.getRight(cameraMatrix)[2] - size *m4.getUp(cameraMatrix)[2], 2*pos[0] -size* m4.getForward(cameraMatrix)[0]-size* m4.getRight(cameraMatrix)[0] + size *m4.getUp(cameraMatrix)[0], -size* m4.getForward(cameraMatrix)[1]-size* m4.getRight(cameraMatrix)[1] + size *m4.getUp(cameraMatrix)[1], 2*pos[1] -size* m4.getForward(cameraMatrix)[2]-size* m4.getRight(cameraMatrix)[2] + size *m4.getUp(cameraMatrix)[2], 2*pos[0] -size* m4.getForward(cameraMatrix)[0]+size* m4.getRight(cameraMatrix)[0] - size *m4.getUp(cameraMatrix)[0], -size* m4.getForward(cameraMatrix)[1]+size* m4.getRight(cameraMatrix)[1] - size *m4.getUp(cameraMatrix)[1], 2*pos[1] -size* m4.getForward(cameraMatrix)[2]+size* m4.getRight(cameraMatrix)[2] - size *m4.getUp(cameraMatrix)[2], 2*pos[0] -size* m4.getForward(cameraMatrix)[0]+size* m4.getRight(cameraMatrix)[0] + size *m4.getUp(cameraMatrix)[0], -size* m4.getForward(cameraMatrix)[1]+size* m4.getRight(cameraMatrix)[1] + size *m4.getUp(cameraMatrix)[1], 2*pos[1] -size* m4.getForward(cameraMatrix)[2]+size* m4.getRight(cameraMatrix)[2] + size *m4.getUp(cameraMatrix)[2], // plane 4 2*pos[0] -size* m4.getForward(cameraMatrix)[0]+size* m4.getRight(cameraMatrix)[0] + size *m4.getUp(cameraMatrix)[0], -size* m4.getForward(cameraMatrix)[1]+size* m4.getRight(cameraMatrix)[1] + size *m4.getUp(cameraMatrix)[1], 2*pos[1] -size* m4.getForward(cameraMatrix)[2]+size* m4.getRight(cameraMatrix)[2] + size *m4.getUp(cameraMatrix)[2], 2*pos[0] -size* m4.getForward(cameraMatrix)[0]+size* m4.getRight(cameraMatrix)[0] - size *m4.getUp(cameraMatrix)[0], -size* m4.getForward(cameraMatrix)[1]+size* m4.getRight(cameraMatrix)[1] - size *m4.getUp(cameraMatrix)[1], 2*pos[1] -size* m4.getForward(cameraMatrix)[2]+size* m4.getRight(cameraMatrix)[2] - size *m4.getUp(cameraMatrix)[2], 2*pos[0] +size* m4.getForward(cameraMatrix)[0]+size* m4.getRight(cameraMatrix)[0] - size *m4.getUp(cameraMatrix)[0], size* m4.getForward(cameraMatrix)[1]+size* m4.getRight(cameraMatrix)[1] - size *m4.getUp(cameraMatrix)[1], 2*pos[1] +size* m4.getForward(cameraMatrix)[2]+size* m4.getRight(cameraMatrix)[2] - size *m4.getUp(cameraMatrix)[2], 2*pos[0] -size* m4.getForward(cameraMatrix)[0]+size* m4.getRight(cameraMatrix)[0] + size *m4.getUp(cameraMatrix)[0], -size* m4.getForward(cameraMatrix)[1]+size* m4.getRight(cameraMatrix)[1] + size *m4.getUp(cameraMatrix)[1], 2*pos[1] -size* m4.getForward(cameraMatrix)[2]+size* m4.getRight(cameraMatrix)[2] + size *m4.getUp(cameraMatrix)[2], 2*pos[0] +size* m4.getForward(cameraMatrix)[0]+size* m4.getRight(cameraMatrix)[0] - size *m4.getUp(cameraMatrix)[0], size* m4.getForward(cameraMatrix)[1]+size* m4.getRight(cameraMatrix)[1] - size *m4.getUp(cameraMatrix)[1], 2*pos[1] +size* m4.getForward(cameraMatrix)[2]+size* m4.getRight(cameraMatrix)[2] - size *m4.getUp(cameraMatrix)[2], 2*pos[0] +size* m4.getForward(cameraMatrix)[0]+size* m4.getRight(cameraMatrix)[0] + size *m4.getUp(cameraMatrix)[0], size* m4.getForward(cameraMatrix)[1]+size* m4.getRight(cameraMatrix)[1] + size *m4.getUp(cameraMatrix)[1], 2*pos[1] +size* m4.getForward(cameraMatrix)[2]+size* m4.getRight(cameraMatrix)[2] + size *m4.getUp(cameraMatrix)[2] ]; } function GeneratePlaneVertex(pos, size, cameraMatrix) { // pos: [x, y](center), size: integer, height: interger, cameraMatrix: 4x4 matrix return [ //plane 2*pos[0] +size* m4.getForward(cameraMatrix)[0]+size* m4.getRight(cameraMatrix)[0] + size *m4.getUp(cameraMatrix)[0], size* m4.getForward(cameraMatrix)[1]+size* m4.getRight(cameraMatrix)[1] + size *m4.getUp(cameraMatrix)[1], 2*pos[1] +size* m4.getForward(cameraMatrix)[2]+size* m4.getRight(cameraMatrix)[2] + size *m4.getUp(cameraMatrix)[2], 2*pos[0] +size* m4.getForward(cameraMatrix)[0]+size* m4.getRight(cameraMatrix)[0] - size *m4.getUp(cameraMatrix)[0], size* m4.getForward(cameraMatrix)[1]+size* m4.getRight(cameraMatrix)[1] - size *m4.getUp(cameraMatrix)[1], 2*pos[1] +size* m4.getForward(cameraMatrix)[2]+size* m4.getRight(cameraMatrix)[2] - size *m4.getUp(cameraMatrix)[2], 2*pos[0] +size* m4.getForward(cameraMatrix)[0]-size* m4.getRight(cameraMatrix)[0] - size *m4.getUp(cameraMatrix)[0], size* m4.getForward(cameraMatrix)[1]-size* m4.getRight(cameraMatrix)[1] - size *m4.getUp(cameraMatrix)[1], 2*pos[1] +size* m4.getForward(cameraMatrix)[2]-size* m4.getRight(cameraMatrix)[2] - size *m4.getUp(cameraMatrix)[2], 2*pos[0] +size* m4.getForward(cameraMatrix)[0]+size* m4.getRight(cameraMatrix)[0] + size *m4.getUp(cameraMatrix)[0], size* m4.getForward(cameraMatrix)[1]+size* m4.getRight(cameraMatrix)[1] + size *m4.getUp(cameraMatrix)[1], 2*pos[1] +size* m4.getForward(cameraMatrix)[2]+size* m4.getRight(cameraMatrix)[2] + size *m4.getUp(cameraMatrix)[2], 2*pos[0] +size* m4.getForward(cameraMatrix)[0]-size* m4.getRight(cameraMatrix)[0] - size *m4.getUp(cameraMatrix)[0], size* m4.getForward(cameraMatrix)[1]-size* m4.getRight(cameraMatrix)[1] - size *m4.getUp(cameraMatrix)[1], 2*pos[1] +size* m4.getForward(cameraMatrix)[2]-size* m4.getRight(cameraMatrix)[2] - size *m4.getUp(cameraMatrix)[2], 2*pos[0] +size* m4.getForward(cameraMatrix)[0]-size* m4.getRight(cameraMatrix)[0] + size *m4.getUp(cameraMatrix)[0], size* m4.getForward(cameraMatrix)[1]-size* m4.getRight(cameraMatrix)[1] + size *m4.getUp(cameraMatrix)[1], 2*pos[1] +size* m4.getForward(cameraMatrix)[2]-size* m4.getRight(cameraMatrix)[2] + size *m4.getUp(cameraMatrix)[2], //plane 2 2*pos[0] +size* m4.getForward(cameraMatrix)[0]-size* m4.getRight(cameraMatrix)[0] + size *m4.getUp(cameraMatrix)[0], size* m4.getForward(cameraMatrix)[1]-size* m4.getRight(cameraMatrix)[1] + size *m4.getUp(cameraMatrix)[1], 2*pos[1] +size* m4.getForward(cameraMatrix)[2]-size* m4.getRight(cameraMatrix)[2] + size *m4.getUp(cameraMatrix)[2], 2*pos[0] +size* m4.getForward(cameraMatrix)[0]-size* m4.getRight(cameraMatrix)[0] - size *m4.getUp(cameraMatrix)[0], size* m4.getForward(cameraMatrix)[1]-size* m4.getRight(cameraMatrix)[1] - size *m4.getUp(cameraMatrix)[1], 2*pos[1] +size* m4.getForward(cameraMatrix)[2]-size* m4.getRight(cameraMatrix)[2] - size *m4.getUp(cameraMatrix)[2], 2*pos[0] -size* m4.getForward(cameraMatrix)[0]-size* m4.getRight(cameraMatrix)[0] - size *m4.getUp(cameraMatrix)[0], -size* m4.getForward(cameraMatrix)[1]-size* m4.getRight(cameraMatrix)[1] - size *m4.getUp(cameraMatrix)[1], 2*pos[1] -size* m4.getForward(cameraMatrix)[2]-size* m4.getRight(cameraMatrix)[2] - size *m4.getUp(cameraMatrix)[2], 2*pos[0] +size* m4.getForward(cameraMatrix)[0]-size* m4.getRight(cameraMatrix)[0] + size *m4.getUp(cameraMatrix)[0], size* m4.getForward(cameraMatrix)[1]-size* m4.getRight(cameraMatrix)[1] + size *m4.getUp(cameraMatrix)[1], 2*pos[1] +size* m4.getForward(cameraMatrix)[2]-size* m4.getRight(cameraMatrix)[2] + size *m4.getUp(cameraMatrix)[2], 2*pos[0] -size* m4.getForward(cameraMatrix)[0]-size* m4.getRight(cameraMatrix)[0] - size *m4.getUp(cameraMatrix)[0], -size* m4.getForward(cameraMatrix)[1]-size* m4.getRight(cameraMatrix)[1] - size *m4.getUp(cameraMatrix)[1], 2*pos[1] -size* m4.getForward(cameraMatrix)[2]-size* m4.getRight(cameraMatrix)[2] - size *m4.getUp(cameraMatrix)[2], 2*pos[0] -size* m4.getForward(cameraMatrix)[0]-size* m4.getRight(cameraMatrix)[0] + size *m4.getUp(cameraMatrix)[0], -size* m4.getForward(cameraMatrix)[1]-size* m4.getRight(cameraMatrix)[1] + size *m4.getUp(cameraMatrix)[1], 2*pos[1] -size* m4.getForward(cameraMatrix)[2]-size* m4.getRight(cameraMatrix)[2] + size *m4.getUp(cameraMatrix)[2], // plane 3 2*pos[0] -size* m4.getForward(cameraMatrix)[0]-size* m4.getRight(cameraMatrix)[0] + size *m4.getUp(cameraMatrix)[0], -size* m4.getForward(cameraMatrix)[1]-size* m4.getRight(cameraMatrix)[1] + size *m4.getUp(cameraMatrix)[1], 2*pos[1] -size* m4.getForward(cameraMatrix)[2]-size* m4.getRight(cameraMatrix)[2] + size *m4.getUp(cameraMatrix)[2], 2*pos[0] -size* m4.getForward(cameraMatrix)[0]-size* m4.getRight(cameraMatrix)[0] - size *m4.getUp(cameraMatrix)[0], -size* m4.getForward(cameraMatrix)[1]-size* m4.getRight(cameraMatrix)[1] - size *m4.getUp(cameraMatrix)[1], 2*pos[1] -size* m4.getForward(cameraMatrix)[2]-size* m4.getRight(cameraMatrix)[2] - size *m4.getUp(cameraMatrix)[2], 2*pos[0] -size* m4.getForward(cameraMatrix)[0]+size* m4.getRight(cameraMatrix)[0] - size *m4.getUp(cameraMatrix)[0], -size* m4.getForward(cameraMatrix)[1]+size* m4.getRight(cameraMatrix)[1] - size *m4.getUp(cameraMatrix)[1], 2*pos[1] -size* m4.getForward(cameraMatrix)[2]+size* m4.getRight(cameraMatrix)[2] - size *m4.getUp(cameraMatrix)[2], 2*pos[0] -size* m4.getForward(cameraMatrix)[0]-size* m4.getRight(cameraMatrix)[0] + size *m4.getUp(cameraMatrix)[0], -size* m4.getForward(cameraMatrix)[1]-size* m4.getRight(cameraMatrix)[1] + size *m4.getUp(cameraMatrix)[1], 2*pos[1] -size* m4.getForward(cameraMatrix)[2]-size* m4.getRight(cameraMatrix)[2] + size *m4.getUp(cameraMatrix)[2], 2*pos[0] -size* m4.getForward(cameraMatrix)[0]+size* m4.getRight(cameraMatrix)[0] - size *m4.getUp(cameraMatrix)[0], -size* m4.getForward(cameraMatrix)[1]+size* m4.getRight(cameraMatrix)[1] - size *m4.getUp(cameraMatrix)[1], 2*pos[1] -size* m4.getForward(cameraMatrix)[2]+size* m4.getRight(cameraMatrix)[2] - size *m4.getUp(cameraMatrix)[2], 2*pos[0] -size* m4.getForward(cameraMatrix)[0]+size* m4.getRight(cameraMatrix)[0] + size *m4.getUp(cameraMatrix)[0], -size* m4.getForward(cameraMatrix)[1]+size* m4.getRight(cameraMatrix)[1] + size *m4.getUp(cameraMatrix)[1], 2*pos[1] -size* m4.getForward(cameraMatrix)[2]+size* m4.getRight(cameraMatrix)[2] + size *m4.getUp(cameraMatrix)[2], // plane 4 2*pos[0] -size* m4.getForward(cameraMatrix)[0]+size* m4.getRight(cameraMatrix)[0] + size *m4.getUp(cameraMatrix)[0], -size* m4.getForward(cameraMatrix)[1]+size* m4.getRight(cameraMatrix)[1] + size *m4.getUp(cameraMatrix)[1], 2*pos[1] -size* m4.getForward(cameraMatrix)[2]+size* m4.getRight(cameraMatrix)[2] + size *m4.getUp(cameraMatrix)[2], 2*pos[0] -size* m4.getForward(cameraMatrix)[0]+size* m4.getRight(cameraMatrix)[0] - size *m4.getUp(cameraMatrix)[0], -size* m4.getForward(cameraMatrix)[1]+size* m4.getRight(cameraMatrix)[1] - size *m4.getUp(cameraMatrix)[1], 2*pos[1] -size* m4.getForward(cameraMatrix)[2]+size* m4.getRight(cameraMatrix)[2] - size *m4.getUp(cameraMatrix)[2], 2*pos[0] +size* m4.getForward(cameraMatrix)[0]+size* m4.getRight(cameraMatrix)[0] - size *m4.getUp(cameraMatrix)[0], size* m4.getForward(cameraMatrix)[1]+size* m4.getRight(cameraMatrix)[1] - size *m4.getUp(cameraMatrix)[1], 2*pos[1] +size* m4.getForward(cameraMatrix)[2]+size* m4.getRight(cameraMatrix)[2] - size *m4.getUp(cameraMatrix)[2], 2*pos[0] -size* m4.getForward(cameraMatrix)[0]+size* m4.getRight(cameraMatrix)[0] + size *m4.getUp(cameraMatrix)[0], -size* m4.getForward(cameraMatrix)[1]+size* m4.getRight(cameraMatrix)[1] + size *m4.getUp(cameraMatrix)[1], 2*pos[1] -size* m4.getForward(cameraMatrix)[2]+size* m4.getRight(cameraMatrix)[2] + size *m4.getUp(cameraMatrix)[2], 2*pos[0] +size* m4.getForward(cameraMatrix)[0]+size* m4.getRight(cameraMatrix)[0] - size *m4.getUp(cameraMatrix)[0], size* m4.getForward(cameraMatrix)[1]+size* m4.getRight(cameraMatrix)[1] - size *m4.getUp(cameraMatrix)[1], 2*pos[1] +size* m4.getForward(cameraMatrix)[2]+size* m4.getRight(cameraMatrix)[2] - size *m4.getUp(cameraMatrix)[2], 2*pos[0] +size* m4.getForward(cameraMatrix)[0]+size* m4.getRight(cameraMatrix)[0] + size *m4.getUp(cameraMatrix)[0], size* m4.getForward(cameraMatrix)[1]+size* m4.getRight(cameraMatrix)[1] + size *m4.getUp(cameraMatrix)[1], 2*pos[1] +size* m4.getForward(cameraMatrix)[2]+size* m4.getRight(cameraMatrix)[2] + size *m4.getUp(cameraMatrix)[2] ]; } // ------------------------------------------------ input control ------------------------------------------------ let keystate = []; function Input(screen) { this.screen = screen; this.target; this.keyboardinputtimer; this.havePointerLock = 'pointerLockElement' in document || 'mozPointerLockElement' in document || 'webkitPointerLockElement' in document; this.InitInput = () => { if (this.havePointerLock){ this.screen.onclick = () => { // requestPointerLock must be in callback this.screen.requestPointerLock = this.screen.requestPointerLock || this.screen.mozRequestPointerLock || this.screen.webkitRequestPointerLock; // Ask the browser to lock the pointer this.screen.requestPointerLock(); } // Hook pointer lock state change events document.addEventListener('pointerlockchange', this.changeCallback, false); document.addEventListener('mozpointerlockchange', this.changeCallback, false); document.addEventListener('webkitpointerlockchange', this.changeCallback, false); document.addEventListener('pointerlockerror', this.errorCallback, false); document.addEventListener('mozpointerlockerror', this.errorCallback, false); document.addEventListener('webkitpointerlockerror', this.errorCallback, false); } return; } // ----------------------mouse management---------------------------------- this.GrabInput = (target) => { this.target = target; this.keyboardinputtimer = setInterval(this.target.moveSomething, 10); return; }; this.manageKeyboardInputDown = () => { if (event.keyCode === 65 || event.keyCode === 97) //a keystate[0] = true; if (event.keyCode === 68 || event.keyCode === 100) //d keystate[1] = true; if (event.keyCode === 83 || event.keyCode === 115) //s keystate[2] = true; if (event.keyCode === 87 || event.keyCode === 119) // w keystate[3] = true; if (event.keyCode === 81 || event.keyCode === 113) // q keystate[4] = true; if (event.keyCode === 69 || event.keyCode === 101) //e keystate[5] = true; if (event.keyCode === 82 || event.keyCode === 114) //r keystate[6] = true; if (event.keyCode === 70 || event.keyCode === 102) // f keystate[7] = true; }; this.manageKeyboardInputUp = () => { if (event.keyCode === 65 || event.keyCode === 97) // a keystate[0] = false; if (event.keyCode === 68 || event.keyCode === 100) //d keystate[1] = false; if (event.keyCode === 83 || event.keyCode === 115) //s keystate[2] = false; if (event.keyCode === 87 || event.keyCode === 119) //w keystate[3] = false; if (event.keyCode === 81 || event.keyCode === 113) //q keystate[4] = false; if (event.keyCode === 69 || event.keyCode === 101) //e keystate[5] = false; if (event.keyCode === 82 || event.keyCode === 114) //r keystate[6] = false; if (event.keyCode === 70 || event.keyCode === 102) // f keystate[7] = false; }; this.errorCallback = (e) => { alert( "Fail to initialize point lock process" ); } this.moveCallback = (e) => { let movementX = 0; let movementY = 0; movementX = e.movementX || e.mozMovementX || e.webkitMovementX || 0, movementY = e.movementY || e.mozMovementY || e.webkitMovementY || 0; if (this.target != undefined) { this.target.direction = this.target.direction + degToRad(movementX); ws.send(JSON.stringify({ type:5, id: this.target.playerID, pos: this.target.pos, direction: this.target.direction })); } } this.ReleasePlayer = () => { clearInterval(this.keyboardinputtimer); return; } this.changeCallback = (e) => { if (document.pointerLockElement === this.screen || document.mozPointerLockElement === this.screen || document.webkitPointerLockElement === this.screen) { // Pointer was just locked // Enable the mousemove listener document.addEventListener("mousemove", this.moveCallback); document.addEventListener("keydown", this.manageKeyboardInputDown); document.addEventListener("keyup", this.manageKeyboardInputUp); document.onmousedown = () => { switch(event.button) { case 0: this.target.FireWeapon(); break; case 2: this.target.DoSpecialSkill(); break; default: break; } } document.onmouseup = () => { if (event.button === 0) this.target.ReleaseFire(); return; } } else { // Disable the mousemove listener document.removeEventListener("mousemove", this.moveCallback); document.removeEventListener("keydown", this.manageKeyboardInputDown); document.removeEventListener("keyup", this.manageKeyboardInputUp); document.onmousedown = () => { return; } document.onmouseup = () => { return; } } } } // ------------------------------------------ Engine Main ---------------------------------------------- let mapdataurl = "http://libertyga.me/index.php?title=%EC%82%AC%EC%9A%A9%EC%9E%90:Senouis/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8/%ED%85%8C%EC%8A%A4%ED%8A%B8%EB%A7%B5&action=raw"; let mapinfo; // map information object let player; let gamerule; function EngineMain() { // init player player = new Player([0, 0], 8, degToRad(0), 1); gamerule = new GameRule(0, 0, 0); // ----------------------------Procedure Start-------------------------------- // Get A WebGL context let canvas = document.getElementById("MainCanvas"); let gl = canvas.getContext("webgl"); if (!gl) { return; } // setup GLSL program let vertexshader = createShader(gl, gl.VERTEX_SHADER, document.getElementById("3d-vertex-shader").text); let fragmentshader = createShader(gl, gl.FRAGMENT_SHADER, document.getElementById("3d-fragment-shader").text); let program = createProgram(gl, vertexshader, fragmentshader); let planevertexshader = createShader(gl, gl.VERTEX_SHADER, document.getElementById("2d-vertex-shader").text); let planefragmentshader = createShader(gl, gl.FRAGMENT_SHADER, document.getElementById("2d-fragment-shader").text); let textureprogram = createProgram(gl, planevertexshader, planefragmentshader); // load map data mapinfo = new MapInfo ("25 45 1\n\ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n\ AFFFFFPFFFFFFFFFFFFAFFFFFFFFFAFFFFFFFFFFFFFFW\n\ AFFFFFPFFFFFFFFFFFFWFFFFFFFFFWFFFFFFFFFFFFFFW\n\ AFFRFFAAAFFFFFFFFFFFFFFFFFFFFFFFFFFFAAAAAFFFW\n\ AFFFFHAFFFFFFFFFFFFWFFFFHFFFFWFFFFFFFFFFWFFFW\n\ AFFFHHAFFFFFFFFWAAAAAAAAAAAAAWFFFFFFFFFFWFFFW\n\ AIIAAAAFFFFFFFFFFFFFFFFFFFFFFWFFFFFFFFFFWFFFW\n\ AFFAFFFFFFFFFFFWFFFAAAAAAAFFFWWWWWWFFFFFWFFFW\n\ AFFAFFFFFFFAAAAWFFFFFFFFFFFFFFFFFFFFFFFFFFFFW\n\ AFFFFFFFFFFFFFFWFFFFFFFFFFFFFFFFFFFFFFFFFFFFW\n\ AFFFFFFFFFFFFFFWWWWWFFFFFWWWFFFFFFAWWWWHFFFFW\n\ WWWWFFFFFFAFFFFFFWFFFFFFFFFWFFFFFFAFFFFFFFFFW\n\ WFFFFFFFFFAFFFFFFFFFFFTFFFFFFFFFFFQFFFFFFFFFW\n\ WFFFFFFFFFQFFFFFFWFFFFFFFFFWFFFFFFQFFFFFFWWWW\n\ WFFFFHWWWWQFFFFFFWWWFFFFFWWWWWFFFFFFFFFFFFFFQ\n\ WFFFFFFFFFFFFFFFFFFFFFFFFFFFFWFFFFFFFFFFFFFFQ\n\ WFFFFFFFFFFFFFFFFFFFFFFFFFFFFWQQQQFFFFFFFQFFQ\n\ WFFFWFFFFFWWWWWWFFFQQQQQQQFFFWFFFFFFFFFFFQFFQ\n\ WFFFWFFFFFFFFFFWFFFFFFFFFFFFFFFFFFFFFFQQQQZZQ\n\ WFFFWFFFFFFFFFFWQQQQQQQQQQQQQWFFFFFFFFQHHFFFQ\n\ WFFFWFFFFFFFFFFWFFFFHFFFFWFFFFFFFFFFFFQHFFFFQ\n\ WFFFQQQQQFFFFFFFFFFFFFFFFFFFFFFFFFFFQQQFFBFFQ\n\ WFFFFFFFFFFFFFFWFFFFFFFFFWFFFFFFFFFFFFCFFFFFQ\n\ WFFFFFFFFFFFFFFQFFFFFFFFFQFFFFFFFFFFFFCFFFFFQ\n\ QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ"); ProcedureAfterMapDataload(); DoSomethingAfterMapLoad(); // ----------------------Procedure End-------------------------------------- //---------------------------------- function used inside the procedure ----------------------------------------- function ProcedureAfterMapDataload () { // -------------------------- initialize web socket ---------------------------------------- ws = new WebSocket("ws://" + ip ); ws.addEventListener("error" , function() { alert("Failed to connect to server..."); }) ws.addEventListener("open", function() { }); ws.addEventListener("message", messageHandler); ws.addEventListener("close", closeHandler); //------------------------ get attribute from 3D Shader program ---------------------------- // look up where the vertex, color data needs to go. var positionLocation = gl.getAttribLocation(program, "a_position"); let colorLocation = gl.getAttribLocation(program, "a_color"); // lookup uniforms var matrixLocation = gl.getUniformLocation(program, "u_matrix"); //------------------------ get attribute from 2D Shader program ---------------------------- // look up where the vertex, color data needs to go. let texpositionLocation = gl.getAttribLocation(textureprogram, "a_position"); let texcoordLocation = gl.getAttribLocation(textureprogram, "a_texcoord"); // lookup uniforms let texmatrixLocation = gl.getUniformLocation(textureprogram, "u_matrix"); let textureLocation = gl.getUniformLocation(textureprogram, "u_texture"); // ----------------------- Create Buffer ------------------------------ let positionBuffer = gl.createBuffer(); // Put geometry data into buffer gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); setMapGeometry(gl, mapinfo); // Put color data into buffer let colorBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); setMapColors(gl, mapinfo); // Put coordinate for texture let texcoordBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer); let texcoords = new Array(2* 6 * 32* MAX_PROJECTILE_PER_PLAYER); gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(texcoords), gl.STATIC_DRAW); var tex = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, tex); let img = new Image(); img.src = "https://static.miraheze.org/libertygamewiki/7/7e/UF_Rocket_Red.png"; img.crossOrigin = "anonymous"; img.addEventListener('load', function() { gl.bindTexture(gl.TEXTURE_2D, tex); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); }); let redplayertex = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, redplayertex); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([255, 0, 0, 255])); let redplayerimg = new Image(); redplayerimg.src = "https://static.miraheze.org/libertygamewiki/c/c7/UF_Player_Red.png"; redplayerimg.crossOrigin = "anonymous"; redplayerimg.addEventListener('load', function() { gl.bindTexture(gl.TEXTURE_2D, redplayertex); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, redplayerimg); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); }); let blueplayertex = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, blueplayertex); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([0, 0, 255, 255])); let blueplayerimg = new Image(); blueplayerimg.src = "https://static.miraheze.org/libertygamewiki/d/d7/UF_Player_Blue.png"; blueplayerimg.crossOrigin = "anonymous"; blueplayerimg.addEventListener('load', function() { gl.bindTexture(gl.TEXTURE_2D, blueplayertex); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, blueplayerimg); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); }); // dead image let redplayerdeadtex = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, redplayerdeadtex); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([255, 0, 0, 255])); let redplayerdeadimg = new Image(); redplayerdeadimg.src = "https://static.miraheze.org/libertygamewiki/f/f4/UF_Player_Dead_Red.png"; redplayerdeadimg.crossOrigin = "anonymous"; redplayerdeadimg.addEventListener('load', function() { gl.bindTexture(gl.TEXTURE_2D, redplayerdeadtex); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, redplayerdeadimg); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); }); let blueplayerdeadtex = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, blueplayerdeadtex); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([0, 0, 255, 255])); let blueplayerdeadimg = new Image(); blueplayerdeadimg.crossOrigin = "anonymous"; blueplayerdeadimg.src = "https://static.miraheze.org/libertygamewiki/6/6a/UF_Player_Dead_Blue.png"; blueplayerdeadimg.addEventListener('load', function() { gl.bindTexture(gl.TEXTURE_2D, blueplayerdeadtex); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, blueplayerdeadimg); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); }); let explosiontex = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, explosiontex); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([0, 0, 255, 255])); let explosionimg = new Image(); explosionimg.src = "https://static.miraheze.org/libertygamewiki/f/f0/UF_Explosion.png"; explosionimg.crossOrigin = "anonymous"; explosionimg.addEventListener('load', function() { gl.bindTexture(gl.TEXTURE_2D, explosiontex); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, explosionimg); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); }); var healthkittex = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, healthkittex); let healthkitimg = new Image(); healthkitimg.src = "https://static.miraheze.org/libertygamewiki/4/46/UF_Healthkit.png"; healthkitimg.crossOrigin = "anonymous"; healthkitimg.addEventListener('load', function() { gl.bindTexture(gl.TEXTURE_2D, healthkittex); gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, healthkitimg); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); }); // Draw screen requestAnimationFrame(drawScene); // Draw the scene. function drawScene() { // Tell WebGL how to convert from clip space to pixels gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); gl.enable(gl.CULL_FACE); gl.enable(gl.BLEND); gl.enable(gl.DEPTH_TEST); gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); // Clear the canvas. gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); // Tell it to use our program (pair of shaders) gl.useProgram(program); // Turn on the attribute gl.enableVertexAttribArray(positionLocation); gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); // Tell the attribute how to get data out of positionBuffer (ARRAY_BUFFER) var size = 3; // 3 components per iteration var type = gl.FLOAT; // the data is 32bit floats var normalize = false; // don't normalize the data var stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position var offset = 0; // start at the beginning of the buffer gl.vertexAttribPointer( positionLocation, size, type, normalize, stride, offset); // Turn on the color attribute gl.enableVertexAttribArray(colorLocation); gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); // Tell the attribute how to get data out of colorBuffer (ARRAY_BUFFER) var size = 3; // 3 components per iteration var type = gl.UNSIGNED_BYTE; // the data is 8bit unsigned values var normalize = true; // normalize the data (convert from 0-255 to 0-1) var stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position var offset = 0; // start at the beginning of the buffer gl.vertexAttribPointer(colorLocation, size, type, normalize, stride, offset); // Compute the matrix var aspect = gl.canvas.clientWidth / gl.canvas.clientHeight; var zNear = 1; var zFar = 10000; var projectionMatrix = m4.perspective(fieldOfViewRadians, aspect, zNear, zFar); projectionMatrix = m4.xRotate(projectionMatrix, player.rotation[0]); projectionMatrix = m4.yRotate(projectionMatrix, player.rotation[1]); projectionMatrix = m4.zRotate(projectionMatrix, player.rotation[2]); projectionMatrix = m4.scale(projectionMatrix, player.scale[0], player.scale[1], player.scale[2]); // Compute a matrix for the camera player.cameraMatrix = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; player.cameraMatrix = m4.yRotation(player.direction); player.cameraMatrix = m4.translate(player.cameraMatrix, -player.GetCenterPosition()[0], player.height, -player.GetCenterPosition()[1]); // Compute a view projection matrix var viewProjectionMatrix = m4.multiply(projectionMatrix, player.cameraMatrix); var matrix = m4.translate(viewProjectionMatrix, -player.GetCenterPosition()[0], player.height, -player.GetCenterPosition()[1]); // Set the matrix. gl.uniformMatrix4fv(matrixLocation, false, matrix); // --------------------------------------------------------draw!!!!------------------------------------------------- // Draw map objects // Bind it to ARRAY_BUFFER (think of it as ARRAY_BUFFER = positionBuffer) offset = 0; var count = (2+mapinfo.mapwallcounter) * 6; gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); let tempArray = mapinfo.polygons; let polygonArray = new Float32Array(tempArray); gl.bufferSubData(gl.ARRAY_BUFFER, 0, polygonArray); // Bind the color buffer. gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); tempArray = mapinfo.mapColors; let mapColorArray = new Uint8Array( tempArray ); gl.bufferSubData(gl.ARRAY_BUFFER, 0, mapColorArray); gl.drawArrays(gl.TRIANGLES, offset, count); // Draw rays for (let playeritem of playerlist) { for (let ray of playeritem.raylist) { if (playeritem.raylist.indexOf(ray) > 10) continue; else if (ray.visible) { tempArray = []; gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); tempArray = tempArray.concat([2*ray.startpos[0], ray.startpos[2], 2*ray.startpos[1]]); tempArray = tempArray.concat([2*ray.endpos[0], 0, 2*ray.endpos[1]]); polygonArray = new Float32Array(tempArray); gl.bufferSubData(gl.ARRAY_BUFFER, 0, polygonArray); gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer); tempArray =[255, 255, 0, 255, 255, 0]; mapColorArray = new Uint8Array( tempArray ); gl.bufferSubData(gl.ARRAY_BUFFER, 0, mapColorArray); // we have already set the matrix, so directly draw gl.drawArrays(gl.LINES, 0, 2); } } } // Draw projectiles // Tell WebGL to use our shader program pair gl.useProgram(textureprogram); gl.enableVertexAttribArray(texpositionLocation); gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); // Tell the attribute how to get data out of positionBuffer (ARRAY_BUFFER) var size = 3; // 3 components per iteration var type = gl.FLOAT; // the data is 32bit floats var normalize = false; // don't normalize the data var stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position var offset = 0; // start at the current position gl.vertexAttribPointer( texpositionLocation, size, type, normalize, stride, offset); // Setup the attributes to pull data from our buffers gl.enableVertexAttribArray(texcoordLocation); gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer); gl.vertexAttribPointer(texcoordLocation, 2, gl.FLOAT, false, 0, 0); // fill the polygon buffer gl.bindTexture(gl.TEXTURE_2D, tex); gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); tempArray = []; count = 0; for (let proj of projectilelist) { tempArray = tempArray.concat(proj.vertexlist); count += 4*6; } polygonArray = new Float32Array(tempArray); gl.bufferSubData(gl.ARRAY_BUFFER, 0, polygonArray); // Tell the shader to get the texture from texture unit 0 gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer); tempArray = []; for (let proj of projectilelist) { tempArray = tempArray.concat([0.5, 0, 0.5, 0.5, 1, 0.5, 0.5, 0, 1, 0.5, 1, 0]); tempArray = tempArray.concat([0.5, 0.5, 0.5, 1.0, 1, 1, 0.5, 0.5, 1, 1, 1, 0.5]); tempArray = tempArray.concat([0, 0, 0.5, 0, 0, 0.5, 0, 0.5, 0.5, 0, 0.5, 0.5]); tempArray = tempArray.concat([0, 0.5, 0, 1, 0.5, 1, 0, 0.5, 0.5, 1, 0.5, 0.5]); } let texcoordinates = new Float32Array( tempArray ); gl.bufferSubData(gl.ARRAY_BUFFER, 0, texcoordinates); // Set the matrix. gl.uniformMatrix4fv(texmatrixLocation, false, matrix); gl.uniform1i(textureLocation, 0); gl.drawArrays(gl.TRIANGLES, 0, count); // Draw Player for (let playeritem of playerlist) { if (playeritem.playerID === player.playerID) continue; tempArray = []; count = 4*6; // vertex if (playeritem.team === 1) { if (playeritem.isdead) gl.bindTexture(gl.TEXTURE_2D, redplayerdeadtex); else gl.bindTexture(gl.TEXTURE_2D, redplayertex); } else { if (playeritem.isdead) gl.bindTexture(gl.TEXTURE_2D, blueplayerdeadtex); else gl.bindTexture(gl.TEXTURE_2D, blueplayertex); } gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); playeritem.vertexlist = GeneratePlaneVertex(playeritem.GetCenterPosition(), 32, m4.lookAt([playeritem.GetCenterPosition()[0], playeritem.height, playeritem.GetCenterPosition()[1]], [player.GetCenterPosition()[0], player.height, player.GetCenterPosition()[1]], up)); tempArray = tempArray.concat(playeritem.vertexlist); polygonArray = new Float32Array(tempArray); gl.bufferSubData(gl.ARRAY_BUFFER, 0, polygonArray); // texture coordinate gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer); tempArray = []; if (radToDeg(playeritem.direction - player.direction) % 360 >= 315 || ( radToDeg(playeritem.direction - player.direction) % 360 >= -45 && radToDeg(playeritem.direction - player.direction) % 360 < 45 ) || radToDeg(playeritem.direction - player.direction) % 360 < -315 ) { tempArray = tempArray.concat([0.5, 0, 0.5, 0.5, 1, 0.5, 0.5, 0, 1, 0.5, 1, 0]); tempArray = tempArray.concat([0.5, 0, 0.5, 0.5, 1, 0.5, 0.5, 0, 1, 0.5, 1, 0]); tempArray = tempArray.concat([0.5, 0, 0.5, 0.5, 1, 0.5, 0.5, 0, 1, 0.5, 1, 0]); tempArray = tempArray.concat([0.5, 0, 0.5, 0.5, 1, 0.5, 0.5, 0, 1, 0.5, 1, 0]); } else if ((radToDeg(playeritem.direction - player.direction) % 360 >= 45 && radToDeg(playeritem.direction - player.direction) % 360 < 135) ||(radToDeg(playeritem.direction - player.direction) % 360 < -225 && radToDeg(playeritem.direction - player.direction) % 360 >= -315)) { tempArray = tempArray.concat([0, 0.5, 0, 1, 0.5, 1, 0, 0.5, 0.5, 1, 0.5, 0.5]); tempArray = tempArray.concat([0, 0.5, 0, 1, 0.5, 1, 0, 0.5, 0.5, 1, 0.5, 0.5]); tempArray = tempArray.concat([0, 0.5, 0, 1, 0.5, 1, 0, 0.5, 0.5, 1, 0.5, 0.5]); tempArray = tempArray.concat([0, 0.5, 0, 1, 0.5, 1, 0, 0.5, 0.5, 1, 0.5, 0.5]); } else if ((radToDeg(playeritem.direction - player.direction) % 360 >= 135 && radToDeg(playeritem.direction - player.direction) % 360 < 225) || (radToDeg(playeritem.direction - player.direction) % 360 < -135 && radToDeg(playeritem.direction - player.direction) % 360 >= -225)) { tempArray = tempArray.concat([0, 0, 0, 0.5, 0.5, 0.5, 0, 0, 0.5, 0.5, 0.5, 0]); tempArray = tempArray.concat([0, 0, 0, 0.5, 0.5, 0.5, 0, 0, 0.5, 0.5, 0.5, 0]); tempArray = tempArray.concat([0, 0, 0, 0.5, 0.5, 0.5, 0, 0, 0.5, 0.5, 0.5, 0]); tempArray = tempArray.concat([0, 0, 0, 0.5, 0.5, 0.5, 0, 0, 0.5, 0.5, 0.5, 0]); } else { tempArray = tempArray.concat([0.5, 0.5, 0.5, 1, 1, 1, 0.5, 0.5, 1, 1, 1, 0.5]); tempArray = tempArray.concat([0.5, 0.5, 0.5, 1, 1, 1, 0.5, 0.5, 1, 1, 1, 0.5]); tempArray = tempArray.concat([0.5, 0.5, 0.5, 1, 1, 1, 0.5, 0.5, 1, 1, 1, 0.5]); tempArray = tempArray.concat([0.5, 0.5, 0.5, 1, 1, 1, 0.5, 0.5, 1, 1, 1, 0.5]); } texcoordinates = new Float32Array( tempArray ); gl.bufferSubData(gl.ARRAY_BUFFER, 0, texcoordinates); // Set the matrix and draw. gl.drawArrays(gl.TRIANGLES, 0, count); } // Draw Healthkit gl.bindTexture(gl.TEXTURE_2D, healthkittex); gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); tempArray = []; count = 0; for (let kit of mapinfo.maphealthkitlist) { if (kit.isSpawned) { tempArray = tempArray.concat(kit.vertexlist); count += 4*6; } } polygonArray = new Float32Array(tempArray); gl.bufferSubData(gl.ARRAY_BUFFER, 0, polygonArray); // Tell the shader to get the texture from texture unit 0 gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer); tempArray = []; for (let kit of mapinfo.maphealthkitlist) { if (kit.isSpawned) { tempArray = tempArray.concat([0.5, 0, 0.5, 0.5, 1, 0.5, 0.5, 0, 1, 0.5, 1, 0]); tempArray = tempArray.concat([0.5, 0.5, 0.5, 1.0, 1, 1, 0.5, 0.5, 1, 1, 1, 0.5]); tempArray = tempArray.concat([0, 0, 0, 0.5, 0.5, 0.5, 0, 0, 0.5, 0.5, 0.5, 0]); tempArray = tempArray.concat([0, 0.5, 0, 1, 0.5, 1, 0, 0.5, 0.5, 1, 0.5, 0.5]); } } texcoordinates = new Float32Array( tempArray ); gl.bufferSubData(gl.ARRAY_BUFFER, 0, texcoordinates); // Set the matrix. gl.uniformMatrix4fv(texmatrixLocation, false, matrix); gl.uniform1i(textureLocation, 0); gl.drawArrays(gl.TRIANGLES, 0, count); // Draw Explosion for (let explosion of explosionlist) { if (explosion.active === false) { continue; } tempArray = []; count = 4*6; gl.bindTexture(gl.TEXTURE_2D, explosiontex); // vertex gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); explosion.vertexlist = GeneratePlaneVertex(explosion.GetCenterPosition(), 32, m4.lookAt([explosion.GetCenterPosition()[0], explosion.height, explosion.GetCenterPosition()[1]], [player.GetCenterPosition()[0], player.height, player.GetCenterPosition()[1]], up)); tempArray = tempArray.concat(explosion.vertexlist); polygonArray = new Float32Array(tempArray); gl.bufferSubData(gl.ARRAY_BUFFER, 0, polygonArray); // texture coordinate gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer); tempArray = []; if ( explosion.counter === 0 ) { tempArray = tempArray.concat([0, 0, 0, 1, 0.25, 1, 0, 0, 0.25, 1, 0.25, 0]); tempArray = tempArray.concat([0, 0, 0, 1, 0.25, 1, 0, 0, 0.25, 1, 0.25, 0]); tempArray = tempArray.concat([0, 0, 0, 1, 0.25, 1, 0, 0, 0.25, 1, 0.25, 0]); tempArray = tempArray.concat([0, 0, 0, 1, 0.25, 1, 0, 0, 0.25, 1, 0.25, 0]); } else if (explosion.counter === 1) { tempArray = tempArray.concat([0.25, 0, 0.25, 1, 0.5, 1, 0.25, 0, 0.5, 1, 0.5, 0]); tempArray = tempArray.concat([0.25, 0, 0.25, 1, 0.5, 1, 0.25, 0, 0.5, 1, 0.5, 0]); tempArray = tempArray.concat([0.25, 0, 0.25, 1, 0.5, 1, 0.25, 0, 0.5, 1, 0.5, 0]); tempArray = tempArray.concat([0.25, 0, 0.25, 1, 0.5, 1, 0.25, 0, 0.5, 1, 0.5, 0]); } else if (explosion.counter === 2) { tempArray = tempArray.concat([0.5, 0, 0.5, 1, 0.75, 1, 0.5, 0, 0.75, 1, 0.75, 0]); tempArray = tempArray.concat([0.5, 0, 0.5, 1, 0.75, 1, 0.5, 0, 0.75, 1, 0.75, 0]); tempArray = tempArray.concat([0.5, 0, 0.5, 1, 0.75, 1, 0.5, 0, 0.75, 1, 0.75, 0]); tempArray = tempArray.concat([0.5, 0, 0.5, 1, 0.75, 1, 0.5, 0, 0.75, 1, 0.75, 0]); } else { tempArray = tempArray.concat([0.75, 0, 0.75, 1, 1, 1, 0.75, 0, 1, 1, 1, 0]); tempArray = tempArray.concat([0.75, 0, 0.75, 1, 1, 1, 0.75, 0, 1, 1, 1, 0]); tempArray = tempArray.concat([0.75, 0, 0.75, 1, 1, 1, 0.75, 0, 1, 1, 1, 0]); tempArray = tempArray.concat([0.75, 0, 0.75, 1, 1, 1, 0.75, 0, 1, 1, 1, 0]); explosion.active = false; } explosion.counter += 1; texcoordinates = new Float32Array( tempArray ); gl.bufferSubData(gl.ARRAY_BUFFER, 0, texcoordinates); // Set the matrix and draw. gl.drawArrays(gl.TRIANGLES, 0, count); } for (let explosion of explosionlist) { if (explosion.active === false) explosionlist.splice(explosionlist.indexOf(explosion), 1); } // draw ui DrawUI(); requestAnimationFrame(drawScene); } } // ---------End---------- } // ---------------------------------Matrix control ------------------------------- var m4 = { orthographic: function(left, right, bottom, top, near, far) { return [ 2 / (right - left), 0, 0, 0, 0, 2 / (top - bottom), 0, 0, 0, 0, 2 / (near - far), 0, (left + right) / (left - right), (bottom + top) / (bottom - top), (near + far) / (near - far), 1, ]; }, perspective: function(fieldOfViewInRadians, aspect, near, far) { var f = Math.tan(Math.PI * 0.5 - 0.5 * fieldOfViewInRadians); var rangeInv = 1.0 / (near - far); return [ f / aspect, 0, 0, 0, 0, f, 0, 0, 0, 0, (near + far) * rangeInv, -1, 0, 0, near * far * rangeInv * 2, 0 ]; }, projection: function(width, height, depth) { // Note: This matrix flips the Y axis so 0 is at the top. return [ 2 / width, 0, 0, 0, 0, -2 / height, 0, 0, 0, 0, 2 / depth, 0, -1, 1, 0, 1, ]; }, multiply: function(a, b) { var a00 = a[0 * 4 + 0]; var a01 = a[0 * 4 + 1]; var a02 = a[0 * 4 + 2]; var a03 = a[0 * 4 + 3]; var a10 = a[1 * 4 + 0]; var a11 = a[1 * 4 + 1]; var a12 = a[1 * 4 + 2]; var a13 = a[1 * 4 + 3]; var a20 = a[2 * 4 + 0]; var a21 = a[2 * 4 + 1]; var a22 = a[2 * 4 + 2]; var a23 = a[2 * 4 + 3]; var a30 = a[3 * 4 + 0]; var a31 = a[3 * 4 + 1]; var a32 = a[3 * 4 + 2]; var a33 = a[3 * 4 + 3]; var b00 = b[0 * 4 + 0]; var b01 = b[0 * 4 + 1]; var b02 = b[0 * 4 + 2]; var b03 = b[0 * 4 + 3]; var b10 = b[1 * 4 + 0]; var b11 = b[1 * 4 + 1]; var b12 = b[1 * 4 + 2]; var b13 = b[1 * 4 + 3]; var b20 = b[2 * 4 + 0]; var b21 = b[2 * 4 + 1]; var b22 = b[2 * 4 + 2]; var b23 = b[2 * 4 + 3]; var b30 = b[3 * 4 + 0]; var b31 = b[3 * 4 + 1]; var b32 = b[3 * 4 + 2]; var b33 = b[3 * 4 + 3]; return [ b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30, b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31, b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32, b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33, b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30, b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31, b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32, b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33, b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30, b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31, b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32, b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33, b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30, b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31, b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32, b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33, ]; }, translation: function(tx, ty, tz) { return [ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1, ]; }, xRotation: function(angleInRadians) { var c = Math.cos(angleInRadians); var s = Math.sin(angleInRadians); return [ 1, 0, 0, 0, 0, c, s, 0, 0, -s, c, 0, 0, 0, 0, 1, ]; }, yRotation: function(angleInRadians) { var c = Math.cos(angleInRadians); var s = Math.sin(angleInRadians); return [ c, 0, -s, 0, 0, 1, 0, 0, s, 0, c, 0, 0, 0, 0, 1, ]; }, zRotation: function(angleInRadians) { var c = Math.cos(angleInRadians); var s = Math.sin(angleInRadians); return [ c, s, 0, 0, -s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, ]; }, scaling: function(sx, sy, sz) { return [ sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1, ]; }, translate: function(m, tx, ty, tz) { return m4.multiply(m, m4.translation(tx, ty, tz)); }, xRotate: function(m, angleInRadians) { return m4.multiply(m, m4.xRotation(angleInRadians)); }, yRotate: function(m, angleInRadians) { return m4.multiply(m, m4.yRotation(angleInRadians)); }, zRotate: function(m, angleInRadians) { return m4.multiply(m, m4.zRotation(angleInRadians)); }, scale: function(m, sx, sy, sz) { return m4.multiply(m, m4.scaling(sx, sy, sz)); }, inverse: function(m) { var m00 = m[0 * 4 + 0]; var m01 = m[0 * 4 + 1]; var m02 = m[0 * 4 + 2]; var m03 = m[0 * 4 + 3]; var m10 = m[1 * 4 + 0]; var m11 = m[1 * 4 + 1]; var m12 = m[1 * 4 + 2]; var m13 = m[1 * 4 + 3]; var m20 = m[2 * 4 + 0]; var m21 = m[2 * 4 + 1]; var m22 = m[2 * 4 + 2]; var m23 = m[2 * 4 + 3]; var m30 = m[3 * 4 + 0]; var m31 = m[3 * 4 + 1]; var m32 = m[3 * 4 + 2]; var m33 = m[3 * 4 + 3]; var tmp_0 = m22 * m33; var tmp_1 = m32 * m23; var tmp_2 = m12 * m33; var tmp_3 = m32 * m13; var tmp_4 = m12 * m23; var tmp_5 = m22 * m13; var tmp_6 = m02 * m33; var tmp_7 = m32 * m03; var tmp_8 = m02 * m23; var tmp_9 = m22 * m03; var tmp_10 = m02 * m13; var tmp_11 = m12 * m03; var tmp_12 = m20 * m31; var tmp_13 = m30 * m21; var tmp_14 = m10 * m31; var tmp_15 = m30 * m11; var tmp_16 = m10 * m21; var tmp_17 = m20 * m11; var tmp_18 = m00 * m31; var tmp_19 = m30 * m01; var tmp_20 = m00 * m21; var tmp_21 = m20 * m01; var tmp_22 = m00 * m11; var tmp_23 = m10 * m01; var t0 = (tmp_0 * m11 + tmp_3 * m21 + tmp_4 * m31) - (tmp_1 * m11 + tmp_2 * m21 + tmp_5 * m31); var t1 = (tmp_1 * m01 + tmp_6 * m21 + tmp_9 * m31) - (tmp_0 * m01 + tmp_7 * m21 + tmp_8 * m31); var t2 = (tmp_2 * m01 + tmp_7 * m11 + tmp_10 * m31) - (tmp_3 * m01 + tmp_6 * m11 + tmp_11 * m31); var t3 = (tmp_5 * m01 + tmp_8 * m11 + tmp_11 * m21) - (tmp_4 * m01 + tmp_9 * m11 + tmp_10 * m21); var d = 1.0 / (m00 * t0 + m10 * t1 + m20 * t2 + m30 * t3); return [ d * t0, d * t1, d * t2, d * t3, d * ((tmp_1 * m10 + tmp_2 * m20 + tmp_5 * m30) - (tmp_0 * m10 + tmp_3 * m20 + tmp_4 * m30)), d * ((tmp_0 * m00 + tmp_7 * m20 + tmp_8 * m30) - (tmp_1 * m00 + tmp_6 * m20 + tmp_9 * m30)), d * ((tmp_3 * m00 + tmp_6 * m10 + tmp_11 * m30) - (tmp_2 * m00 + tmp_7 * m10 + tmp_10 * m30)), d * ((tmp_4 * m00 + tmp_9 * m10 + tmp_10 * m20) - (tmp_5 * m00 + tmp_8 * m10 + tmp_11 * m20)), d * ((tmp_12 * m13 + tmp_15 * m23 + tmp_16 * m33) - (tmp_13 * m13 + tmp_14 * m23 + tmp_17 * m33)), d * ((tmp_13 * m03 + tmp_18 * m23 + tmp_21 * m33) - (tmp_12 * m03 + tmp_19 * m23 + tmp_20 * m33)), d * ((tmp_14 * m03 + tmp_19 * m13 + tmp_22 * m33) - (tmp_15 * m03 + tmp_18 * m13 + tmp_23 * m33)), d * ((tmp_17 * m03 + tmp_20 * m13 + tmp_23 * m23) - (tmp_16 * m03 + tmp_21 * m13 + tmp_22 * m23)), d * ((tmp_14 * m22 + tmp_17 * m32 + tmp_13 * m12) - (tmp_16 * m32 + tmp_12 * m12 + tmp_15 * m22)), d * ((tmp_20 * m32 + tmp_12 * m02 + tmp_19 * m22) - (tmp_18 * m22 + tmp_21 * m32 + tmp_13 * m02)), d * ((tmp_18 * m12 + tmp_23 * m32 + tmp_15 * m02) - (tmp_22 * m32 + tmp_14 * m02 + tmp_19 * m12)), d * ((tmp_22 * m22 + tmp_16 * m02 + tmp_21 * m12) - (tmp_20 * m12 + tmp_23 * m22 + tmp_17 * m02)) ]; }, vectorMultiply: function(v, m) { var dst = []; for (var i = 0; i < 4; ++i) { dst[i] = 0.0; for (var j = 0; j < 4; ++j) { dst[i] += v[j] * m[j * 4 + i]; } } return dst; }, getRight: function (m) { return [m[8], m[9], m[10], 0]; }, getForward: function(m) { return [m[0], m[1], m[2], 0]; }, getUp: function (m) { return [m[4], m[5], m[6], 0]; }, lookAt: function(cameraPosition, target, up) { // all of the parameters is vector var zAxis = this.normalize( this.subtractVectors(cameraPosition, target)); var xAxis = this.normalize(this.cross(up, zAxis)); var yAxis = this.normalize(this.cross(zAxis, xAxis)); return [ xAxis[0], xAxis[1], xAxis[2], 0, yAxis[0], yAxis[1], yAxis[2], 0, zAxis[0], zAxis[1], zAxis[2], 0, cameraPosition[0], cameraPosition[1], cameraPosition[2], 1, ]; }, cross: function (a, b) { return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]]; }, subtractVectors: function (a, b) { return [a[0] - b[0], a[1] - b[1], a[2] - b[2]]; }, normalize: function (v) { var length = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); // make sure we don't divide by 0. if (length > 0.00001) { return [v[0] / length, v[1] / length, v[2] / length]; } else { return [0, 0, 0]; } }, }; // Fill the buffer with the values of "W" and "F". function setMapGeometry(gl, mapInfo) { let temparray = mapInfo.polygons.concat( new Array(6* MAX_RAY_NUM)); // for ray temparray = temparray.concat (new Array(3* 6 * 4 * MAX_PROJECTILE_NUMBER )); // for projectile temparray = temparray.concat (new Array(3*6*32)); // for player temparray = temparray.concat(new Array(3* 6 * MAX_PROJECTILE_NUMBER )); // for explosion let polygonArray = new Float32Array(temparray); gl.bufferData( gl.ARRAY_BUFFER, polygonArray, gl.STATIC_DRAW); return; } function setMapColors(gl, mapInfo) { for (let object of mapInfo.mapobjectlist){ if (object.constructor === Door) { if (object.team === 1) { mapInfo.mapColors = mapInfo.mapColors.concat([ 146, 25, 14, 146, 25, 14, 146, 25, 14, 146, 25, 14, 146, 25, 14, 146, 25, 14, //wall 2 146, 25, 14, 146, 25, 14, 146, 25, 14, 146, 25, 14, 146, 25, 14, 146, 25, 14 ]); } else if (object.team === 2) { mapInfo.mapColors = mapInfo.mapColors.concat([ 50, 14, 146, 50, 14, 146, 50, 14, 146, 50, 14, 146, 50, 14, 146, 50, 14, 146, //wall 2 50, 14, 146, 50, 14, 146, 50, 14, 146, 50, 14, 146, 50, 14, 146, 50, 14, 146 ]); } else { mapInfo.mapColors = mapInfo.mapColors.concat([ 146, 125, 14, 146, 125, 14, 146, 125, 14, 146, 125, 14, 146, 125, 14, 146, 125, 14, //wall 2 146, 125, 14, 146, 125, 14, 146, 125, 14, 146, 125, 14, 146, 125, 14, 146, 125, 14 ]); } } else if (object.constructor === GameObject) { if (object.flag === 0) { mapInfo.mapColors = mapInfo.mapColors.concat([ 50, 146, 14, 50, 146, 14, 50, 146, 14, 50, 146, 14, 50, 146, 14, 50, 146, 14, //wall 2 50, 146, 14, 50, 146, 14, 50, 146, 14, 50, 146, 14, 50, 146, 14, 50, 146, 14, //wall 3 50, 146, 14, 50, 146, 14, 50, 146, 14, 50, 146, 14, 50, 146, 14, 50, 146, 14, //wall 4 50, 146, 14, 50, 146, 14, 50, 146, 14, 50, 146, 14, 50, 146, 14, 50, 146, 14 ]); } else if (object.flag === 2) { mapInfo.mapColors = mapInfo.mapColors.concat([ 50, 14, 146, 50, 14, 146, 50, 14, 146, 50, 14, 146, 50, 14, 146, 50, 14, 146, //wall 2 50, 14, 146, 50, 14, 146, 50, 14, 146, 50, 14, 146, 50, 14, 146, 50, 14, 146, //wall 3 50, 14, 146, 50, 14, 146, 50, 14, 146, 50, 14, 146, 50, 14, 146, 50, 14, 146, //wall 4 50, 14, 146, 50, 14, 146, 50, 14, 146, 50, 14, 146, 50, 14, 146, 50, 14, 146 ]); } else if (object.flag === 1) { mapInfo.mapColors = mapInfo.mapColors.concat([ 146, 25, 14, 146, 25, 14, 146, 25, 14, 146, 25, 14, 146, 25, 14, 146, 25, 14, //wall 2 146, 25, 14, 146, 25, 14, 146, 25, 14, 146, 25, 14, 146, 25, 14, 146, 25, 14, //wall 3 146, 25, 14, 146, 25, 14, 146, 25, 14, 146, 25, 14, 146, 25, 14, 146, 25, 14, //wall 4 146, 25, 14, 146, 25, 14, 146, 25, 14, 146, 25, 14, 146, 25, 14, 146, 25, 14 ]); } } } let temparray = mapInfo.mapColors.concat(new Array(2*3* MAX_RAY_NUM)); temparray = temparray.concat (new Array(3* 6 * 4 * MAX_PROJECTILE_NUMBER )); // for projectile temparray = temparray.concat (new Array(3*6*32)); // for player temparray = temparray.concat(new Array(3* 6 * MAX_PROJECTILE_NUMBER )); // for explosion let mapColorArray = new Uint8Array(temparray); gl.bufferData(gl.ARRAY_BUFFER, mapColorArray, gl.STATIC_DRAW); return; } // ---------------------------------------HTML document managing function------------------------------------- let ip = ""; let playername = ""; let ws; let killloglist = []; function killlog_Timeout() { if (killloglist.length > 0) { killloglist.splice(0, 1); } return; } function DoInitialJob () { createCanvasAndShader (); EngineMain(); } function closeHandler() { alert(serverclosereason); } /////////////////////////////////////////////////////////////////////////////////////////////// // ---------------------------------Client-side message---------------------------------------- // -------------------------------------------------------------------------------------------- // -------------------------------type of receiving message------------------------------------ // 0: list of players (has heavy net load, do not use this frequently) // 1: connection notice // 2: disconnection notice // 3: connection rejected(due to server player number limit or else) // 4: reserved for chat // 5: player's current status renewal // 6: received fired ray // 7: received fired projectilelist // 8: initial player information // 9: reserved for game objective(GameRule related) // 10: kill log event // 11: damaging event // 12: explosion event // 13: reserved for list of building // 14: map version request // 15: player name change event // 16: reply to teammate number request // 17: Healthkit touch event // 18: sound play request // 19: sound stop request // 20: respawn event // 21: scriptversion request // 22: weapon change notice // -------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------- // -------------------------------type of sending message-------------------------------------- // 0: request for all player's status // 1: map version // 2: player name set request // 3: class change request // 4: reserved for chat // 5: player current position, looking direction info // 6: fired ray info // 7: fired projectile info // 8: reserved for all building's current status // 9: reserved for building repair // 10: reserved for building destruction // 11: heal event request // 12: teammate number request // 13: reload request // 14: script version // 15: Special skill request(include building construction, zoom in, etc.) // 16: Weapon change request // -------------------------------------------------------------------------------------------- let serverclosereason = "서버로부터 연결이 끊겼습니다"; function messageHandler(message) { let messageinfo = JSON.parse(message.data); switch (messageinfo.type) { case 0: playerlist = []; for (let playeritem of messageinfo.playerlist){ playerlist.push(new Player(playeritem.pos, 12, playeritem.direction, playeritem.team, playeritem.health, playeritem.id, playeritem.isdead, playeritem.playername, playeritem.classnumber)); } break; case 1: if (player.playerID != messageinfo.id) { // other player is connected playerlist.push(new Player(messageinfo.pos, 12, messageinfo.direction, messageinfo.team, messageinfo.health, messageinfo.id)); } else { // ok, this is same with my player information, I have to set a reference of player variable to specific element of playerlist playerlist[messageinfo.id] = player; } if (messageinfo.team === 1) { redteamnum += 1; } else if (messageinfo.team === 2) { blueteamnum += 1; } break; case 2: var index = messageinfo.id; let teamnumber = playerlist[index].team; playerlist.splice(index, 1); if (teamnumber === 1) { redteamnum -= 1; } else if (teamnumber === 2) { blueteamnum -= 1; } //arrange the new playerlist for (let i in playerlist) { playerlist[i].PlayerID = i; } break; case 3: serverclosereason = messageinfo.message; ws.close(); break; case 5: if (messageinfo.id === player.playerID){ player.pos = messageinfo.pos; player.direction = messageinfo.direction; player.team = messageinfo.team; player.healthpoint = messageinfo.health; player.canbedamaged = messageinfo.canbedamaged; player.classnumber = messageinfo.classnum; player.isdead = messageinfo.isdead; } playerlist[messageinfo.id].pos = messageinfo.pos; playerlist[messageinfo.id].direction = messageinfo.direction; playerlist[messageinfo.id].team = messageinfo.team; playerlist[messageinfo.id].healthpoint = messageinfo.health; playerlist[messageinfo.id].canbedamaged = messageinfo.canbedamaged; playerlist[messageinfo.id].classnumber = messageinfo.classnum; playerlist[messageinfo.id].isdead = messageinfo.isdead; break; case 6: playerlist[messageinfo.id].raylist = []; for (let rayinfo of messageinfo.raylist) { playerlist[messageinfo.id].raylist.push(new Ray(rayinfo.startpos, rayinfo.endpos)); } for (let ray of playerlist[messageinfo.id].raylist){ ray.DrawRay(); } break; case 7: projectilelist = []; for (let projectile of messageinfo.projectilelist) { switch (projectile.type) { case 0: projectilelist.push(new Projectile_Rocket (projectile.pos, 8, projectile.direction, projectile.team, playerlist[projectile.shooterid], "http://libertyga.me/images/4/46/UF_Healthkit.png", projectile.type)); break; default: break; } } break; case 8: player = new Player(messageinfo.pos, 12, messageinfo.direction, messageinfo.team, messageinfo.health, messageinfo.id, true, playername, 0); player.canbedamaged = messageinfo.canbedamaged; player.classnumber = messageinfo.classnum; player.isdead = messageinfo.isdead; ws.send(JSON.stringify({ type: 2, id: messageinfo.id, newname: playername })); break; case 9: // reserved for gamerule control break; case 10: let killtext = playerlist[messageinfo.attackerID].playername + " killed " + playerlist[messageinfo.victimID].playername + " with "; switch (messageinfo.killtype) { case -1: // suicide killtext = playerlist[messageinfo.attackerID].playername + " suicided"; break; case 0: // killed by pistol killtext = killtext + "pistol"; break; case 1: // reserved for nail gun break; case 2: // reserved for short shotgun break; case 3: // reserved break; case 4: // killed by power shotgun killtext = killtext + "power shotgun"; break; case 5: // killed by minigun killtext = killtext + "minigun"; break; case 6: // killed by rocket launcher explosion killtext = killtext + "rocket launcher"; break; default: killtext = playerlist[messageinfo.attackerID].playername + " killed " + playerlist[messageinfo.victimID].playername; console.log("unknown type kill event" + messageinfo.killtype); break; } if (killloglist.length >= 10) { killloglist.splice(0, 1); } killloglist.push(killtext); setTimeout(killlog_Timeout, 4000); break; case 11: // damaging event if (player.playerID === messageinfo.victimID){ player.healthpoint -= messageinfo.damage; player.isdead = messageinfo.isdead; if (messageinfo.isdead) { // if player is dead player.healthpoint = 0; inputhandler.ReleasePlayer(); player.ReloadWeapon = () => { return; }; player.FireWeapon = () =>{ return; }; player.DoSpecialSkill = () => { return; }; player.ReleaseFire = () => { return; }; clearTimeout(player.deadtimer); player.deadtimer = setTimeout(deadStateHandler, 4000); } } else { playerlist[messageinfo.victimID].healthpoint -= messageinfo.damage; playerlist[messageinfo.victimID].isdead = messageinfo.isdead; if (messageinfo.isdead) { playerlist[messageinfo.victimID].healthpoint = 0; } } break; case 12: // reserved for explosion draw // explosiontype 0: damaging explosion, 1:healing explosion explosionlist.push(new Explosion(messageinfo.pos, messageinfo.radius, messageinfo.explosiontype)); break; case 13: // reserved for the list of buildings break; case 14: ws.send(JSON.stringify({type:1, id:player.playerID, mapversion:mapinfo.mapversion})); break; case 15: playerlist[messageinfo.id].playername = messageinfo.newname; console.log("client "+ messageinfo.id +" changed name to "+ messageinfo.newname); break; case 16: redteamnum = messageinfo.redteamnum; blueteamnum = messageinfo.blueteamnum; break; case 17: if (messageinfo.id === player.playerID) { player.healthpoint = player.maxhealthpoint; } mapinfo.maphealthkitlist[messageinfo.healthkitid].isSpawned = messageinfo.isSpawned; break; case 18: // soundplay start break; case 19: // soundplay stop break; case 20: // respawn if (player.playerID === messageinfo.id) { player.pos = messageinfo.respawnpos; player.isdead = false; } else { playerlist[messageinfo.id].pos = messageinfo.respawnpos; playerlist[messageinfo.id].isdead = false; } break; case 21: ws.send(JSON.stringify({ type: 14, id: player.playerID, version: scriptversion})); break; case 22: if (player.playerID != messageinfo.id) { playerlist[messageinfo.id].currentweapon = messageinfo.currentweapon; } break; default: console.log("received message type "+ messageinfo.type); break; } } function deadStateHandler() { player.isdead = false; player.healthpoint = player.maxhealthpoint; inputhandler.GrabInput(player); player.ReloadWeapon = () => { if (player.currentweapon === 0) { player.secondweapon.ReloadWeapon(); } else { player.firstweapon.ReloadWeapon(); } }; player.FireWeapon = () =>{ if (player.currentweapon === 0) { player.secondweapon.FireWeapon(); } else { player.firstweapon.FireWeapon(); } }; player.DoSpecialSkill = () => { if (player.currentweapon === 0) { player.secondweapon.DoSpecialSkill(); } else { player.firstweapon.DoSpecialSkill(); } }; player.ReleaseFire = () => { if (player.currentweapon === 0) { player.secondweapon.ReleaseFire(); } else { player.firstweapon.ReleaseFire(); } }; if (player.team === 1) { player.pos = [mapinfo.RedSpawn[0] + 4 , mapinfo.RedSpawn[1] + 4 ]; } else { player.pos = [mapinfo.BlueSpawn[0] + 4 , mapinfo.BlueSpawn[1] + 4 ]; } } function createIPInputBox () { let gamedisplay = document.getElementById("mw-content-text"); gamedisplay.style.height = "1080px"; let paragraph = document.createElement("p"); paragraph.setAttribute("id", "infoparagraph"); paragraph.innerHTML = "IP주소와 포트를 쓰고 그 오른쪽 칸에 닉네임를 입력해주세요." gamedisplay.appendChild(paragraph); let mainInputBox = document.createElement("input"); mainInputBox.setAttribute("id", "input"); mainInputBox.setAttribute("placeholder", "(ex: 127.0.0.1:8080)"); mainInputBox.addEventListener("keydown", CheckInputBox); gamedisplay.appendChild(mainInputBox); let nameInputBox = document.createElement("input"); nameInputBox.setAttribute("id", "playername"); nameInputBox.setAttribute("placeholder", "Game Nickname"); nameInputBox.addEventListener("keydown", CheckInputBox); gamedisplay.appendChild(nameInputBox); function CheckInputBox(e) { if (e.keyCode === 13) { // Pressing Enter key if (document.getElementById("input").value === "" || document.getElementById("playername").value === "" ) { alert("데이터가 없습니다! 빈칸을 내버려두지 마세요!") return; } ip = document.getElementById("input").value; playername = document.getElementById("playername").value; document.getElementById("input").value = ""; document.getElementById("playername").value = ""; document.getElementById("mw-content-text").removeChild(document.getElementById("input")); document.getElementById("mw-content-text").removeChild(document.getElementById("playername")); document.getElementById("mw-content-text").removeChild(document.getElementById("infoparagraph")); DoInitialJob(); } } } function createCanvasAndShader () { let gamedisplay = document.getElementById("mw-content-text"); gamedisplay.height = "1080px"; let baseDiv = document.createElement("div"); baseDiv.setAttribute("id", "baseDiv"); baseDiv.style = "z-index:0;display:block;"; baseDiv.style.position = "absolute"; baseDiv.width = "1440px"; baseDiv.height = "1080px"; baseDiv.style.top = "0px"; baseDiv.style.left = "0px"; gamedisplay.appendChild(baseDiv); let baseDiv2 = document.createElement("div"); baseDiv2.setAttribute("id", "baseDiv2"); baseDiv2.style = "z-index:10;display:block;"; baseDiv2.style.position = "absolute"; baseDiv2.width = "1440px"; baseDiv2.height = "1080px"; baseDiv2.style.top = "0px"; baseDiv2.style.left = "0px"; gamedisplay.appendChild(baseDiv2); //create canvases let mainCanvas = document.createElement("canvas"); mainCanvas.setAttribute("id", "MainCanvas"); mainCanvas.style.border = "none"; mainCanvas.style.align = "center"; mainCanvas.setAttribute("width", "800"); mainCanvas.setAttribute("height", "600"); baseDiv.appendChild(mainCanvas); let uiCanvas = document.createElement("canvas"); uiCanvas.setAttribute("id", "UICanvas"); uiCanvas.style.border = "none"; uiCanvas.style.align = "center"; uiCanvas.setAttribute("width", "800"); uiCanvas.setAttribute("height", "600"); baseDiv2.appendChild(uiCanvas); // create shader script(GLSL) let vertexshader = document.createElement("script"); vertexshader.setAttribute("id", "3d-vertex-shader"); vertexshader.setAttribute("type", "notjs"); vertexshader.innerText = "\ attribute vec4 a_position; \ attribute vec4 a_color; \ uniform mat4 u_matrix; \ varying vec4 v_color; \ void main() { \ gl_Position = u_matrix * a_position; \ v_color = a_color; \ }"; gamedisplay.appendChild(vertexshader); let fragmentshader = document.createElement("script"); fragmentshader.setAttribute("id", "3d-fragment-shader"); fragmentshader.setAttribute("type", "notjs"); fragmentshader.innerText = "\ precision mediump float; \ varying vec4 v_color; \ \ void main() { \ gl_FragColor = v_color;\ }"; gamedisplay.appendChild(fragmentshader); let planevertexshader = document.createElement("script"); planevertexshader.setAttribute("id", "2d-vertex-shader"); planevertexshader.setAttribute("type", "notjs"); planevertexshader.innerText = "\ attribute vec4 a_position; \ attribute vec2 a_texcoord; \ uniform mat4 u_matrix; \ varying vec2 v_texcoord; \ void main() { \ gl_Position = u_matrix * a_position; \ v_texcoord = a_texcoord; \ }"; gamedisplay.appendChild(planevertexshader); let planefragmentshader = document.createElement("script"); planefragmentshader.setAttribute("id", "2d-fragment-shader"); planefragmentshader.setAttribute("type", "notjs"); planefragmentshader.innerText = "\ precision mediump float; \ varying vec2 v_texcoord; \ uniform sampler2D u_texture; \ void main() { \ gl_FragColor = texture2D(u_texture, v_texcoord);\ gl_FragColor.rgb *= gl_FragColor.a;\ }"; gamedisplay.appendChild(planefragmentshader); return; } createIPInputBox (); // ------------------------------------------------------------------------------------------------------------ // ----------------------------------------- put your own code here ------------------------------------------- // ------------------------------------------------------------------------------------------------------------ // ---------------------------------------------------------------------------------------------------- // --------------------------- UncycloFortress client-side Script ------------------------------------- // ---------------------------------------------------------------------------------------------------- let scriptversion = 0.1; let inputhandler; function Projectile_Rocket(pos, size, direction, team, shooter, imgsrc) { Projectile.call(this, pos, size, direction, team, shooter, imgsrc); this.vertexlist = GenerateProjectile(this.GetCenterPosition(), this.size, this.cameraMatrix); } Projectile_Rocket.prototype = Object.create(Projectile.prototype); Projectile_Rocket.prototype.constructor = Projectile_Rocket; function Weapon (type, owner) { this.type = type; this.owner = owner; this.timerhandler; this.loadedbullet = 1; this.firedelay = 1000; this.reloaddelay = 1000; this.isReloading = false; this.isFiring = false; this.MaxAmmo = this.loadedbullet; this.weaponname = "?"; this.ReloadWeapon = () => { this.isFiring = false; if (!this.isReloading && this.loadedbullet != this.MaxAmmo){ clearTimeout(this.timerhandler); this.timerhandler = setTimeout(this.ReloadWeapon_sub, this.reloaddelay); this.isReloading = true; } }; this.ReloadWeapon_sub = () => { // use fetch to fire event and get result // apply the result // if result failed(due to timing or else) // if result is success this.loadedbullet = this.MaxAmmo; this.isReloading = false; ws.send(JSON.stringify({ type: 13, id: player.playerID, currentweapon: player.currentweapon })); return; } this.FireWeapon = () =>{ if (this.type != 9 && this.loadedbullet === 0 && !this.isReloading) { this.ReloadWeapon(); } else if (!this.isReloading && !this.isFiring) { // use fetch to fire event and get result // apply the result // if result failed(due to timing or else) // if result is success clearTimeout(this.timerhandler); this.timerhandler = setTimeout(this.FireWeapon_sub, this.firedelay); this.isFiring = true; } }; this.FireWeapon_sub = () => { this.isFiring = false; }; this.ReleaseFire = () => { return; }; this.DoSpecialSkill = () => { // use fetch to fire event and get result // apply the result // if result failed(due to timing or else) // if result is success }; } function Weapon_Pistol (type, owner) { Weapon.call(this, type, owner); this.loadedbullet = 6; this.firedelay = 300; this.reloaddelay = 1000; this.MaxAmmo = this.loadedbullet; this.weaponname = "Pistol"; this.FireWeapon = () =>{ if (this.type != 9 && this.loadedbullet === 0 && !this.isReloading) { this.ReloadWeapon(); } else if (!this.isReloading && !this.isFiring) { // use fetch to fire event and get result // apply the result // if result failed(due to timing or else) // if result is success if (this.type != 9 && this.loadedbullet > 0)this.loadedbullet -= 1; this.owner.raylist = new Array(1); let randomNum = Math.random(); this.owner.raylist[0] = new Ray ([this.owner.GetCenterPosition()[0], this.owner.GetCenterPosition()[1], -18], [this.owner.GetCenterPosition()[0]- 10000* Math.cos(this.owner.direction+Math.PI/2- Math.PI/360+randomNum* Math.PI/180), this.owner.GetCenterPosition()[1] - 10000* Math.sin(this.owner.direction +Math.PI/2 - Math.PI/360+randomNum* Math.PI/180), 0]); ws.send(JSON.stringify({ type:6, id:player.playerID, raylist: [{startpos:[this.owner.GetCenterPosition()[0], this.owner.GetCenterPosition()[1], -18], endpos: [this.owner.GetCenterPosition()[0]- 10000* Math.cos(this.owner.direction+Math.PI/2- Math.PI/360+randomNum* Math.PI/180), this.owner.GetCenterPosition()[1] - 10000* Math.sin(this.owner.direction +Math.PI/2 - Math.PI/360+randomNum* Math.PI/180), 0]}] })); this.owner.raylist[0].AddPenetratingObjects(mapinfo.mapobjectlist); this.owner.raylist[0].endpos = this.owner.raylist[0].GetClosestCollidedPosition(); this.owner.raylist[0].DrawRay(); clearTimeout(this.timerhandler); this.timerhandler = setTimeout(this.FireWeapon_sub, this.firedelay); this.isFiring = true; } }; this.FireWeapon_sub = () => { this.isFiring = false; }; this.ReleaseFire = () => { return; } } Weapon_Pistol.prototype = Object.create(Weapon.prototype); Weapon_Pistol.prototype.constructor = Weapon_Pistol; function Weapon_PowerShotgun (type, owner) { Weapon.call(this, type, owner); this.loadedbullet = 4; this.firedelay = 800; this.reloaddelay = 1000; this.MaxAmmo = this.loadedbullet; this.weaponname = "Power Shotgun"; this.FireWeapon = () =>{ if (this.type != 9 && this.loadedbullet === 0 && !this.isReloading) { this.ReloadWeapon(); } else if (!this.isReloading && !this.isFiring) { // use fetch to fire event and get result // apply the result // if result failed(due to timing or else) // if result is success if (this.type != 9 && this.loadedbullet > 0)this.loadedbullet -= 1; this.owner.raylist = new Array(9); let raylist = []; for (let i = 0 ; i < 9; i++) { // 9 < MAX_RAY_PER_PERSON this.owner.raylist[i] = new Ray ([this.owner.GetCenterPosition()[0], this.owner.GetCenterPosition()[1], -18], [this.owner.GetCenterPosition()[0]- 10000* Math.cos(this.owner.direction+Math.PI/2- Math.PI/12+i* Math.PI/48), this.owner.GetCenterPosition()[1] - 10000* Math.sin(this.owner.direction +Math.PI/2- Math.PI/12+i* Math.PI/48), 0]); raylist.push({startpos:[this.owner.GetCenterPosition()[0], this.owner.GetCenterPosition()[1], -18], endpos: [this.owner.GetCenterPosition()[0]- 10000* Math.cos(this.owner.direction+Math.PI/2- Math.PI/12+i* Math.PI/48), this.owner.GetCenterPosition()[1] - 10000* Math.sin(this.owner.direction +Math.PI/2- Math.PI/12+i* Math.PI/48), 0]}); } ws.send(JSON.stringify({ type:6, id:player.playerID, raylist: raylist })); for (let i = 0 ; i < 9 ; i++) { this.owner.raylist[i].AddPenetratingObjects(mapinfo.mapobjectlist); this.owner.raylist[i].endpos = this.owner.raylist[i].GetClosestCollidedPosition(); this.owner.raylist[i].DrawRay(); } clearTimeout(this.timerhandler); this.timerhandler = setTimeout(this.FireWeapon_sub, this.firedelay); this.isFiring = true; } }; this.FireWeapon_sub = () => { this.isFiring = false; }; this.ReleaseFire = () => { return; } } Weapon_PowerShotgun.prototype = Object.create(Weapon.prototype); Weapon_PowerShotgun.prototype.constructor = Weapon_PowerShotgun; function Weapon_Minigun (type, owner) { Weapon.call(this, type, owner); this.loadedbullet = 200; this.firedelay = 100; this.reloaddelay = 5000; this.MaxAmmo = this.loadedbullet; this.weaponname = "Minigun"; this.FireWeapon = () =>{ if (this.type != 9 && this.loadedbullet === 0 && !this.isReloading) { this.ReloadWeapon(); } else if (!this.isReloading && !this.isFiring) { // use fetch to fire event and get result // apply the result // if result failed(due to timing or else) // if result is success if (this.type != 9 && this.loadedbullet > 0)this.loadedbullet -= 1; this.owner.raylist = new Array(2); let raylist = []; for (let i = 0 ; i < 2; i++) { // 2 < MAX_RAY_PER_PERSON let randomNum = Math.random(); this.owner.raylist[i] = new Ray ([this.owner.GetCenterPosition()[0], this.owner.GetCenterPosition()[1], -18], [this.owner.GetCenterPosition()[0]- 10000* Math.cos(this.owner.direction+Math.PI/2- Math.PI/24+randomNum* Math.PI/12), this.owner.GetCenterPosition()[1] - 10000* Math.sin(this.owner.direction +Math.PI/2 - Math.PI/24+randomNum* Math.PI/12), 0]); raylist.push({startpos:[this.owner.GetCenterPosition()[0], this.owner.GetCenterPosition()[1], -18], endpos: [this.owner.GetCenterPosition()[0]- 10000* Math.cos(this.owner.direction+Math.PI/2- Math.PI/24+randomNum* Math.PI/12), this.owner.GetCenterPosition()[1] - 10000* Math.sin(this.owner.direction +Math.PI/2 - Math.PI/24+randomNum* Math.PI/12), 0]}); } ws.send(JSON.stringify({ type:6, id:player.playerID, raylist: raylist })); for (let i = 0 ; i < 2; i++) { // 2 < MAX_RAY_PER_PERSON this.owner.raylist[i].AddPenetratingObjects(mapinfo.mapobjectlist); this.owner.raylist[i].endpos = this.owner.raylist[i].GetClosestCollidedPosition(); this.owner.raylist[i].DrawRay(); } clearTimeout(this.timerhandler); this.timerhandler = setTimeout(this.FireWeapon_sub, this.firedelay); this.isFiring = true; } }; this.FireWeapon_sub = () => { if (this.loadedbullet > 0 ){ // use fetch to fire event and get result // apply the result // if result failed(due to timing or else) // if result is success this.loadedbullet -= 1; this.owner.raylist = new Array(2); let raylist = []; for (let i = 0 ; i < 2; i++) { // 2 < MAX_RAY_PER_PERSON let randomNum = Math.random(); this.owner.raylist[i] = new Ray ([this.owner.GetCenterPosition()[0], this.owner.GetCenterPosition()[1], -18], [this.owner.GetCenterPosition()[0]- 10000* Math.cos(this.owner.direction+Math.PI/2- Math.PI/24+randomNum* Math.PI/12), this.owner.GetCenterPosition()[1] - 10000* Math.sin(this.owner.direction +Math.PI/2 - Math.PI/24+randomNum* Math.PI/12), 0]); raylist.push({startpos:[this.owner.GetCenterPosition()[0], this.owner.GetCenterPosition()[1], -18], endpos: [this.owner.GetCenterPosition()[0]- 10000* Math.cos(this.owner.direction+Math.PI/2- Math.PI/24+randomNum* Math.PI/12), this.owner.GetCenterPosition()[1] - 10000* Math.sin(this.owner.direction +Math.PI/2 - Math.PI/24+randomNum* Math.PI/12), 0]}); } ws.send(JSON.stringify({ type:6, id:player.playerID, raylist: raylist })); for (let i = 0 ; i < 2; i++) { // 2 < MAX_RAY_PER_PERSON this.owner.raylist[i].AddPenetratingObjects(mapinfo.mapobjectlist); this.owner.raylist[i].endpos = this.owner.raylist[i].GetClosestCollidedPosition(); this.owner.raylist[i].DrawRay(); } this.timerhandler = setTimeout(this.FireWeapon_sub, this.firedelay); } }; this.ReleaseFire = () => { if (this.isFiring) { clearTimeout(this.timerhandler); this.isFiring = false; } return; } } Weapon_Minigun.prototype = Object.create(Weapon.prototype); Weapon_Minigun.prototype.constructor = Weapon_Minigun; function Weapon_RocketLauncher (type, owner) { Weapon.call(this, type, owner); this.loadedbullet = 6; this.firedelay = 800; this.reloaddelay = 1000; this.MaxAmmo = this.loadedbullet; this.weaponname = "Rocket Launcher"; this.FireWeapon = () =>{ if (this.type != 9 && this.loadedbullet === 0 && !this.isReloading) { this.ReloadWeapon(); } else if (!this.isReloading && !this.isFiring) { // use fetch to fire event and get result // apply the result // if result failed(due to timing or else) // if result is success if (this.type != 9 && this.loadedbullet > 0)this.loadedbullet -= 1; let tempprojectile = new Projectile_Rocket([this.owner.GetCenterPosition()[0] - 8, this.owner.GetCenterPosition()[1] - 8], 1, this.owner.direction, 1, this.owner, "UF_Rocket_Red.png"); tempprojectile.visible = true; if (projectilelist.length < MAX_PROJECTILE_NUMBER)projectilelist.push(tempprojectile); ws.send(JSON.stringify({ type:7, id:player.playerID, pos: [this.owner.GetCenterPosition()[0] - 8, this.owner.GetCenterPosition()[1] - 8], direction:this.owner.direction, shooterid: this.owner.playerID, projectiletype: 0 })); clearTimeout(this.timerhandler); this.timerhandler = setTimeout(this.FireWeapon_sub, this.firedelay); this.isFiring = true; } }; this.FireWeapon_sub = () => { this.isFiring = false; }; this.ReleaseFire = () => { return; } } Weapon_RocketLauncher.prototype = Object.create(Weapon.prototype); Weapon_RocketLauncher.prototype.constructor = Weapon_RocketLauncher; function DoSomethingAfterMapLoad () { // add class selection button let gamedisplay = document.getElementById("mw-content-text"); let classbutton1 = document.createElement("button"); classbutton1.setAttribute("name", "classbutton1"); classbutton1.setAttribute("type", "button"); classbutton1.setAttribute("value", "1"); classbutton1.innerText = "Speedster"; classbutton1.onclick = ChangeMyCharacter; gamedisplay.appendChild(classbutton1); let classbutton2 = document.createElement("button"); classbutton2.setAttribute("name", "classbutton2"); classbutton2.setAttribute("type", "button"); classbutton2.setAttribute("value", "2"); classbutton2.innerText = "Tank"; classbutton2.onclick = ChangeMyCharacter; gamedisplay.appendChild(classbutton2); let classbutton3 = document.createElement("button"); classbutton3.setAttribute("name", "classbutton3"); classbutton3.setAttribute("type", "button"); classbutton3.setAttribute("value", "3"); classbutton3.innerText = "Tankbuster"; classbutton3.onclick = ChangeMyCharacter; gamedisplay.appendChild(classbutton3); // spawn initial player player = new Player([mapinfo.RedSpawn[0], mapinfo.RedSpawn[1]], 8, [degToRad(0), degToRad(0), degToRad(0)], degToRad(0), 1, 0); player.secondweapon = new Weapon(0,player); // weapon 0 player.firstweapon = new Weapon(4,player); // weapon 1 player.currentweapon = 0; player.ReloadWeapon = () => { }; player.FireWeapon = () =>{ }; player.DoSpecialSkill = () => { }; player.ReleaseFire = () => { }; gamerule = new GameRule(180, 180, 0); inputhandler = new Input(document.getElementById("UICanvas")); inputhandler.InitInput(); return; } function DrawUI () { if (player != undefined && player.secondweapon != undefined && player.firstweapon != undefined){ let ctx = document.getElementById("UICanvas").getContext("2d"); ctx.canvas.width = 800; // reset the ui canvas ctx.beginPath(); ctx.rect(0, 500, 800, 100); ctx.fillStyle = "rgba(125, 125, 5, 1)"; ctx.fill(); ctx.font = "18px Arial, sans-serif"; ctx.fillStyle = "rgba(255, 255, 0, 1)"; if (player.currentweapon === 0)ctx.fillText("Current Weapon: "+ player.secondweapon.weaponname,20,20); else ctx.fillText("Current Weapon: "+ player.firstweapon.weaponname,20,20); ctx.fillStyle = "rgba(255, 0, 0, 1)"; ctx.fillText(String.format("{0}:{1}", Math.floor(gamerule.RedClock /60), gamerule.RedClock % 60),400-90,20 ); ctx.fillStyle = "rgba(25, 125, 255, 1)"; ctx.fillText(String.format("{0}:{1}", Math.floor(gamerule.BlueClock /60), gamerule.BlueClock % 60),400,20 ); // reserved for kill log ctx.fillStyle = "rgba(255, 255, 0, 1)"; ctx.fillText("Health: "+player.healthpoint, 20, 580); if (player.currentweapon === 0) { if (player.secondweapon.isReloading) { ctx.fillStyle = "rgba(255, 25, 0, 1)"; ctx.fillText("Reloading", 700, 560); } ctx.fillText("Ammo: "+player.secondweapon.loadedbullet, 700, 580); } else { if (player.firstweapon.isReloading) { ctx.fillStyle = "rgba(255, 25, 0, 1)"; ctx.fillText("Reloading", 700, 560); } ctx.fillText("Ammo: "+player.firstweapon.loadedbullet, 700, 580); } ctx.closePath(); ctx.beginPath(); ctx.arc(400, 300, 10, 0, 2*Math.PI, true); ctx.closePath(); ctx.lineWidth = 2; ctx.strokeStyle = "#FFFF00"; ctx.stroke(); ctx.beginPath(); ctx.font = "12px Arial, sans-serif"; for (let killlog of killloglist){ ctx.fillStyle = "rgba(0, 255, 0, 1)"; ctx.fillText(killlog, 760 - 5*killlog.length, 40+8*killloglist.indexOf(killlog)); } ctx.closePath(); if (keystate[7]){ //draw player list board ctx.beginPath(); ctx.rect(100, 100, 600, 600); ctx.fillStyle = "rgba(0, 0, 0, 0.5)"; ctx.fill(); ctx.font = "18px Arial, sans-serif"; ctx.fillStyle = "rgba(0, 255, 0, 1)"; ctx.fillText("Players", 400 - "Players".length / 2, 110); let blueteamplayer = 0; let redteamplayer = 0; for (let playeritem of playerlist) { if (playeritem.team === 1 ) { ctx.fillStyle = "rgba(255, 0, 0, 1)"; ctx.fillText(playeritem.playername, 660 - 8*playeritem.playername.length, 140+9*redteamplayer); redteamplayer += 1; } else if (playeritem.team === 2) { ctx.fillStyle = "rgba(0, 0, 255, 1)"; ctx.fillText(playeritem.playername, 140, 140+9*blueteamplayer); blueteamplayer += 1; } } ctx.closePath(); } } return; } function GetMyNewWeapon(type) { let newweapon = new Weapon(type,player); switch (type) { case 0: // pistol newweapon = new Weapon_Pistol(type, player); break; case 1: // nail gun newweapon.loadedbullet = 30; newweapon.firedelay = 200; newweapon.reloaddelay = 1000; break; case 2: // short shotgun newweapon.loadedbullet = 8; newweapon.firedelay = 400; newweapon.reloaddelay = 2000; break; case 4: // power shotgun newweapon = new Weapon_PowerShotgun(type, player); break; case 5: // minigun newweapon = new Weapon_Minigun (type, player); break; case 6: // rocket shooter newweapon = new Weapon_RocketLauncher (type, player); break; case 7: // medibeam shooter newweapon.loadedbullet = -1; newweapon.firedelay = 200; newweapon.reloaddelay = 0; break; case 8: // watershooter newweapon.loadedbullet = -1; newweapon.firedelay = 200; newweapon.reloaddelay = 0; break; case 9: // wrench newweapon.loadedbullet = 200; newweapon.firedelay = 800; newweapon.reloaddelay = 1000; break; case 10: // pipe shooter newweapon.loadedbullet = 8; newweapon.firedelay = 400; newweapon.reloaddelay = 2000; break; case 11: // sniper rifle newweapon.loadedbullet = 1; newweapon.firedelay = 400; newweapon.reloaddelay = 2000; break; case 12: // knife newweapon.loadedbullet = -1; newweapon.firedelay = 800; newweapon.reloaddelay = 1000; break; default: newweapon.loadedbullet = 1; newweapon.firedelay = 400; newweapon.reloaddelay = 1000; break; } newweapon.MaxAmmo = newweapon.loadedbullet; return newweapon; } function ChangeMyCharacter(event) { inputhandler.ReleasePlayer(); switch(event.target.value) { case "1": if (player.team === 1) { player = new Player(player.pos, 12, degToRad(0), player.team, 100, player.playerID, true, player.playername, 1); } else { player = new Player(player.pos, 12, degToRad(180), player.team, 100, player.playerID, true, player.playername, 1); } player.secondweapon = GetMyNewWeapon(0); // weapon 0 player.firstweapon = GetMyNewWeapon(4); // weapon 1 player.movespeed = 2; break; case "2": if (player.team === 1) { player = new Player(player.pos, 12, degToRad(0), player.team, 300, player.playerID, true, player.playername, 2); } else { player = new Player(player.pos, 12, degToRad(180), player.team, 300, player.playerID, true, player.playername, 2); } player.secondweapon = GetMyNewWeapon(0); // weapon 0 player.firstweapon = GetMyNewWeapon(5); // weapon 1 player.movespeed = 0.5; break; case "3": if (player.team === 1) { player = new Player(player.pos, 12, degToRad(0), player.team, 200, player.playerID, true, player.playername, 3); } else { player = new Player(player.pos, 12, degToRad(180), player.team, 200, player.playerID, true, player.playername, 3); } player.secondweapon = GetMyNewWeapon(0); // weapon 0 player.firstweapon = GetMyNewWeapon(6); // weapon 1 player.movespeed = 1; break; default: //only possible in initial entrance break; } if (player.team === 1) { player.SetCenterPosition([mapinfo.RedSpawn[0] + mapobjectsizeconstant/2, mapinfo.RedSpawn[1] + mapobjectsizeconstant/2]); } else { player.SetCenterPosition([mapinfo.BlueSpawn[0] + mapobjectsizeconstant/2, mapinfo.BlueSpawn[1] + mapobjectsizeconstant/2]); } player.currentweapon = 0; ws.send(JSON.stringify({ type:3, id:player.playerID, classnum:player.classnumber, team: player.team })); clearTimeout(player.deadtimer); player.deadtimer = setTimeout(deadStateHandler, 4000); return; }