LGame学习笔记1-----LGame游戏引擎大体架构

先说点题外话。话说去年我想做个小游戏,那时候不懂安卓,只是有点了解而已。在网上下载了本游戏开发入门的书籍,按着里面介绍的SurfaceView框架开始了游戏开发,但总感觉不方便,有很多东西需要自己去实现,然后听网友说到了游戏引擎,推荐我用LGame,那时候刚刚接触android,基本是零经验,看着LGame跟天书差不了多少,然后教程方面除了作者的说明文档,笨木头的博客和几篇零碎的文章,其他基本没有,对于我这样一个刚接触android的小白来说,无异于登天了。一段时间后感觉LGame实在学不下去了,就开始搜索其他游戏引擎的资料,然后知道了现在最火的cocos2dx,可惜,是C++的,其他的如libgdx、AndEngine、OGEngine还有刚出的cocos2dx-java,即cocosEditor。原本是打算学习cocos2dx的,因为网上这方面的资料还是比较多的,学习之后才发现不是那么容易。首先cocos2dx的版本变更快,版本间差别比较大,网上的大多书籍和资料都是旧版的,对于新版已经不适用。其次是C++,我只是在大学学过一点,而且基本都忘光了。再一个就是用VS调试实在是不习惯,不知所措,可能是水平不够吧。然后又接触了libgdx,学过几天,还是因为资料太少,文档都是英文,学习很不便,至于其他的游戏引擎,看了看,唉,还是放弃了,,,,最后转了一圈,又回到了LGame。

 现在接触android有半年多了,做了几个项目,水平也高了那么一点点,再次看LGame的源码,发现不是天书了,,,

android中,LGame有两个版本,一个canvas的,一个是OpenGLES的,对比了下,OpenGLES注重性能,源码很多,canvas只是模拟实现,源码较少。鉴于目前本人对android的理解和游戏开发的水平(游戏开发水平其实是零,,,),决定选择较简单的canvas版本,这样就可以根据源码来学习,入门相对较容易。

这是作者的原CSDN博客:http://blog.csdn.net/cping1982

作者刚建博当站长了:http://www.xrpmoon.com/blog 大家可以去看下,可以了解很多东西的。

然后就是LGame的GitHub地址:https://github.com/cping/LGame 有兴趣的可以下载下来体验体验。

再有我把canvas上传了,懒得下载LGame源码的可以直接下载用:http://download.csdn.net/detail/wblyuyang/8538345


好了,废话到此为止,进入正题。这篇文章主要是介绍下LGame的大体架构,只是粗略介绍,有错误的地方欢迎指正。


建立Android工程后,首先应该继承LGameAndroid2DActivity,作者在LGameAndroid2DActivity里面建立游戏最底层的FrameLayout,如下:

[java]  view plain  copy
  1. // 构建整个游戏使用的最底层FrameLayout  
  2.     this.frameLayout = new FrameLayout(LGameAndroid2DActivity.this);  
然后建立游戏View,即继承自SurfaceView的LGameAndroid2DView,如下:
[java]  view plain  copy
  1. private LGameAndroid2DView gameView;  
  2.     // 创建游戏View  
  3.     this.gameView = new LGameAndroid2DView(LGameAndroid2DActivity.this, landscape, mode);  
通过gameView获取当前游戏的控制句柄:
[java]  view plain  copy
  1. // 获得当前游戏操作句柄  
  2.     this.gameHandler = gameView.getGameHandler();  
由于水平有限,只能粗略理解CP大神的代码意图。猜测gameHandler游戏句柄是用来操作整个游戏的,如获取屏幕尺寸,Screen操作等。
然后根据不同的显示模式添加view:

[java]  view plain  copy
  1. if (mode == LMode.Defalut){  
  2.     // 添加游戏View,显示为指定大小,并居中  
  3.     this.addView(gameView, gameHandler.getWidth(), gameHandler.getHeight(), Location.CENTER);  
  4.     }  
  5.     else if (mode == LMode.Ratio){  
  6.     ........  
  7.     ........  
addView方法:

[java]  view plain  copy
  1. /** 
  2.  * 添加指定的View到游戏界面的指定位置,并将View设置为指定大小 
  3.  *  
  4.  * @param view 
  5.  * @param location 
  6.  */  
  7. public void addView(final View view, int w, int h, Location location) {  
  8.     android.widget.RelativeLayout viewLayout = new android.widget.RelativeLayout(LGameAndroid2DActivity.this);  
  9.     android.widget.RelativeLayout.LayoutParams relativeParams = LSystem.createRelativeLayout(location, w, h);  
  10.     viewLayout.addView(view, relativeParams);  
  11.     addView(viewLayout);  
  12. }  
可以看出是初始化了一个RelativeLayout布局,然后放入了传入的view,即声明的gameView。然后是addView(viewLayout)加入布局:

[java]  view plain  copy
  1. /** 
  2.  * 添加指定的View到游戏界面 
  3.  *  
  4.  * @param view 
  5.  */  
  6. public void addView(final View view) {  
  7.     frameLayout.addView(view, LSystem.createFillLayoutParams()); //这是调用系统的addView函数  
  8. }  

至此,我们可以知道,已经把继承自SurfaceView的LGameAndroid2DView的实例化gameView变量加入了游戏的最底层的framelayout,这样就可以通过改变gameView的画面来实现游戏的画面。最后是显示Screen,即showScreen():

[java]  view plain  copy
  1. /** 
  2.  * 显示游戏窗体 
  3.  */  
  4. public void showScreen() {  
  5.     setContentView(frameLayout);  //看到这句应该明白了吧,,,  
  6.     try{  
  7.         getWindow().setBackgroundDrawable(null);  
  8.     } catch (Exception e){  
  9.   
  10.     }  
  11. }  

然后再说说 LGameAndroid2DView,它继承自SurfaceView,具体功能没有深入分析,不过大体原理跟surfaceView应该是一样的。通过一个线程CanvasThread来不断刷新游戏画面,然后通过LHandler的实例handler来调用runTimer和draw函数:

[java]  view plain  copy
  1. /** 
  2.  * 游戏窗体主循环 
  3.  */  
  4. public void run() {  
  5.     ...  
  6.     ...  
  7.     handler.runTimer(timerContext);  
  8.     ...  
  9.     ...  
  10.     handler.draw(gl);  
  11.     ...  
  12.     ...  
  13. }  

然后LHandler类里面的runTimer和draw函数再通过Screen类的实例来调用Screen类里面的runTimer和createUI函数:

[java]  view plain  copy
  1. ....  
  2. ...  
  3. currentControl.runTimer(context);  
  4. ...  
  5. ...  
  6. currentControl.createUI(g);  
  7. ...  
  8. ...  

然后Screen里面的runTimer和createUI函数再调用本类里面的虚函数alter和draw:

[java]  view plain  copy
  1.    public void runTimer(final LTimerContext timer) {  
  2.     ...  
  3.     this.alter(timer);  
  4.     ...  
  5. }  
  6.   
  7. public abstract void alter(LTimerContext timer);  
  8.   
  9. public synchronized void createUI(LGraphics g) {  
  10.     ...  
  11.     draw(g);  
  12.     ...  
  13. }  
  14.   
  15. public abstract void draw(LGraphics g);  

而开发者需要继承虚类Screen来具体实现,如下:

[java]  view plain  copy
  1. public class MyScreen extends Screen{  
  2.   
  3.     @Override  
  4.     public void draw(LGraphics g) {  
  5.           
  6.     }  
  7.   
  8.     @Override  
  9.     public void alter(LTimerContext timer) {  
  10.           
  11.     }  
  12.   
  13.     @Override  
  14.     public void onTouchDown(LTouch e) {  
  15.           
  16.     }  
  17.   
  18.     @Override  
  19.     public void onTouchUp(LTouch e) {  
  20.           
  21.     }  
  22.   
  23.     @Override  
  24.     public void onTouchMove(LTouch e) {  
  25.           
  26.     }  
  27.   
  28. }  

至此,screen里面的alter和draw函数我们已经知道了其在整个框架中是如何运行的了。

alter函数应该实现游戏的逻辑处理,而draw函数应该实现游戏的画面绘制,其他三个函数是触屏的操作,作者封装好了,可以直接用。我还记得我当时写游戏时,光触屏操作救你费了好大的劲,,,

写到这里,大家应该发现很熟悉,对,这就是surfaceView框架的处理逻辑,新增一条线程,然后不断重复逻辑控制和画面绘制,这样游戏画面和任务就动了起来。作者把底层的一些东西进行封装,不仅使用起来更加方便,而且作者还开发了一系列的组件,可以很好的实现游戏的快速开发。

猜你喜欢

转载自blog.csdn.net/u012278016/article/details/80104880
今日推荐