1

** NOTE: I've Edited the javascript below and linked to a new JSFiddle but still not getting the buttons to control the snake's movement like the arrow keys on the keyboard **

I’m trying to create a real easy snake game for project but need it to have buttons so the game will work on mobile. This is almost there except i need to have the buttons control the movement of the snake on screen:

HTML:

<div class="game-container">

<div class="container">

    <div class="SplashScreen">
        <h1>
            Snake
        </h1>
        <h2>
            Click To Start.
        </h2>
        <input class="StartButton" type="button" value="Start" />
    </div>

    <div class="FinishScreen" style="display:none">
        <h1>
            Game Over
        </h1>
        <p>
            Your score was: <span id="score"></span>
        </p>
        <input class="StartButton" type="button" value="Restart" />
    </div>

    <canvas id="canvasArea" width="450" height="450" style="display:none;"></canvas>

</div>

<div class="button-pad">

    <div class="btn-up">
        <button type="submit" class="up">
            <img src="http://aaronblomberg.com/sites/ez/images/btn-up.png" />
        </button>
    </div>

    <div class="btn-right">
        <button type="submit" class="right">
            <img src="http://aaronblomberg.com/sites/ez/images/btn-right.png" />
        </button>
    </div>

    <div class="btn-down">
        <button type="submit" class="down">
            <img src="http://aaronblomberg.com/sites/ez/images/btn-down.png" />
        </button>
    </div>

    <div class="btn-left">
        <button type="submit" class="left">
            <img src="http://aaronblomberg.com/sites/ez/images/btn-left.png" />
        </button>
    </div>

</div>

jQuery:

( function( $ ) {

$( function() {



    $(document).ready(function () {

        $(".StartButton").click(function () {
            $(".SplashScreen").hide();
            $(".FinishScreen").hide();
            $("#canvasArea").show();
            init();
        });

        //Canvas stuff
        var canvas = $("#canvasArea")[0];
        var ctx = canvas.getContext("2d");
        var w = $("#canvasArea").width();
        var h = $("#canvasArea").height();

        //Lets save the cell width in a variable for easy control
        var sw = 10;
        var direction;
        var nd;
        var food;
        var score;

        //Lets create the snake now
        var snake_array; //an array of cells to make up the snake

        function endGame() {
            $("#canvasArea").hide();
            $("#score").text(score);
            $(".FinishScreen").show();
        }

        function init() {
            direction = "right"; //default direction
            nd = [];
            create_snake();
            create_food(); //Now we can see the food particle
            //finally lets display the score
            score = 0;

            //Lets move the snake now using a timer which will trigger the paint function
            //every 60ms
            if (typeof game_loop != "undefined") clearInterval(game_loop);
            game_loop = setInterval(paint, 60);
        }

        function create_snake() {
            var length = 5; //Length of the snake
            snake_array = []; //Empty array to start with
            for (var i = length - 1; i >= 0; i--) {
                //This will create a horizontal snake starting from the top left
                snake_array.push({
                    x: i,
                    y: 0
                });
            }
        }

        //Lets create the food now
        function create_food() {
            food = {
                x: Math.round(Math.random() * (w - sw) / sw),
                y: Math.round(Math.random() * (h - sw) / sw),


            };
            //This will create a cell with x/y between 0-44
            //Because there are 45(450/10) positions accross the rows and columns

        }

        //Lets paint the snake now
        function paint() {
            if (nd.length) {
                direction = nd.shift();
            }

            //To avoid the snake trail we need to paint the BG on every frame
            //Lets paint the canvas now
            ctx.fillStyle = "#0056a0";
            ctx.fillRect(0, 0, w, h);
            ctx.strokeStyle = "#ffffff";
            ctx.strokeRect(0, 0, w, h);

            //The movement code for the snake to come here.
            //The logic is simple
            //Pop out the tail cell and place it infront of the head cell
            var nx = snake_array[0].x;
            var ny = snake_array[0].y;

            //These were the position of the head cell.
            //We will increment it to get the new head position
            //Lets add proper direction based movement now
            if (direction == "right") nx++;
            else if (direction == "left") nx--;
            else if (direction == "up") ny--;
            else if (direction == "down") ny++;

            //Lets add the game over clauses now
            //This will restart the game if the snake hits the wall
            //Lets add the code for body collision
            //Now if the head of the snake bumps into its body, the game will restart
            if (nx == -1 || nx == w / sw || ny == -1 || ny == h / sw || check_collision(nx, ny, snake_array)) {
                //end game
                return endGame();
            }

            //Lets write the code to make the snake eat the food
            //The logic is simple
            //If the new head position matches with that of the food,
            //Create a new head instead of moving the tail
            if (nx == food.x && ny == food.y) {
                var tail = {
                    x: nx,
                    y: ny
                };
                score++;

                //Create new food
                create_food();
            } else

            {
                var tail = snake_array.pop(); //pops out the last cell
                tail.x = nx;
                tail.y = ny;
            }

            //The snake can now eat the food.
            snake_array.unshift(tail); //puts back the tail as the first cell

            for (var i = 0; i < snake_array.length; i++) {
                var c = snake_array[i];

                //Lets paint 10px wide cells
                paint_cell(c.x, c.y);
            }

            //Lets paint the food
            paint_cell(food.x, food.y);

            //Lets paint the score
            var score_text = "Score: " + score;
            ctx.fillStyle = "#ffffff";
            ctx.fillText(score_text, 5, h - 5);

            //Set the font and font size
            ctx.font = '12px Arial';

            //position of the fill text counter
            ctx.fillText(itemCounter, 10, 10);

        }

        //Lets first create a generic function to paint cells
        function paint_cell(x, y) {
            ctx.fillStyle = "#d8d8d8";
            ctx.fillRect(x * sw, y * sw, sw, sw);
        }

        function check_collision(x, y, array) {
            //This function will check if the provided x/y coordinates exist
            //in an array of cells or not
            for (var i = 0; i < array.length; i++) {
                if (array[i].x == x && array[i].y == y) return true;
            }

            return false;
        }

        // Lets prevent the default browser action with arrow key usage
        var keys = {};
        window.addEventListener("keydown",
            function(e){
                keys[e.keyCode] = true;
                switch(e.keyCode){
                    case 37: case 39: case 38:  case 40: // Arrow keys
                    case 32: e.preventDefault(); break; // Space
                    default: break; // do not block other keys
                }
            },
        false);
        window.addEventListener('keyup',
            function(e){
                keys[e.keyCode] = false;
            },
        false);


        //Lets add the keyboard controls now
        $(document).keydown(function (e) {
            var key = e.which;
            var td;
            if (nd.length) {
                var td = nd[nd.length - 1];

            } else {
                td = direction;
            }

            //We will add another clause to prevent reverse gear
            if (key == "37" && td != "right") nd.push("left");
            else if (key == "38" && td != "down") nd.push("up");
            else if (key == "39" && td != "left") nd.push("right");
            else if (key == "40" && td != "up") nd.push("down");

            //The snake is now keyboard controllable

        });

    });


    $(document).on('click', '.button-pad > button', function(e) {
        if ($(this).hasClass('left-btn')) {
            e = 37;
        }
        else if ($(this).hasClass('up-btn')) {
            e = 38;
        }
        else if ($(this).hasClass('right-btn')) {
            e = 39;
        }
        else if ($(this).hasClass('down-btn')) {
            e = 40;
        }
        $.Event("keydown", {keyCode: e});
    }); 

});

})( jQuery );

JSFiddle

http://jsfiddle.net/aaronblomberg/9w3gk3ma/3/

This is ALMOST where i need it but i need the up, down, left, and right arrow buttons to control the snake...

any help with would be greatly greatly appreciated.

  • Ok I recommend you add the buttons, then use those buttons instead of the keys. – Andrew Jun 03 '15 at 00:11
  • Stop depending on the keyboard. Have functions that manage the directions irregardless where the event is triggered. Then add event listeners for keyboard and button clicks that call that one "moveDirection" button. You need to learn to separate your game logic from your presentation logic. As it stands this code is kinda all over the place and in some places redundant (two key event listeners? jQuery handles that for you). – Sukima Jun 04 '15 at 00:21
  • Why is there two *wait for document ready* nested functions? This is silly – Sukima Jun 04 '15 at 01:18
  • Placing all your state in a bunch of closure variables is just as bad a using global variables. Why not break out the different types of state into Finite State Machines and link them together with messages (function calls or custom events). – Sukima Jun 04 '15 at 01:20

2 Answers2

0

You cold make something like this:

var isMobile;
checkMobile = function() {
    if ($(window).width() <= 766) {
        isMobile = true;
    }
    else {
        isMobile = false;
    }
}


$(window).resize(checkMobile());
$(document).ready(checkMobile());    

if (isMobile) {
    $('.button-pad').show();
}
else {
    $('.button-pad').hide();
}

.button-pad:

$(document).on('click', '.button-pad > button', function(e) {
    if ($(this).hasClass('left')) {
        e = 37;
    }
    else if ($(this).hasClass('up')) {
        e = 38;
    }
    else if ($(this).hasClass('right')) {
        e = 39;
    }
    else if ($(this).hasClass('down')) {
        e = 40;
    }
    $.Event("keydown", {keyCode: e});
}
Aramil Rey
  • 3,387
  • 1
  • 19
  • 30
  • Thanks, I create a new JSFiddle with some tweaks. but, the "buttons" are not controlling the snake's movement still. take a look here: http://jsfiddle.net/aaronblomberg/9w3gk3ma/3/ – Aaron Blomberg Jun 03 '15 at 17:13
  • I don't understand why you would want to attach to a keyboard event then attach a button click to simulate the key board when you could just make a `changeDirection` function that handles a movement command and let each event listener figure out which command to send? – Sukima Jun 04 '15 at 01:17
  • @Sukima: I was adding syntax, not changing, I would've made a Snake function() and throw everything there, (food eaten, direction, behaviours) I was trying to make this work with what was done so far. Aaron Blomberg: The problem is that the JQuery.Event is not being fired for some reason, and the jquery syntax is not well formatted to your html, must check that also. – Aramil Rey Jun 04 '15 at 18:52
0

Here is the code to add moile control to the snake game; (If you want the whole code for the snake game please comment);

//Here is javascript;

// left key
  function l() {
    if(snake.dx === 0) {
      snake.dx = -grid;
      snake.dy = 0;
    }
  }

  // up key
  function u() {
    if(snake.dy === 0) {
      snake.dy = -grid;
      snake.dx = 0;
    }
  }

  // right key 
  function r() {
    if(snake.dx === 0) {
      snake.dx = grid;
      snake.dy = 0;
    }
  }
  // down key 
  function d() {
    if(snake.dy === 0) {
      snake.dy = grid;
      snake.dx = 0;
    }
  }

Here is HTML;

<div>
  <button onclick="u()" type="button" id="U">U</button>
  <button onclick="l()" type="button" id="L">L</button>
  <button onclick="r()" type="button" id="R">R</button>
  <button onclick="d()" type="button" id="D">D</button>
</div>

Description: I simply added four buttons in the html page, created four functions in the js which will move snake as it should move in different directions and simply added them to the 'onclick' attribute of the different buttons respectively.

Irfan wani
  • 4,084
  • 2
  • 19
  • 34