web 基于jquery和canvas的打飞机小游戏

简易的 利用canvas 实现打飞机

h5里的canvas应该是很强大的,能做的东西很多,因为也是刚接触,所以,尝试用canvas实现了一个简易的网页打飞机小游戏。本来想用一下worker工作线程,但是一下也没想到很好的方案,而且,本来js也没有多线程的概念,因为js是单线程的。

canvas基本的api我前面的博客也介绍了,有这些基本api方法已经可以做很多事情了。
今天我们就来实现一个简单的网页打飞机

这里写图片描述

最下面是玩家,我这里的飞机都还是方块,没有替换成飞机的图片,不过没什么影响,重要的是逻辑实现。玩家可以发子弹,敌机随机从上面直线落下来,玩家需要拦截所有敌机,如果飞机越过底线,或者玩家撞上敌机游戏就结束了,并显示相应的分数。

好了,下面就来简单介绍一下,这个网页打飞机是怎么实现。

首先,我们要知道一个游戏是有主循环的,代码逻辑类似下面这样

最简单的主循环
bool game_is_running = true;//游戏状态

while( game_is_running ) {
update_game();//更新游戏状态
display_game();//刷新页面
}
//每秒的循环次数,就是我们玩游戏常说的帧数(fps)

其实,这里,我的实现可能不是标准的一个游戏开发逻辑,由于我也不是游戏开发人员,所以,游戏主循环实现这方面,也暂时没有理解很清楚是一个怎么样的步骤,应该是有固定套路的,感兴趣的盆友,可以详细了解一下

我这里就是简单实现一个打飞机的小逻辑,规范性和优化性完整性可能都需要再深一步优化和规范。

首先,页面就摆一个canvas画布就可以了,我们的游戏界面和内容都是这一个canvas内完成。
html代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>planeShoot</title>
    <link rel="stylesheet" href="style/default.css"/>
    <script src="script/jquery-1.12.4.js"></script>
</head>
<body>
<div class="background-center">
    <canvas id="bgCanvas" width="400" height="600"></canvas>
</div>
<script src="script/default.js"></script>
</body>
</html>

因为用到了jquery,所以需要引入jquery的js包,default.js是我们实现逻辑的地方

为了方便理解,我这里直接贴出完成js代码,并加上注释

(function (window) {
    var plane = {
        state: true,//游戏状态,true游戏中,false游戏结束
        init: function () {
            var that = this;
            var $canvas = $("#bgCanvas");//获取画布
            var canvas = $canvas[0];
            var ctx = canvas.getContext("2d");//获取画笔
            //fps 60 1s 60次刷新
            //监听用户操作
            that.mianlistener($canvas);
        },
        mianlistener: function ($canvas) {//用户动作监听
            var that = this;
            //鼠标动作监听
            $canvas.on("mousemove mousedown touchstart touchmove", function (e) {
                if (e.type === "mousemove" || e.type === "touchmove") {
                    that.attribute.plane = that.getLocation($canvas[0], e.clientX, e.clientY);
                } else if (e.type === "mousedown" || e.type === "touchstart") {
                    //新增一个子弹进数组
                    that.attribute.bullet.push(that.getLocation($canvas[0], e.clientX, e.clientY));
                }
            });
            //开一个定时器,固定时间建造随机位置的敌机
            setInterval(function () {
                //判断当前敌机数量
                if (!that.state) {
                    return;
                }
                if (that.attribute.enemy.length >= 20) {
                    console.log("够多了不造了");
                    return;
                }
                var x = Math.random() * $canvas[0].width;
                var y = 0;
                that.attribute.enemy.push({x: x, y: y});
            }, 500);
            //fps 60 1s 60次刷新 游戏主循环,也是用定时器实现的
            setInterval(function () {
                that.drawCanvas($canvas[0], that.attribute);//刷屏
            }, 16);
        },
        /**
         * 屏幕坐标与cavas画布坐标转化
         * @param canvas 画布节点对象
         * @param x 屏幕坐标x
         * @param y 屏幕坐标y
         * @returns {{x: number, y: number}} cavas画布坐标
         */
        getLocation: function (canvas, x, y) {
            var bbox = canvas.getBoundingClientRect();
            return {
                x: (x - bbox.left) * (canvas.width / bbox.width),
                y: (y - bbox.top) * (canvas.height / bbox.height)
                // x: (x - bbox.left),
                // y: (y - bbox.top)
                /*
                 * 此处不用下面两行是为了防止使用CSS和JS改变了canvas的高宽之后是表面积拉大而实际
                 * 显示像素不变而造成的坐标获取不准的情况
                */
            };
        },
        drawCanvas: function (canvas, attribute) {//游戏刷屏
            var that = this;
            //清空屏幕
            var ctx = canvas.getContext("2d");
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            if (!that.state) {
                //绘制重写开始
                ctx.font = "20px Arial";
                ctx.fillText(JSON.stringify(attribute.code), canvas.width / 2 - 1, canvas.height / 2 - 1);
                return;
            }
            //碰撞检测
            //子弹和敌机
            that.destroyEnemy(attribute.enemy, attribute.bullet);
            that.destroyPlane(attribute.plane, attribute.enemy);
            //根据属性绘制其他元素
            //飞机
            that.drawPlane(ctx, attribute.plane);
            //子弹
            that.drawBullet(ctx, attribute.bullet);
            //敌机
            that.drawEnemy(ctx, attribute.enemy, canvas.height);
        },
        drawPlane: function (ctx, location) {//画用户飞机
            ctx.fillRect(location.x - 4, location.y - 4, 8, 8);
        },
        drawBullet: function (ctx, location) {//画飞机的子弹
            var that = this;
            if (location && location.length > 0) {
                var bullet = [];
                for (var i = 0, len = location.length; i < len; i++) {
                    var x = location[i].x;
                    var y = location[i].y;
                    ctx.fillRect(x - 1.5, y - 1.5, 3, 3);
                    //改变子弹位置,y值-10
                    if (y > 10) {
                        y = y - 10;
                    } else {
                        //移除这个子弹
                        continue;
                    }
                    bullet.push({x: x, y: y});
                }
                //更新数据
                that.attribute.bullet = JSON.parse(JSON.stringify(bullet));
            }
        },
        drawEnemy: function (ctx, locations, height) {//画敌机
            var that = this;
            if (locations && locations.length > 0) {
                var enemy = [];
                for (var i = 0, len = locations.length; i < len; i++) {
                    var x = locations[i].x;
                    var y = locations[i].y;
                    ctx.fillRect(x - 4, y - 4, 8, 8);
                    //改变敌机位置,y值+1
                    if (y < height) {
                        y = y + 1;//敌机速度 直线下落
                    } else {
                        //敌机越过底线,游戏结束
                        that.state = false;
                        continue;
                    }
                    enemy.push({x: x, y: y});//把最新的敌机位置坐标存起来
                }
                //更新敌机位置集合数据
                that.attribute.enemy = JSON.parse(JSON.stringify(enemy));
            }
        },
        destroyEnemy: function (enemey, bullet) {//子弹与敌机碰撞检测
            var that = this;
            //遍历两个数组
            if (enemey && enemey.length > 0 && bullet && bullet.length) {
                for (var i = enemey.length-1; i >= 0; i--) {
                    for (var j = bullet.length-1; j >= 0; j--) {
                        if (Math.abs(enemey[i].x - bullet[j].x) <= 8 && Math.abs(enemey[i].y - bullet[j].y) <= 8) {
                            //子弹打中敌机 移除敌机
                            that.attribute.code = that.attribute.code + 1;
                            console.log("打中了敌机 = " + that.attribute.code);
                            enemey.splice(enemey.indexOf(enemey[i]), 1);//移除敌机
                            bullet.splice(bullet.indexOf(bullet[j]), 1);//移除子弹
                        }
                    }
                }
            }
        },
        destroyPlane: function (palne, enemey) {//飞机与敌机碰撞检测
            var that = this;
            //遍历两个数组
            if (enemey && enemey.length > 0 && palne) {
                for (var i = 0; i < enemey.length; i++) {
                    if (Math.abs(enemey[i].x - palne.x) <= 8 && Math.abs(enemey[i].y - palne.y) <= 8) {
                        //飞机撞到了敌机
                        console.log("撞到了敌机");
                        that.state = false;//游戏结束
                        return;
                    }

                }
            }
        },
        attribute: {//游戏公共参数,关系到canvas绘画位置
            plane: {x: 50, y: 50},//飞机位置
            bullet: [],//子弹位置
            enemy: [],//敌机位置
            enemyBullet: [],//敌机子弹位置
            drug: {x: -1, y: -1},//药位置
            code: 0//分数
        }
    };
    window.onload = function () {
        plane.init();
    };
    window.plane = plane;
    return window;
})(window);

简单的打飞机,实现就是这么简单,有什么问题,大家可以留言,有更好的实现方案,各位可以分享一下。

完成项目下载地址:https://download.csdn.net/download/lakebobo/10641387

原文链接:加载失败,请重新获取