当前位置: 首页 > 工具软件 > Lgame > 使用案例 >

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

养星汉
2023-12-01

先说点题外话。话说去年我想做个小游戏,那时候不懂安卓,只是有点了解而已。在网上下载了本游戏开发入门的书籍,按着里面介绍的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,如下:

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

if (mode == LMode.Defalut){
	// 添加游戏View,显示为指定大小,并居中
	this.addView(gameView, gameHandler.getWidth(), gameHandler.getHeight(), Location.CENTER);
    }
    else if (mode == LMode.Ratio){
    ........
    ........
addView方法:

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

	/**
	 * 添加指定的View到游戏界面
	 * 
	 * @param view
	 */
	public void addView(final View view) {
		frameLayout.addView(view, LSystem.createFillLayoutParams()); //这是调用系统的addView函数
	}

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

	/**
	 * 显示游戏窗体
	 */
	public void showScreen() {
		setContentView(frameLayout);  //看到这句应该明白了吧,,,
		try{
			getWindow().setBackgroundDrawable(null);
		} catch (Exception e){

		}
	}

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

/**
 * 游戏窗体主循环
 */
public void run() {
	...
	...
	handler.runTimer(timerContext);
	...
	...
	handler.draw(gl);
	...
	...
}

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

....
...
currentControl.runTimer(context);
...
...
currentControl.createUI(g);
...
...

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

    public void runTimer(final LTimerContext timer) {
		...
		this.alter(timer);
		...
	}

	public abstract void alter(LTimerContext timer);
	
	public synchronized void createUI(LGraphics g) {
		...
		draw(g);
		...
	}
	
	public abstract void draw(LGraphics g);

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

public class MyScreen extends Screen{

	@Override
	public void draw(LGraphics g) {
		
	}

	@Override
	public void alter(LTimerContext timer) {
		
	}

	@Override
	public void onTouchDown(LTouch e) {
		
	}

	@Override
	public void onTouchUp(LTouch e) {
		
	}

	@Override
	public void onTouchMove(LTouch e) {
		
	}

}

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

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

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


 类似资料: