ゲーム プログラミング

ショーモナイノ/ ソースコード(クライアントサイド)

投稿日:

サーバサイドのソースコードを公開したところ、結構ビュー数が伸びているようです。
なのでクライアントサイドも公開しておきます。何かの役に立てればと思います。

内容はとんでもないジャンクコードとなっています。バグも多く含まれているでしょう。使えそうな箇所のみ参考にしてもらえればと思います。

【概要】
3〜11行:初期化、変数設定など
18〜33行:PC、モバイルの判別
37〜201行:フィールド、カメラ、効果音などの設定
206〜238行:マウスポインタロックの設定
241〜245行:描画スタート
248〜251行:ヘルプビュー設定
259〜263行:変数設定
264〜370行:キーイベント設定
373〜456行:マウスイベント設定
459〜632行:モバイル用、タッチ画面・イベント設定
635〜650行:ゲームスタート
659〜1324行:socket通信、毎フレームの描画
1327〜1373行:ビクロイ画面
1376〜1492行:socket通信、各イベントの受信

game-3d.js

//window.focus();

const socket = io();
const canvas2d = $('#canvas-2d')[0];
const context = canvas2d.getContext('2d');
const canvas3d = $('#canvas-3d')[0];
//const playerImage = $("#player-image")[0];
const canvasVic = $('#canvas-vic')[0];
const contextVic = canvasVic.getContext('2d');
const canvasMob = $('#canvas-mob')[0];
const contextMob = canvasMob.getContext('2d');

window.onload=function(){
    console.log('------window.onload-------');

}

var mDeviceType = 'PC'; //0:PC, 1:Mobile
function mGetDeviceType() {
    console.log('Device:'+navigator.userAgent);
    if (navigator.userAgent.match(/iPhone|iPad|Android/)) { ///iPhone|Android.+Mobile/
        mDeviceType = 'Mobile';
        //$("#canvas-mob").show();
      //return true;
    } else {
      //return false;
      //$("#canvas-mob").hide();
    }
    //mDeviceType = navigator.userAgent;
}

mGetDeviceType();
console.log('mDeviceType:'+mDeviceType);



const FIELD_SC = 32;
const FIELD_WIDTH = 1000*FIELD_SC, FIELD_HEIGHT = 1000*FIELD_SC;
var mFieldGridSize = 250;

const renderer = new THREE.WebGLRenderer({canvas: canvas3d});
renderer.setClearColor('grey');//'skyblue'
renderer.shadowMap.enabled = true;

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 90, 2, 0.1, FIELD_WIDTH*2 );

const textureLoader = new THREE.TextureLoader();

// Floor
var mSc = 2;
const groundTexture = textureLoader.load('/static/image/p0305_m.jpeg');
const groundMaterial = new THREE.MeshLambertMaterial( { map: groundTexture } );
const floorGeometry = new THREE.PlaneGeometry(FIELD_WIDTH*2, FIELD_HEIGHT*2, 1, 1);
const floorMaterial = new THREE.MeshLambertMaterial({color : 'green'});//'lawngreen'
const floorMesh = new THREE.Mesh(floorGeometry, floorMaterial); //groundMaterial
floorMesh.position.set(FIELD_WIDTH/2, 0, FIELD_HEIGHT/2);
floorMesh.receiveShadow = true;
floorMesh.rotation.x = - Math.PI / 2; 
scene.add(floorMesh);

// Side 
const sideGeometry = new THREE.CylinderGeometry(FIELD_WIDTH,FIELD_WIDTH,FIELD_WIDTH*2,50,50,true); //(FIELD_WIDTH,FIELD_WIDTH,FIELD_WIDTH,50);
//const sideTexture = new THREE.Texture(playerImage);
const sideTexture = textureLoader.load('/static/image/ELFADSC08963_TP_V.jpg'); //skyimage1.png, skyimage1.png
//sideTexture.needsUpdate = true;
const sideMaterial = new THREE.MeshLambertMaterial({map: sideTexture, side: THREE.DoubleSide});//'lawngreen'
// const sideMaterial = new THREE.MeshBasicMaterial({
//     map: texture, // テクスチャーを指定
//     color: 0x007eff, // 色
//     transparent: true, // 透明の表示許可
//     blending: THREE.AdditiveBlending, // ブレンドモード
//     side: THREE.DoubleSide, // 表裏の表示設定
//     depthWrite: false // デプスバッファへの書き込み可否
//   });
const sideMesh = new THREE.Mesh(sideGeometry, sideMaterial);
sideMesh.position.set(FIELD_WIDTH/2, FIELD_WIDTH-100, FIELD_HEIGHT/2);
sideMesh.receiveShadow = true;
//sideMesh.rotation.x = - Math.PI / 2; 
scene.add(sideMesh);


// Grid
// for(var i=0;i<FIELD_WIDTH/mFieldGridSize/2;i++){
//     for(var j=0;j<FIELD_WIDTH/mFieldGridSize/2;j++){
//     var floorGeometry1 = new THREE.PlaneGeometry(mFieldGridSize, mFieldGridSize, 1, 1);
//     var floorMaterial1 = new THREE.MeshLambertMaterial({color : 'lawngreen'});//'lawngreen'
//     var floorMesh1 = new THREE.Mesh(floorGeometry1, floorMaterial1);
//     floorMesh1.position.set(mFieldGridSize*i*2+mFieldGridSize/2, 1, mFieldGridSize*j*2+mFieldGridSize/2);
//     floorMesh1.receiveShadow = true;
//     floorMesh1.rotation.x = - Math.PI / 2; 
//     scene.add(floorMesh1);
//     }
// } 

var ng_ = 5;
for(var i=0;i<ng_;i++){
    for(var j=0;j<ng_;j++){
        var s_ = FIELD_WIDTH/ng_;
        var floorGeometry1 = new THREE.PlaneGeometry(s_, s_, 1, 1);
        var floorMaterial1 = new THREE.MeshLambertMaterial({color : 'lawngreen'});//'lawngreen'
        var floorMesh1 = new THREE.Mesh(floorGeometry1, groundMaterial);
        floorMesh1.position.set(s_*i+s_/2, 3, s_*j+s_/2);
        floorMesh1.receiveShadow = true;
        floorMesh1.rotation.x = - Math.PI / 2; 
        scene.add(floorMesh1);
    }
} 


camera.position.set(1000*mSc, 300, 1000*mSc);
//camera.lookAt(floorMesh.position);

// Materials
const bulletMaterial = new THREE.MeshLambertMaterial( { color: 'gold' } );

const wallTexture = textureLoader.load('/static/image/picture_pc_74734f96022aee0a492c0d64925a0d1c.jpg'); //KAZTDSCF2532_TP_V.jpg
const wallMaterial = new THREE.MeshLambertMaterial( { map: wallTexture } );
const wallMaterial_t = new THREE.MeshLambertMaterial( { map: wallTexture, opacity: 0.5, transparent: true } );
const rockTexture = textureLoader.load('/static/image/stone_00007.jpg'); 
const rockMaterial = new THREE.MeshLambertMaterial( { map: rockTexture } );

const playerMaterial1 = new THREE.MeshLambertMaterial( { color: 'blue' } );
const playerMaterial2 = new THREE.MeshLambertMaterial( { color: 'red' } );
const playerMaterial3 = new THREE.MeshLambertMaterial( { color: 'yellow' }); //, opacity: 0.5, transparent: true } );
const playerMaterial3b = new THREE.MeshLambertMaterial( { color: 'grey' } );
const playerMaterialg = new THREE.MeshLambertMaterial( { color: 'black' } );
const playerMaterialf = new THREE.MeshBasicMaterial( { color: 'orange' } );
const faceTexture1 = textureLoader.load('/static/image/face20200525_001.png'); 
const faceMaterial1 = new THREE.MeshLambertMaterial( { map: faceTexture1, side: THREE.DoubleSide } );
const botTexture1 = textureLoader.load('/static/image/e0137995_18414394.jpg'); 
const botMaterial1 = new THREE.MeshLambertMaterial( { map: botTexture1 } );
const playerTexture1 = textureLoader.load('/static/image/skin-2933371_960_720.jpg'); 
const playerMaterialtx1 = new THREE.MeshLambertMaterial( { map: playerTexture1 } );
const paraTexture1 = textureLoader.load('/static/image/tatami_1.jpg'); 
const paraMaterial1 = new THREE.MeshLambertMaterial( { map: paraTexture1, side: THREE.DoubleSide } );

const textMaterial = new THREE.MeshBasicMaterial({ color: 0xf39800, side: THREE.DoubleSide });
const nicknameMaterial = new THREE.MeshBasicMaterial({ color: 'black', side: THREE.DoubleSide });
const bandageMaterial = new THREE.MeshLambertMaterial( { color: 'white' } );
const bandageMaterial2 = new THREE.MeshLambertMaterial( { color: 'red' } );
const potionMaterial = new THREE.MeshLambertMaterial( { color: 'blue' } );
const stormMaterial = new THREE.MeshLambertMaterial( { color: 'red', side: THREE.DoubleSide,opacity: 0.3, transparent: true } );

// Light
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(FIELD_WIDTH/2, FIELD_WIDTH, FIELD_HEIGHT/2);//(-100, 300, -100)
light.castShadow = false; //true;
light.shadow.camera.left = -2000;
light.shadow.camera.right = 2000;
light.shadow.camera.top = 2000;
light.shadow.camera.bottom = -2000;
light.shadow.camera.far = 2000;
light.shadow.mapSize.width = 2048;
light.shadow.mapSize.height = 2048;
scene.add(light);
const ambient = new THREE.AmbientLight(0x808080);
scene.add(ambient);

const loader = new THREE.FontLoader();
let font;
loader.load('/static/helvetiker_bold.typeface.json', function(font_) {
    font = font_;
});
        

// Helpers
// scene.add(new THREE.CameraHelper(light.shadow.camera));
// scene.add(new THREE.GridHelper(200, 50));
// scene.add(new THREE.AxisHelper(2000));
// scene.add(new THREE.DirectionalLightHelper(light, 20));

// Sound
//var music = new Audio('mymusic.mp3');
var ClickSound = new Audio("/static/sound/mBeam.wav");
var ShotSound1 = new Audio("/static/sound/sniperrifle--firing1.mp3");
var ShotSoundOthers1 =  ShotSound1.cloneNode();// new Audio("/static/sound/shotgun-firing1.mp3");
var ShotSound2 = new Audio("/static/sound/shotgun-firing1.mp3");
var ShotSound3 = new Audio("/static/sound/largerifle-firing1.mp3");
var EmptySound = new Audio("/static/sound/handgun-out-bullets1.mp3"); 
var SetGunSound = new Audio("/static/sound/set-gun.mp3"); 
var ReloadSound1 = new Audio("/static/sound/machinegun-slide1.mp3");
var ReloadSound2 = new Audio("/static/sound/shotgun-pumpaction1.mp3");
var ReloadSound3 = new Audio("/static/sound/largerifle-boltaction1.mp3");
var GiveDamageSound = new Audio("/static/sound/sword-clash4.mp3");//shot-struck1
var RecieveDamageSound = new Audio("/static/sound/stab.mp3");
var RemoveSound = new Audio("/static/sound/flee1.mp3");
var WallSetSound = new Audio("/static/sound/set-wall.mp3");
var WallDamageSound = new Audio("/static/sound/metal1.mp3"); //stab-wall
var UsedBandageSound = new Audio("/static/sound/recovery1.mp3");
var CannotUseBandageSound = new Audio("/static/sound/notcorrect1.mp3");
var ChurchSound = new Audio("/static/sound/church.mp3");
var GetItemSound = new Audio("/static/sound/puyon.mp3");

function mSoundEffect(s_, vol_)
{
    s_.pause();
    s_.currentTime = 0;
    s_.volume = vol_;
    s_.play();
}



//Pointer lock
function ElementRequestPointerLock(element){
    var list = [
        "requestPointerLock",
        "webkitRequestPointerLock",
        "mozRequestPointerLock"
    ];
    var i;
    var num = list.length;
    for(i=0;i < num;i++){
        if(element[list[i]]){
            element[list[i]]();
            return true;
        }
    }
    return false;
}

function DocumentExitPointerLock(document_obj){
    var list = [
        "exitPointerLock",
        "webkitExitPointerLock",
        "mozExitPointerLock"
    ];
    var i;
    var num = list.length;
    for(i=0;i < num;i++){
        if(document_obj[list[i]]){
            document_obj[list[i]]();
            return true;
        }
    }
    return false;
}


function animate() {
	requestAnimationFrame( animate );
	renderer.render( scene, camera );
}
animate();


function mShowHelp(){
    $("#help-screen").toggle();
}
$("#help-screen").hide();

//Stats();
const stats = new Stats();
stats.showPanel(0);
document.body.appendChild(stats.dom);


var mID = '';
var mWeapon = 1;
var mIsZoom = 0;
var mMode = 1;
let movement = {};
$(document).on('keydown keyup', (event) => {
    const KeyToCommand = {
        'ArrowUp': 'forward',
        'ArrowDown': 'back',
        'ArrowLeft': 'left',
        'ArrowRight': 'right',
        'w': 'forward',
        's': 'back',
        'a': 'sideleft',
        'd': 'sideright',
    };
    const command = KeyToCommand[event.key];
    if(command){
        if(event.type === 'keydown'){
            movement[command] = true;
        }else{ /* keyup */
            movement[command] = false;
        }
        socket.emit('movement', movement);
    }
    // if(event.key === ' ' && event.type === 'keydown'){
    //     socket.emit('shoot');        
    //     mSoundEffect(ShotSound1,1.0);
    // }
    if(event.key === 'q' && event.type === 'keydown'){
        socket.emit('buildWall');        
        //mSoundEffect(WallSetSound,1.0);
        mMode = 2;
    }
    if(event.key === 'z' && event.type === 'keydown'){
        socket.emit('buildFloor');        
        //mSoundEffect(WallSetSound,1.0);
        mMode = 2;
    }
    if(event.key === 'e' && event.type === 'keydown'){
        socket.emit('buildSlope');        
        //mSoundEffect(WallSetSound,1.0);
        mMode = 2;
    }
    if(event.key === 'y' && event.type === 'keydown'){
        socket.emit('jumper');        
        //mSoundEffect(WallSetSound,1.0);
        //mMode = 2;
    }
    if(event.key === 'Control'  && event.type === 'keydown'){
        socket.emit('squat');        
    }
    if(event.key === ' '  && event.type === 'keydown'){
        socket.emit('jump');        
    }
    if(event.key === '1'  && event.type === 'keydown'){
        socket.emit('weaponChange',1);  
        mWeapon = 1; 
        mSoundEffect(SetGunSound,1.0);
        mMode = 1;
    }
    if(event.key === '2'  && event.type === 'keydown'){
        socket.emit('weaponChange',2);     
        mWeapon = 2;   
        mSoundEffect(SetGunSound,1.0);
        mMode = 1;
    }
    if(event.key === '3'  && event.type === 'keydown'){
        socket.emit('weaponChange',3);       
        mWeapon = 3; 
        mSoundEffect(SetGunSound,1.0);
        mMode = 1;
    }
    if(event.key === '4'  && event.type === 'keydown'){
        socket.emit('weaponChange',4);       
        mWeapon = 4; 
        mMode = 1;
    }
    if(event.key === '5'  && event.type === 'keydown'){
        socket.emit('weaponChange',5);       
        mWeapon = 5;
        mMode = 1; 
    }
    if(event.key === 'r'  && event.type === 'keydown'){
        socket.emit('reload');
        if(mWeapon==1){
            mSoundEffect(ReloadSound1,1.0);
        }
        if(mWeapon==2){
            mSoundEffect(ReloadSound2,1.0);
        }
        if(mWeapon==3){
            mSoundEffect(ReloadSound3,1.0);
        }
    }
    if(event.key === 'f'  && event.type === 'keydown'){
        socket.emit('modeChanged', 1);
        mMode = 1;       
    }
    if(event.key === 'b'  && event.type === 'keydown'){
        socket.emit('emote');       
    }


    if(event.key === 'p'  && event.type === 'keydown'){
        ElementRequestPointerLock(canvas2d);
    }
    if(event.key === 'h'  && event.type === 'keydown'){
        mShowHelp();
    }

});

//--- Mouse event ---//
var mShootCount = 0;
canvas2d.addEventListener('mousedown', function(e)
{
    if(mMode==1){
        if(e.button==0){
            if(mWeapon<=3){
                movement['shoot'] = true;
                socket.emit('movement', movement);    
            }
            else if(mWeapon==4){
                socket.emit('useBandage', 1);
            }
            else if(mWeapon==5){
                socket.emit('usePotion', 1);
            }
        }//    

        if(e.button==2){
            camera.zoom = 2;
            if(mWeapon ==3){
                camera.zoom = 10;
            }
            camera.updateProjectionMatrix();
            //mSoundEffect(ShotSound2,1.0);
        }    
    }//
    else if(mMode==2){
        socket.emit('doBuild');   
        mSoundEffect(WallSetSound,1.0); 
        //mMode = 1;
    }


});

canvas2d.addEventListener('mouseup', function(e)
{
    if(e.button==0){
        movement['shoot'] = false;
        socket.emit('movement', movement);
    }

    if(e.button==2){
        camera.zoom = 1;
        camera.updateProjectionMatrix();
    }

});

var mLastMouseX = 0;
var mLastMouseY = 0;
canvas2d.addEventListener('mousemove', function(e)
{
    // use pointer lock
    var ang_ = (e.movementX) / 250 * 3.1415/2;
    socket.emit('mousemoveX', ang_);

    var ang2_ = (e.movementY) / 500 * 3.1415/2;
    socket.emit('mousemoveY', ang2_);

    //console.log('ang_:'+ang_+' movement:'+e.movementX);  
});

canvas2d.addEventListener('wheel', function(e)
{
    var v_ = e.wheelDelta;
    if(v_<0){ //up
        mWeapon += 1;
        //mWeapon = Math.min(5,mWeapon);
        if(mWeapon>=6){
            mWeapon = 1;
        }
    }
    if(v_>0){ //down
        mWeapon -= 1;
        //mWeapon = Math.max(1,mWeapon);
        if(mWeapon<=0){
            mWeapon = 5;
        }
    }
    console.log('mWeapon:'+mWeapon);  
    socket.emit('weaponChange',mWeapon);       
    //console.log('wheel:'+v_);  
});


//--- Touch event ---//
// Mobile gui
var mBtnRadius = canvasMob.height / 10;
var mBtnUp_Px = canvasMob.width / 5;
var mBtnUp_Py = canvasMob.height / 2;
var mBtnDown_Px = mBtnUp_Px;
var mBtnDown_Py = mBtnUp_Py + mBtnRadius * 3;
var mBtnRight_Px = mBtnUp_Px + mBtnRadius * 1.5;
var mBtnRight_Py = mBtnUp_Py + mBtnRadius * 1.5;
var mBtnLeft_Px = mBtnUp_Px - mBtnRadius * 1.5;
var mBtnLeft_Py = mBtnUp_Py + mBtnRadius * 1.5;

var mBtnAngUp_Px = canvasMob.width / 5 * 4;
var mBtnAngUp_Py = canvasMob.height / 3;
var mBtnAngDown_Px = mBtnAngUp_Px;
var mBtnAngDown_Py = mBtnAngUp_Py + mBtnRadius * 3;
var mBtnAngRight_Px = mBtnAngUp_Px + mBtnRadius * 1.5;
var mBtnAngRight_Py = mBtnAngUp_Py + mBtnRadius * 1.5;
var mBtnAngLeft_Px = mBtnAngUp_Px - mBtnRadius * 1.5;
var mBtnAngLeft_Py = mBtnAngUp_Py + mBtnRadius * 1.5;

var mBtnShoot_Px = canvasMob.width - mBtnRadius*1.5;
var mBtnShoot_Py = canvasMob.height / 4;
var mBtnReload_Px = mBtnShoot_Px;
var mBtnReload_Py = mBtnShoot_Py + mBtnRadius*2.5;
var mBtnJump_Px = mBtnShoot_Px - mBtnRadius*2.5;
var mBtnJump_Py = mBtnShoot_Py;
var mBtnSquat_Px = mBtnJump_Px;
var mBtnSquat_Py = mBtnReload_Py;


function mCreateMobileGUI(){

    var W_ = canvasMob.width;
    var H_ = canvasMob.height;
    var x_,y_,w_,w2_,h_;

    contextMob.clearRect(0, 0, W_, H_);
    
    var lw_ = canvasMob.height / 100;
    contextMob.globalAlpha = 0.5;
    contextMob.strokeStyle = "blue";
    contextMob.lineWidth = lw_;

    contextMob.beginPath();
    contextMob.arc(mBtnUp_Px, mBtnUp_Py, mBtnRadius, 0, Math.PI*2, 0);
    contextMob.stroke();

    contextMob.beginPath();
    contextMob.arc(mBtnDown_Px, mBtnDown_Py, mBtnRadius, 0, Math.PI*2, 0);
    contextMob.stroke();

    contextMob.beginPath();
    contextMob.arc(mBtnRight_Px, mBtnRight_Py, mBtnRadius, 0, Math.PI*2, 0);
    contextMob.stroke();

    contextMob.beginPath();
    contextMob.arc(mBtnLeft_Px, mBtnLeft_Py, mBtnRadius, 0, Math.PI*2, 0);
    contextMob.stroke();

    contextMob.strokeStyle = "red";
    contextMob.beginPath();
    contextMob.arc(mBtnShoot_Px, mBtnShoot_Py, mBtnRadius, 0, Math.PI*2, 0);
    contextMob.stroke();

    contextMob.beginPath();
    contextMob.arc(mBtnReload_Px, mBtnReload_Py, mBtnRadius, 0, Math.PI*2, 0);
    contextMob.stroke();

    contextMob.strokeStyle = "green";
    contextMob.beginPath();
    contextMob.arc(mBtnJump_Px, mBtnJump_Py, mBtnRadius, 0, Math.PI*2, 0);
    contextMob.stroke();

    contextMob.beginPath();
    contextMob.arc(mBtnSquat_Px, mBtnSquat_Py, mBtnRadius, 0, Math.PI*2, 0);
    contextMob.stroke();

    contextMob.globalAlpha = 1.0;
}

function mDis(x1,y1,x2,y2){
    return Math.sqrt( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) );
}


const touches = {};
$('#canvas-mob').on('touchstart', (event)=>{
    // socket.emit('shoot');
    // movement.forward = true;
    // socket.emit('movement', movement);
    Array.from(event.changedTouches).forEach((touch) => {
        touches[touch.identifier] = {pageX: touch.pageX, pageY: touch.pageY};

        var x_ = touch.pageX;
        var y_ = touch.pageY;
        var d_ = mDis(x_,y_,mBtnUp_Px,mBtnUp_Py);
        if( d_ <= mBtnRadius ){
            movement.forward = true;
            socket.emit('movement', movement);
        }

        d_ = mDis(x_,y_,mBtnDown_Px,mBtnDown_Py);
        if( d_ <= mBtnRadius ){
            movement.back = true;
            socket.emit('movement', movement);
        }

        d_ = mDis(x_,y_,mBtnRight_Px,mBtnRight_Py);
        if( d_ <= mBtnRadius ){
            movement.sideright = true;
            socket.emit('movement', movement);
        }

        d_ = mDis(x_,y_,mBtnLeft_Px,mBtnLeft_Py);
        if( d_ <= mBtnRadius ){
            movement.sideleft = true;
            socket.emit('movement', movement);
        }

        d_ = mDis(x_,y_,mBtnShoot_Px,mBtnShoot_Py);
        if( d_ <= mBtnRadius ){
            movement.shoot = true;
            socket.emit('movement', movement);
            ShotSound1.load();
        }

        d_ = mDis(x_,y_,mBtnReload_Px,mBtnReload_Py);
        if( d_ <= mBtnRadius ){
            socket.emit('reload');
        }

        d_ = mDis(x_,y_,mBtnJump_Px,mBtnJump_Py);
        if( d_ <= mBtnRadius ){
            socket.emit('jump');
        }

        d_ = mDis(x_,y_,mBtnSquat_Px,mBtnSquat_Py);
        if( d_ <= mBtnRadius ){
            socket.emit('squat');
        }

    });
    event.preventDefault();
});
$('#canvas-mob').on('touchmove', (event)=>{
    var W_ = canvas2d.width;
    var H_ = canvas2d.height;
    movement.right = false;
    movement.left = false;
    Array.from(event.touches).forEach((touch) => {
        const startTouch = touches[touch.identifier];

        if( (touch.pageX>W_/2) && (startTouch.pageX>W_/2)  ){
            movement.right |= touch.pageX - startTouch.pageX > 30;
            movement.left |= touch.pageX - startTouch.pageX < -30;    

            movement.angdown |= touch.pageY - startTouch.pageY > 30;
            movement.angup |= touch.pageY - startTouch.pageY < -30;
        }
    });
    socket.emit('movement', movement);
    event.preventDefault();
});
$('#canvas-mob').on('touchend', (event)=>{
    Array.from(event.changedTouches).forEach((touch) => {
        delete touches[touch.identifier];
    });
    if(Object.keys(touches).length === 0){
        movement = {};
        socket.emit('movement', movement);
    }
    event.preventDefault();
});


function gameStart(){
    const nickname = $("#nickname").val();
    socket.emit('game-start', {nickname: nickname});
    $("#start-screen").hide();
    $("#canvas-vic").hide();
    $("#help-screen").hide();

    if(mDeviceType=='Mobile'){
        mCreateMobileGUI();
        $("#canvas-mob").show();
        mSoundEffect(ShotSound1,vol_);
    }

    ElementRequestPointerLock(canvas2d);
}
$("#start-button").on('click', gameStart);



var mFontSize1 = Math.floor(canvas2d.width/100);
var mFontSize2 = mFontSize1*2;

var mDisplayDamage = 0;
const Meshes = [];
socket.on('state', (players, bullets, walls, slopes, rocks, bandages, potions, mStorm) => {

    stats.update();

    Object.values(Meshes).forEach((mesh) => {mesh.used = false;});
    
    var W_ = canvas2d.width;
    var H_ = canvas2d.height;
    context.clearRect(-W_/2, -H_/2, W_*2, H_*2);

    //Device
    context.font = mFontSize1+'px Bold Arial'; //'20px Bold Arial';
    context.fillStyle="black";
    context.fillText( mDeviceType+':'+screen.availWidth, W_/4, mFontSize1*1.5);
 

    var p_ = 0;
    // Players
    Object.values(players).forEach((player) => {
        let playerMesh = Meshes[player.id];
        if(!playerMesh){
            //console.log('create player mesh');
            playerMesh = new THREE.Group();
    		playerMesh.castShadow = true;
    		Meshes[player.id] = playerMesh;
    		scene.add(playerMesh);
        }
        playerMesh.used = true;
        var pz = player.tall;
        if(player.isSquat==1){
            pz = player.tall / 2;
        }
        var px = player.x;// + player.width/2;
        var py = player.z + pz/2*0;
        var pz = player.y;// + player.height/2;
        playerMesh.position.set(px, py, pz);
        playerMesh.rotation.y = - player.angle;
        
        var coA_ =-3.1415/180.0*10.0;
        var pL_ = player.tall/3;
        var pW_ = player.tall/2;
        var pW2_ = pL_/2;
        var A_ = 3.1415/10;
        var pA_ = A_;
        var ofz_ = -pW_/2;// * 2;
        var pa2_ = player.angle2;
        var ofx_ = 200 * Math.sin(-pa2_) * 0;
        var sq_ = player.isSquat;
        if(player.isMoving==1){
            pA_ = A_ * Math.sin( player.timeCount/10.0*3.1415*2.0);
        //     //console.log('timeCount:'+player.timeCount);
        }

        if(player.socketId !== socket.id){
            ofx_ = 0;
            ofz_ = 0;
        }

        let mesh1 = playerMesh.getObjectByName('bodyL1');
        if(mesh1){
            playerMesh.remove(mesh1);
            mesh1.geometry.dispose();
            mesh1 = null;
        }
        if(player.isBot==0){
            mesh = new THREE.Mesh(new THREE.BoxGeometry(pL_, pL_, pW2_), playerMaterialtx1);//playerMaterial1);
        }
        else{
            mesh = new THREE.Mesh(new THREE.BoxGeometry(pL_, pL_, pW2_), botMaterial1);
        }
        mesh.position.set(ofx_,pL_/2,pW2_/2+ofz_);
        mesh.rotation.z = - pA_;
        
        mesh.castShadow = true;
        mesh.name = 'bodyL1';
        playerMesh.add(mesh);

        let mesh2 = playerMesh.getObjectByName('bodyL2');
        if(mesh2){
            playerMesh.remove(mesh2);
            mesh2.geometry.dispose();
            mesh2 = null;
        }
        if(player.isBot==0){
            mesh = new THREE.Mesh(new THREE.BoxGeometry(pL_, pL_, pW2_), playerMaterialtx1);//playerMaterial1);
        }
        else{
            mesh = new THREE.Mesh(new THREE.BoxGeometry(pL_, pL_, pW2_), botMaterial1);
        }
        mesh.position.set(ofx_,pL_/2,-pW2_/2+ofz_);
        mesh.rotation.z =  pA_;
        mesh.castShadow = true;
        mesh.name = 'bodyL2';
        playerMesh.add(mesh);
        
        if(!playerMesh.getObjectByName('body')){
            //console.log('create body mesh');
    		// mesh = new THREE.Mesh(new THREE.BoxGeometry(player.width, pz, player.height), playerMaterial);
    		// mesh.castShadow = true;
    		// mesh.name = 'body';
            // playerMesh.add(mesh);
        }

        let meshB = playerMesh.getObjectByName('body');
        if(meshB){
            playerMesh.remove(meshB);
            meshB.geometry.dispose();
            meshB = null;
        }
        if(player.isBot==0){
            //mesh = new THREE.Mesh(new THREE.BoxGeometry(pL_, pL_, pW_), playerMaterial2);
            mesh = new THREE.Mesh(new THREE.BoxGeometry(pL_, pL_, pW_), playerMaterialtx1);
        }
        else{
            mesh = new THREE.Mesh(new THREE.BoxGeometry(pL_, pL_, pW_), botMaterial1);
        }
        mesh.position.set(ofx_,pL_/2+pL_-pL_/2*sq_,0+ofz_);
        mesh.rotation.y = -3.1415/4;
        mesh.rotation.z = -3.1415/3*sq_;
        mesh.castShadow = true;
        mesh.name = 'body';
        playerMesh.add(mesh);

        let meshA1 = playerMesh.getObjectByName('bodyA1');
        if(meshA1){
            playerMesh.remove(meshA1);
            meshA1.geometry.dispose();
            meshA1 = null;
        }
        if(player.isBot==0){
            //mesh = new THREE.Mesh(new THREE.BoxGeometry(pL_, pL_/2, pL_/2), playerMaterial2);
            mesh = new THREE.Mesh(new THREE.BoxGeometry(pL_, pL_/2, pL_/2), playerMaterialtx1);
        }
        else{
            mesh = new THREE.Mesh(new THREE.BoxGeometry(pL_, pL_/2, pL_/2), botMaterial1);
        }        
        mesh.position.set(ofx_,pL_*2-pL_/4-pL_*sq_,pW_/2+ofz_);
        mesh.rotation.y = 0;
        mesh.rotation.z = -player.angle2;
        mesh.castShadow = true;
        mesh.name = 'bodyA1';
        playerMesh.add(mesh);

        let meshA2 = playerMesh.getObjectByName('bodyA2');
        if(meshA2){
            playerMesh.remove(meshA2);
            meshA2.geometry.dispose();
            meshA2 = null;
        }
        if(player.isBot==0){
            //mesh = new THREE.Mesh(new THREE.BoxGeometry(pL_, pL_/2, pL_/2), playerMaterial2);
            mesh = new THREE.Mesh(new THREE.BoxGeometry(pL_, pL_/2, pL_/2), playerMaterialtx1);
        }
        else{
            mesh = new THREE.Mesh(new THREE.BoxGeometry(pL_, pL_/2, pL_/2), botMaterial1);
        }
        mesh.position.set(ofx_+pL_/2,pL_*2-pL_/4-pL_*sq_, -pW_/2+pL_/4+ofz_);
        mesh.rotation.y = -3.1415/4;;
        mesh.castShadow = true;
        mesh.name = 'bodyA2';
        playerMesh.add(mesh);

        let meshH = playerMesh.getObjectByName('bodyH');
        if(meshH){
            playerMesh.remove(meshH);
            meshH.geometry.dispose();
            meshH = null;
        }
        if(player.isBot==0){
            mesh = new THREE.Mesh(new THREE.BoxGeometry(pL_, pL_, pL_), playerMaterial3);
        }
        else{
            mesh = new THREE.Mesh(new THREE.BoxGeometry(pL_, pL_, pL_), playerMaterial3b);
        }
        mesh.position.set(ofx_+pL_/2*sq_, pL_/2+pL_*2 -pL_*sq_ ,+ofz_);
        mesh.rotation.y = 0;
        if(player.isEmote == 1){
            mesh.rotation.y = 3.1415 - coA_;
        }
        mesh.castShadow = true;
        mesh.name = 'bodyH';
        playerMesh.add(mesh);

        if(player.isBot==0){

            let meshFace = playerMesh.getObjectByName('bodyFace');
            if(meshFace){
                playerMesh.remove(meshFace);
                meshFace.geometry.dispose();
                meshFace = null;
            }
            meshFace = new THREE.Mesh(new THREE.PlaneGeometry(pL_, pL_, 1, 1), faceMaterial1); //playerMaterial3); //
            
            meshFace.position.set(ofx_+pL_/2*sq_+pL_/2, pL_/2+pL_*2 -pL_*sq_ ,+ofz_);
            meshFace.rotation.y = 3.1415/2;
            if(player.isEmote == 1){
                meshFace.position.set(ofx_+pL_/2*sq_+pL_/2*1.01*Math.cos(3.1415+coA_), pL_/2+pL_*2 -pL_*sq_ ,+ofz_+pL_/2*1.01*Math.sin(-coA_));
                meshFace.rotation.y = 3.1415/2 - coA_;
            } 
            //meshFace.castShadow = true;
            meshFace.name = 'bodyFace';
            playerMesh.add(meshFace);
        }


        let meshG = playerMesh.getObjectByName('bodyG');
        if(meshG){
            playerMesh.remove(meshG);
            meshG.geometry.dispose();
            meshG = null;
        }
        var gL_ = pL_*2;
        var gW_ = pL_/2;
        if(player.weapon==2){
            gW_ = pL_/2*2;
        }
        else if(player.weapon==3){
            gL_ = pL_*4;
        }
        
        if(player.weapon<=3){
            mesh = new THREE.Mesh(new THREE.BoxGeometry(gL_, pL_/2, gW_), playerMaterialg);
            mesh.position.set(ofx_+gL_/2*Math.cos(pa2_) ,pL_*2 -pL_*sq_ +gL_/2*Math.sin(-pa2_), pW_/2+ ofz_);
            mesh.rotation.y = 0;
            mesh.rotation.z = -pa2_;
            mesh.castShadow = true;
            mesh.name = 'bodyG';
            playerMesh.add(mesh);    
        }

        if((player.weapon==4) && (player.bandages>0) ){
            mesh = new THREE.Mesh(new THREE.CylinderGeometry(gW_,gW_,gL_,10,10,false), bandageMaterial); 
            mesh.position.set(ofx_+gL_/2*Math.cos(pa2_) ,pL_*2 -pL_*sq_ +gL_/2*Math.sin(-pa2_), pW_/2+ ofz_);
            mesh.rotation.y = 0;
            mesh.rotation.z = -pa2_;
            mesh.castShadow = true;
            mesh.name = 'bodyG';
            playerMesh.add(mesh);    
        }
        else if( (player.weapon==5) && (player.potions>0) ){
            mesh = new THREE.Mesh(new THREE.CylinderGeometry(gW_,gW_,gL_,10,10,false), potionMaterial); 
            mesh.position.set(ofx_+gL_/2*Math.cos(pa2_) ,pL_*2 -pL_*sq_ +gL_/2*Math.sin(-pa2_), pW_/2+ ofz_);
            mesh.rotation.y = 0;
            mesh.rotation.z = -pa2_;
            mesh.castShadow = true;
            mesh.name = 'bodyG';
            playerMesh.add(mesh);    
        }

        let meshF = playerMesh.getObjectByName('bodyF');
        if(meshF){
            playerMesh.remove(meshF);
            meshF.geometry.dispose();
            meshF = null;
        }
        if(player.isShoot == 1){
            mesh = new THREE.Mesh(new THREE.BoxGeometry(2, gW_*3, gW_*3), playerMaterialf);
            mesh.position.set(ofx_+gL_*Math.cos(pa2_) ,pL_*2 -pL_*sq_ +gL_*Math.sin(-pa2_), pW_/2+ ofz_);
            mesh.rotation.y = 0;
            mesh.rotation.z = -pa2_;
            mesh.rotation.x = Math.random()* 3.1415 / 2;
            mesh.castShadow = true;
            mesh.name = 'bodyF';
            playerMesh.add(mesh);    
        }

        let meshP = playerMesh.getObjectByName('bodyP');
        if(meshP){
            playerMesh.remove(meshP);
            meshP.geometry.dispose();
            meshP = null;
        }
        if(player.mode==0){
            //mesh = new THREE.Mesh(new THREE.PlaneGeometry(pL_*2, pL_*8, 1,1), paraMaterial1);
            mesh = new THREE.Mesh(new THREE.BoxGeometry(pL_*2, pL_/4, pL_*8), paraMaterial1);
            mesh.position.set(ofx_, pL_*4, ofz_);
            //mesh.rotation.x = Math.PI/2;
            mesh.castShadow = true;
            mesh.name = 'bodyP';
            playerMesh.add(mesh);    
        }


        // buildTemp
        if(player.socketId === socket.id){
            if(player.buildTemp)
            { 
                let wallt = player.buildTemp;
                let walltMesh = Meshes[wallt.id];
                if(!walltMesh){
                    console.log('walltMesh');
                    walltMesh = new THREE.Mesh(new THREE.BoxGeometry(wallt.width, wallt.tall, wallt.height), wallMaterial_t);
                    var wx = wallt.x + wallt.width/2 -px*0;
                    var wy = wallt.z + wallt.tall/2 -py*0;
                    var wz = wallt.y + wallt.height/2 -pz*0;
                    if(player.buildType==2){
                        wx = wallt.x + mFieldGridSize/2;
                        wz = wallt.y + mFieldGridSize/2;
                        wy = wallt.z - wallt.tall;
                    }
                    walltMesh.position.set(wx, wy, wz);
                    
                    if(player.buildType==2){
                        walltMesh.rotation.y = wallt.angle;
                        walltMesh.rotation.z = wallt.angle2;
                        if((wallt.angle == 3.1415/2)||(wallt.angle == 3.1415/2*3) ){
                            walltMesh.rotation.z = -wallt.angle2;
                        }    
                    }
                    //walltMesh.castShadow = true;
                    //Meshes.push(walltMesh);
                    Meshes[wallt.id] = walltMesh;
                    scene.add(walltMesh);
                }
                if(player.mode == 2){
                    walltMesh.used = true;
                    console.log('walltMesh used');
                }
                
            }
        }

        
        if(font){
            if(!playerMesh.getObjectByName('nickname'))
            {
                //console.log('create nickname mesh');
                if(player.socketId !== socket.id){
                    let meshN = playerMesh.getObjectByName('nickname');

                    if(!meshN){
                        meshN = new THREE.Mesh(
                            new THREE.TextGeometry(player.nickname,
                                {font: font, size: 10, height: 1}),
                                nicknameMaterial,
                        );
                        meshN.name = 'nickname';
                        playerMesh.add(meshN);    
                    }
                    meshN.position.set(0, player.tall+20, 0);
                    meshN.rotation.y = -Math.PI/2;
                }
            }
            {
                // if(player.socketId !== socket.id)
                // {
                //     let mesh = playerMesh.getObjectByName('health');

                //     if(mesh && mesh.health !== player.health){
                //         playerMesh.remove(mesh);
                //         mesh.geometry.dispose();
                //         mesh = null;
                //     }
                //     if(!mesh){
                //         //console.log('create health mesh');
                //         mesh = new THREE.Mesh(
                //             new THREE.TextGeometry('*'.repeat(player.health),
                //                 {font: font, size: 10, height: 1}),
                //                 textMaterial,
                //         );
                //         mesh.name = 'health';
                //         mesh.health = player.health;
                //         playerMesh.add(mesh);
                //     }
                //     mesh.position.set(0, player.tall, 0);
                //     mesh.rotation.y = -Math.PI/2;
                // }//
            }
        }
        
        
        if(player.socketId === socket.id){
            // Your player
            var d_ = 120;//170;

            // Camera
			camera.position.set(
			    player.x - d_ * Math.cos(player.angle +coA_) * Math.cos(pa2_),
			    player.z + (player.tall -player.tall/2*sq_)*0.8 + d_*Math.sin(pa2_),
                player.y - d_ * Math.sin(player.angle+coA_) * Math.cos(pa2_) 
            );

            //camera.rotation.order = "XYZ";
            camera.rotation.order = "YXZ";
            camera.rotation.y = - player.angle - Math.PI/2;
            camera.rotation.x = -player.angle2;

            // Write to 2D canvas
            var x_,y_,w_,w2_,h_;
            
            // Scope
            if( (mWeapon==3) && (camera.zoom != 1) )
            {    
                context.strokeStyle="black";
                var r_ = W_/2*0.52;
                context.lineWidth = 1;
                context.beginPath();
                context.arc(W_/2, H_/2, r_, 0, Math.PI*2, false);
                context.closePath();
                context.stroke();

                r_ = W_/2*0.6;
                context.lineWidth = 50;
                context.beginPath();
                context.arc(W_/2, H_/2, r_, 0, Math.PI*2, false);
                context.closePath();
                context.stroke();
                
                context.lineWidth = 1;
                context.beginPath();
                context.moveTo(W_/2, H_/2-r_);
                context.lineTo(W_/2, H_/2+r_);
                context.closePath();
                context.stroke();
            }
            //else{
                var s_ = W_/30;
                context.strokeStyle="black";
                context.lineWidth = 2;
                context.beginPath();
                context.setLineDash([5,10]);
                context.moveTo(W_/2, H_/2-s_);
                context.lineTo(W_/2, H_/2+s_);
                context.closePath();
                context.stroke();
                context.beginPath();
                context.moveTo(W_/2-s_, H_/2);
                context.lineTo(W_/2+s_, H_/2);
                context.closePath();
                context.stroke();

                context.setLineDash([]);
            //}

            // Player angle
            x_ = canvas2d.width / 2;
            y_ = mFontSize2;
            context.font = mFontSize2 + 'px Bold Arial';
            context.fillStyle="black";
            context.fillText( Math.floor(player.angle/3.1415*180), x_, y_);

            y_ = mFontSize2*2;
            context.fillText( Math.floor(-player.angle2/3.1415*180), x_, y_);

            // life gauge
            context.strokeStyle = 'black';
            context.fillStyle='green'; 
            if(player.inStorm==1){
                context.fillStyle='red';
            }
            w_ = canvas2d.width / 4;
            w2_ = canvas2d.width / 4 * player.health / player.maxHealth;
            h_ = canvas2d.height / 20;
            x_ = canvas2d.width / 20;
            y_ = canvas2d.height - h_*2;
            //console.log('life:'+[x_,y_,w_,w2_,h_]);
            context.fillRect(x_,y_,w2_,h_);
            context.strokeRect(x_,y_,w_,h_);
            
            // potion gauge
            context.fillStyle='skyblue'; 
            w_ = canvas2d.width / 4;
            w2_ = canvas2d.width / 4 * player.shield / player.maxShield;
            h_ = canvas2d.height / 20;
            x_ = canvas2d.width / 20;
            y_ = canvas2d.height - h_*3;
            context.fillRect(x_,y_,w2_,h_);
            context.strokeRect(x_,y_,w_,h_);


            //weapons
            w_ = canvas2d.width / 5;
            w2_ = w_ / 5;
            h_ = canvas2d.height / 10;
            x_ = canvas2d.width / 4 * 3;
            y_ = canvas2d.height - h_*2;
            
            context.lineWidth = 10;
            for(var i=0;i<5;i++){
                context.strokeStyle = 'white';
                context.strokeRect(x_+w2_*i,y_,w2_,h_);
            }
            context.strokeStyle = 'red';
            context.strokeRect(x_+w2_*(player.weapon-1),y_,w2_,h_);

            context.font = mFontSize2+ 'px Bold Arial';
            context.fillStyle="black";
            context.fillText( 'AR', x_+w2_*0+10,y_+h_*0.7);
            context.fillText( 'SG', x_+w2_*1+10,y_+h_*0.7);
            context.fillText( 'SR', x_+w2_*2+10,y_+h_*0.7);
            context.fillText( 'B'+player.bandages, x_+w2_*3+10,y_+h_*0.7);
            context.fillText( 'P'+player.potions, x_+w2_*4+10,y_+h_*0.7);

            // give damage
            if(mDisplayDamage>0){
                x_ = W_/2;
                y_ = H_/2;
                var t_ = mDisplayDamage * 3;
                context.font = (mFontSize1*5)+'px Bold Arial';
                context.fillStyle="yellow";
                context.fillText( ' +'+player.giveDamage*1, x_+t_,y_-t_);        
            }


        }// your player

        // Player list
        if(1){
            var x_,y_,w_,w2_,h_;
            w_ = canvas2d.width / 8;
            h_ = canvas2d.height / 60;
            x_ = canvas2d.width / 50;
            y_ = 100 + h_*4*p_;

            context.lineWidth = 1;
            context.font = mFontSize1+'px Bold Arial';
            context.fillStyle="white";
            context.fillText(player.nickname, x_, y_-3);
            context.strokeStyle = 'black';

            context.fillStyle='skyblue';
            w2_ = w_ * player.shield / player.maxShield;
            context.fillRect(x_,y_,w2_,h_);
            context.strokeRect(x_,y_,w_,h_);
            context.fillStyle='green';
            if(player.inStorm==1){
                context.fillStyle='red';
            }
            y_ += h_; 
            w2_ = w_ * player.health / player.maxHealth;
            context.fillRect(x_,y_,w2_,h_);
            context.strokeRect(x_,y_,w_,h_);
        }

        p_ += 1;
    }); //players
    
    // Bullets
    Object.values(bullets).forEach((bullet) => {
        let mesh = Meshes[bullet.id];
        if(!mesh){
            mesh = new THREE.Mesh(new THREE.BoxGeometry(bullet.width, bullet.height, bullet.height), bulletMaterial);
		    mesh.castShadow = true;
    		Meshes[bullet.id] = mesh;
		    // Meshes.push(mesh);
		    scene.add(mesh);
        }
        mesh.used = true;
        var bl = bullet.width/2;
        var ba = bullet.angle;
        var ba2 = bullet.angle2;
        mesh.position.set(bullet.x + bl*Math.cos(-ba2)*Math.cos(ba)*0, bullet.z + bl*Math.sin(-ba2)*0, bullet.y + bl*Math.cos(-ba2)*Math.sin(ba)*0);
        mesh.rotation.y = - ba;
        mesh.rotation.z = - ba2;
    });
    
    // Walls
    Object.values(walls).forEach((wall) => {
        let mesh = Meshes[wall.id];
        if(!mesh){
    		mesh = new THREE.Mesh(new THREE.BoxGeometry(wall.width, wall.tall, wall.height), wallMaterial);
    		mesh.castShadow = true;
    		//Meshes.push(mesh);
    		Meshes[wall.id] = mesh;
    		scene.add(mesh);
        }
        mesh.used = true;
        mesh.position.set(wall.x + wall.width/2, wall.z+wall.tall/2, wall.y + wall.height/2);
        //mesh.rotation.y = - wall.angle;
    });

    // Rocks
    Object.values(rocks).forEach((rock) => {
        let mesh = Meshes[rock.id];
        if(!mesh){
            mesh = new THREE.Mesh(new THREE.BoxGeometry(rock.width, rock.tall, rock.height), rockMaterial);
            //Meshes.push(mesh);
            Meshes[rock.id] = mesh;
            scene.add(mesh);
        }
        mesh.used = true;
        mesh.position.set(rock.x + rock.width/2, rock.z+rock.tall/2, rock.y + rock.height/2);
        //mesh.rotation.y = - wall.angle;
    });

    // Slopes
    Object.values(slopes).forEach((slope) => {
        let mesh = Meshes[slope.id];
        if(!mesh){
            mesh = new THREE.Mesh(new THREE.BoxGeometry(slope.width, slope.tall, slope.height), wallMaterial);
            //Meshes.push(mesh);
            Meshes[slope.id] = mesh;
            scene.add(mesh);
        }
        mesh.used = true;
        mesh.position.set(slope.x + mFieldGridSize/2, slope.z - slope.tall, slope.y + mFieldGridSize/2);
        mesh.rotation.y = slope.angle;
        mesh.rotation.z = slope.angle2;    
        if((slope.angle == 3.1415/2)||(slope.angle == 3.1415/2*3) ){
            mesh.rotation.z = -slope.angle2;
        }    
    });

    
    // Bandages
    Object.values(bandages).forEach((bandage) => {
        let mesh = Meshes[bandage.id];
        if(!mesh){
            mesh = new THREE.Mesh(new THREE.CylinderGeometry(bandage.width,bandage.width,bandage.tall,10,10,false), bandageMaterial); 
            mesh.position.set(bandage.x + bandage.width/2, bandage.z+bandage.tall/2, bandage.y + bandage.height/2);
    		mesh.castShadow = true;
    		Meshes.push(mesh);
    		Meshes[bandage.id] = mesh;
    		scene.add(mesh);            
        }
        mesh.used = true;
        
    });

    // Potions
    Object.values(potions).forEach((potion) => {
        let mesh = Meshes[potion.id];
        if(!mesh){
    		mesh = new THREE.Mesh(new THREE.CylinderGeometry(potion.width,potion.width,potion.tall,10,10,false), potionMaterial); 
    		mesh.castShadow = true;
    		Meshes.push(mesh);
    		Meshes[potion.id] = mesh;
    		scene.add(mesh);
        }
        mesh.used = true;
        mesh.position.set(potion.x + potion.width/2, potion.z+potion.tall/2, potion.y + potion.height/2);
    });

    
    let meshStorm = Meshes[mStorm.id];
    if(!meshStorm){
        meshStorm = new THREE.Mesh(new THREE.CylinderGeometry(mStorm.width, mStorm.width, FIELD_WIDTH, 50,50,true), stormMaterial); 
        Meshes.push(meshStorm);
        Meshes[mStorm.id] = meshStorm;
        scene.add(meshStorm);    
    }
    meshStorm.used = true;
    meshStorm.position.set(mStorm.x, -10, mStorm.y);
    var storm_scale = mStorm.width / meshStorm.geometry.parameters.radiusTop;
    //console.log('storm:'+mStorm.width+', '+meshStorm.geometry.parameters.radiusTop);
    console.log('storm:'+storm_scale);
    meshStorm.scale.x = storm_scale;
    meshStorm.scale.z = storm_scale;


    
    // Clear unused Meshes
    Object.keys(Meshes).forEach((key) => {
        const mesh = Meshes[key];
        if(!mesh.used){
            //console.log('removing mesh', key);
            scene.remove(mesh);
            mesh.traverse((mesh2) => {
                if(mesh2.geometry){
                    mesh2.geometry.dispose();
                }
            });
            delete Meshes[key];
        }
    });
});

// Victory
function mDrawVictroy(){

    var W_ = canvasVic.width;
    var H_ = canvasVic.height;
    var x_,y_,w_,w2_,h_;

    contextVic.clearRect(0, 0, W_, H_);
    
    var s_ = (mFontSize1*10);
    x_ = W_ / 4;
    y_ = H_ / 10;
    w_ = W_/2;
    h_ = s_ * 1.3;
    contextVic.fillStyle="blue";
    contextVic.fillRect(x_, y_, w_, h_);

    x_ = W_ / 2 - s_*2;
    y_ += s_;
    contextVic.font = s_+'px Bold Arial';
    contextVic.fillStyle="white";
    contextVic.fillText( '#1 優勝!!', x_, y_);
    s_ = (mFontSize1*2);
    y_ +=  s_;
    contextVic.font = s_+'px Bold Arial';
    contextVic.fillStyle="white";
    x_ = W_ / 2 - s_*3;
    contextVic.fillText( '夕飯はお寿司だ', x_, y_);

}

function mDrawResults(n_){

    var W_ = canvasVic.width;
    var H_ = canvasVic.height;
    var x_,y_,w_,w2_,h_;

    contextVic.clearRect(0, 0, W_, H_);
    
    var s_ = (mFontSize1*10);
    x_ = W_ / 2 - s_;
    y_ = H_ / 5;
    contextVic.font = s_+'px Bold Arial';
    contextVic.fillStyle="black";
    contextVic.fillText( '#'+n_, x_,y_);
    contextVic.font = '40px Bold Arial';

}


socket.on('id', id_ => {
    mID = id_;
    console.log('mID:'+mID);
});

socket.on('shoot', function(a_) {
    var id_ = a_[0];
    var wp_ = a_[1];
    var vol_ = 0.3;

    if(id_==mID){
        vol_=1.0;
        if(wp_==1){
            mSoundEffect(ShotSound1,vol_);
        }
        else if(wp_==2){
            mSoundEffect(ShotSound2,vol_);
        }
        else if(wp_==3){
            mSoundEffect(ShotSound3,vol_);
        }    
    }
    else{
        if(wp_==1){
            mSoundEffect(ShotSound1.cloneNode(),vol_);
        }
        else if(wp_==2){
            mSoundEffect(ShotSound2.cloneNode(),vol_);
        }
        else if(wp_==3){
            mSoundEffect(ShotSound3.cloneNode(),vol_);
        }    
    }


});

socket.on('empty', () => {
    mSoundEffect(EmptySound,1.0);
});

socket.on('shootFromOthers', function(a_) 
{
    //console.log('shootFromOthers:'+a_[0]);
    if(a_[0]==1){
        mSoundEffect(ShotSound1,a_[1]);
    }
    else if(a_[0]==2){
        mSoundEffect(ShotSound2,a_[1]);
    }
    else if(a_[0]==3){
        mSoundEffect(ShotSound3,a_[1]);
    }
    
});

socket.on('shootFromBot', vol_ => {
    mSoundEffect(ShotSoundOthers1,vol_);
});

socket.on('displayGiveDamage', v_ => {
    mDisplayDamage = v_;
});

socket.on('givedamage', vol_ => {
    mSoundEffect(GiveDamageSound,vol_);
});
socket.on('recievedamage', vol_ => {
    mSoundEffect(RecieveDamageSound,vol_);
});
socket.on('walldamage', vol_ => {
    mSoundEffect(WallDamageSound,vol_);
});

socket.on('deadothers', () => {
    mSoundEffect(RemoveSound,1.0);
});

socket.on('getItem', () => {
    mSoundEffect(GetItemSound,1.0);
});

socket.on('usedBandage', () => {
    mSoundEffect(UsedBandageSound,1.0);
});

socket.on('cannotUseBandage', () => {
    mSoundEffect(CannotUseBandageSound,1.0);
});

socket.on('usedPotion', () => {
    mSoundEffect(UsedBandageSound,1.0);
});

socket.on('cannotUsePotion', () => {
    mSoundEffect(CannotUseBandageSound,1.0);
});

socket.on('victory', () => {
    DocumentExitPointerLock(canvas2d);
    mDrawVictroy();
    //$("#help-screen").show();
    $("#canvas-vic").show();
    //$("#start-screen").show();
    
    //mSoundEffect(ChurchSound,1.0);
    ChurchSound.play();
});

socket.on('dead', n_ => {
    if(n_>1){
        mDrawResults(n_);
        $("#canvas-vic").show();
    }
    $("#help-screen").show();
    $("#start-screen").show();  
});

-ゲーム, プログラミング

執筆者:

関連記事

今さらNode.js+Three.jsでゲームを作る理由 – なぜUnity, Unreal Engineでないのか

目次 目的を「コードを書いてゲームを作る」に絞る捨てる物余談、私自身の目的皆さんに言えるJavascriptでゲームを作るメリット 目的を「コードを書いてゲームを作る」に絞る ゲーム作成経験のない場合 …

iPhoneアプリ公開でAppStoreにて言語が英語になる場合の対処 | Xcode

日本語にしか対応していないアプリを作成してAppStoreConnectでも言語を日本語しか選択していないのに、公開したらAppStoreでの言語表記が「英語」に。日本語にしたい場合の対処法です。[対 …

Admob アプリ起動時広告(Open ad)は使わない事にした話 – 例題通りやっても審査落ち?

Admob広告は初期にはバナーとインタースティシャルしかなかったと記憶しています。その後、少し複雑なリワード広告が登場しました。新しい広告タイプについてはWebに情報が増えてきたら実装に挑戦しています …

ライフゲームをWebブラウザで遊ぶ Conway’s Game of Life – Javascript (ソースコード公開あり)

ブラウザで遊べるライフゲーム(Conway’s Game of Life)を作成してみました。緑の自セルを配置して赤い敵セルを消してみましょう。基本的なパター …

Railway.appでついにRegion選択が可能になった – 2023年版PaaS選び

PaaS選びの際、Web検索で情報収集をすると多くの記事が見つかりますが、料金情報などを並べただけで実際に利用した情報がないように思われます。本記事では実際に身銭を切っている立場からPaaS選びについ …

スポンサーリンク