一个简单用原生js实现的小游戏----FlappyBird

这是一个特别简单的用原生js实现的一个小鸟游戏,比较简单,适合新手练习

这是html结构

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>

</head>

<body>

<div id="game">
<div id="bird"></div>
</div>
<script src="flappybird.js"></script>
<script src="animate.js"></script>
</body>
</html>

  

  整个案例结构并不多,下面是css样式

 body {
            margin: 0;
            padding: 0;
        }

        #game {
            width: 800px;
            height: 600px;
            border: 1px solid #000;
            background: url(images/sky.png);
            overflow: hidden;
            position: relative;
        }

        #game .pipeD {
            background: url(images/pipe1.png) top center;
            position: absolute;
        }

        #game .pipeU {
            background: url(images/pipe2.png) bottom center;
            position: absolute;
        }

        #bird {
            width: 34px;
            height: 25px;
            /*border-radius: 10px;*/
            /*background-color: red;*/
            position: absolute;
            top: 100px;
            left: 100px;
            background: url(images/birds.png) -8px -10px no-repeat;
        }

下面就是原生js代码了,这个小案例还运用了自己前期封装的一个小的动画方法

function animate(obj, json, fn) {
    clearInterval(obj.timer);
    obj.timer = setInterval(function () {
        var flag = true;
        for (var k in json) {
            if (k === "opacity") {
                var leader = getStyle(obj, k) * 100;
                var target = json[k] * 100;
                var step = (target - leader) / 10;
                step = step > 0 ? Math.ceil(step) : Math.floor(step);
                leader = leader + step;
                obj.style[k] = leader / 100;
            } else if (k === "zIndex") {
                obj.style.zIndex = json[k];
            } else {
                var leader = parseInt(getStyle(obj, k)) || 0;
                var target = json[k];
                var step = (target - leader) / 10;
                step = step > 0 ? Math.ceil(step) : Math.floor(step);
                leader = leader + step;
                obj.style[k] = leader + "px";
            }
            if (leader !== target) {
                flag = false;
            }
        }
        if (flag) {
            clearInterval(obj.timer);
            if (fn) {
                fn();
            }
        }
    }, 15);
}
function getStyle(obj, attr) {
    if (window.getComputedStyle) {
        return window.getComputedStyle(obj)[attr];
    } else {
        return obj.currentStyle[attr];
    }
}

  下面就是控制游戏的js代码了

var birdElement = document.getElementById("bird");
var game = document.getElementById("game");
var gameover = false;
var g = 1;
var i = 0;
var timer=null;
var bird = {
    x: birdElement.offsetLeft,
    y: birdElement.offsetTop,
    speedX: 5,
    speedY: 0,
    entity: birdElement
};
var sky = {
    x: 0
};

//var timer=setInterval(function(){
//    birdElement.style.backgroundPositionX=-52*i+"px";
//    i++;
//    if(i===3){
//        i=0;
//    }
//},100);

setInterval(function () {
    //游戏没有结束的时候运行代码
    if (!gameover) {
        //整个游戏背景x轴移动的距离
        sky.x = sky.x - bird.speedX;
        game.style.backgroundPositionX = sky.x + "px";
        //小鸟下落时y轴的坐标
        bird.speedY = bird.speedY + g;
        //设置一个变量用来接收小鸟下落时y轴的坐标,用来设置小鸟下降时的速度
        var step = bird.speedY;
        bird.y = bird.y + step;
        //用一个变量来设定小鸟下落的最低高度,用来 判断游戏是否结束
        var overY = game.offsetHeight - birdElement.offsetHeight;
        //小鸟的y轴坐标大于最低高度,所以游戏停止
        if (bird.y > overY) {
            bird.y = overY;
            stop();
        }
        //小鸟的y轴坐标小于0,说明碰到顶部边框,所以游戏结束
        if (bird.y < 0) {
            bird.y = 0;
            stop();
        }
        //设置游戏开始时小鸟出现的位置
        bird.entity.style.top = bird.y + "px";
    }
}, 25);
//添加键盘事件,实现键盘上下键控制小鸟
document.onkeyup = function (e) {
    if (e.keyCode === 38) {
        bird.speedY = -10;
    }
}

function Pipe(positonX) {
    //管子的坐标
    this.x = positonX;
    this.upPipeY = 0;
    this.width = 52;
    this.upPipeH = parseInt(Math.random() * 175 + 100);
    this.downPipeY = this.upPipeH + 200;
    this.downPipeH = game.offsetHeight - this.downPipeY;
    // 动态添加管子
    var divUp = document.createElement("div");
    divUp.className = "pipeU";
    divUp.style.width = this.width + "px";
    divUp.style.height = this.upPipeH + "px";
    divUp.style.left = this.x + "px";
    divUp.style.top = this.upPipeY + "px";
    game.appendChild(divUp);
    var divDown = document.createElement("div");
    divDown.className = "pipeD";
    divDown.style.width = this.width + "px";
    divDown.style.height = this.downPipeH + "px";
    divDown.style.left = this.x + "px";
    divDown.style.top = this.downPipeY + "px";
    game.appendChild(divDown);
    //因为定时器会混乱this的指向问题,所以提前保存this的指向,这里的this指向调用该方法的实例
    var that = this;
    // 设置定时器让管子向后移动
    this.timer=setInterval(function () {
        that.x = that.x - 1;
        //简单实现管子无缝滚动
        if (that.x < -52) {
            that.x = 800;
        }
        if (!gameover) {
            divUp.style.left = that.x + "px";
            divDown.style.left = that.x + "px";
        }
        // 设置变量,进行游戏碰撞检测,并停止游戏
        var downCrash = (bird.x + 34 > that.x) && (bird.x < that.x + 52) && (bird.y + 25 > that.downPipeY);
        var upCrash = (bird.x + 34 > that.x) && (bird.x < that.x + 52) && (bird.y < that.upPipeH);
        if (downCrash || upCrash) {
            //gameover = true;
            stop();
        }
    }, 10);
}
//执行上面的函数方法
var arr=[];
for (var i = 0; i < 4; i++) {
    arr[i]=new Pipe(i * 200 + 400);
}
//封装一个用来停止游戏的方法,
function stop(){
    gameover=true;
    clearInterval(timer);
    for(var i=0;i<arr.length;i++){
        clearInterval(arr[i].timer);
    }
}

  注释都写在了了代码里,一个简单小游戏就完成了

  

 

转载于:https://www.cnblogs.com/microcosm1994/p/6657933.html

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下载后可以在webstrom中打开运行。 1. underscore中random产生随机数、without从数组中移除数据 2. 在游戏开发的时候,应该始终用面向对象的思想来做。有一个游戏管控大类(Game)。 3. 用一个json文件,保存我们需要的图片数据,方便在内存中创建每一张图片对象。 4. canvas的宽度和高度不能固定,根据电脑动态设置。 5. 使用ES6语法创建类。 6. FPS (每秒传输帧数(Frames Per Second)) 刷新率FNO 记录当前走过总帧数 7. 在每一次canvas绘制之前,都要进行清屏操作。ctx.clearRect(0, 0, canvas.width, canvas.height); 8. 资源加载。通过AJAX加载资源。静态资源类StaticResourceUtil.js用来加载本地图片。 9. 图片绘制,背景类BackGround.js,用来绘制背景。 通过图片的移动实现游戏的移动。 图片的移动即不断改变图片的X坐标,不断绘制。 图片的无缝移动:绘制图片的两倍,当全部图片宽度走完的时候,将图片X重新改为0. 背景图的速度设置,事物离得越近速度越快,越远速度越慢。 10. 取整、字符串转数字:parseInt(txt); 11. 管道绘制,管道类Pipe.js,用来绘制管道。 管道的高度、位置要随机生成。 但要有最小高度与最大高度。 需要一个管道数组来保存所有的管道。 当管道移出画布,需要将管道从管道数组中移除。 12. 用gameEnd来标志游戏是否结束。 13. 鸟的绘制,鸟类bird.js,用来绘制鸟。 根据帧率不断煽动翅膀。 14. 模拟重力加速度,利用dY,不断更新鸟的y值。导致鸟的下落越来越快。 15. 鸟的旋转。利用save和restore保存和恢复画布的状态。 利用translate旋转画布的x、y轴,旋转鸟恢复。 16. 鼠标点击事件,在鸟的上升过程中,固定值模拟阻力。 17. 边界检测。上边界ycanvas.height - 地板高度 - 鸟高度 18. 碰撞检测。利用管道进行检测。首先判断鸟有没有进到管道竖着的区域,再判断鸟是在空白天空区域还是管道区域,从而进行检测。 19. 小鸟死亡,在死亡的地方绘制鲜血。鲜血撒完游戏结束。 20. 分数类。根据几位判断分数显示基准线。判断小鸟是否飞到管道竖着的部分,如果飞过,则分数加一。 21. 求一个数字有几位。num.toString().length 22. 游戏初始化。设置背景及图片,点击开始后div隐藏。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值