Monday, 3 December 2018

Source code for a snake game in Java Language

A Snake game developed in Java Language for bigginners to understand how can they make simple game by thereself

Here is the code with comments for better understand




/**
 * A Bigginers start version of the classic arcade game
 * "Snake"
 - Made code more readable
 * Also Comments added to understand code propely
 */

///////////// SETTINGS /////////////

// number of {rows|columns}
var N = 20;

// starting length of snake
// click "Restart" if you change this
var START_LENGTH = 1;

// increase to slow down the game
var GAME_SPEED = 3;

// how many cycles to wait before letting the
// user restart
var GAME_OVER_TIMEOUT = 20;

// if false, game over when snake moves beyond
// game boundaries
var WRAP_AROUND = true;


///////////// GLOBAL VARIABLES /////////////

var apple; // the avatar to be eaten next
var snake;

var gameOver; // true when the game is over
var gameOverTimer;

// height is the canvas height
var rowHeight = height / N;
// keep track of arrow keypresses
var keystack = [];

///////////// IMAGE VARIABLES /////////////

var star = getImage("cute/Star");
var oldspice = getImage("avatars/old-spice-man");
var mrpink = getImage("avatars/mr-pink");
var marcimus = getImage("avatars/marcimus");
var pants = getImage("avatars/mr-pants");
var squid = getImage("avatars/orange-juice-squid");
var purple = getImage("avatars/purple-pi");
var images = [oldspice, mrpink, marcimus,
              pants, squid, purple];


///////////// UTILITY FUNCTIONS /////////////

// generate a random integer
var randomInt = function(min, max) {
    var num = random(min, max);
    return floor(num);
};

// a generic timer function
var Timer = function(limit) {
    // initialize
    var t = limit;
    return {
        reset: function() {
            t = limit;
        },
        decr: function() {
            if (t > 0) {
                t -= 1;
            } else {
                t = 0;
            }
        },
        isUp: function() {
            return t === 0;
        }
    };
};

// record key presses
var keyPressed = function() {
    if (!gameOver) {
        if (keyCode === RIGHT || keyCode === LEFT ||
            keyCode === UP || keyCode === DOWN) {
            keystack.push(keyCode);
        }
    }
};


///////////// DRAWING FUNCTIONS /////////////

var drawUnit = function(row, col, i) {
    var h = rowHeight;
    var x = col * h;
    var y = row * h;
    image(images[i], x, y, h, h);
};


var drawBackground = function(opacity) {
    fill(36, 36, 36, opacity);
    rect(0, 0, height, height);
};

var drawGrid = function() {
    stroke(46, 46, 46);
    for (var i = 0; i < N; i += 1) {
        var x = i / N * height;
        line(x, 0, x, height);
        line(0, x, height, x);
    }
};

var drawGameOverScreen = function() {
    drawBackground(150);
    var font = createFont("monospace", 20);
    textFont(font, 20);
    textSize(60);
    fill(49, 201, 26);
    text("GAME OVER", 38, 175);
    textSize(26);
    text("Score: " + snake.score(), 132, 239);
    if (gameOverTimer.isUp()) {
        textSize(16);
        text("Press any key to start over.", 66, 314);
    }
};


///////////// APPLE /////////////

var Apple = function() {

    this.init = function() {
        this.row = randomInt(0, N);
        this.col = randomInt(0, N);
        this.img = randomInt(0, images.length);
    };

    this.positionMatch = function(row, col) {
        return this.row === row && this.col === col;
    };

    this.draw = function() {
        stroke(69, 69, 69);
        strokeWeight(1);
        fill(20, 20, 20);
        var h = rowHeight;
        var x = (this.col + 0.5) * h;
        var y = (this.row + 0.5) * h;
        ellipse(x, y, h * 1.5, h * 1.5);
        drawUnit(this.row, this.col, this.img);
    };

    this.init();
};


///////////// SNAKE /////////////

var Snake = function() {
    var rowArr = []; // row index of each body part
    var colArr = []; // column index of each body part
    var imgArr = []; // index of image for each body part
    var direction; // current direction of snake movement
    var nextDirection; // direction in the next frame

    var score; // number of apples this snake has eaten

    var init = function() {
        // start with a brand new snake
        rowArr = [];
        colArr = [];
        imgArr = [];

        // start the snake off in the upper left corner
        // the last element is the head
        for (var i = 0; i < START_LENGTH; i += 1) {
            rowArr.push(0);
            colArr.push(i);
            // generate a random image for each body
            // segment
            imgArr.push(randomInt(0, images.length));
        }

        // start snake moving to the right
        direction = RIGHT;

        score = 0;
    };

    // delta (change increment) for the snake's movement
    var getDelta = function(direction) {
        var row = 0;
        var col = 0;
        if (direction === DOWN) {
            row = 1;
        } else if (direction === UP) {
            row = -1;
        } else if (direction === LEFT) {
            col = -1;
        } else if (direction === RIGHT) {
            col = 1;
        }
        return {row: row, col: col};
    };

    // set index so that it's within the bounds [0, N-1]
    var makeInBounds = function(index, wrapAround) {
        if (!wrapAround) {
            if (index === N || index === -1) {
                gameOver = true;
                return;
            }
        } else {
            if (index === N) {
                index = 0;
            } else if (index === -1) {
                index = N;
            }
        }
        return index;
    };

    // true if a snake segment exists at (row, col)
    var segmentAt = function(row, col) {
        var len = rowArr.length;
        for (var i = 0; i < len; i += 1) {
            if (row === rowArr[i] && col === colArr[i]) {
                return true;
            }
        }
        return false;
    };

    var changeDirection = function() {
        var dir = direction;
        // by default the next direction will be the
        // same as the current direction
        nextDirection = dir;

        if (keystack.length) {
            var key = keystack.pop();
            if (dir === RIGHT || dir === LEFT) {
                if (key === UP || key === DOWN) {
                    nextDirection = key;
                }
            } else if (dir === UP || dir === DOWN) {
                if (key === RIGHT || key === LEFT) {
                    nextDirection = key;
                }
            }
        }
    };

    this.move = function(apple) {
        // don't move unless the frame number is a
        // multiple of GAME_SPEED
        if (frameCount % GAME_SPEED !== 0) {
            return;
        }

        changeDirection();

        // get snake "head"
        var row = rowArr[rowArr.length-1];
        var col = colArr[colArr.length-1];

        // get next movement
        direction = nextDirection;
        var delta = getDelta(direction);
        var rowNext = row + delta.row;
        var colNext = col + delta.col;
        rowNext = makeInBounds(rowNext, WRAP_AROUND);
        colNext = makeInBounds(colNext, WRAP_AROUND);

        // if the snake collides with itself, game over
        if (segmentAt(rowNext, colNext)) {
            gameOver = true;
        }

        // exit before advancing the snake
        if (gameOver) {
            return;
        }

        // if the next movement lands on the apple
        if (apple.positionMatch(rowNext, colNext)) {
            // add it to the snake tail
            imgArr.unshift(apple.img);
            apple.init();
            score++;
        } else {
            // otherwise, "move" the snake by removing
            // the tail segment
            rowArr.shift();
            colArr.shift();
        }

        // "move" the snake by adding a new segment to
        // the head (note that imgArr is not changed)
        rowArr.push(rowNext);
        colArr.push(colNext);
    };

    this.draw = function() {
        fill(255, 64, 64);
        var h = rowHeight;
        var len = rowArr.length;
        for (var i = 0; i < len; i += 1) {
            if (i === len - 1) {
                // draw a star for the head
                var x = colArr[i] * h;
                var y = (rowArr[i] - 0.7) * h;
                image(star, x, y, h, h * 2);
            } else {
                // use the image for everything else
                drawUnit(rowArr[i], colArr[i], imgArr[i]);
            }
        }
    };

    this.score = function() {
        return score;
    };

    init();
};


///////////// START GAME /////////////

var startGame = function() {
    snake = new Snake();
    apple = new Apple();

    gameOverTimer = Timer(GAME_OVER_TIMEOUT);
    gameOver = false;
};

// begin with a new game
startGame();


///////////// MAIN GAME LOOP /////////////

var draw = function() {
    drawBackground(255);
    drawGrid();

    snake.draw();
    apple.draw();

    if (!gameOver) {
        snake.move(apple);
    } else {
        drawGameOverScreen();
        // don't let the user restart the game
        // until the timer is up
        if (keyIsPressed && gameOverTimer.isUp()) {
            startGame();
        } else {
            gameOverTimer.decr();
        }
    }
};

No comments:

Post a Comment

Featured Post

All Answers of Quiz regarding to this course on Fiverr "Online Freelancing Essentials: Be A Successful Fiverr Seller"

To Clear All quiz of mentioned Course you can have a look on or check questions answers as well. Course name:  Online Freelancing Essentials...

Popular Posts