用jQuery和 100行Javascript构建 Flappy

分享于 

13分钟阅读

Web开发

  繁體

介绍

用jQuery和 100行Javascript构建 Flappy

Gasp手机游戏游戏。

Background

当开发者离开 $50,000时,Flappy成为了一个大的news:。 我下载了一个游戏,玩了它- 它看起来简单而愚蠢。 我把它放在一边,然后我的朋友发出了同样的话题,并且玩了几天。 $50,000 business我应该,不过我在工作中忙。 ,other finally 我 reject reject clones clones因为 soo many clones clones clones clones clones clones clones clones clones clones clones我 thought get this this this this this。 用正确的时间和一点运气- 那 $50,000/day 可以是我的。"
我在这里展示的版本花了我whooping小时来构建和在我的javascript的十行下。

对于那些不了解游戏的人- 走出你的洞穴。 你点击,给它一些初始的速度。 然后开始下降( 重力下)。 你需要把它放在空中,避免障碍物碰到它。 为了简化目标,鸟只是向上和向下移动,对horisontal运动的感知是acheived滚动的background。 就是这样,每天完成 $50,000.

资产

游戏只需要 5张图片: 鸟,background 草,background 天空,障碍和 instuction tap-to-start。


如你所见,要使自己保存一些 headace,使用动画gif文件在帧动画上出现 skimping。 这样浏览器可以更有效地使用它。 此外,它也阻止了我在 Windows Phone 上发布它- 因为浏览器控件不支持动态GIF文件。

基本html也很简单:

<divid='board'style='position:absolute; left:50px; top:50px; width:478px;
 height:300px; overflow:hidden;'><divid='score'style='position:absolute; left:400px; top:0px; height:25px;
 z-index:5; color:red; font-weight:900'></div><imgclass="c"id='bird'src="b2.gif"style="z-index:5"/><imgid='instr'src='instr.png'class='c'style="left:205px; top:75px;
 z-index:100"/><divclass="bg"id='bGrnd'style="top:-20px; height:320px;
 background-image:url(bg1.png)"/><divclass="bg"id='fGrnd'style="top:235px; height:85px; z-index:4;
 background-image:url(bg2.png)"/></div>
我还包括来自 http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.js的最新 jQuery

全局变量和初始化

游戏使用以下全局变量:

鸟类jQuery对象来支持我们的鸟类
母板可以用于保存板对象的jQuery对象
dimPipe障碍物尺寸
cPos当前鸟类位置( 只有Y 坐标可以改变)
重力可以配置的重力常数- 鸟下落的速度
iniSpeed可以配置的初始速度
curSpeedbird的垂直速度
评分当前得分
noClr清除的障碍数
tmStep用于定位鸟儿并启动障碍物的步骤计时器
状态游戏状态:0 - 未启动,1 - 播放;2 - 游戏结束
游戏以 2个步骤初始化: 通常的jQuery $.ready 和可以重用 start(),我们每次重新启动游戏时都可以调用它:
$(document).ready(function() {
 bird = $('#bird');
 var evt = (typeof(bird[0].ontouchend) == "function")
? "touchstart" : "mousedown";
 board = $('#board').bind(evt, onTap);
 start();
});function start() {
 state = noClr = score = 0; // not started cPos = { x: 80, y:100, h:40, w:50 };
 bird.css({left:cPos.x, top:cPos.y, width:cPos.w, height:cPos.h, rotate:0});
 $('.obs').remove();
 $('#instr').show();
}
可以看到,我们初始化bird和母板全局变量,附加tap事件处理程序到母板并调用函数。 关于tap的一个词:在Android设备的mouseDown事件之后,我们将在代码中检查是否有onTouchEnd元素,因此在上面的代码中,我们检查元素是否有元素并使用它表示触摸。
在 start() 函数中,我重置所有变量,删除板上的任何障碍并显示指示图像提示。

点击/点击处理

所以游戏已经准备好了。 缺少的部分是当你点击棋盘时发生的事情。 此时游戏启动主定时器( BirdStep ) ( 如果需要),并设置bird的初始速度:

function onTap() {
 if (state> 1) return;
 if (state == 0) {
 state = 1;
 $('#instr').hide();
 tmStep = window.setInterval(BirdStep, 30);
 }
 curSpeed = iniSpeed;
}
需要考虑的是,程序使用 3个状态-
  • 0 - 未运行
  • 1 - 播放模式
  • 2 - 模模式- 不接受输入。
所以我们要检查- 如果我们处于死亡模式-。 如果我们不玩,进入播放模式- 改变状态,隐藏介绍图像和开始计时。 除了我们想让我们的鸟儿初始速度。

但是,主要逻辑是在BirdStep计时器函数中完成的:
function BirdStep() {
 // update bird position curSpeed += gravity;
 cPos.y = Math.max(cPos.y + curSpeed, 0);
 var mh = board.height()-cPos.h, m = -12, lo = 0, actPipe = $('.obs');
 bird.css({top: cPos.y});
 // check if we hit the floor or other obstaclesif (cPos.y> mh)
 return gameOver();
 for (var i = actPipe.length-1; i> = 0; i--) {
 var s = actPipe[i].style, x = parseInt(s.left), y = parseInt(s.top);
 lo = Math.max(lo, x);
 if (x+dimPipe.width +m <cPos.x || x> cPos.x+cPos.w+m) continue;
 if (y+dimPipe.height+m <cPos.y || y> cPos.y+cPos.h+m) continue;
 return gameOver();
 }
 // check if can launch more obstaclesif (actPipe.length> 3 || lo> 300 || Math.random()> = 0.05 * (1+noClr))
 return;
 var og = cPos.h * 2;
 var oh = og + Math.floor(Math.random() * (mh-og+1));
 var obs = $("<img/><img/>").addClass('c obs').css({left:480, zIndex:3}).css(dimPipe).attr('src', 'vine.png')
. appendTo(board).animate({left:-50}, 3000, 'linear', function() {
 $('#score').text(' Score: ' + (score += 1 + Math.floor(++noClr/10)));
 this.remove();
 });
 obs[0].style.top = oh + 'px';
 obs[1].style.top = (oh - og - dimPipe.height) + "px";
}
你可以看到,这个函数尝试执行 3个主要操作: 每次BirdStep定时器执行时更新鸟位,当前的鸟速度增加,并增加当前鸟的位置。 在这一点上我检查,确保鸟不会飞 上面 天花板( 负Y )。 点击这里我们测试 bird bird bird ( Y 超出母板高度) obstacles loop loop loop loop检查鸟类( 存储在 cPos 中,并通过一些 fudge margin = 12像素减少) 是否与任何障碍物相交- - obs obs。 如果这样,游戏就会丢失- 我们可以出去。 如果新障碍可以启动,首先要启动新障碍:
  • 屏幕上已经有 4个障碍
  • 最后的障碍距离一定距离
  • 添加一些随机因素
如果满足条件,我们可以启动 2个障碍物,在另一个上方,在板的右边缘上随机放置 2个鸟类大小,在板的右边。
创建后,它们被动画从屏幕( 左= -50像素)的左边缘移动,得分增加,障碍被移除。 我们使用简单简单的jQuery线性动画来制作动画。

铃声和 wistles: 视差滚动效果

这是个游戏。 但到目前为止它看起来太普通了。 添加一些umpf让我们添加视差滚动效果。 实际上我们增加了 2个视差层- 天空和草地。 我们还需要增加深度感知- 在这个实现中,天空将会慢慢移动- - 应该足够了。 创建视差图层,我将创建一个非常宽的div 元素( 16,000像素),并将需要的图像设置为背景。 浏览器将复制图像。 我需要做的唯一事情就是添加动画- 使用非常方便的jQuery动画设置div的左位置:

function Parallax(elm, tmo) {
 elm.css('left', 0).animate({left:-15360}, {
 duration:tmo*1000, easing:'linear',
 complete : function() { Parallax(elm, tmo); }
 });
}function onTap() {
 if (state == 0) {
. . .
 Parallax($('#bGrnd'), 240);
 Parallax($('#fGrnd'), 80);
. . .
 }
}
就像你所看到的代码非常简单: div的左位置设置为 0px,然后线性动画到 -15,360px ( 最大公共分母 LESS,所有 background 图像宽度为 16,000,所以我不需要添加额外的参数到函数。) 之后,整个过程重复执行。 提供的参数是动画时间- 前景( 草地) 应该滚动 80秒和 background ( 天空) - 240秒- 3时间较慢。

铃声和 wistles: 旋转

除了视差之外,旋转鸟将会很好,当它飞起来时,向上倾斜,下降。 当游戏结束时,to over。 为此,我创建了简单的jquery css。 请查阅jQuery文档关于 CSS钩子的详细信息。

$.cssNumber.rotate = true;
$.cssHooks.rotate = {
 set : function(el, v) {
 if (typeof v === 'string')
 v = (v.indexOf("rad")!= -1)? parseInt(v) * 180/Math.PI : parseInt(v);
 v = (~~v);
 if (v == ($.data(el, 'rotate') || 0)) return;
 el.style["MozTransform"] = el.style["MozTransform"] = el.style["-webkit-transform"]
 = el.style["transform"] = " rotate(" + (v % 360) + "deg)";
 $.data(el, 'rotate', v);
 },
 get : function(el, computed) {
 return $.data(el, 'rotate') || 0;
 }
};
可以看到,我们在 $.data("rotate") 中存储当前的旋转值,并设置元素特定CSS属性的浏览器来设置当前旋转值。
要使用新获得的功能,让我们改变 BirdStep 函数,以 5倍速度旋转一只鸟。 鸟飞起和速度偏移,鸟向上倾斜,如果鸟落下,速度是正的,鸟向下倾斜。 此外,我们希望限制 -20度和 90度之间的倾斜- 完全任意:
function BirdStep() {
. . .
 var ang = curSpeed * 5;
 bird.css({top: cPos.y, rotate:(ang < -20)? -20 : (ang >90)? 90 : ang});
. . .
}
我们也可以引入一个很好的动画当鸟死- 它将落到地面并旋转 540度,然后等待另一半:
function gameOver() {
 state = 2;
 $(":animated").stop();
 if (tmStep) tmStep = window.clearInterval(tmStep);
 bird.animate({ top:board.height()-cPos.h, rotate:540}, 1000)
. animate({ top:board.height()-cPos.h}, 500, function() {
 $('#score').text(' Score: ' + score);
 start();
 });
}
that我们设置游戏状态,所以在显示动画时,我们不会检查任何点击,停止所有动画,停止小鸟计时器,等等。 之后我们可以播放'模具序列',一旦完成后回到开始屏幕。

Points of Interest

正如我刚刚提到的这是一个初始版本的游戏,花了我 2小时的时间放在一起。 添加 PhoneGap 进入星系并完全沮丧 即使在最慢的笔记本电脑上工作,它也会完全阻塞,即使在最好的智能手机上,我也要花两天时间,这样我就不能在计时器执行的时候 spend,计时器执行之间的时间就会 accounting。 即使有所有这些改进,取决于智能手机的性能模式也可能会有些失望。

至于我在市场上做了 3个月的/day,我在这个游戏中做了一个很酷的$20,或者是我花了大约/hr 个时间。 我再一次把我的成功归因于完美的时机和一点点的运气。 幸好我已经拥有了谷歌开发者账号,苹果开发者帐户,微软商店( $99/year ) 和网络发布( $49/year ) - 否则,它可能是非常昂贵的技术。 但是由于我已经付款了- 这是一个 $20我没有- 玻璃半满 !

历史记录


JAVA  Javascript  构建  FLA  
相关文章