1
\$\begingroup\$

How do I change the arrowkey movement so that is based off of the click of the buttons instead?

Cheers

<script type="text/javascript">
    var ctx = null;
    var gameMap = [
        0, 0, 0, 0, 0,
        0, 1, 1, 1, 0,
        0, 1, 0, 0, 0,
        0, 1, 1, 1, 0,
        0, 0, 0, 0, 0
    ];
    var tileW = 40, tileH = 40;
    var mapW = 5, mapH = 5;
    var currentSecond = 0, frameCount = 0, framesLastSecond = 0, lastFrameTime = 0;

 new tile
    var keysDown = {
        37: false,
        38: false,
        39: false,
        40: false
    };

    var player = new Character();

    function Character() {
        this.tileFrom = [1, 1];
        this.tileTo = [1, 1];
        this.timeMoved = 0;
        this.dimensions = [30, 30];
        this.position = [45, 45];
        this.delayMove = 700;
    }
    Character.prototype.placeAt = function (x, y) {
        this.tileFrom = [x, y];
        this.tileTo = [x, y];
        this.position = [((tileW * x) + ((tileW - this.dimensions[0]) / 2)),
        ((tileH * y) + ((tileH - this.dimensions[1]) / 2))];
    };
    Character.prototype.processMovement = function (t) {
        if (this.tileFrom[0] == this.tileTo[0] && this.tileFrom[1] == this.tileTo[1]) { return false; }

        if ((t - this.timeMoved) >= this.delayMove) {
            this.placeAt(this.tileTo[0], this.tileTo[1]);
        }
        else {
            this.position[0] = (this.tileFrom[0] * tileW) + ((tileW - this.dimensions[0]) / 2);
            this.position[1] = (this.tileFrom[1] * tileH) + ((tileH - this.dimensions[1]) / 2);

            if (this.tileTo[0] != this.tileFrom[0]) {
                var diff = (tileW / this.delayMove) * (t - this.timeMoved);
                this.position[0] += (this.tileTo[0] < this.tileFrom[0] ? 0 - diff : diff);
            }
            if (this.tileTo[1] != this.tileFrom[1]) {
                var diff = (tileH / this.delayMove) * (t - this.timeMoved);
                this.position[1] += (this.tileTo[1] < this.tileFrom[1] ? 0 - diff : diff);
            }

            this.position[0] = Math.round(this.position[0]);
            this.position[1] = Math.round(this.position[1]);
        }

        return true;
    }

    function toIndex(x, y) {
        return ((y * mapW) + x);
    }

    window.onload = function () {
        ctx = document.getElementById('game').getContext("2d");
        requestAnimationFrame(drawGame);
        ctx.font = "bold 10pt sans-serif";

        window.addEventListener("keydown", function (e) {
            if (e.keyCode >= 37 && e.keyCode <= 40) { keysDown[e.keyCode] = true; }
        });
        window.addEventListener("keyup", function (e) {
            if (e.keyCode >= 37 && e.keyCode <= 40) { keysDown[e.keyCode] = false; }
        });
    };

    function drawGame() {
        if (ctx == null) { return; }

        var currentFrameTime = Date.now();
        var timeElapsed = currentFrameTime - lastFrameTime;

        var sec = Math.floor(Date.now() / 1000);
        if (sec != currentSecond) {
            currentSecond = sec;
            framesLastSecond = frameCount;
            frameCount = 1;
        }
        else { frameCount++; }

        if (!player.processMovement(currentFrameTime)) {
            if (keysDown[38] && player.tileFrom[1] > 0 && gameMap[toIndex(player.tileFrom[0], player.tileFrom[1] - 1)] == 1) { player.tileTo[1] -= 1; }
            else if (keysDown[40] && player.tileFrom[1] < (mapH - 1) && gameMap[toIndex(player.tileFrom[0], player.tileFrom[1] + 1)] == 1) { player.tileTo[1] += 1; }
            else if (keysDown[37] && player.tileFrom[0] > 0 && gameMap[toIndex(player.tileFrom[0] - 1, player.tileFrom[1])] == 1) { player.tileTo[0] -= 1; }
            else if (keysDown[39] && player.tileFrom[0] < (mapW - 1) && gameMap[toIndex(player.tileFrom[0] + 1, player.tileFrom[1])] == 1) { player.tileTo[0] += 1; }

            if (player.tileFrom[0] != player.tileTo[0] || player.tileFrom[1] != player.tileTo[1]) { player.timeMoved = currentFrameTime; }
        }

        for (var y = 0; y < mapH; ++y) {
            for (var x = 0; x < mapW; ++x) {
                switch (gameMap[((y * mapW) + x)]) {
                    case 0:
                        ctx.fillStyle = "#685b48";
                        break;
                    default:
                        ctx.fillStyle = "#5aa457";
                }

                ctx.fillRect(x * tileW, y * tileH, tileW, tileH);
            }
        }

        ctx.fillStyle = "#0000ff";
        ctx.fillRect(player.position[0], player.position[1],
            player.dimensions[0], player.dimensions[1]);

        ctx.fillStyle = "#ff0000";
        ctx.fillText("FPS: " + framesLastSecond, 10, 20);

        lastFrameTime = currentFrameTime;
        requestAnimationFrame(drawGame);
    }
</script>

<canvas id="game" width="400" height="400"></canvas>
<table>
    <tr>
        <td></td>
        <td>
            <button id="NORTH" onclick="NORTH()">NORTH</button>
        </td>
        <td></td>
    </tr>

    <tr>
        <td>
            <button id="WEST" onclick="WEST()">WEST</button>
        </td>
        <td></td>
        <td>
            <button id="EAST" onclick="EAST()">EAST</button>
        </td>
    </tr>

    <tr>
        <td></td>
        <td>
            <button id="SOUTH" onclick="SOUTH()">SOUTH</button>
        </td>
        <td></td>
    </tr>
</table>

\$\endgroup\$
0
\$\begingroup\$

This should be doable by attaching click events to the buttons and saving which one was clicked, then resetting it.

First remove the onclick= occurences from your html. They currently don't work because there is no global NORTH/EAST/SOUTH/WEST functions defined.

Next, define an object in which you can store the direction that the user clicked.

var movementState = {
      east: false,
      north: false,
      south: false,
      west: false
    };

After that, in the window.onload callback, instead of binding to keydown and keyup you want to bind an event to the buttons:

document.getElementById('NORTH').addEventListener('click', function(e) {
    movementState.north = true;
});

document.getElementById('EAST').addEventListener('click', function(e) {
    movementState.east = true;
});

document.getElementById('SOUTH').addEventListener('click', function(e) {
    movementState.south = true;
});

document.getElementById('WEST').addEventListener('click', function(e) {
    movementState.west = true;
});

Lastly, you'll want to alter the drawGame function. Specifically the part where keysDown is used to determine where the player should move.

    if (!player.processMovement(currentFrameTime)) {
    if (movementState.north && player.tileFrom[1] > 0 && gameMap[toIndex(player.tileFrom[0], player.tileFrom[1] - 1)] == 1) { player.tileTo[1] -= 1; movementState.north = false; }
    else if (movementState.south && player.tileFrom[1] < (mapH - 1) && gameMap[toIndex(player.tileFrom[0], player.tileFrom[1] + 1)] == 1) { player.tileTo[1] += 1; movementState.south = false; }
    else if (movementState.west && player.tileFrom[0] > 0 && gameMap[toIndex(player.tileFrom[0] - 1, player.tileFrom[1])] == 1) { player.tileTo[0] -= 1; movementState.west = false;}
    else if (movementState.east && player.tileFrom[0] < (mapW - 1) && gameMap[toIndex(player.tileFrom[0] + 1, player.tileFrom[1])] == 1) { player.tileTo[0] += 1; movementState.east = false; }

    if (player.tileFrom[0] != player.tileTo[0] || player.tileFrom[1] != player.tileTo[1]) { player.timeMoved = currentFrameTime; }
}

Now you can clean up all occurrences of keysDown. An implementation can be found at https://jsfiddle.net/9bdgxfdo/9/

\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.