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\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .