JavaScript 实现flappy bird小游戏

前言:

《flappy bird》是一款由来自越南的独立游戏开发者Dong Nguyen所开发的作品,游戏于2013年5月24日上线,并在2014年2月突然暴红。2014年2月,《Flappy Bird》被开发者本人从苹果及谷歌应用商店撤下。2014年8月份正式回归APP STORE,正式加入Flappy迷们期待已久的多人对战模式。游戏中玩家必须控制一只小鸟,跨越由各种不同长度水管所组成的障碍。

正文:

试玩链接:点击试玩

接下来就是一步一步来实现它

步骤1:页面布局,这儿就不多说了,页面内容如下:

这里写图片描述

步骤2:如何让小鸟下落以及让小鸟跳起来

鸟下降:

给小鸟一个speed,初始值为0,通过计时器让speed每隔30ms加1,当speed超出最大值speedMax,即speed>8时,让速度保持最大值。

//获取鸟div
var bird = document.getElementById("flybird");
//鸟下降
function down() {
    speed += 1;
    bird.id = 'flybird_down';
    up_bgm.pause();//关闭小鸟上升音乐;
    //当鸟下落速度达到最大值speedMax时,保持不变
    if(speed >= speedMax) {
        speed = speedMax;
    }
    bird.style.top = bird.offsetTop + speed + 'px';
    floorText(); //落地检测
}
鸟上升:

上升,即小鸟的top值减小的过程。让speed减小即可。同时,在鸟上升时,关闭小鸟下降的计时器,以及上次起跳时的上升的计时器,并重新启动上升计时器。在这儿,有个isGameOver,为游戏开关,默认为ture,即当该值为false时,游戏未开始,小鸟无法起跳。

//小鸟上升
function up() {
    speed -= 0.8;
    bird.id = 'flybird_up'//该id下的样式为小鸟下降的背景图片,并增加动画不断替换小鸟的背景图像,让小鸟翅膀动起来~
    up_bgm.play()
    if(speed <= 0) {
        speed = 0;
        clearInterval(upTimer);
        DownTimer = setInterval(down, 30);
    }
    bird.style.top = bird.offsetTop - speed + 'px';
}
//鸟跳动的方法;
function birdJump() {
    speed = speedMax;
    if(isGameOver) {
        //每次向上跳时,先将向上、向下计时器清楚,防止叠加
        clearInterval(upTimer);
        clearInterval(DownTimer); //清除向下的定时器;
        upTimer = setInterval(up, 30);
    }
}
//判断小鸟落地或者小鸟跳出上边界,此时游戏结束
function floorText() {
    var t1 = bird.offsetTop;
    if(t1 > 396) {
        //游戏结束;
        gameover();
    }
    if(t1 < 0) {
        gameover();
    }
}

步骤3:通过以上步骤,小鸟可以起跳啦。接下来就是管道的创建。玩过flappybird游戏的都知道,里面的管道的高度是随机的,但上下两个管道之间的距离是固定的。用Math.random()来产生随机数。

//随机函数,用来随机产生钢管的高度
function rand(min, max) {
    return parseInt(Math.random() * (max - min) + min);
}
//创建管道。在点击开始按钮后,通过计时器来创建
function create_pipe() {
    var conduit_group = document.querySelector(".conduit_group");
    var conduitItem = document.createElement("div");
    //给创建的管道一个样式
    conduitItem.className = 'conduitItem';
    //将创建的管道放入外层div
    conduit_group.appendChild(conduitItem);
    var topHeight = rand(60, 223);//管道里面 上管道的高度值
    var bottomHeight = 323 - 100 - topHeight;//管道里面 下管道的高度值
    //创建上下管道
    conduitItem.innerHTML = '<div class="top_conduit"><div style="height:' + topHeight + 'px"></div></div><div class="bottom_conduit"><div style="height:' + bottomHeight + 'px"></div></div>'
    //获取最外层div的宽度,即为管道可以移动的最大值
    var maxWidth = canvas.offsetWidth;
    //让管道刚开始在canvas外面,一开始看不到
    conduitItem.style.left = maxWidth + 'px';
    //加分开关,每通过一个管道分数才能加1
    conduitItem.AddToscore = true;
    //管道移动方法,通过计时器不断使其的left值递减来实现管道移动。
    conduitItem.movetimer = setInterval(function() {
        maxWidth -= 3;//每30ms向左移动3个像素
        conduitItem.style.left = maxWidth + 'px'
        //在管道跑出去之后,清除使该管道移动的计时器,并将其移除。
        if(maxWidth <= -70) {
            clearInterval(conduitItem.movetimer);
            conduit_group.removeChild(conduitItem);
        }
        //当管道的offsetLeft小于30时,即小鸟成功通过管道之后,分数加1
        if(conduitItem.offsetLeft <= 30 && conduitItem.AddToscore == true) {
            score++;
            conduitItem.AddToscore = false;
            scoreFn(score);
        }
    }, 30)
}

步骤4:通过以上步骤,移动的管道创建好了,小鸟也可以跳了。接下来就是进行碰撞检测,判断小鸟是否碰到管道。

//鸟和管道碰撞检测,obj1为小鸟,obj2为上下管道的父集
//直接获取上下管道,offsetLeft为0,因此要获取其父集;
function crashTest(obj1, obj2) {
    //小鸟的相关量
    var l1 = bird.offsetLeft;
    console.log(l1)
    var r1 = l1 + bird.offsetWidth;
    var t1 = bird.offsetTop;
    var b1 = t1 + bird.offsetHeight
    //管道的相关量
    var l2 = obj2.offsetLeft;
    var r2 = l2 + obj2.offsetWidth;
    var t2 = obj1.offsetTop;
    var b2 = t2 + obj1.offsetHeight;
    //判断条件
    if(r1 > l2 && l1 < r2 && b1 > t2 && t1 < b2) {
        gameover();
    }
}
function judge() {
    //获取创造的在当前页面显示的所有管道,为一个数组
    var conduitItem = document.querySelector('.conduit_group').querySelectorAll('.conduitItem');
    //遍历显示的管道,为crashTest方法传递参数来进行判断。
    for(var i = 0; i < conduitItem.length; i++) {
        var top_conduit = conduitItem[i].querySelector('.top_conduit');
        var bottom_conduit = conduitItem[i].querySelector('.bottom_conduit');
        crashTest(top_conduit, conduitItem[i]);
        crashTest(bottom_conduit, conduitItem[i]);
    }
}

步骤5:游戏结束方法。当碰到管道,碰到上边界,落地,游戏结束,显示本局分数,并显示历史最高记录。

//游戏结束
function gameover() {
    //游戏结束背景音乐打开
    gameover_bgm.play();
    isGameOver = false;
    //结束音乐
    bgm.pause();
    clearTimer();
    //小鸟换回原来的样式
    bird.id = 'flybird'
    bird.className = 'birddown'
    bird.style.top = '392px';
    //存储最高纪录
    var historyscore = localStorage.getItem('maxScore');
    //当历史记录不存在或者历史记录小于当前记录时,创建masScore.
    if(historyscore == null || historyscore < score) {
        localStorage.setItem('maxScore', score);
        //刷新记录
        historyscore = score;
    }
    //历史最高纪录
    historyScore.innerHTML = historyscore;
    //当前分数
    thisScore.innerHTML = score;
    //显示游戏结束画面
    document.querySelector('.gameover').style.display = 'block';
}

步骤7:游戏开始方法。

//游戏初始化
function init() {
    //为start_btn,即页面刚开始显示的start创建点击事件,即开始按钮
    start_btn.onclick = function() {
        //点击之后,开始界面隐藏
        gameStartDiv.style.display = 'none';
        //小鸟显示出来
        bird.style.display = 'block';
        //使小鸟在中间显示
        bird.style.top = '200px';
        bgm.play();
        //通过点击,来调用birdJump方法,来使小鸟上升
        //开始创造管道
        conduitTimer = setInterval(create_pipe, 2000)
        document.addEventListener('click', birdJump, false)
        crashTestTimer = setInterval(judge, 1000 / 60);
    }
}
init();

步骤7:游戏重新开始方法

//重新开始
var game_restart = document.querySelector(".game_restart")
game_restart.onclick = restart;
var conduit_group = document.querySelector(".conduit_group")
//回到刚开始的界面
function restart() {
    bird.className = 'bird'
    clearTimer();
    scoreDiv.innerHTML = null;
    isGameOver = true;
    speed = 0;
    score=0;
    speedMax = 8;
    document.querySelector('.gameover').style.display = 'none';
    gameStartDiv.style.display = 'block';
    bird.style.display = 'none';
    conduit_group.innerHTML = '';
}
这儿用到的clearTimer方法为清除所有记时器,代码如下:
function clearTimer() {
    var timer = setInterval(function() {}, 30);
    for(i = 0; i < timer; i++) {
        clearInterval(i);
    }
}

这样游戏大致已经做好啦。

效果图如下:
flappy bird
下面附上源码下载地址,请在谷歌浏览器上进行试验。
源码下载地址

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值