2D Array Platformer Wall Collision - Javascript - PullRequest
0 голосов
/ 08 мая 2018

Я пытаюсь построить платформерную игру в 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 голосов
/ 08 мая 2018

Допустим, номер 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;
          }
         }
        }    
    }
}}
...