关闭

HTML5游戏引擎lufylegend深入浅出 - 引擎介绍&原理

标签: 黄艺斌前端开发html5技术lufylegend
970人阅读 评论(0) 收藏 举报
分类:

又很久没有更新博客了,在这段时间里发生的事还蛮多的,回想起来才发现时间过得好快啊。至于博客嘛,天天都会关注,一来想看看大家是否写了一些评论,二来想看看大神们(如lufy,浅墨,雾央,Himi等)有没有写新的文章。不过最近没有什么新“发明”,所以就没什么好写的了~Ok,进入正题。


一,说在前面的话

最近有的朋友说他们很喜欢原生的javascript的代码,不喜欢看用引擎封装后的,所以希望我写一些原生html5代码。于是我原本就准备在这篇中讲讲用原生html5写游戏,但是写过来写过去发现还得用到lufylegend中的一些原理。于是就想到可以讲讲lufylegend中的一些原理。毕竟知道原理比只知道用法好得多。首先我们得看看lufylegend引擎的介绍。

【lufy在以前的文章中也提到过lufylegend的原理,但我个人认为介绍地不详细,没有说清楚原理,后来我自己慢慢看,才看懂了一些。所以我希望我能通过文章的形式来谈谈自己对lufylegend的理解,如果文章中有疏漏的地方,欢迎提出~】


二,lufylegend.js引擎介绍

这是官方的介绍:

lufylegend是一个HTML5开源引擎,它实现了利用仿ActionScript3.0的语法进行HTML5的开发, 包含了LSprite,LBitmapData,LBitmap,LLoader,LURLLoader,LTextField,LEvent等多个AS开发人员熟悉的类, 支持Google Chrome,Firefox,Opera,IE9,IOS,Android等多种热门环境。 利用lufylegend可以轻松的使用面向对象编程,并且可以配合Box2dWeb制作物理游戏, 另外它还内置了LTweenLite缓动类等非常实用的功能, 现在开始使用它吧,它可以让你更快的进入HTML5的世界!


从上面的文字可以看出啊,lufy大神的文字功底还是很屌的。其实说白了,lufylegend是一个兼容性极高,功能极多,使用方便的HTML5游戏引擎。

那么,在众多html5游戏引擎中,lufylegend优势何呢?

首先我觉得,最扯的一个优势就是:Lufylegend is made by Chinese。当然Cocos2d-html5也是made by Chinese啊~但是,lufylegend的API文档是中文的,Cocos2d-html5就不一样了。也许你非常懂英文,但是至少而言,你看中文还是比看英文习惯一些,不是吗?

第二个优点就是它效率十分高。在单核CPU上跑,FPS在15-23之间,在手机也就差不多是这个档次了。也许有朋友笑曰:“我X,FPS在15-23之间好意思说出口?”,但其实不然,你要清楚啊,html5和OpenGL等不是一个档次的,OpenGL发展N年了,而html5仍然被认为是一项新技术。以前,我也试着去学习Cocos2d-html5,但说真的,效率感觉比不上lufylegend。

第三个优点就是配置简单。有些引擎,东西一大堆,使用者根本无从下手。而使用lufylegend,只需要把lufylegend-xxx.min.js复制到项目下面即可。

其实说实话,只有你使用它以后,才能真正地感受到带来的方便。


当然,我还是再次把引擎的地址display出来:

官方网站:http://lufylegend.com/lufylegend

API文档:http://lufylegend.com/lufylegend/api

引擎的logo:



三,引擎原理

我们知道,游戏主要由事件和画面组成,在lufylegend的事件中,有鼠标事件(MOUSE_DOWN,MOUSE_UP,MOUSE_MOVE),键盘事件(KEY_DOWN,KEY_UP),时间轴事件(ENTER_FRAME),这些事件中,前两项so easy,好理解,但时间轴事件对于一些刚接触游戏开发的新生而言,有些摸不着头脑。其实时间轴事件相当于一个定时器,这个事件的监听者(listener,也就是事件回调函数)每隔一段时间就会触发一次。但这个东西有什么用呢?我们举个例子吧,假如我们做一个飞机大战的游戏,要让敌机缓缓地移动起来,如果我们直接将它们的x或者y设置为某值,那飞机就会在嗖地一声在瞬间之内移动到那里。这样很不“礼貌”,因为动作太大了~我们要做到缓缓地移动,这时候时间轴事件就该派上用处了,我们可以在监听函数中给飞机的x或者y增加某个值,这样的话,监听函数每被调用一次,就会将飞机移动一下,又因为每隔一段时间监听函数才被调用一次,所以说飞机就能够达到慢慢移动的效果,这样就”礼貌“多了,对吧?当然,要让飞机移动地更帅一点,那就要用到缓动类LTweenLite,什么是缓动类?好吧,我直观地告诉你,就是像jQuery淡入淡出那种逐渐变化从而实现某种效果的一个功能。这里有lufy对缓动类进行巧妙地利用,做出的一个超帅动画:HTML5超帅动画制作-LTweenLite的妙用

说完事件,我们再来说说画面。lufylegend中,但凡是加入到画面上的显示对象都是通过一个setInverval不停绘制的,这样做有什么必要呢?首先,是可以实现层次化,如果我们把所有对象放入一个数组中,通过遍历的方式获取每个对象并调用函数将其显示,那么第一个被加入的对象就会先被画在最下面,其余的依次画上,这样一来就实现了层次化效果。其次,还有个好处就是可以通过直接更改对象的属性从而在下次重绘时表现出来,比如说我们加入一个图片对象(对象名字为img),这时我们要改变它的显示方式为不显示(visible属性改为false),那么直接把img.visible改为false即可,那在下次重绘时就控制它不显示。另外,在上面提到的时间轴事件触发的速度也是由重画速度决定的——每画一次就调用一次。

在lufylegend中,但凡是可显示的对象,大都继承自LDisplayObject。这个类有个ll_show方法,用于在循环渲染时变幻画布,绘制该显示的东西。


四,利用引擎初始化游戏

在引擎中,要初始化游戏需要用到引擎内部的init函数,使用方法举例如下:

[javascript] view plaincopy在CODE上查看代码片派生到我的代码片
  1. init(50,"mylegend",800,480,main)  
这个函数的参数是:

init(speed,divid,width,height,completeFunc);

speed:游戏速度设定

divid:传入一个div的id,库件进行初始化的时候,会自动将canvas加入到此div内部

width:游戏界面宽

height:游戏界面高

completeFunc:游戏初始化后,调用此函数

在使用lufylegend时,不用在html文件中写什么<canvas>标签,不过要写一个div,如下:

[javascript] view plaincopy在CODE上查看代码片派生到我的代码片
  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4. <meta charset="UTF-8">  
  5. <title>demo</title>  
  6. </head>  
  7. <body>  
  8. <div id="mylegend">loading……</div>  
  9. <script type="text/javascript" src="../lufylegend-x.x.x.min.js"></script>   
  10. <script>  
  11. init(50,"mylegend",800,480,main);  
  12. function main(){  
  13.     alert("感谢您使用lufylegend库件");  
  14. }  
  15. </script>  
  16. </body>  
  17. </html>  
还是很简单的,不是吗?不过值得一提的是,init的参数speed或许有的朋友不理解什么是游戏速度,其实就是我在原理中介绍到的setInterval的速度,这个速度控制的是重绘速度和时间轴触发速度,如果设得超大,你的画面会很卡,不管你是什么双核CPU还是什么四核CPU。如果设得超小,比如说1-10,那有些性能差的电脑显示起来就会有些差,一卡一卡的~所以我一般设置为30-50,这之间的数应该都挺合适的。


五,引擎基本功能及原理

1,LGlobal(LStage、LSystem)静态类

这个类掌管游戏中许多全局的设置,比如说更改游戏速度,获取游戏界面高度、宽度,canvas标签,canvas标签的getContext("2d"),和当前操作系统等,可以到API文档中看个究竟。

在LGlobal中,有个childList属性,这个属性在最新的几个版本里面主要存放LGlobal.stage(最底层,一个LSprite对象。LSprite是什么?下文会慢慢介绍的),LTweenLite(缓动类),LSound.Container(音频容器,貌似里面有用于判断音频是否结束的函数)。引擎循环渲染便是从这个地方开始的。引擎中通过遍历LGlobal.childList获取这几个对象,然后调用每个对象的ll_show方法来实现循环执行每个对象应该执行的命令,例如LGlobal.stage就应该执行LSprite该做的向下循环子对象,LTweenLite就应该调用缓动函数来改变缓动数据等。


2,全屏设置

html5最大的优势就是跨平台,所以游戏要能在手机上运行最好,但是能运行不能就完了,还要能达到全屏。以前lufylegend的全屏有点问题,不过最近改好了,不仅能手机全屏,PC机也OK,还提供了三种全屏模式:

LStageScaleMode.EXACT_FIT:[静态] 指定整个应用程序在指定区域中可见,但不尝试保持原始高宽比。

LStageScaleMode.SHOW_ALL:[静态] 指定整个应用程序在指定区域中可见,且不会发生扭曲,同时保持应用程序的原始高宽比。

LStageScaleMode.NO_SCALE:[静态] 指定应用程序的大小是固定的,因此,即使在更改播放器窗口大小时,它仍然保持不变。

※设置完舞台的缩放模式之后,调用LSystem.screen(LStage.FULL_SCREEN);就可以实现全屏。

原理很简单,就是设置canvas标签的style.width和style.height来实现GPU缩放。


3,加入对象/移除对象:addChild,removeChild

在lufylegend中要加入显示对象到银幕上,需要使用addChild,如果直接调用这个函数,就是把对象加入最底层,当然LSprite也有addChild,是把对象添加到LSprite上,从而实现层次化效果。

removeChild是一样的,只不过是把对象删除而已~

addChild和removeChild等同于LGlobal.stage.addChild和LGlobal.stage.removeChild。原理为把参数所指定的对象从LSprite的childList里面删除掉。


4,LLoadManage加载文件

主要用于加载游戏中的文件,如图片,音频,js文件,其他文件(需要用到服务器),用法可查API文档。

原理:通过判断文件不同的类型从而分别调用LLoader(读取图片),LURLLoader(读取文本文件,包括js文件),LSound(读取音频)。当然你可以直接用上述的几个类读取数据,但是咱们的LLoadManage胃口更大,可以批量读取不同类型的文件,使用起来还会更方便,因为其中还提供了进度条的显示。


5,图片类LBitmap,LBitmapData

这个两个类主要配合显示图片,不过显示之前需要加载图片,方法如下:

[javascript] view plaincopy在CODE上查看代码片派生到我的代码片
  1. var loadData = [  
  2. {name:"yorhom",path:"./images/yorhom.png"}  
  3. ];  
  4. var datalist=[];   
  5. function main(){   
  6.     loadingLayer = new LoadingSample1();   
  7.     addChild(loadingLayer);   
  8.     LLoadManage.load(   
  9.         imgData,   
  10.         function(progress){   
  11.             loadingLayer.setProgress(progress);   
  12.         },   
  13.         gameInit   
  14.     );   
  15. }   
  16. function gameInit(result){   
  17.     datalist = result;   
  18.     removeChild(loadingLayer);   
  19.     loadingLayer = null;   
  20.       
  21.     var bitmapData = new LBitmapData(datalist["yorhom"]);  
  22.     var bitmap = new LBitmap(bitmapData);  
  23.     addChild(bitmap);  
  24. }  

通过这俩的名字可以看出来,一个是负责提供数据,一个负责按数据要求显示,类似于教研员和考生。LBitmap是LDisplayObject的子类,在ll_show中会调用到绘制图像的函数。同时也会进行相应的画布变幻。


6,LSprite层次化效果

LSprite的定义是:LSprite 类是基本显示列表构造块,一个可显示图形并且也可包含子项的显示列表节点。这个有点复杂,但其实说白了就是一个Layer层。我们在前面说到过,加入越后的对象会显示在最顶部,但是我要让后加的对象显示在先加的对象下方,就要用到LSprite分层显示了。LSprite也有addChild和removeChild方法,用于添加对象。此外,LSprite还有addEventListener函数,用于给对象加入事件。具体的一些功能可以到官方API去看看。

LSprite也有个childList属性,装有其子成员,在ll_show中,LSprite执行画布变幻和循环自己的childList,然后调用循环到的子对象的ll_show方法。


7,LTextField文字显示

这个类如LBitmap一般,需要用addChild加入到界面中。这个类的属性很多,不过用起来挺不错的,大家可以到API中去看一看,使用举例如下:

[javascript] view plaincopy在CODE上查看代码片派生到我的代码片
  1. init(20,"mylegend",500,400,main);   
  2. var backLayer,title;   
  3. function main(){   
  4.     backLayer = new LSprite();   
  5.     addChild(backLayer);   
  6.     title = new LTextField();   
  7.     title.size = 30;   
  8.     title.color = "#ff0000";   
  9.     title.text = "文字显示测试";   
  10.     backLayer.addChild(title);   
  11. }  

这个类嘛和LBitmap执行的命令差不多,画图的命令改为画文字的命令即可。


六,CSDN博客之星评选活动【已过时,大家忽略掉吧】

我原本想特此写一篇文章拉票的,但是我觉得这样不妥,因为我很久没写文章了,结果好不容易发一个却是一个广告,这样没意义,对吧~所以呢我还是坚持分享一下自己的收获,于是写下了这篇文章。当然,如果您认为我做出的努力对你有帮助,不妨投我一票吧:http://vote.blog.csdn.net/blogstaritem/blogstar2013/yorhomwang 最后的结果对我而言并不重要,但是大家的支持是我继续更新博客的动力~


Ok,就说到这里,搞定,收工~


本章就到此为止,以上就是本篇所有内容,欢迎大家交流。

----------------------------------------------------------------

欢迎大家转载我的文章。

转载请注明:转自Yorhom's Game Box

http://blog.csdn.net/yorhomwang

欢迎继续关注我的博客

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场