2D阵列平台墙碰撞 - Javascript

时间:2018-05-08 14:00:02

标签: javascript arrays multidimensional-array collision

我试图用javascript构建一个平台游戏,使用二维数组进行关卡设计。

您可以在此处查看我的代码:https://pastebin.com/bGRqsrPM

var c;
var ctx;

var gridMap = [

    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

];

var tileW = 40;
var tileH = 40;

var player = new Player(0, 0, 40, 0);

var floor = false;

var holdLeft;
var holdRight;

window.onload = function(){

    c = document.getElementById('game');
    ctx = c.getContext('2d');

    drawRect(0, 0, c.width, c.height, 'black');

    document.addEventListener('keydown', keyDown);
    document.addEventListener('keyup', keyUp);

    update();

}

function keyDown(e){

    switch(e.keyCode){

        case 38:
            if(floor){

                player.yVel = -5;   

            }           
            break;
        case 37:
            holdLeft = true;
            break;      
        case 39:
            holdRight = true;
            break;
    }


}

function keyUp(e){

    switch(e.keyCode){

        case 38:
            if(player.yVel < -5){

                    player.yVel = -5;               

                }                   
            break;
        case 37:
            holdLeft = false;
            break;
        case 39:
            holdRight = false;
            break;
    }


}


var drawRect = function (x, y, size, color){

    ctx.fillStyle = color;
    ctx.fillRect(x, y, size, size);

}

function Player(x, y, s, v){

    this.x = x;
    this.y = y;
    this.s = s;
    this.v = v;

    this.xVel = 0;
    this.yVel = 0;

    this.move = function(){

        this.y += this.yVel;
        this.x += this.xVel;

    }

    this.draw = function(){

        ctx.fillStyle =  'red';
        ctx.fillRect(this.x, this.y, this.s, this.s);
        ctx.fillStyle =  'black';   

    }


}

function gravity(){ 

        player.yVel += 0.2; 

}

function drawGrid(){

    for(col=0; col < gridMap.length; col++){

        for(row=0; row < gridMap[col].length; row++){

            if(gridMap[col][row] == 1){

                drawRect(row*tileW, col*tileH, tileH, 'white');

            }           

        }

    }
}



function checkFloor(){

    for(col=0; col < gridMap.length; col++){

        for(row=0; row < gridMap[col].length; row++){           

            if(gridMap[col][row] == 1){

                var tileX = row*tileW;
                var tileY = col*tileH;


                if(player.x + player.s >= tileX && player.x <= tileX + tileW && player.y + player.s >= tileY && player.y <= tileY + tileH){                 

                    floor = true;
                    player.yVel = 0;
                    player.y = tileY - player.s;

                }


            }                   

        }
    }

}


function update(){  

    drawRect(0, 0, c.width, c.height, 'black');

    drawGrid();

    if(floor){

        player.xVel *= 0.8;

    }
    else{

        gravity();  

    }

    floor = false;

    if(holdLeft){

        player.xVel = -2;
    }   

    if(holdRight){

        player.xVel = 2;
    }

    player.move();  

    checkFloor();

    player.draw();

    requestAnimationFrame(update);  

}

让玩家在平台上行走工作正常 - 但我无法找到一个逻辑解决方案让我的角色在接近墙壁时停止移动。

显然,它会被抛到顶部的瓷砖上,因为我的代码正在检查玩家坐标是否与平台重叠。

因此,我需要检查我的播放机前面的下一个瓷砖是否是墙,并阻止我的角色进一步移动。

有关如何完成此任务的任何建议?

感谢

1 个答案:

答案 0 :(得分:0)

让我们说2号是一堵墙。由于你在checkFloor中循环,你可以检查与2号的碰撞。希望这个例子让你知道你可以做什么。

function checkFloor(){

for(col=0; col < gridMap.length; col++){

    for(row=0; row < gridMap[col].length; row++){           

        if(gridMap[col][row] == 1){

            var tileX = row*tileW;
            var tileY = col*tileH;


            if(player.x + player.s >= tileX && player.x <= tileX + tileW && player.y + player.s >= tileY && player.y <= tileY + tileH){                 

                floor = true;
                player.yVel = 0;
                player.y = tileY - player.s;

            }
        }else  if(gridMap[col][row] == 2){  
          var tileX = row*tileW;
          //if player + the next movement is same as tileX stop the movement
          if((player.xVel+player.x) == tileX){
             player.xVel = 0;
          }
         }
        }    
    }
}}