0
\$\begingroup\$

I've been watching this tutorial and found the code works flawlessly. Although, there is something he doesn't cover in the video. How to move the player one tile at a time. Every tutorial I've found (alot) only explains how to make a player move with acceleration. For example, this tutorial shows a similar process. The code is below.

(function(){

var canvas = document.getElementById("canvas");   // the canvas where game will be drawn
var context = canvas.getContext("2d");            // canvas context
var levelCols=11;                           // level width, in tiles
var levelRows=9;                            // level height, in tiles
var tileSize=32;                            // tile size, in pixels
var playerCol=5;                                  // player starting column
var playerRow=4;                                  // player starting row
var leftPressed=false;                            // are we pressing LEFT arrow key?
var rightPressed=false;                           // are we pressing RIGHT arrow key?
var upPressed=false;                              // are we pressing UP arrow key?
var downPressed=false;                            // are we pressing DOWN arrow key?
var movementSpeed=3;                              // the speed we are going to move, in pixels per frame
var playerXSpeed=0;                               // player horizontal speed, in pixels per frame
var playerYSpeed=0;                               // player vertical speed, in pixels per frame

var level = [                               // the 11x9 level - 1=wall, 0=empty space
    [1,1,1,1,1,1,1,1,1,1,1],
    [1,1,0,0,0,0,0,0,0,1,1],
    [1,0,0,0,0,0,0,0,0,0,1],
    [1,0,0,0,1,0,1,0,0,0,1],
    [1,0,0,0,0,0,0,0,0,0,1],
    [1,0,0,0,1,0,1,0,0,0,1],
    [1,0,0,0,0,0,0,0,0,0,1],
    [1,1,0,0,0,0,0,0,0,1,1],
    [1,1,1,1,1,1,1,1,1,1,1]
];

var playerYPos=playerRow*tileSize;              // converting Y player position from tiles to pixels
var playerXPos=playerCol*=tileSize;               // converting X player position from tiles to pixels

canvas.width=tileSize*levelCols;                   // canvas width. Won't work without it even if you style it from CSS
canvas.height=tileSize*levelRows;                   // canvas height. Same as before

// simple WASD listeners

document.addEventListener("keydown", function(e){
    console.log(e.keyCode);
    switch(e.keyCode){
        case 65:
            leftPressed=true;
            break;
        case 87:
            upPressed=true;
            break;
        case 68:
            rightPressed=true;
            break;
        case 83:
            downPressed=true;
            break;
    }
}, false);

document.addEventListener("keyup", function(e){
    switch(e.keyCode){
        case 65:
            leftPressed=false;
            break;
        case 87:
            upPressed=false;
            break;
        case 68:
            rightPressed=false;
            break;
        case 83:
            downPressed=false;
            break;
    }
}, false);

// function to display the level

function renderLevel(){
    // clear the canvas
    context.clearRect(0, 0, canvas.width, canvas.height);
    // walls = red boxes
    context.fillStyle = "#ff0000";
    for(i=0;i<levelRows;i++){
        for(j=0;j<levelCols;j++){
            if(level[i][j]==1){
                context.fillRect(j*tileSize,i*tileSize,tileSize,tileSize);  
            }
        }
    }
    // player = green box
    context.fillStyle = "#00ff00";
    context.fillRect(playerXPos,playerYPos,tileSize,tileSize);
}

// this function will do its best to make stuff work at 60FPS - please notice I said "will do its best"

window.requestAnimFrame = (function(callback) {
    return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
    function(callback) {
        window.setTimeout(callback, 1000/60);
    };
})();

// function to handle the game itself

function updateGame() {

    // no friction or inertia at the moment, so at every frame initial speed is set to zero
    playerXSpeed=0;
    playerYSpeed=0;

    // updating speed according to key pressed
    if(rightPressed){
        playerXSpeed=movementSpeed
    }
    else{
        if(leftPressed){
            playerXSpeed=-movementSpeed;
        }
        else{
            if(upPressed){
                playerYSpeed=-movementSpeed;
            }
            else{
                if(downPressed){
                    playerYSpeed=movementSpeed;
                }         
            }          
        }         
    }

    // updating player position

    playerXPos+=playerXSpeed;
    playerYPos+=playerYSpeed;

    // rendering level

    renderLevel();

    // update the game in about 1/60 seconds

    requestAnimFrame(function() {
        updateGame();
    });
}

updateGame();

})();

I would appreciate any assistance.

EDIT:

I've fixed the move tile to tile issue, and I've stopped the player from moving continuously while holding down the key. Now, I'm having an issue with collision.

//Check if tile is a path
function isPathTile(level, x, y) {
    return (level[x][y] === 0);
}                      

I added this code along with changing this:

//No collision detected
if(rightPressed){
    if (isPathTile(level, playerXPos + 32, playerYPos)) {
        playerXPos +=32;
    }
        rightPressed=false;
    }
else{
    if(leftPressed){
        playerXPos -=32;
        leftPressed=false;
    }
    else{
        if(upPressed){
            playerYPos -=32;
            upPressed=false;
        }
        else{
            if(downPressed){
                playerYPos +=32;
                downPressed=false;
            }         
        }          
    }         
}

Currently I only set the right movement to check for collision, so If something went wrong I can still check the other options (that should work fine). When hitting the right key the page freezes. something I'm missing? I imagine it has something to do with the level index array not being at the same scale as the players movements (32 per tile). I'm not sure how to fix this beyond multiplying the index by 32.

\$\endgroup\$
  • \$\begingroup\$ What have you tried so far? \$\endgroup\$ – Ocelot Jun 30 '19 at 0:10
  • \$\begingroup\$ I've tried removing the speed variable entirely and replacing the update game fuction if else statements with changes to the players current position. playerXPos "+=1" and vis versa. Although, this dosn't stop the player from moving if they continue to press the button. I want a single click. \$\endgroup\$ – Jason Schayer Jun 30 '19 at 0:54
  • 1
    \$\begingroup\$ You should study in details what the code does then. Through experimentation or the use of the search engines, looking up each function you have no idea about the purpose it serves. But to give a hint onto the right direction, try to add code right in the switch statement of a certain button in addEventListener() of the event "keyup". \$\endgroup\$ – Ocelot Jun 30 '19 at 2:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.