井井客

搜索

Canvas 小游戏(儿时的记忆)

特别棒的一款canvas小游戏,反正我小时候是玩过~

Canvas 小游戏(儿时的记忆)

原文摘自:http://canvas.migong.org/category/canvas-animation/page/10

代码如下,建议可以看一下原文,里面有解释更多。

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Canvas 小游戏(儿时的记忆)</title>
    <style>
        @import url('https://fonts.googleapis.com/css?family=Press+Start+2P');
        html, body {
            overflow: hidden;
            height: 100%;
            margin: 0;
            padding: 0;
            background: #111;
            color: white;
            text-shadow: 0 3px 0 rgba(0,0,0,.4);
            background: radial-gradient(#333, #000);
            font: 12px "Press Start 2P";
            cursor: crosshair;
        }

        #breakout {
            cursor: none;
            position: absolute;
            top: 0;
            left: 50%;
            margin-left: -200px;
            width: 400px;
            overflow: hidden;
            box-shadow: 0 50px 100px rgba(0, 0, 0, .9);
            border: 1px solid rgba(255, 255, 255, .2);
        }

        #game {
            background: linear-gradient(#ff0084, #33001b);
        }

        #score,#highscore {
            position: absolute;
            top: 15px;
        }

        #score {
            left: 10px;
        }

        #highscore {
            right: 10px;
        }

        #lives {
            position: absolute;
            bottom: 10px;
            right: 10px;
        }
        #lives span {
            font-size: 8px;
        }

        .message {
            position: absolute;
            left: 0;
            bottom: 150px;
            right: 0;
            text-align: center;
            opacity: 0;
            -webkit-transform: translateY(100px) scale(0);
                    transform: translateY(100px) scale(0);
            -webkit-transition: .25s all;
                    transition: .25s all;
        }
        .message h2 {
            font-size: 16px;
        }

        .gameover.message h2 {
            font-size: 24px;
        }

        .start.message {
            bottom: 300px;
            opacity: 1;
            -webkit-transform: translateY(0) scale(1);
                    transform: translateY(0) scale(1);
        }

        .message-shown {
            opacity: 1;
            -webkit-transform: translateY(0) scale(1);
                    transform: translateY(0) scale(1);
        }
    </style>
</head>
<body>
    <div id="breakout">
        <canvas id="game" width="400" height="600"></canvas>
        <div id="score">SCORE:<span>000000</span></div>
        <div id="highscore">HIGH:<span>000000</span></div>
        <div id="lives">♥ <span>5</span></div>
        <div id="message" class="start message">
            <h2>HTML5 Breakout</h2>
            <p>Insert coin</p>
        </div>
    </div>
    <script>
        (function () {
            //不同等级的砖块摆放形状变量
            var levels = [

                [   '             ',
                    '             ',
                    '   **   **   ',
                    '  *00* *00*  ',
                    ' *0000*00*0* ',
                    ' *1111111*1* ',
                    ' *222222222* ',
                    ' *3333333*3* ',
                    '  *3344333*  ',
                    '  *3444433*  ',
                    '   *44443*   ',
                    '   *44443*   ',
                    '    *443*    ',
                    '     *3*     ',
                    '      *      ',
                ],
              
                [   '   0     0   ',
                    '   0     0   ',
                    '    0   0    ',
                    '    0   0    ',
                    '   1111111   ',
                    '   2222222   ',
                    '  333333333  ',
                    '  444444444  ',
                    ' 4* 44*44 *4 ',
                    ' ** 4***4 ** ',
                    ' **44***44** ',
                    ' **444*444** ',
                    ' 4 4444444 4 ',
                    ' 3 3     3 3 ',
                    '   2     2   ',
                    '    11 11    ',
                    '    00 00    ',
                ],

                [   '      5     ',
                    '     555     ',
                    '    4 5 4    ',
                    '   3  5  3   ',
                    '  2   5   2  ',
                    ' 1    5    1 ',
                    '01   5 5   10',
                    '0 2 4   4 2 0',
                    '0  3     3  0',
                    '0 2 4   4 2 0',
                    '01   5 5   10 ',
                    ' 1    5    1 ',
                    '  2   5   1  ',
                    '   3  5  1   ',
                    '    4 5 1    ',
                    '     555     ',
                    '      5      ',
                ],

                [   '             ',
                    '  1       1  ',
                    ' 12   5   21 ',
                    '    55555    ',
                    '   4344434   ',
                    '   3 343 3   ',
                    '   4  3  4   ',
                    '   4445444   ',
                    '    54545    ',
                    '    4 4 4    ',
                    '             ',
                    '    4 4 4    ',
                    '    44444    ',
                    ' 12  555  21 ',
                    '  1       1  ',
                ],

                [   '     000    ',
                    '   0000000   ',
                    '  111111111  ',
                    '  222222222  ',
                    ' 333 333 333 ',
                    ' 444 444 444 ',
                    ' 555 555 555 ',
                    ' 444 444 444 ',
                    ' 33333333333 ',
                    ' 2 2222222 2 ',
                    ' 1  22222  1 ',
                    ' 11  222  11 ',
                    '  11     111  ',
                    '  211   112  ',
                    '   2111112   ',
                    '    22222    ',
                    '     333     ',
                ],

                [   '00000   00000',
                    ' 11111 11111 ',
                    '  222222222  ',
                    '   3333333   ',
                    '4   44444   4',
                    '**   ***   **',
                    '000   0   000',
                    '1111     1111',
                    '22222   22222',
                    ' 33333 33333 ',
                    '  444444444  ',
                    '   *******   ',
                    '0   00000   0',
                    '11   111   11',
                    '222   2   222',
                ],

                [   '      p      ',
                    '      *      ',
                    '      *      ',
                    '      *      ',
                    '   r *** r   ',
                    '   r *** r   ',
                    '   * *** *   ',
                    '   *b*r*b*   ',
                    '   b*rrr*b   ',
                    '   b*rrr*b   ',
                    '   **r*r**   ',
                    ' p*********p ',
                    ' *********** ',
                    ' ** rr*rr ** ',
                    ' ** rr*rr ** ',
                    ' *    *    * ',
                ],
            ];

            //颜色变量
            var colors = {
                '0': '#AEEA00',
                '1': '#C6FF00',
                '2': '#EEFF41',
                '3': '#F4FF81',
                '4': '#F5FFB4',

                'r': '#FF1744',
                'g': '#B2FF59',
                'b': '#80D8FF',
                'y': '#FFF59D',
                'o': '#FFE082',
            },
            defaultColor = '#F9FBD6';   //默认颜色

            //选择器变量
            var $ = function (selector) {
                return document.querySelector(selector);
            };
            //初始化变量
            var canvas  = $('#game'),
                context = canvas.getContext('2d');

            var paused = true,
                speed = 3,
                bricksMargin = 1,
                bricksWidth = 0,
                bricksHeight = 18,
                bricks,
                round, score, lives,
                highscore = localStorage.getItem('highscore') || 0;

            //球 变量
            var ball = {
                w: 6,
                h: 6,
                x: 0,
                y: 0,
                speedX: 0,
                speedY: 0,
            };

            //底部托盘变量
            var player = {
                w: 60,
                h: 4,
                x: (canvas.width / 2) - 30,
                y: canvas.height - 40,
            };

            //音效变量
            var soundInstance = 0,
                sounds = [],
                sound, music1, music2;

            //向数组 sounds 添加 音效
            for (var s = 0; s < 5; s ++) {
                sound = document.createElement('audio');
                sound.setAttribute('src', 'http://jaysalvat.github.io/codepen-assets/breakout/beep.mp3');
                sounds.push(sound);
            }

            //开始音效
            music1 = document.createElement('audio');
            music1.setAttribute('src', 'http://jaysalvat.github.io/codepen-assets/breakout/start.mp3');

            //结束音效
            music2 = document.createElement('audio');
            music2.setAttribute('src', 'http://jaysalvat.github.io/codepen-assets/breakout/gameover.mp3');

            //绘制动画兼容
            window.requestAnimationFrame = window.requestAnimationFrame
                || window.mozRequestAnimationFrame
                || window.webkitRequestAnimationFrame
                || window.msRequestAnimationFrame;

            //播放声音函数
            function playSound () {
                if (soundInstance >= sounds.length) {
                    soundInstance = 0;
                }
                sounds[soundInstance ++].play();
            }

            //创建砖块堆砌形状函数
            function buildLevel () {
                var index, level, row, column, color;

                index  = (round % levels.length || levels.length) - 1;
                level  = levels[index];
                bricks = [];    //砖块数组

                for (row = 0; row < level.length; row ++) {
                    for (column = 0; column < 13; column ++) {

                        if (!level[row][column] || level[row][column] === ' ') {
                            continue;
                        }
                        bricksWidth = (canvas.width - bricksMargin * 2) / 13;

                        //给砖块添加相应颜色
                        color = colors[level[row][column]];
                        //如果没有,则使用默认颜色
                        if (!color) {
                            color = defaultColor;
                        }

                        //向砖块数组中添加数据(位置,宽高,颜色)
                        bricks.push({
                            x: bricksMargin * 2 + (bricksWidth * column),
                            y: bricksHeight * row + 60,
                            w: bricksWidth - bricksMargin * 2,
                            h: bricksHeight - bricksMargin * 2,
                            color: color,
                        });
                    }
                }
            }

            //重置小球
            function resetBall () {
                ball.x = (canvas.width / 2) - (ball.w / 2);
                ball.y = (canvas.height / 1.8) - (ball.h / 2);
                ball.speedX = speed;
                ball.speedY = speed;

                //开始游戏后,小球随机弹射方向(0或1 都是 true 所以会执行if语句内的代码)
                if (Math.round(Math.random() * 1)) {
                    ball.speedX = -speed;
                }
            }

            //碰撞函数
            function detectCollision () {

                // 小球碰撞底部托盘时触发

                if (ball.y + ball.h >= player.y
                 && ball.y + ball.h <= player.y + player.h
                 && ball.x >= player.x
                 && ball.x <= player.x + player.w
                ) {
                    playSound();    //播放碰撞音乐
                    ball.speedY = -ball.speedY;
                    ball.speedX = (ball.x - (player.x + player.w / 2)) * 0.25;
                }

                // 小球碰撞砖块时触发

                for (var i = 0; i < bricks.length; i ++) {
                    var brick = bricks[i];

                    if (ball.y + ball.h >= brick.y
                     && ball.y <= brick.y + brick.h
                     && ball.x + ball.w >= brick.x
                     && ball.x <= brick.x + brick.w
                    ) {
                        playSound();    //播放碰撞音乐
                        ball.speedY = -ball.speedY;

                        score ++;
                        bricks.splice(i, 1);

                        if (bricks.length <= 0) {
                            round ++;
                            speed += .5;
                            startGame();
                        }

                        break;
                    }
                }
            }

            //移动对象函数
            function moveObjects () {
                if (paused) {
                    return;
                }

                detectCollision();  //小球碰撞砖块和底部托盘函数

                ball.x += ball.speedX;
                ball.y += ball.speedY;

                //小球碰撞X轴墙壁判断
                if (ball.x <= 0 || ball.x + ball.w >= canvas.width) {
                    ball.speedX = -ball.speedX;
                }

                //小球碰撞Y轴墙壁判断
                if (ball.y <= 0 || ball.y + ball.h >= canvas.height) {
                    ball.speedY = -ball.speedY;
                }

                //判断球的位置(球y轴+球的高度) >= Canvas 高度
                if (ball.y + ball.h >= canvas.height) {
                    lives --;       //减少生命

                    if (lives === 0) {
                        gameover(); //如果生命等于 0 游戏结束
                    } else {
                        ready();    //从新准备开始
                    }
                    resetBall();    //重置球
                }
            }

            //显示得分函数
            function displayScore (score) {
                return Array(6 - String(score).length + 1).join('0') + score;
            }

            //更新对象函数
            function updateObjects () {
                $('#score span').textContent = displayScore(score);     //更新分数
                $('#lives span').textContent = lives;                   //剩余生命

                context.clearRect(0, 0, canvas.width, canvas.height);   //清除矩形

                //绘制对象函数传参
                drawObject(ball.x, ball.y, ball.w, ball.h);                     //更新球的位置
                drawObject(player.x, player.y, player.w, player.h, colors[2]);  //更新底部托盘位置

                bricks.forEach(function (brick) {                               //更新砖块(循环遍历砖块数组)
                    drawObject(brick.x, brick.y, brick.w, brick.h, brick.color);
                });
            }

            //绘制对象函数
            function drawObject (x, y, w, h, color) {
                context.fillStyle = 'rgba(0, 0, 0, .15)';
                context.fillRect(x + bricksWidth / 2, y + bricksHeight, w, h);

                context.fillStyle = color || 'white';
                context.fillRect(x, y, w, h);
            }

            //更新游戏函数
            function refreshGame () {
                requestAnimationFrame(refreshGame);
                moveObjects();
                updateObjects();
            }

            //隐藏消息函数
            function hideMessage () {
                $('#message').className = 'message';
            }

            //准备开始游戏函数
            function ready () {
                music1.play();  //播放开始音效

                paused = true;  //暂停

                $('#message h2').textContent = 'ROUND ' + round;
                $('#message p').textContent  = 'Click when ready!';
                $('#message').className = 'message message-shown';

                $('#highscore span').textContent = displayScore(highscore);
            }

            //游戏结束函数
            function gameover () {
                music2.play();  //播放结束音效

                paused = true;  //暂停

                if (score > highscore) {
                    highscore = score;
                    localStorage.setItem('highscore', score);
                }

                $('#message h2').textContent = 'GAME OVER';
                $('#message p').textContent  = 'Click to play again!';
                $('#message').className = 'gameover message message-shown';

                $('#highscore span').textContent = displayScore(highscore);
            }

            //重置游戏
            function resetGame () {
                round = 1;
                score = 0;
                lives = 5;
            }

            //开始游戏
            function startGame () {
                resetBall();
                buildLevel();
                ready();
            }

            //监听键盘按键
            document.body.addEventListener('keydown', function (e) {
                switch (e.keyCode) {
                    case 32:    //空格
                        paused = !paused;
                        hideMessage();
                    break;
                    case 37:    //左
                        player.x -= 20;
                    break;
                    case 39:    //右
                        player.x += 20;
                    break;
                }
            });

            //监听点击事件(开始游戏,隐藏消息提示)
            document.body.addEventListener('click', function () {
                if (lives === 0) {  //生命值等于0重置游戏
                    resetGame();
                    startGame();
                    return;
                }

                hideMessage();      //隐藏消息
                paused = false;
            });

            //监听鼠标移动事件
            document.body.addEventListener('mousemove', function (evt) {
                var rect   = canvas.getBoundingClientRect(),    //获取 Canvas 在页面中的位置
                    mouseX = evt.clientX - rect.left,
                    half   = player.w / 2;

                if (mouseX <= half) {
                    mouseX = half;
                }

                if (mouseX >= canvas.width - half) {
                    mouseX = canvas.width - half;
                }

                player.x = mouseX - half;
            });

            //重置,刷新,开始游戏
            resetGame();
            startGame();
            refreshGame();
        })();
    </script>
</body>
</html>

文章TAG:canvas

作者:井井客整理来源:互联网
本文标题:Canvas 小游戏(儿时的记忆)
本文链接:http://www.jingjingke.com/c/24292.html

上一篇:Canvas 闪电动画
下一篇:Canvas 液体波浪动画

文章分类

相关阅读

随便看看