也来山寨一版Flappy Bird (js版)
随着Flappy Bird的火爆,各种实现的版也不断出现,于是也手痒简单实现了一版。
其实本来只是想实现一下这只笨鸟的飞翔运动的,后来没忍住,就直接实现一个完整游戏了……
因为这个游戏本身实现起来就没啥难度,这次就没用任何框架,也没搭就原生手写完了所有代码,不过只对高级浏览器支持,共花了1天半时间,不过至少有半天时间是在玩,这游戏玩起来确实停不下来。。。。。
飞翔的运动代码就是这样,利用了上抛运动公式,比起一般的缓动公式,这样比较有质感吧…
function value(y, h, t, g){
g = g || 0.98;
function fn(v, t){
return v * t - 0.5 * g * t * t;
}
function v0(h){
return Math.sqrt(2 * h * g);
}
return y - fn(v0(h), t);
}
可以在指定时刻获取当前的y坐标值,然后用该值进行对象的渲染(位置更新)就行了。
再说下水管地图的随机生成原理:在一个范围内生成随机数,这个数就是下半部水管的y坐标,然后以这个y坐标渲染下半部的水管,还是以这个y坐标减去上下水管的距离值,就可以得到上半部水管的最大y值,再根据这个y值渲染上半部的水管就行了,文字描述比较抽象,大家看完整代码就能明白了……
最后将水管序列进行位移,再跟这个二货鸟的矩形进行水管上下半部两个矩形的碰撞检测就行了。
好了,很简单的一个游戏和实现,就不多说了,这里是完整js代码和演(zi)示(nue)地址,代码没太去组织,有点乱,大家将就看吧。。。
function Timer(n){
var itvID;
n = n || 1000 / 60;
return {
start : function(cb){
itvID = window.setInterval(cb, n);
},
stop : function(){
window.clearInterval(itvID);
}
};
}
function overlay(x1, y1, w1,h1, x2, y2, w2, h2){
return x2 < x1 + w1
&& x2 + w2 > x1
&& y2 < y1 + h1
&& y2 + h2 > y1;
}
function value(y, h, t, g){
g = g || 0.98;
function fn(v, t){
return v * t - 0.5 * g * t * t;
}
function v0(h){
return Math.sqrt(2 * h * g);
}
return y - fn(v0(h), t);
}
function rotate(nd, v){
nd.style.mozTransform = "rotate(" + v + "deg)";
nd.style.oTransform = "rotate(" + v + "deg)";
nd.style.webkitTransform = "rotate(" + v + "deg)";
nd.style.transform = "rotate(" + v + "deg)";
}
function Pipe(sw, sh, pnd, y, d){
var et = pnd.cloneNode(true);
var h = 42;
var pb = et.querySelector("[data-node='bottomPipe']");
var pt = et.querySelector("[data-node='topPipe']");
var x = sw;
var pbh;
var pth;
var speed = 5;
var baseY;
et.removeAttribute("id");
et.style.display="";
function updateY(y){
pbh = sh - y + h;
pth = y - d - h;
pb.style.top = y + "px";
pb.querySelector(".pipe").style.height = pbh + "px";
pt.querySelector(".pipe").style.height = pth + "px";
baseY = y;
}
updateY(y);
return {
entity : et,
updateY : updateY,
preX : function(){
return preX;
},
x : function(v){
if(typeof v !== "undefined"){
preX = x;
x = v;
et.style.left = x + "px";
}
return x;
},
w : function(){
return 93;
},
topH : function(){
return pth + h;
},
bottomH : function(){
return pbh + h;
},
baseY : function(){
return baseY;
}
}
}
function check(b, p){
var pipeDeltaH = 200;
var v = 3;
var pr1 = {
x : p.x() + v,
y : p.baseY() + v,
w : p.w() - 2 * v,
h : p.bottomH() + pipeDeltaH - 2 * v
};
var pr2 = {
x : p.x() + v,
y : -pipeDeltaH - v,
w : p.w() - 2 * v,
h : p.topH() + pipeDeltaH - 2 * v
};
return overlay(b.x, b.y, b.w, b.h, pr1.x, pr1.y, pr1.w, pr1.h)
|| overlay(b.x, b.y, b.w, b.h, pr2.x, pr2.y, pr2.w, pr2.h);
}
function checkScore(b, p, s){
if(b.x <= p.preX() && b.x > p.x()){
s.add(1);
s.update();
}
}
function PipeManager(stage, sw, sh, bird, n, timer, cb){
var list=[];
var pcNd = document.getElementById("pipeContainer");
var d = 190;
var y;
var h = 42 * 2;
var pipe;
var timer;
var speed = 3.5;
var i;
var right = 250;
n = n || 3;
function getMaxX(){
var i = list.length;
var x = 0;
while(i--){
list[i].x() > x && (x = list[i].x());
}
return x;
}
function startHandle(){
var l = list.length;
var p;
for(i = 0; i< l; i++){
p = list[i];
p.x(p.x() - speed);
if(p.x() <= -100){
p.updateY(Math.floor(Math.random() * (sh - 2 * h - d) + h + d));
p.x(getMaxX() + 300);
}
if(check(bird, p)){
cb && cb();
}
checkScore(bird, p, Score);
}
}
for(i = 0; i < n; i++){
y = Math.floor(Math.random() * (sh - 2 * h - d) + h + d);
pipe = Pipe(sw, sh, pcNd, y, d);
list.length ? pipe.x(getMaxX() + 300) : pipe.x(sw + right);
list.push(pipe);
stage.appendChild(pipe.entity);
}
return {
reset : function(){
var l = list.length;
var i;
list[0].x(sw + right);
for(i = 1; i < l; i++){
list[i].x(getMaxX() + 300);
}
timer.stop();
},
start : function(){
timer.start(startHandle);
}
}
}
var Bird = {
x : 100,
y : 300,
w : 64,
h : 45,
fly : function(y, h, dt, btm, timer, cb){
var t = 0;
var v = 0;
var ag = 0;
var agv = 4;
var pv;
var me = this;
timer.stop();
timer.start(function(){
t += dt;
v = value(y, h, t);
if(v >= btm + 30){
me.died(timer, btm);
}
if(typeof pv !=="undefined"){
ag = Math.min(Math.max(ag + (v - pv) / agv, angleArr[0]), angleArr[1]);
}
cb(v, ag);
pv=v;
});
},
enabled : true,
died : function(timer, btm){
var et = this.entity;
var t = 0;
rotate(et, 90);
et.style.left = parseInt(et.style.left, 10) + 10 + "px";
et.style.top = parseInt(et.style.top, 10) + 20 + "px";
this.enabled = false;
timer.stop();
pipeTimer.stop();
timer.start(function(){
var v;
t += 0.5;
v = value(parseInt(et.style.top, 10), 0, t, 0.7);
if(v >= btm + 30){
timer.stop();
v = btm + 30;
}
et.style.top = v + "px";
});
state = "end";
},
reset : function(){
this.y = 300;
this.x = 100;
this.entity.style.left = this.x + "px";
this.entity.style.top = this.y + "px";
this.enabled = true;
rotate(this.entity, 0);
},
entity : document.getElementById("bird")
};
var Score = {
v : 0,
entity : document.getElementById("score"),
add : function(n){
this.v += n;
},
update : function(){
this.entity.innerHTML = this.v;
},
reset : function(){
this.v = 0;
this.update();
}
};
var Stage = {
w : 520,
h : 600,
entity : document.getElementById("stage")
}
var angleArr=[-25, 90];
var birdTimer = Timer();
var pipeTimer = Timer();
var isStart = false;
var state = "start";
var pm = PipeManager(Stage.entity, Stage.w, Stage.h, Bird, 3, pipeTimer, function(){
Bird.died(birdTimer, Stage.h);
});
Bird.x = parseInt(Bird.entity.style.left, 10);
window.onmousedown = function(evt){
var y;
switch(state){
case "hold" :
pm.reset();
Bird.reset();
Score.reset();
state = "start";
break;
case "end" :
state = "";
setTimeout(function(){
state = "hold";
},1000);
break;
case "start" :
pm.start();
state = "play";
case "play" :
y = parseInt(Bird.entity.style.top, 10);
Bird.enabled && Bird.y >= 0 && Bird.fly(y, 100, 0.9, Stage.h, birdTimer, function(v, ag){
Bird.entity.style.top = v + "px";
Bird.y = v;
rotate(Bird.entity, ag);
});
}
evt && evt.preventDefault();
window.event && (window.event.returnValue = false);
};
也来山寨一版Flappy Bird (js版)的更多相关文章
- C语言版flappy bird黑白框游戏
在此记录下本人在大一暑假,2014.6~8这段时间复习C语言,随手编的一个模仿之前很火热的小游戏----flappy bird.代码bug基本被我找光了,如果有哪位兄弟找到其他的就帮我留言下吧,谢谢了 ...
- cocos2dx-html5 实现网页版flappy bird游戏
我也是第一次使用cocos2d_html5,对js和html5也不熟,看引擎自带的例子和引擎源码,边学边做,如果使用过cocos2d-x的话,完成这个游戏还是十分简单的.游戏体验地址: http:// ...
- 封装环形加载进度条(Vue插件版和原生js版)
1.效果预览 2.用到的知识 主要利用SVG的stroke-dasharray和stroke-dashoffset这两个属性. 在看下面文章之前,你需要了解 <!DOCTYPE html> ...
- 转载:Flappy Bird源代码 win32 console版
#include"StdAfx.h" #include<stdio.h> #include<stdlib.h> #include<conio.h> ...
- [MFC] 高仿Flappy bird 桌面版
这是今年年初做的东西,一直没有时间整理,现在拿出来分享下~ 目录 开发背景 开发语言及运行环境 效果展示 游戏框架说明 游戏状态及逻辑说明 经典算法说明 重量级问题解决 开发感想 一.开发背景: fl ...
- Flappy bird源代码(略吊)
#include<stdio.h> #include<stdlib.h> #include<conio.h> #include<time.h> #inc ...
- 使用Hilo.JS快速开发Flappy Bird
http://hiloteam.github.io/tutorial/flappybird.html#_9 Flappy Bird是一款前不久风靡世界的休闲小游戏.虽然它难度超高,但是游戏本身却非常简 ...
- 教你从头到尾利用DQN自动玩flappy bird(全程命令提示,GPU+CPU版)【转】
转自:http://blog.csdn.net/v_JULY_v/article/details/52810219?locationNum=3&fps=1 目录(?)[-] 教你从头到尾利用D ...
- HTML5 版的flappy bird
Flappy Bird这款简单的小游戏累计下载量已经超过5000万次,每天收入至少5万美元.然而,2月10日其开发者Dong Nguyen却将Flappy Bird从苹果App Store和Googl ...
随机推荐
- PostgreSQL-安装9.2
一.环境 VM虚拟机 NAME="Ubuntu" VERSION="12.04.4 LTS, Precise Pangolin" 二.过程 1.安装make ...
- 使用DBI(perl)实现文本文件的导入导出mysql
DBI 是perl脚本连接数据库的一个模块.perl脚本相对shell更灵活,功能更强大,跨平台能力强.相对可执行jar包要简单很多. 1.下载安装包DBI-1.631.tar.gzperl脚本下载 ...
- java汉化
http://download.eclipse.org/technology/babel/babel_language_packs/R0.13.0/luna/luna.php _x86_64版本下载地 ...
- elasticsearch 集群搭建
需要编辑的文件是config/elasticsearch.yml文件 需要配置的项目有: # Use a descriptive name for your cluster: # cluster.na ...
- nodejs模块——fs模块
fs模块用于对系统文件及目录进行读写操作. 一.同步和异步 使用require('fs')载入fs模块,模块中所有方法都有同步和异步两种形式. 异步方法中回调函数的第一个参数总是留给异常参数(exce ...
- HDU 4630 No Pain No Game 树状数组+离线操作
题意:给一串数字,每次查询[L,R]中两个数的gcd的最大值. 解法:容易知道,要使取两个数让gcd最大,这两个数最好是倍数关系,所以处理出每个数的所有倍数,两两间根据倍数关系形成一条线段,值为该数. ...
- u3d_shader_surface_shader_1
http://docs.unity3d.com/Manual/SL-SurfaceShaders.html 一:surface shader是啥 Writing shaders that intera ...
- Sphinx和coreseek检索引擎
Sphinx是检索英文用,coreseek是检索中文用. Sphinx(斯芬克斯)是一个基于SQL的全文检索引擎,可以结合MySQL,PostgreSQL做全文搜索,它可以提供比数据库本身更专业的搜索 ...
- gzip: stdout: No space left on device问题的解决
一.问题描述 最近安装了ubuntu14.04,并在ubuntu14.04中编译了一次内核.这之后大部分情况下用sudo apt-get install 安装应用都会出现“gzip: stdout: ...
- javascript里面this机制的几个例子
javascript里面的this值会随着使用场景的不同二发生变化,但是总有一个原则,那就是this总指向当前调用函数的那个对象.以下我会举几个例子来说明这个问题.1.this本身总是指向当前的类的实 ...