02. Canvas

01. Draw:
– Bicycle

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        canvas{
            margin-left: 250px;
            border: 1px solid black;
        }
    </style>
</head>
<body>
    <canvas id="the-canvas" width="800" height="500">This is not supported for your browser!</canvas>
    <script>
        drawBicycle();
        function drawBicycle () {
            var canvas = document.getElementById('the-canvas');
            var context = canvas.getContext('2d');
            var x = 100;
            var y = 250;
            context.fillStyle = '#8EC8D4';
            context.strokeStyle = '#518B97';
            context.lineWidth = 2;
            drawWheels(context, x, y);
            drawBicycleFrame(context, x, y);
            drawBicycleSeat(context, x, y);
            drawBicycleSteeringWheel(context, x, y);
            drawBicyclePedals (context, x, y);
        }
        function drawWheels(context, x, y){
            var numberOfWheels = 2;
            var wheelX = x;
            var wheelY = y + 150;
            var radius = 60;
            for (var i = 1; i <= numberOfWheels; i++) {
                if (i === 1) {
                    wheelX += 100;
                }
                else if (i === 2) {
                    wheelX += 300;
                }
                drawWheel (context, wheelX, wheelY, radius);
            }
        }
        function drawWheel(context, x, y, radius){
            context.beginPath();
            context.arc(x, y, radius, 0, 2 * Math.PI);
            context.fill();
            context.stroke();
        }
        function drawBicycleFrame(context, x, y) {
            context.moveTo(x + 100, y + 150);
            context.lineTo(x + 200, y + 70);
            context.lineTo(x + 350, y + 70);
            context.lineTo(x + 250, y + 150);
            context.lineTo(x + 100, y + 150);
            context.stroke();
        }
        function drawBicycleSeat (context, x, y) {
            // Seat frame
            context.beginPath();
            context.moveTo(x + 250, y + 150);
            context.lineTo(x + 175, y + 30);
            context.stroke();
            // Seat
            context.beginPath();
            context.moveTo(x + 145, y + 30);
            context.lineTo(x + 205, y + 30);
            context.stroke();
        }
        function drawBicycleSteeringWheel (context, x, y) {
            context.beginPath();
            context.moveTo(x + 400, y + 150);
            context.lineTo(x + 325, y + 30);
            context.lineTo(x + 280, y + 50);
            context.moveTo(x + 325, y + 30);
            context.lineTo(x + 340, y);
            context.stroke();
        }
        function drawBicyclePedals (context, x, y) {
            context.beginPath();
            var radius = 17;
            context.arc(x + 250, y + 150, radius, 0, 2 * Math.PI);
            context.stroke();
            // Pedals
            context.beginPath();
            context.moveTo(x + 235, y + 145);
            context.lineTo(x + 205, y + 135);
            context.stroke();
            context.beginPath();
            context.moveTo(x + 265, y + 155);
            context.lineTo(x + 295, y + 165);
            context.stroke();
        }
    </script>
</body>
</html>


- House

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        canvas{
            margin-left: 250px;
            border: 1px solid black;
        }
    </style>
</head>
<body>
    <canvas id="the-canvas" width="800" height="500">This is not supported for your browser!</canvas>
    <script>
        drawHouse();
        function drawHouse () {
            var canvas = document.getElementById('the-canvas');
            var context = canvas.getContext('2d');
            var x = 300;
            var y = 200;
            var baseSideWidth = 300;
            var baseSideHeight = 250;
            context.fillStyle = '#975B5B';
            context.strokeStyle = '#000000';
            context.lineWidth = 2;
            drawRoof(context, x, y, baseSideWidth, baseSideHeight);
            drawBase(context, x, y, baseSideWidth, baseSideHeight);
        }
        function drawRoof (context, x, y, baseSideWidth, baseSideHeight) {
            context.beginPath();
            context.moveTo(x, y);
            context.lineTo(x + baseSideWidth / 2, y - baseSideHeight + 100);
            context.lineTo(x + baseSideWidth, y);
            context.fill();
            context.stroke();
            drawChimney(context, x, y);
        }
        function drawChimney (context, x, y) {
            context.beginPath();
            context.moveTo(x + 218, y - 30);
            context.lineTo(x + 218, y - 100);
            context.lineTo(x + 250, y - 100);
            context.lineTo(x + 250, y - 30);
            context.fill();
            context.stroke();
        }
        function drawBase (context, x, y, baseSideWidth, baseSideHeight) {
            context.fillRect(x, y, baseSideWidth, baseSideHeight);
            context.strokeRect(x, y, baseSideWidth, baseSideHeight);
            drawDoor(context, x, y);
            drawBigWindows (context, x, y, baseSideWidth, baseSideHeight);
        }
        function drawDoor (context, x, y) {
            // Door's base
            context.beginPath();
            context.bezierCurveTo(330, 370, 380, 320, 420, 370);
            context.moveTo(x + 120, y + 170);
            context.lineTo(x + 120, y + 250);
            context.moveTo(x + 30, y + 170);
            context.lineTo(x + 30, y + 250);
            context.moveTo(x + 77, y + 147);
            context.lineTo(x + 77, y + 250);
            context.stroke();
            // Locks
            context.beginPath();
            context.arc(x + 65, y + 215, 4, 0, 2 * Math.PI);
            context.stroke();
            context.beginPath();
            context.arc(x + 87, y + 215, 4, 0, 2 * Math.PI);
            context.stroke();
        }
        function drawBigWindows (context, x, y, baseSideWidth, baseSideHeight) {
            var windowsX = x;
            var windowsY = y;
            var numberOfBigWindows = 3;
            for (var i = 1; i <= numberOfBigWindows; i++) {
                if (i === 1) {
                    windowsX += baseSideWidth / 10;
                    windowsY += baseSideHeight / 10;
                }
                else if (i === 2) {
                    windowsX += baseSideWidth / 1.7;
                    windowsY += baseSideHeight / 10;
                }
                else if (i === 3) {
                    windowsX += baseSideWidth / 1.7;
                    windowsY += baseSideHeight / 2;
                }
                var numberOfSmallWindows = 4;
                var width = 50;
                var height = 30;
                for (var j = 1; j <= numberOfSmallWindows; j++) {
                    if (j === 2) {
                        windowsY += height + 2;
                    }
                    else if (j === 3) {
                        windowsX += width + 2;
                        windowsY -= height + 2;
                    }
                    else if (j === 4){
                        windowsY += height + 2;
                    }
                    drawSmallWindows(context, windowsX, windowsY, width, height);
                }
                windowsX = x;
                windowsY = y;
            }
        }
        function drawSmallWindows (context, x, y, width, height) {
            context.beginPath();
            context.rect(x, y, width, height);
            context.rect(x, y, width, height);
            context.fillStyle = 'black';
            context.fill();
        }
    </script>
</body>
</html>

- Snowman

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        #the-canvas{
            border: 1px solid black;
        }
    </style>
</head>
<body>
    <canvas id="the-canvas" width="1000" height="500"></canvas>

    <script>
        window.onload = function() {
            var canvas = document.getElementById('the-canvas');
            var context = canvas.getContext('2d');
            var snowman = new Snowman(context, 300, 300);
        };
        function Snowman (context, x, y) {
            this.x = x;
            this.y = y;
            this.fillColor = '#8EC8D4';
            this.strokeColor = '#396693';
            this.drawHead = drawHead(context, this.x, this.y, 60, this.strokeColor, this.fillColor);
            this.drawFace = drawFace(context, this.x, this.y, 10, this.strokeColor);
            this.drawHat = drawHat(context, this.x - 225, this.y - 60, 20, this.strokeColor);
        }
        function drawHead (context, x, y, radius, strokeColor, fillColor) {
            context.beginPath();
            context.arc(x, y, radius, 0, 2 * Math.PI);
            context.strokeStyle = strokeColor;
            context.fillStyle = fillColor;
            context.lineHeight = 2;
            context.fill();
            context.stroke();
        }
        function drawFace (context, x, y, radius, strokeColor) {
            drawEye(context, x - 120, y - 20, 8, strokeColor);
            drawEyeball(context,  x - 120,  y - 20, 3, strokeColor);
            drawEye(context, x - 90, y - 20, 8, strokeColor);
            drawEyeball(context,  x - 120,  y - 65, 3, strokeColor)
            drawNose(context, x, y, strokeColor);
            drawMouth(context, x, y, 8, strokeColor);
        }
        function drawEye (context, x, y, radius, strokeColor) {
            context.save();
            context.scale(1.5, 1);
            context.beginPath();
            context.arc(x, y, radius, 0, 2 * Math.PI);
            context.strokeStyle = strokeColor;
            context.lineWidth = 2;
            context.stroke();
            context.restore();
        }
        function drawEyeball (context, x, y, radius, fillColor) {
            context.save();
            context.rotate(Math.PI / 2);
            context.save();
            context.scale(2, 1);
            context.beginPath();
            context.arc(x - 40, y - 545, radius, 0, 2 * Math.PI);
            context.restore();
            context.fillStyle = fillColor;
            context.fill();
            context.restore();
        }
        function drawNose (context, x, y, strokeColor) {
            context.beginPath();
            context.moveTo(x - 5, y - 20);
            context.lineTo(x - 20, y + 10);
            context.lineTo(x - 5, y + 10);
            context.lineWidth = 2;
            context.strokeStyle = strokeColor;
            context.stroke();
        }
        function drawMouth (context, x, y, radius, strokeColor) {
            context.save();
            context.rotate(Math.PI / 17);
            context.save();
            context.scale(3, 1);
            context.beginPath();
            context.arc(x - 185, y - 25, radius, 0, 2 * Math.PI);
            context.strokeStyle = strokeColor;
            context.lineWidth = 1.5;
            context.restore()
            context.stroke();
            context.restore();
        }
        function drawHat (context, x, y, radius, fillColor) {
            context.save();
            context.scale(4, 1);
            context.beginPath();
            context.arc(x, y, radius, 0, 2 * Math.PI);
            context.lineWidth = 1;
            context.fillStyle = fillColor;
            context.fill();
            context.stroke();
            context.restore();
            drawCylinder(context, x, y, 20, fillColor);
        }
        function drawCylinder (context, x, y, radius, filColor) {
            context.beginPath();
            context.rect(x + 185, y - 80, x + 5, y - 150);
            context.fillStyle = filColor;
            context.fill();
            context.beginPath();
            context.save();
            context.scale(2, 1);
            context.arc(x + 75, y - 80, radius, 0, 2 * Math.PI);
            context.fill();
            context.restore();
        }
    </script>
</body>
</html>

02.Draw a circle that flies inside a box
- When it reaches an edge, it should bounce that edge

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        canvas{
            border: 1px solid black;
        }
        form {
            border: 1px solid black;
            position: relative;
            top: -506px;
            left: 850px;
            width: 200px;
            height: 100px;
        }
        #color{
            margin-left: 7px;
        }
        #start-btn, #stop-btn, label {
            margin: 20px;
            width: 50px;
        }
    </style>
</head>
<body>
    <canvas id="the-canvas" width="800" height="500">This is not supported for your browser!</canvas>

    <form>
        <input type="button" value="Start" id="start-btn"/>
        <input type="button" value="Stop" id="stop-btn"/> <br/>
        <label for="#color">Fill color:</label>
        <input type="color" id="color"/><br/>
    </form>

    <script>
        (function(){
            var canvas = document.getElementById('the-canvas');
            var context = canvas.getContext('2d');
            var isAnimationOn = false;
            var startBtn = document.getElementById('start-btn');
            var stopBtn = document.getElementById('stop-btn');
            var color = document.getElementById('color');
            var ball = new Ball(30, 30, 10, 5, context);
            startBtn.addEventListener('click', function () {
                startBtn.disabled = true;
                stopBtn.disabled = false;
                isAnimationOn = true;
                requestAnimationFrame(animationFrame);
            }, false);
            stopBtn.addEventListener('click', function () {
                startBtn.disabled = false;
                stopBtn.disabled = true;
                isAnimationOn = false;
            }, false);
            color.addEventListener('change', function () {
                ball.fillColor = color.value;
            }, false);
            function animationFrame () {
                context.clearRect(0, 0, context.CANVAS.width, context.CANVAS.height);
                ball.move();
                ball.draw(context);
                if (isAnimationOn) {
                    requestAnimationFrame(animationFrame);
                }
            }
            function Ball (startX, startY, radius, speed, context) {
                this.startX = startX;
                this.startY = startY;
                this.nextX = speed;
                this.nextY = speed;
                this.radius = radius;
                this.strokeColor = 'purple';
                this.fillColor = 'black';
                this.draw = function () {
                    context.beginPath();
                    context.arc(this.startX, this.startY, this.radius, 0, 2 * Math.PI);
                    context.strokeStyle = this.strokeColor;
                    context.fillStyle = this.fillColor;
                    context.fill();
                    context.stroke();
                };
                this.move = function () {
                    this.startX += this.nextX;
                    this.startY += this.nextY;
                    if(this.startX === context.CANVAS.width - radius || this.startX === radius) {
                        this.nextX *= -1;
                    }
                    if(this.startY === context.CANVAS.height - radius || this.startY === radius) {
                        this.nextY *= -1;
                    }
                };
            }
        }());
    </script>
</body>
</html>

*03.Create the famous game "Snake"
- The snake is a sequence of rectangles/ellipses
- The snake can move left, right, up or down
- The snake dies if it reaches any of the edges or when it tries to eat itself
- A food should be generated
- When the snake eats the food, it grows and new food is generated at random position
- Implement a high-score board, kept in localStorage

I'm using RequireJS
index.html

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <link href="styles/style.css" type="text/css" rel="stylesheet"/>
    <script src="scripts/libs/require.js" data-main="scripts/app"></script>
</head>
<body>
    <p id="points">Points: <span id="pointsSpan">0</span></p>
    <canvas id="the-canvas" width="800" height="400"></canvas>
</body>
</html>

style.css

canvas {
    border: 1px solid black;
    margin-top: 40px;
}

p {
    font-size: 25px;
    width: 150px;
    position: absolute;
    top: -10px;
}

scripts/app.js

(function() {
    require(['MainModules/GlobalConstants', 'MainModules/Snake', 'MainModules/Stone', 'Controllers/Drawer', 'Helper/EndGame',
        'Controllers/Updater', 'Controllers/Events'], function(GlobalConst, Snake, Stone, Drawer, EndGame, Updater, Event) {

        var snake = new Snake();
        Event.getPosition(snake);

        var animationFrame = setInterval(function() {
            GlobalConst.CONTEXT.clearRect(0, 0, GlobalConst.CONTEXT.canvas.width, GlobalConst.CONTEXT.canvas.height);
            Drawer.drawStones();
            Drawer.drawFood();
            snake.drawSnake(GlobalConst.CONTEXT);
            EndGame.checkGameEnd(snake, animationFrame);
            snake.moveSnake();
            Updater.update(snake);
        }, GlobalConst.GAME_SPEED);
    });
}());

scripts/Controllers/Drawer.js

define(['MainModules/Stone', 'MainModules/Food', 'MainModules/GlobalConstants'], function(Stone, Food, GlobalConst) {
    function drawStones() {
        for (var i = 0; i < Stone.stones.length; i++) {
            GlobalConst.CONTEXT.drawImage(Stone.stones[i], Stone.stonesCoordinates[i].x,
                Stone.stonesCoordinates[i].y, Stone.stones[i].width, Stone.stones[i].height);
        }
    }

    function drawFood() {
        GlobalConst.CONTEXT.drawImage(Food.food, Food.foodCoordinates.x, Food.foodCoordinates.y,
            Food.food.width, Food.food.height);
    }

    function drawGameOverImage(gameOverImage) {
        GlobalConst.CONTEXT.drawImage(gameOverImage, GlobalConst.GAME_OVER_POSITION_X, GlobalConst.GAME_OVER_POSITION_Y,
            GlobalConst.GAME_OVER_WIDTH, GlobalConst.GAME_OVER_HEIGHT);
    }

    return {
        drawStones: drawStones,
        drawFood: drawFood,
        drawGameOverImage: drawGameOverImage
    };
});


<strong>scripts/Controllers/Events.js</strong>

define(['MainModules/Snake'], function(Snake) {
    function getPosition(snake) {
        window.addEventListener('keydown', function(event) {
            event = event || window.event;

            switch (event.keyCode) {
                case 38:
                    if(snake.getPosition().y !== 1) {
                        snake.moveUp();
                    }
                    break;
                case 40:
                    if(snake.getPosition().y !== -1) {
                        snake.moveDown();
                    }
                    break;
                case 37:
                    if(snake.getPosition().x !== 1) {
                        snake.moveLeft();
                    }
                    break;
                case 39:
                    if(snake.getPosition().x !== -1) {
                        snake.moveRight();
                    }
                    break;
            }
        }, false);
    }

    return {
        getPosition: getPosition
    };
});

scripts/Controllers/Updater.js

define(['MainModules/GlobalVariables', 'MainModules/Snake', 'MainModules/Food'], function(GlobalVariables, Snake, Food) {
    function update(snake) {
        if(snake.getHeadPosition().x === Food.foodCoordinates.x && snake.getHeadPosition().y === Food.foodCoordinates.y) {
            Food.generateNewCoordinates();
            snake.snakeGrow();
            updatePoints();
        }
    }

    function updatePoints() {
        GlobalVariables.points += 10;
        GlobalVariables.pointsField.innerHTML = GlobalVariables.points.toString();
    }

    return {
        update: update
    }
});

scripts/Helper/EndGame.js

define(['MainModules/GlobalConstants', 'Controllers/Drawer' ,'MainModules/Stone'], function(GlobalConst, Drawer, Stone) {
    var gameOverImage = createGameOverImage();

    function checkGameEnd(snake, animationFrame) {
        if(isSnakeHitStone(snake) || isSnakeEatsItself(snake) || isSnakeHitCanvasBorders(snake)) {
            clearInterval(animationFrame);
            Drawer.drawGameOverImage(gameOverImage);
            window.prompt('Enter your name: ');
        }
    }

    function isSnakeHitStone(snake) {
        for (var i = 0; i < Stone.stones.length; i++) {
            if(snake.getHeadPosition().x === Stone.stonesCoordinates[i].x &&
                snake.getHeadPosition().y === Stone.stonesCoordinates[i].y) {

                return true;
            }
        }
    }

    function isSnakeEatsItself(snake) {
        for (var i = 0; i < snake.snakeBody.length; i++) {
            if(snake.getHeadPosition().x === snake.snakeBody[i].x &&
                snake.getHeadPosition().y === snake.snakeBody[i].y) {

                return true;
            }
        }
    }

    function isSnakeHitCanvasBorders(snake) {
        if(snake.getHeadPosition().x < 0 || snake.getHeadPosition().x === GlobalConst.CANVAS.clientWidth ||
            snake.getHeadPosition().y < 0 || snake.getHeadPosition().y === GlobalConst.CANVAS.clientHeight) {

            return true;
        }
    }

    function createGameOverImage() {
        var gameOverImage = new Image();
        gameOverImage.src = 'images/game_over.png';
        gameOverImage.width = GlobalConst.GAME_OVER_WIDTH;
        gameOverImage.height = GlobalConst.GAME_OVER_HEIGHT;

        return gameOverImage;
    }

    return {
        checkGameEnd: checkGameEnd
    };
});

scripts/Helper/RandomGenerator.js

define(['MainModules/GlobalConstants'], function(GlobalConst) {
    function getRandomCoordinates(clientParameter) {
        return Math.round((Math.random() * clientParameter - GlobalConst.BLOCK_SIZE) / GlobalConst.BLOCK_SIZE) * GlobalConst.BLOCK_SIZE;
    }

    return {
        getRandomCoordinates: getRandomCoordinates
    }
});

scripts/MainModules/Food.js

define(['MainModules/GlobalConstants', 'MainModules/Stone', 'Helper/RandomGenerator',
    'MainModules/Position'] ,function(GlobalConst, Stone, RandomGenerator, Position) {

    var food = createFood();
    var foodCoordinates = createCoordinates();

    function createFood() {
        food = new Image();
        food.src = 'images/apple.png';
        food.width = GlobalConst.BLOCK_SIZE;
        food.height = GlobalConst.BLOCK_SIZE;

        return food;
    }

    function createCoordinates() {
        var foodCoordinateX;
        var foodCoordinateY;

        while(true) {
            foodCoordinateX = RandomGenerator.getRandomCoordinates(GlobalConst.CANVAS.clientWidth);
            foodCoordinateY = RandomGenerator.getRandomCoordinates(GlobalConst.CANVAS.clientHeight);

            if(areFoodCoordinatesValid(foodCoordinateX, foodCoordinateY)) {
                break;
            }
        }

        return new Position(foodCoordinateX, foodCoordinateY);
    }

    function areFoodCoordinatesValid(foodCoordinateX, foodCoordinateY){
        if(foodCoordinateX < 0 || foodCoordinateY < 0 ||
            foodCoordinateX > GlobalConst.CANVAS.clientWidth || foodCoordinateY > GlobalConst.CANVAS.clientHeight) {
            return false;
        }

        if(foodCoordinateX <= GlobalConst.BLANK_POSITION.x && foodCoordinateY <= GlobalConst.BLANK_POSITION.y) {
            return false;
        }

        for (var i = 0; i < Stone.stonesCoordinates.length; i++) {
            if(foodCoordinateX === Stone.stonesCoordinates[i].x && foodCoordinateY === Stone.stonesCoordinates[i].y) {
                return false;
            }
        }

        return true;
    }

    function generateNewCoordinates() {
        this.foodCoordinates = createCoordinates();
    }

    return {
        food: food,
        foodCoordinates: foodCoordinates,
        generateNewCoordinates: generateNewCoordinates
    };
});

scripts/MainModules/GlobalConstants.js

define(function() {
    var CANVAS = document.getElementById('the-canvas');
    var CONTEXT = CANVAS.getContext('2d');
    var GAME_SPEED = 150;
    var BLOCK_SIZE = 20;
    var NUMBER_OF_STONES = 30;
    var SNAKE_LENGTH = 5;
    var GAME_OVER_POSITION_X = 100;
    var GAME_OVER_POSITION_Y = 120;
    var GAME_OVER_WIDTH = 500;
    var GAME_OVER_HEIGHT = 200;
    var BLANK_POSITION = {
        x: 200,
        y: 20
    };

    return {
        CANVAS: CANVAS,
        CONTEXT: CONTEXT,
        GAME_SPEED: GAME_SPEED,
        BLOCK_SIZE: BLOCK_SIZE,
        NUMBER_OF_STONES: NUMBER_OF_STONES,
        SNAKE_LENGTH: SNAKE_LENGTH,
        GAME_OVER_POSITION_X: GAME_OVER_POSITION_X,
        GAME_OVER_POSITION_Y: GAME_OVER_POSITION_Y,
        GAME_OVER_WIDTH: GAME_OVER_WIDTH,
        GAME_OVER_HEIGHT: GAME_OVER_HEIGHT,
        BLANK_POSITION: BLANK_POSITION
    };
});

scripts/MainModules/GlobalVariables.js

define(function() {
    var pointsField = document.getElementById('pointsSpan');
    var points = 0;

    return {
        pointsField: pointsField,
        points: points
    }
});

scripts/MainModules/Position.js

define(function() {
    function Position(x, y) {
        this.x = x;
        this.y = y;
    }

    return Position;
});

scripts/MainModules/Snake.js

define(['MainModules/Position', 'MainModules/GlobalConstants'], function(Position, GlobalConst) {
    var Snake = (function() {
        function createSnake() {
            this.head = new Position(this.startX, this.startY);
            this.snakeBody  = new Array(this.snakeLength);

            for (var i = 0; i < this.snakeLength; i++) {
                this.snakeBody[i] = new Position(this.startX - GlobalConst.BLOCK_SIZE * (i + 1), this.startY);
            }
        }

        function Snake() {
            this.head = null;
            this.snakeBody = [];
            this.startX = 100;
            this.startY = 20;
            this.snakeLength = GlobalConst.SNAKE_LENGTH;
            this.position = {
                x: 1,
                y: 0
            };
            createSnake.call(this);
        }

        Snake.prototype.drawSnake = function(context) {
            for (var i = 0; i < this.snakeBody.length; i++) {
                if (i === 0 ) {
                    context.fillStyle = 'darkgreen';
                }
                else {
                    context.fillStyle = 'green';
                }

                context.beginPath();
                context.rect(this.snakeBody[i].x, this.snakeBody[i].y, GlobalConst.BLOCK_SIZE, GlobalConst.BLOCK_SIZE);
                context.fill();
            }
        };

        Snake.prototype.moveSnake = function() {
            this.snakeBody.pop();
            this.snakeBody.unshift(new Position(this.head.x, this.head.y));
            this.head.x += this.position.x * GlobalConst.BLOCK_SIZE;
            this.head.y += this.position.y * GlobalConst.BLOCK_SIZE;
        };

        Snake.prototype.moveUp = function() {
            this.position = {
                x: 0,
                y: -1
            };
        };

        Snake.prototype.moveDown = function() {
            this.position = {
                x: 0,
                y: 1
            };
        };

        Snake.prototype.moveLeft = function() {
            this.position = {
                x: -1,
                y: 0
            };
        };

        Snake.prototype.moveRight = function() {
            this.position = {
                x: 1,
                y: 0
            };
        };

        Snake.prototype.getPosition = function() {
            return this.position;
        };

        Snake.prototype.getHeadPosition = function() {
            return {
                x: this.head.x,
                y: this.head.y
            };
        };

        Snake.prototype.snakeGrow = function() {
            this.snakeBody.push(new Position(this.snakeBody[this.snakeBody.length - 1].x, this.snakeBody[this.snakeBody.length - 1].y));
        };

        return Snake;
    }());

    return Snake;
});

scripts/MainModules/Stone.js

define(['MainModules/GlobalConstants', 'MainModules/Position', 'Helper/RandomGenerator'], function(GlobalConst, Position, RandomGenerator) {
    var stones = [];
    var stonesCoordinates = [];

    createStones(stones);
    createCoordinates(stonesCoordinates);

    function createStones(stones) {
        for (var i = 0; i < GlobalConst.NUMBER_OF_STONES; i++) {
            stones.push(new Image());
            stones[i].src = 'images/stone.png';
            stones[i].width = GlobalConst.BLOCK_SIZE;
            stones[i].height = GlobalConst.BLOCK_SIZE;
        }
    }

    function createCoordinates(stonesCoordinates){
        var stoneCoordinateX;
        var stoneCoordinateY;

        for (var i = 0; i < GlobalConst.NUMBER_OF_STONES; i++) {
            while(true) {
                stoneCoordinateX = RandomGenerator.getRandomCoordinates(GlobalConst.CANVAS.clientWidth);
                stoneCoordinateY = RandomGenerator.getRandomCoordinates(GlobalConst.CANVAS.clientHeight);

                if(areStoneCoordinatesValid(stoneCoordinateX, stoneCoordinateY, stonesCoordinates)) {
                    stonesCoordinates.push(new Position(stoneCoordinateX, stoneCoordinateY));
                    break;
                }
            }
        }
    }

    function areStoneCoordinatesValid(stoneCoordinateX, stoneCoordinateY, stonesCoordinates) {
        if(stoneCoordinateX < 0 || stoneCoordinateY < 0 ||
            stoneCoordinateX > GlobalConst.CANVAS.clientWidth || stoneCoordinateY > GlobalConst.CANVAS.clientHeight) {
            return false;
        }

        if(stoneCoordinateX <= GlobalConst.BLANK_POSITION.x && stoneCoordinateY <= GlobalConst.BLANK_POSITION.y) {
            return false;
        }

        for (var i = 0; i < stonesCoordinates.length; i++) {
            if(stoneCoordinateX === stonesCoordinates[i].x && stoneCoordinateY === stonesCoordinates[i].y) {
                return false;
            }
        }

        return true;
    }

    return {
        stones: stones,
        stonesCoordinates: stonesCoordinates
    };
});
Advertisements

One response to “02. Canvas

  1. Pingback: 04. Modules and Patterns | Plamen Georgiev·

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s