HTML---FlappyBird

原创
2020/03/24 18:00
阅读数 112

开发工具:Visual Studio Code

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

1.设置画布

<canvas id="canvas" width="340" height="453" style="border: 2px solid #000;background: #fff;"></canvas>
 
2.导入js
 
<script src="bird.js" type="text/javascript"></script>
 
3.bird类
 
function Bird(x, y, image) {
    this.x = x,
    this.y = y,
    this.width = image.width / 2,
    this.height = image.height,
    this.image = image;
    this.draw = function(context, state) {
        if (state === "up")
            context.drawImage(image, 0, 0, this.width, this.height, this.x, this.y, this.width, this.height);
        else{
 
            context.drawImage(image, this.width, 0, this.width, this.height, this.x, this.y, this.width,
                this.height);
        }
    }
};

 

4.obstacle类

 
function Obstacle(x, y, h, image) {
    this.x = x,
    this.y = y,
    this.width = image.width / 2,
    this.height = h,
    this.flypast=false;//没被飞过
    this.draw = function(context, state) {
        if (state === "up") {
            context.drawImage(image, 0, 0, this.width, this.height, this.x, this.y, this.width, this.height);
        } else {
 
            context.drawImage(image, this.width, image.height - this.height, this.width, this.height, this.x,
                this.y, this.width, this.height);
        }
    }
};
 
5.FlappyBird类
 
function FlappyBird(){}
FlappyBird.prototype={
bird: null, // 小鸟
bg: null, // 背景图
obs: null, // 障碍物
obsList: [],
 
mapWidth: 340, // 画布宽度
mapHeight: 453, // 画布高度
startX: 90, // 起始位置
startY: 225,
obsDistance: 150, // 上下障碍物距离
obsSpeed: 2, // 障碍物移动速度
obsInterval: 2000, // 制造障碍物间隔ms
upSpeed: 8, // 上升速度
downSpeed: 3, // 下降速度
line: 56, // 地面高度
score: 0, // 得分
touch: false, // 是否触摸
gameOver: false,
 
6.设置背景 
 
CreateMap:function(){
        this.bg=new Image();
        //背景
        this.bg.src='img/bg.png';
        var starBg=new Image();
        starBg.src='img/start.jpg';
        starBg.onload=function(){
            c.drawImage(starBg,0,0);
        };
        //小鸟
        var image=new Image();
        image.src='img/bird.png';
        image.onload=function(){
            this.bird=new Bird(this.startX,this.startY,image);
        }.bind(this);
        //障碍物
        this.obs=new Image();
        this.obs.src='img/obs.png';
        this.obs.onload=function(){
            var h=100;
            var h2=this.mapHeight-h-this.obsDistance;
            var obs1=new Obstacle(this.mapWidth,0,h,this.obs);
            var obs2=new Obstacle(this.mapWidth,this.mapHeight-h2,h2-this.line,this.obs);
            this.obsList.push(obs1);
            this.obsList.push(obs2);
        }.bind(this);
    },
 
7.随机产生障碍物上管道高度
 
CreateObs:function(){
       //随机产生障碍物上管道高度
        var h=Math.floor(Math.random()*(this.mapHeight-this.obsDistance-this.line));
        var h2=this.mapHeight-h-this.obsDistance;
        var obs1=new Obstacle(this.mapWidth,0,h,this.obs);
        var obs2=new Obstacle(this.mapWidth,this.mapHeight-h2,h2-this.line,this.obs);
        this.obsList.push(obs1);
        this.obsList.push(obs2);
 
        //移除越界障碍物
        if(this.obsList[0].x<-this.obsList[0].width)
            this.obsList.splice(0,2);
   },

 

8.绘制障碍物

DrawObs:function(){//绘制障碍物
        c.fillStyle='#00ff00';
        for (var i=0;i<this.obsList.length;i++){
            this.obsList[i].x-=this.obsSpeed;
            if(i%2)
                this.obsList[i].draw(c,'up');
            else
                this.obsList[i].draw(c,'down');
        }
   },

 

9.计分与显示分数

  CountScore:function() {//计分数
       if (this.obsList[0].x + this.obsList[0].width < this.startX && this.obsList[0].flypast == false) {
           //小鸟坐标超过obslist【0】障碍物
           this.score += 1;
           this.obsList[0].flypast = true;
       }
   },
   ShowScore:function() {//显示分数
       c.strokeStyle = '#000';
       c.lineWidth = 1;
       c.fillStyle = '#fff';
       c.fillText(this.score, 10, 50);
       c.strokeText(this.score, 10, 50);
   },
 
10.碰撞检测
 
CanMove: function(){
        if(this.bird.y<0|| this.bird.y>this.mapHeight-this.bird.height-this.line){
            this.gameOver=true;
        }else{
            var boundary=[{
                x:this.bird.x,
                y:this.bird.y
            },{
                x:this.bird.x+this.bird.width,
                y:this.bird.y
            },{
                x:this.bird.x,
                y:this.bird.y+this.bird.height
            },{
                x:this.bird.x+this.bird.width,
                y:this.bird.y+this.bird.height
            }];
            for (var i=0;i<this.obsList.length;i++){
                for(var j=0;j<4;j++){
                    if(boundary[j].x>=this.obsList[i].x&& boundary[j].x<=this.obsList[i].x+this.obsList[i].width
                        && boundary[j].y>=this.obsList[i].y && boundary[j].y<=this.obsList[i].y+this.obsList[i].height){
                            this.gameOver=true;
                            break;
                        }
                }
                if (this.gameOver){
                    break;
                }
            }
        }
    },

11.检测触屏与清屏

CheckTouch:function() {//检测触摸
       if (this.touch) {
           this.bird.y -= this.usSpeed;
           this.bird.draw(c, 'up');
       } else {
           this.bird.y += this.downSpeed;
           this.bird.draw(c, 'down');
       }
   },
 
   ClearScreen:function(){//清屏
        c.drawImage(this.bg,0,0);
    },
 
12.游戏运行函数
 
function RunGame(speed) {
    var updateTimer = setInterval(function() {
        // 若小鸟通过第一个障碍物启动记分器
        game.CanMove();
        if (game.gameOver) {
            game.ShowOver();
            clearInterval(updateTimer);
            return;
        }
        game.ClearScreen();
        game.DrawObs();
        game.CheckTouch();
        game.ShowScore();
    }, speed);
    var obsTimer = setInterval(function() {
        if (game.gameOver) {
            clearInterval(obsTimer);
            return;
        }
        game.CreateObs();
    }, 

 

代码参考:

bird.html

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Flappy Bird</title>
</head>
<body>
    <canvas id="canvas" width="340" height="453" style="border: 2px solid #000;background: #fff;"></canvas>
    <script src="bird.js" type="text/javascript"></script>
</body>
</html>
 
bird.js
 
var c = canvas.getContext("2d");
//三个类,Bird类,Obstacle类,FlappyBird类(游戏主要函数)
 
function Bird(x, y, image) {
    this.x = x,
    this.y = y,
    this.width = image.width / 2,
    this.height = image.height,
    this.image = image;
    this.draw = function(context, state) {
        if (state === "up")
            context.drawImage(image, 0, 0, this.width, this.height, this.x, this.y, this.width, this.height);
        else{
 
            context.drawImage(image, this.width, 0, this.width, this.height, this.x, this.y, this.width,
                this.height);
        }
    }
};
 
function Obstacle(x, y, h, image) {
    this.x = x,
    this.y = y,
    this.width = image.width / 2,
    this.height = h,
    this.flypast=false;//没被飞过
    this.draw = function(context, state) {
        if (state === "up") {
            context.drawImage(image, 0, 0, this.width, this.height, this.x, this.y, this.width, this.height);
        } else {
 
            context.drawImage(image, this.width, image.height - this.height, this.width, this.height, this.x,
                this.y, this.width, this.height);
        }
    }
};
//FlappyBird类包括了游戏主要参数及运行时需要的函数。
function FlappyBird(){}
FlappyBird.prototype={
bird: null, // 小鸟
bg: null, // 背景图
obs: null, // 障碍物
obsList: [],
 
mapWidth: 340, // 画布宽度
mapHeight: 453, // 画布高度
startX: 90, // 起始位置
startY: 225,
obsDistance: 150, // 上下障碍物距离
obsSpeed: 2, // 障碍物移动速度
obsInterval: 2000, // 制造障碍物间隔ms
upSpeed: 8, // 上升速度
downSpeed: 3, // 下降速度
line: 56, // 地面高度
score: 0, // 得分
touch: false, // 是否触摸
gameOver: false,
 
/*变化参数可以改变游戏难度。
函数列表:
CreateMap: function() {}    // 绘制画布
CreateObs: function() {}    // 创造障碍物
DrawObs: function() {}       // 绘制障碍物
CountScore: function() {}   // 判断是否启动记分器
ShowScore: function() {}   // 显示分数
CanMove: function() {}       // 判断是否可以移动及游戏结束
CheckTouch: function() {} // 判断是否触摸
ClearScreen: function() {} // 清屏
ShowOver: function() {}     // 显示游戏结束
*/
 
//产生游戏主要的画面
    CreateMap:function(){
        this.bg=new Image();
        //背景
        this.bg.src='img/bg.png';
        var starBg=new Image();
        starBg.src='img/start.jpg';
        starBg.onload=function(){
            c.drawImage(starBg,0,0);
        };
        //小鸟
        var image=new Image();
        image.src='img/bird.png';
        image.onload=function(){
            this.bird=new Bird(this.startX,this.startY,image);
        }.bind(this);
        //障碍物
        this.obs=new Image();
        this.obs.src='img/obs.png';
        this.obs.onload=function(){
            var h=100;
            var h2=this.mapHeight-h-this.obsDistance;
            var obs1=new Obstacle(this.mapWidth,0,h,this.obs);
            var obs2=new Obstacle(this.mapWidth,this.mapHeight-h2,h2-this.line,this.obs);
            this.obsList.push(obs1);
            this.obsList.push(obs2);
        }.bind(this);
    },
   CreateObs:function(){
       //随机产生障碍物上管道高度
        var h=Math.floor(Math.random()*(this.mapHeight-this.obsDistance-this.line));
        var h2=this.mapHeight-h-this.obsDistance;
        var obs1=new Obstacle(this.mapWidth,0,h,this.obs);
        var obs2=new Obstacle(this.mapWidth,this.mapHeight-h2,h2-this.line,this.obs);
        this.obsList.push(obs1);
        this.obsList.push(obs2);
 
        //移除越界障碍物
        if(this.obsList[0].x<-this.obsList[0].width)
            this.obsList.splice(0,2);
   },
   DrawObs:function(){//绘制障碍物
        c.fillStyle='#00ff00';
        for (var i=0;i<this.obsList.length;i++){
            this.obsList[i].x-=this.obsSpeed;
            if(i%2)
                this.obsList[i].draw(c,'up');
            else
                this.obsList[i].draw(c,'down');
        }
   },
 
   CountScore:function() {//计分数
       if (this.obsList[0].x + this.obsList[0].width < this.startX && this.obsList[0].flypast == false) {
           //小鸟坐标超过obslist【0】障碍物
           this.score += 1;
           this.obsList[0].flypast = true;
       }
   },
   ShowScore:function() {//显示分数
       c.strokeStyle = '#000';
       c.lineWidth = 1;
       c.fillStyle = '#fff';
       c.fillText(this.score, 10, 50);
       c.strokeText(this.score, 10, 50);
   },
 
    CanMove: function(){
        if(this.bird.y<0|| this.bird.y>this.mapHeight-this.bird.height-this.line){
            this.gameOver=true;
        }else{
            var boundary=[{
                x:this.bird.x,
                y:this.bird.y
            },{
                x:this.bird.x+this.bird.width,
                y:this.bird.y
            },{
                x:this.bird.x,
                y:this.bird.y+this.bird.height
            },{
                x:this.bird.x+this.bird.width,
                y:this.bird.y+this.bird.height
            }];
            for (var i=0;i<this.obsList.length;i++){
                for(var j=0;j<4;j++){
                    if(boundary[j].x>=this.obsList[i].x&& boundary[j].x<=this.obsList[i].x+this.obsList[i].width
                        && boundary[j].y>=this.obsList[i].y && boundary[j].y<=this.obsList[i].y+this.obsList[i].height){
                            this.gameOver=true;
                            break;
                        }
                }
                if (this.gameOver){
                    break;
                }
            }
        }
    },
 
   CheckTouch:function() {//检测触摸
       if (this.touch) {
           this.bird.y -= this.usSpeed;
           this.bird.draw(c, 'up');
       } else {
           this.bird.y += this.downSpeed;
           this.bird.draw(c, 'down');
       }
   },
 
   ClearScreen:function(){//清屏
        c.drawImage(this.bg,0,0);
    },
   ShowOver:function(){
        var overImg=new Image();
        overImg.src='img/over.png';
        overImg.onload=function(){
            c.drawImage(overImg,(this.mapWidth-overImg.width)/2,(this.mapHeight-overImg.height)/2-50);
        }.bind(this);
        return;
    }
};
 
var game = new FlappyBird();
var Speed = 20;
var IsPlay = false;
var GameTime = null;
var btn_start;
window.onload = InitGame;
 
function InitGame() {
    c.font = "3em 微软雅黑";
    game.CreateMap();
    canvas.onmousedown = function() {
        game.touch = true;
    }
    canvas.onmouseup = function() {
        game.touch = false;
    };
    canvas.onclick = function() {
        if (!IsPlay) {
            IsPlay = true;
            GameTime = RunGame(Speed);
        }
    }
}
 
//游戏运行函数
function RunGame(speed) {
    var updateTimer = setInterval(function() {
        // 若小鸟通过第一个障碍物启动记分器
        game.CanMove();
        if (game.gameOver) {
            game.ShowOver();
            clearInterval(updateTimer);
            return;
        }
        game.ClearScreen();
        game.DrawObs();
        game.CheckTouch();
        game.ShowScore();
    }, speed);
    var obsTimer = setInterval(function() {
        if (game.gameOver) {
            clearInterval(obsTimer);
            return;
        }
        game.CreateObs();
    }, game.obsInterval);
 
}

 

运行结果:

​​​​​​​

 
展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部