ゲーム プログラミング

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

投稿日:

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

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

【概要】
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();  
});

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

執筆者:

関連記事

Android studio|FFmpegでやりたい放題するための準備

動画を利用したアプリを作成するにあたりFFmpegを使用できると大変便利です。Web上に多数の情報がありますが、数年前の記事は役に立たなかったり、実用的な情報が少なかったりします。本記事ではAndro …

弾丸と壁/人の接触判定を少し真面目に実装してみる|ゲーム作成

フォートナイトみたいなオンラインバトロワゲームを作っています。優秀なサンプルコードから作成を開始したので早い段階で一応形にはなりました。しかし、サンプルをいじりすぎて接触判定に矛盾が生じてきてしまいま …

Found an unexpected Mach-O header code: 0x72613c21 への対処 Xcode, Admob, xcframework

日々変わっていくAdmobの仕様への対応にとても苦労しています。そんな中、アプリをApple Store Connectへ提出するためXcodeにてArchiveを作成してValidateしようとした …

Fortnite won’t launch. How to fix it? [Mac OSX/MacBook pro]

[Last verification: 2020/07/19 v13.20 ][Solution]Just update the Mac OSX to 10.15 (Catalina).With 10 …

エピックのアップル提訴問題 じゃあフォートナイトフォン作っちゃいなよ

8月13日、フォートナイトの開発元の米エピックゲームズがスマホアプリ課金システムなどが独占に当たるとして米アップルと米グーグルを提訴したそうです。現在、多数のフォートナイトプレイヤーYouTuberの …

スポンサーリンク