也来山寨一版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 ...
随机推荐
- Python类属性的延迟计算
所谓类属性的延迟计算就是将类的属性定义成一个property,只在访问的时候才会计算,而且一旦被访问后,结果将会被缓存起来,不用每次都计算. 优点 构造一个延迟计算属性的主要目的是为了提升性能 实现 ...
- ubuntu16.04源码编译安装wine1.8.6安装不上引来的错误
configure: libxcomposite 64-bit development files not found, Xcomposite won't be supported. configur ...
- hadoop2.6.2分布式环境搭建
1.准备三台机器,机器名是:master.slave01.slave02 1.1 最小化安装centos6.5 1.2 安装ssh,yum -y install openssh-clients(这一步 ...
- Hadoop Kernel tunning
/etc/security/limits.conf @ochadoop soft nofile 102642 @ochadoop hard nofile 102642 @ochadoop soft n ...
- [转]nopcommerce商城系统--如何编写一个插件
本文转自:http://www.cnblogs.com/ganqiyin/p/3680771.html 原址:http://www.nopcommerce.com/docs/77/how-to-wri ...
- 遇到一位ITer,一位出租车司机,必看。
百木-ITer职业交流 群-北京 :141588103 今天去用户那,一个政府的事业单位. 遇到一位ITer,B同学,一个行业的,和他们公司既是合作关系,又是竞争关系.最近我们接了该单位的 ...
- No 'Access-Control-Allow-Origin' header is present on the requested resource.
今天做一个AJAX案例时,浏览器监控到如下错误: XMLHttpRequest cannot load http://54.169.69.60:8081/process_message. No 'Ac ...
- hdu5269 Chip Factory
地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=5536 题目: Chip Factory Time Limit: 18000/9000 MS ( ...
- 当元素的样式为display:none时获取他的宽高
其实这里可以用一个偷梁换柱的办法,把display:none改为 display:block;visibility:hidden;position:absolute; 在jquery的swap方法中实 ...
- Kali linux渗透测试常用工具汇总1
1.ProxyChains 简介:代理工具.支持HTTP/SOCKS4/SOCK5的代理服务器,允许TCP/DNS通过代理隧道. 应用场景:通过代理服务器上网. 配置:/etc/proxychains ...