Bootstrap

HTML(8)基于HTML5的贪吃蛇游戏的设计与实现

一、实验项目

 8.1 基于HTML5的贪吃蛇游戏的设计与实现

功能要求:贪吃蛇游戏是一款经典的单机休闲游戏,玩家通过上下左右按键控制蛇头的移动方向使其向指定方向前进,并吃掉随机位置上产生食物来获得分数。每吃掉一次食物,贪吃蛇的蛇身都会变长,并且会继续在随机位置上产生下一个食物。如果蛇头撞到墙壁或蛇身,则判定游戏失败。根据游戏的难度可以设置不同的游戏速度,蛇的爬行速度越快,游戏难度越大。

8.1.2 界面布局设计

1. 整体界面设计

使用<div>划分区域

CSS外部样式表snake.css

2. 信息展示区设计

使用<div>划分区域

3.主游戏界面设计

使用<canvas>元素制作游戏画面

使用<button>元素制作按钮

二、实验源代码

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>贪吃蛇游戏的设计与实现</title>
        <link rel="stylesheet" href="css/snake.css">
    </head>
    <body>
        <div id="container">
            <h3>基于HTML5的贪吃蛇小游戏</h3>
            <hr>
            <!--状态信息栏-->
            <div id="status">
                <!--历史最高分-->
                <div class="box">
                    历史最高分:<span id="bestScore">0</span>
                </div>
                <!--当前分数-->
                <div class="box">
                    当前分数:<span id="currentScore">0</span>
                </div>
            </div>
            <!--设置游戏画布-->
            <canvas id="myCanvas" width="400" height="400" style="border:1px solid"></canvas>
            <div>
                <button onclick="window.location.reload()">
                    重新开始
                </button>
            </div>
        </div>
        <script>
            //=====================
            // 游戏参数设置
            //=====================
            //游戏界面刷新的间隔时间(数字越大,蛇的速度越慢)
            var time = 200;
            //蛇身长
            var t = 3;
            //记录蛇运行轨迹,用数组记录每一个坐标点uuuj
            var snakeMap = [];
            //蛇身单元大小
            var w = 10;
            // 方向代码:左37,上38,右39,下40
            var direction = 37;
            //蛇的初始坐标
            var x = 0;
            var y = 0;
            //食物的初始化坐标
            var foodX = 0;
            var foodY = 0;
            //当前得分
            var score = 0;
            //历史最高分纪录
            var bestScore = 0;
            //画布的宽和高
            var width = 400;
            var height = 400;
            //根据id找到指定的画布
            var c = document.getElementById("myCanvas");
            //创建2D的context对象
            var ctx = c.getContext("2d");

            // 获得历史最高分记录
            showBestScore();

            //开始游戏
            GameStart();


             //=====================
            // 启动游戏
            //=====================
            function GameStart() {
                // 调用drawFood()函数,在随机位置绘制第一个食物
                drawFood();

                //随机生成贪吃蛇的蛇头坐标
                x = Math.floor(Math.random() * width / w) * w;
                y = Math.floor(Math.random() * height / w) * w;

                //随机生成蛇的前进方向
                direction = 37 + Math.floor(Math.random() * 4);

                // 每隔time毫秒,则刷新一次游戏内容
                setInterval("gameRefresh()", time);
            }

            //=====================
            // 游戏画面刷新函数
            //=====================
            function gameRefresh() {
                //将当前坐标数据添加到贪吃蛇的运动轨迹坐标数组中
                snakeMap.push({
                    'x' : x,
                    'y' : y
                });

                //绘制贪吃蛇
                drawSnake();

                // 根据方向移动蛇头的下一个位置
                switch(direction) {
                //左37
                case 37:
                    x -= w;
                    break;
                //上38
                case 38:
                    y -= w;
                    break;
                //右39
                case 39:
                    x += w;
                    break;
                //下40
                case 40:
                    y += w;
                    break;
                }

                //碰撞检测,返回值0表示没有撞到障碍物
                var code = detectCollision();
                //如果返回值不为0,表示游戏失败
                if (code != 0) {
                    //如果当前得分高于历史最高分,则更新历史最高分记录
                    if (score > bestScore)
                        localStorage.setItem("bestScore", score);
                    //返回值1表示撞到墙壁
                    if (code == 1) {
                        alert("撞到了墙壁,游戏失败!当前得分:" + score);
                    }
                    //返回值2表示撞到蛇身
                    else if (code == 2) {
                        alert("撞到蛇身,游戏失败!当前得分:" + score);
                    }
                    //重新加载页面
                    window.location.reload();
                }

                //吃到食物判定
                if (foodX == x && foodY == y) {
                    //吃到一次食物加10分
                    score += 10;
                    //更新状态栏中的当前分数
                    var currentScore = document.getElementById("currentScore");
                    currentScore.innerHTML = score;
                    //在随机位置绘制下一个食物
                    drawFood();
                    //蛇身长度加1
                    t++;
                }

            }



             //==================
            // 绘制贪吃蛇函数
            //==================
            function drawSnake() {
                //设置蛇身内部填充颜色
                ctx.fillStyle = "lightblue";
                //绘制最新位置的蛇身矩形
                ctx.fillRect(x, y, w, w);

                //数组只保留蛇身长度的数据,如果蛇前进了则删除最旧的坐标数据
                if (snakeMap.length > t) {
                    //删除数组第一项,即蛇的尾部最后一个位置的坐标记录,并且返回
                    var lastBox = snakeMap.shift();
                    //画布清除蛇的尾部最后一个位置,从而实现移动效果
                    ctx.clearRect(lastBox['x'], lastBox['y'], w, w);
                }
            }


            //================
            // 绘制食物函数
            //================
            function drawFood() {
                //随机生成食物坐标
                foodX = Math.floor(Math.random() * width / w) * w;
                foodY = Math.floor(Math.random() * height / w) * w;
                //内部填充颜色
                ctx.fillStyle = "#FF0000";
                //绘制矩形
                ctx.fillRect(foodX, foodY, w, w);
            }



            //==================
            // 改变蛇方向的按键监听
            //==================
            document.onkeydown = function(e) {
                // 根据按键更新前进方向code:左37,上38,右39,下40
                if (e.keyCode == 37 || e.keyCode == 38 || e.keycode == 39 || e.keyCode == 40)
                    direction = e.keyCode;
            }


            //================
            // 碰撞检测函数
            //================
            function detectCollision() {
                //蛇头碰撞到了四周的墙壁,则游戏失败
                if (x > width || y > height || x < 0 || y < 0) {
                    return 1;
                }
                //蛇头碰撞到了蛇身,则游戏失败
                for (var i = 0; i < snakeMap.length; i++) {
                    if (snakeMap[i].x == x && snakeMap[i].y == y) {
                        return 2;
                    }
                }
                return 0;
            }

            //=====================
            // 显示历史最高分记录
            //=====================
            function showBestScore() {
                //从本地存储数据中读取历史最高分
                bestScore = localStorage.getItem("bestScore");
                //如果尚未记录最高分,则重置为0
                if (bestScore == null)
                    bestScore = 0;
                //将历史最高分更新到状态栏中
                var best = document.getElementById("bestScore");
                best.innerHTML = bestScore;
            }

           
          

           
           
           
        </script>
    </body>
</html>

三、实验结果

四、主要知识点

  1. Canvas绘图
  2. JavaScript基础语法
  3. 键盘事件监听:贪吃蛇游戏需要监听用户的键盘输入来控制蛇的移动方向,因此需要使用事件监听来响应键盘输入事件。
;