用JavaScript实现贪吃蛇游戏_艾孜尔江撰

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <title>JavaScript实现贪吃蛇游戏_/艾孜尔江撰/</title>
    <style>
        article,
        aside,
        details,
        figcaption,
        figure,
        footer,
        header,
        hgroup,
        menu,
        nav,
        section {
            display: block;
        }

        body {
            background-color: #CCC;
        }

        h1 {
            text-align: center;
        }

        p {
            text-align: center;
        }

        canvas {
            display: block;
            margin: 0 auto;
            background-color: #666;
        }
    </style>
</head>

<body>

    <h1>贪吃蛇</h1>

    <div>
        <canvas id="maincanvas" width="320" height="240">
    </div>

    <p>使用WASDHJKL或上下左右键控制方向</p>
    <p>随着蛇身变长,速度也会变快</p>
    <p>按空格开始游戏</p>
    <p>艾孜尔江复现</p>

    <script>
        var canvas = document.getElementById("maincanvas");
        var context = canvas.getContext("2d");
        var game, snake, food;

        game = {

            score: 0,
            fps: 8,
            over: false,
            message: null,

            start: function () {
                game.over = false;
                game.message = null;
                game.score = 0;
                game.fps = 8;
                snake.init();
                food.set();
            },

            stop: function () {
                game.over = true;
                game.message = 'GAME OVER - PRESS SPACEBAR';
            },

            drawBox: function (x, y, size, color) {
                context.fillStyle = color;
                context.beginPath();
                context.moveTo(x - (size / 2), y - (size / 2));
                context.lineTo(x + (size / 2), y - (size / 2));
                context.lineTo(x + (size / 2), y + (size / 2));
                context.lineTo(x - (size / 2), y + (size / 2));
                context.closePath();
                context.fill();
            },

            drawScore: function () {
                context.fillStyle = '#999';
                context.font = (canvas.height) + 'px Impact, sans-serif';
                context.textAlign = 'center';
                context.fillText(game.score, canvas.width / 2, canvas.height * 0.9);
            },

            drawMessage: function () {
                if (game.message !== null) {
                    context.fillStyle = '#00F';
                    context.strokeStyle = '#FFF';
                    context.font = (canvas.height / 10) + 'px Impact';
                    context.textAlign = 'center';
                    context.fillText(game.message, canvas.width / 2, canvas.height / 2);
                    context.strokeText(game.message, canvas.width / 2, canvas.height / 2);
                }
            },

            resetCanvas: function () {
                context.clearRect(0, 0, canvas.width, canvas.height);
            }

        };

        snake = {

            size: canvas.width / 40,
            x: null,
            y: null,
            color: '#0F0',
            direction: 'left',
            sections: [],

            init: function () {
                snake.sections = [];
                snake.direction = 'left';
                snake.x = canvas.width / 2 + snake.size / 2;
                snake.y = canvas.height / 2 + snake.size / 2;
                for (var i = snake.x + (5 * snake.size); i >= snake.x; i -= snake.size) {
                    snake.sections.push(i + ',' + snake.y);
                }
            },

            move: function () {
                switch (snake.direction) {
                    case 'up':
                        snake.y -= snake.size;
                        break;
                    case 'down':
                        snake.y += snake.size;
                        break;
                    case 'left':
                        snake.x -= snake.size;
                        break;
                    case 'right':
                        snake.x += snake.size;
                        break;
                }
                snake.checkCollision();
                snake.checkGrowth();
                snake.sections.push(snake.x + ',' + snake.y);
            },

            draw: function () {
                for (var i = 0; i < snake.sections.length; i++) {
                    snake.drawSection(snake.sections[i].split(','));
                }
            },

            drawSection: function (section) {
                game.drawBox(parseInt(section[0]), parseInt(section[1]), snake.size, snake.color);
            },

            checkCollision: function () {
                if (snake.isCollision(snake.x, snake.y) === true) {
                    game.stop();
                }
            },

            isCollision: function (x, y) {
                if (x < snake.size / 2 ||
                    x > canvas.width ||
                    y < snake.size / 2 ||
                    y > canvas.height ||
                    snake.sections.indexOf(x + ',' + y) >= 0) {
                    return true;
                }
            },

            checkGrowth: function () {
                if (snake.x == food.x && snake.y == food.y) {
                    game.score++;
                    if (game.score % 5 == 0 && game.fps < 60) {
                        game.fps++;
                    }
                    food.set();
                } else {
                    snake.sections.shift();
                }
            }

        };

        food = {

            size: null,
            x: null,
            y: null,
            color: '#0FF',

            set: function () {
                food.size = snake.size;
                food.x = (Math.ceil(Math.random() * 10) * snake.size * 4) - snake.size / 2;
                food.y = (Math.ceil(Math.random() * 10) * snake.size * 3) - snake.size / 2;
            },

            draw: function () {
                game.drawBox(food.x, food.y, food.size, food.color);
            }

        };

        var inverseDirection = {
            'up': 'down',
            'left': 'right',
            'right': 'left',
            'down': 'up'
        };

        var keys = {
            up: [38, 75, 87],
            down: [40, 74, 83],
            left: [37, 65, 72],
            right: [39, 68, 76],
            start_game: [13, 32]
        };

        function getKey(value) {
            for (var key in keys) {
                if (keys[key] instanceof Array && keys[key].indexOf(value) >= 0) {
                    return key;
                }
            }
            return null;
        }

        addEventListener("keydown", function (e) {
            var lastKey = getKey(e.keyCode);
            if (['up', 'down', 'left', 'right'].indexOf(lastKey) >= 0
                && lastKey != inverseDirection[snake.direction]) {
                snake.direction = lastKey;
            } else if (['start_game'].indexOf(lastKey) >= 0 && game.over) {
                game.start();
            }
        }, false);

        var requestAnimationFrame = window.requestAnimationFrame ||
            window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame;

        function loop() {
            if (game.over == false) {
                game.resetCanvas();
                game.drawScore();
                snake.move();
                food.draw();
                snake.draw();
                game.drawMessage();
            }
            setTimeout(function () {
                requestAnimationFrame(loop);
            }, 1000 / game.fps);
        }

        requestAnimationFrame(loop);
    </script>
</body>

</html>

欢迎广大读者交流分享代码、经验、及新观点、新主意!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值