AndEngine游戏开发系列教程(一)

链接地址:http://www.apkbus.com/android-130403-1-1.html


一、简介

AndEngine基于libGDX框架开发,使用OpenGL ES进行图形绘制,底层使用C++编写,通过JNI调用来实现,因此比较高效,功能强大。同时集成了Box2D物理引擎,因此能实现一些较为复杂的物理效果。在Rokon(另一个Android 2D游戏引擎)宣布停止更新以后,AndEngine成为Android最为流行的2D游戏引擎。相较Libgdx引擎:AndEngine拥有更多的游戏组件与扩展功能;并且它在默认情况下已经可以支持中文;采用屏幕坐标系绘也更符合一般Android绘图习惯。特点如下:

①开源
 AndEngine是一个开源项目。这使得开发者在遇到问题时可以直接从源码上找到答案,也能按照自己的需要对AndEngine进行修改和扩展。AndEngine的源码在github上托管。
②高效
AndEngine主要使用Java语言开发,但在大运算量的耗时功能时,AndEngine使用了C/C++本地代码进行开发。比如物理引擎或者音频处理。作为用户,你只需要关注Java端就可以了,它已经把所有的本地代码封装好了。相比于其他android游戏引擎,AndEngine的效率优势十分明显。
③特效
AndEngine拥有Particle System (粒子系统),能够高效逼真的模拟火焰、雨雪、流水等效果。还拥有Motion Streak (动态模糊)、Ratial Blur (径向模糊) 等高级特效。
④物理引擎
AndEngine对于物理引擎Box2D[3]的封装是让人惊讶的。 它使用JNI封装了Box2D的C++端,使得其运行效率比其他同级的物理引擎如Box2D快不少。如果你的游戏准备使用物理引擎,请优先考虑AndEngine。       
⑤扩展丰富

AndEngine官方提供数个扩展包。例如:AndEngineLiveWallpaperExtension动态壁纸扩展、AndEngineTexturePackerExtension纹理打包扩展、AndEnginePhysicsBox2DExtension物理引擎扩展、AndEngineMultiplayerExtension多玩家扩展 等等。这使得开发者可以轻松实现众多功能。

二、初始构建

1.新建一个工程,在工程根目录新建一个lib文件夹(如果有就不必新建),将jar文件粘贴到lib文件夹下,右击jar文件--build path--add to build path ,接下来,右击jar文件--build path--configure build path-如图将andengine.jar勾选

AndEngine游戏开发系列教程(一)_第1张图片

2.简单的启动画面

 这里将用andengine将一个贴图绘制出来,需要修改Activity代码。

public class LeekaoActivity extends BaseGameActivity {

// 摄像头尺寸
private static final int CAMERA_WIDTH = 800;
private static final int CAMERA_HEIGHT = 480;
private Camera mCamera;
// 贴图
private Texture mTexture;
private TextureRegion mLeekaoTextureRegion;

// 以下是覆写超类及接口中的方法
@Override
public Engine onLoadEngine() {
this.mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);

// TODO Auto-generated method stub
return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE,
new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT),
this.mCamera));
}

@Override
public void onLoadResources() {
// TODO Auto-generated method stub
this.mTexture = new Texture(1024, 1024,
TextureOptions.BILINEAR_PREMULTIPLYALPHA);
this.mLeekaoTextureRegion = TextureRegionFactory.createFromAsset(
this.mTexture, this, "leekao/leekao.jpg", 0, 0);
this.mEngine.getTextureManager().loadTexture(this.mTexture);

}

@Override
public Scene onLoadScene() {
// TODO Auto-generated method stub
this.mEngine.registerUpdateHandler(new FPSLogger());
final Scene scene=new Scene(1);
//摄像头置于画面中央
final int centerX=(CAMERA_WIDTH-this.mLeekaoTextureRegion.getWidth())/2;
final int centerY=(CAMERA_HEIGHT-this.mLeekaoTextureRegion.getHeight())/2;

//创建Sprite对象并加入Scene对象中
final Sprite leekao=new Sprite(centerX,centerY, mLeekaoTextureRegion);
scene.getLastChild().attachChild(leekao);
return scene;
}

@Override
public void onLoadComplete() {
// TODO Auto-generated method stub

}  

效果图如下:

AndEngine游戏开发系列教程(一)_第2张图片

上面代码的效果是显示一个画面,代码看起来好像好多,现在来看看代码:

       可以发现和平时不一样的是,继承了BaseGameActivity类,该类是完成了AndEngine的一些初始化工作,并提供了相关的覆写方法。(在写代码时可以右击--source--Override/implement mthods 勾选相关方法来加快写代码速度 )。接着设置了摄像头视角的尺寸。
      代码覆写方法解析:
      【】onLoadEngine()会在游戏引擎被该activity所加载时调用,这里初始化了摄像头与引擎对象。在引擎对象中,我将屏幕方向设置为横屏(LANDSCAPE)。接着有一个RatioResolutionPolicy的ResolutionPolicy对象,引擎可以根据该策略在不同的屏幕大小下缩放图像,同时保持原有的纵横比。
      【】onLoadResources()方法会在加载资源时被调用。这里需要创建一个Texture对象来存放TextureRegion对象进行图像的加载。至于TextureOptions为图片的渲染方式,将在之后的章节说明。最后将贴图对象载入引擎的TextureManage中去。(在assets/leekao文件夹夹下已经准备好了图片)
      【】onLoadScene()方法会在引擎将要显示场景时调用,在代码中初始化了帧数计数器,创建了一个仅有一层的场景,并将摄像头至于画面的中央,创建了表示启动画面的精灵对象,将他附到场景上。
     【】onLoadComplete()方法会在引擎初始化完成时调用,目前还没在此阶段进行操作。


示例源码免费下载地址:http://download.csdn.net/detail/lan410812571/5858285


三、Engine对象

从上一章中可以知道,AndEngine包含了一个叫做Engine的类,该类同Android运行环境一起来实现游戏的进行。Engine是Activity的核心,开发AndEngine游戏首先要做的就是覆写onLoadEngine()方法。初始化Engine对象:

@Override
public Engine onLoadEngine() {
this.mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);

// TODO Auto-generated method stub
return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE,
new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT),
this.mCamera));
}

Engine对象的作用:

①初始化并持续维护着OpenGL的SurfaceView对象,该对象用来在屏幕上绘制
②管理用户的输入行为
③管理各种传感器的输入
④管理文本字体库
⑤创建并管理音乐音效的加载和播放。
⑥定期更新AndEngine其余部分的逻辑, 以推动游戏状态的改变。

Engine的默认构造器是:
public Engine(final EngineOptions pEngineOptions) 

EngineOptions类的构造器:
public EngineOptions(boolean pFullscreen, ScreenOrientation pScreenOrientation, IResolutionPolicy pResolutionPolicy, Camera pCamera)
传给新EngineOptions的参数告知AndEngine应如何设置游戏的Engine对象
①pFullscreen:是否全屏显示;
②ScreenOrientation:可取的值 LANDSCAPE(横屏) PORTRAIT(竖屏)
③pResolutionPolicy:告知Engine对象如何处理不同的设备屏幕大小:

RatioResourcePolcy:在保持长宽比不变的情况下尽可能的拉伸图像以填满屏幕。上面的就是用这个方法。
FillResourcePolicy:忽略长宽比,直接填满整个屏幕。
FixedResourcePolicy:使用固定的长宽比,不进行缩放。
RelativeResourcePolicy:将原图缩放到指定的倍数。

④pCamera:表示玩家观察场景所用的摄像机视点,构造器:

public  Camera(float pX, float pY, float pWidth, float pHeight)

pX与pY表示原点坐标,pWidth与pHeight表示场景可见部分的长和宽,单位就是像素。


四、菜单场景

AndEngine提供了一个菜单系统MenuScene,该系统将菜单集成到游戏当中去,支持文本菜单和图形菜单。菜单在AndEngine中属于一个特殊的场景类,显示的是一个由文本或图形组成的有序列表,而且当玩家触摸时可以相应带动画的效果。
MenuScene类是Scene的子类,有4个构造器:
1)MenuScene()
2)MenuScene(final Camera pCamer)
3)MenuScene(final IOnMenuItemClickListencer pOnMenuItemClickListencer )
4)MenuScene(final Camera pCamer,final IOnMenuItemClickListencer pOnMenuItemClickListencer )

    pCamer用以显示场景的Canmera对象
    pOnMenuItemClickListencer 为菜单点击事件的监听器

MenuScene类的相关方法
①addMenuItem(final IMenuItem pMeuItem)
    加入菜单项

②getMenuItmCount()
     返回菜单列表中所含菜单项的数目

③setChildScene(Scene pChildScene, boolean pModalDraw, boolean pModalUpdate, boolean pModalTouch)
     将一个场景作为子场景附加到当前菜单场景上

菜单项的种类:
   TextMenuItem文字菜单项:构造器
   TextMenuItem(int pID, Font pFont, String pText)
   pID:唯一的整数标识符,用于在onClick()回调方法中标识被点击的菜单。
   pFont:显示菜单时所用的字体
   pText:显示的文本

SpriteMenuItem图形菜单项:

  SpriteMenuItem(int pID, TextureRegion pTextureRegion)
  pTextureRegion:用以显示图形菜单项的精灵贴图

AnimatedSpritMenuItem动画菜单项:

  AnimatedSpriteMenuItem(final  int pID,fina TiledTextureRegion pTileTextureRegion)
  pTileTextureRegion:显示动画精灵的贴图,之后的章节会讲。

ColorMenuItemDecorator复合颜色菜单项:
ColorMenuItemDecorator(IMenuItem pMenuItem, float pSelectedRed, float pSelectedGreen, float pSelectedBlue, float pUnselectedRed, float pUnselectedGreen, float pUnselectedBlue)
当点击时菜单项的颜色会发生改变,虽然参数好多,其实很简单的,就是RGB的颜色值而以。
pMenuItem要修饰的菜单项。

ScaleMenuItemDecorator复合缩放菜单项:
  ScaleMenuItemDecorator(IMenuItem pMenuItem,float pSelectedScale,float pUnselctedScale)
  跟上面的方法差不多,当点击时菜单项的大小会发生改变。

除了默认的Engine外,AndEngine还提供了其他的Engine类,以下这些类都是Engine类的子类,所以继承了其基本特点。
FixedStepEngine:可以达到最快的帧速率
LimitedFPSEngine:以固定的帧速率运行
SingleSceneSplitScreenEngine:在两个窗口中分别从不同的视点显示同一个场景
DoubleSceneSplitScreenEngine:分屏显示不同的场景

示例源码免费下载地址:http://download.csdn.net/detail/lan410812571/5858501


AndEngine游戏开发系列教程(一)_第3张图片

<P>public class MainMenu extends BaseGameActivity implements
IOnMenuItemClickListener {

private static final int CAMERA_WIDTH = 800;
private static final int CAMERA_HEIGHT = 480;
// 菜单项的引索ID
protected static final int MENU_PLAY = 0;
protected static final int MENU_SCORES = MENU_PLAY + 1;
protected static final int MENU_OPTIONS = MENU_SCORES + 1;
protected static final int MENU_ABOUT = MENU_OPTIONS + 1;
protected static final int MENU_EXIT = MENU_ABOUT + 1;

protected Camera mCamera;
protected Scene mMenuScene;

private Texture mMenuBGTexture;
private TextureRegion mMenuBGTextureRegion;

private Texture mExitTexture;
private TextureRegion mExitTextureRegion;

protected MenuScene mStaticMenuScene;
private Font mfont;
protected Texture mFontTexture;

@Override
public Engine onLoadEngine() {
// TODO Auto-generated method stub
this.mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE,
new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT),
this.mCamera));

}

@Override
public void onLoadResources() {
// TODO Auto-generated method stub
// 载入font与texture
this.mFontTexture = new Texture(256, 256,
TextureOptions.BILINEAR_PREMULTIPLYALPHA);
FontFactory.setAssetBasePath("fonts/");
this.mfont = FontFactory.createFromAsset(this.mFontTexture, this,
"JOKERMAN.TTF", 50, true, Color.RED);
this.mEngine.getTextureManager().loadTexture(this.mFontTexture);
this.mEngine.getFontManager().loadFont(this.mfont);

this.mMenuBGTexture = new Texture(2048, 1024,
TextureOptions.BILINEAR_PREMULTIPLYALPHA);
this.mMenuBGTextureRegion = TextureRegionFactory.createFromAsset(
mMenuBGTexture, this, "menu/menu_bg.jpg", 0, 0);
this.mEngine.getTextureManager().loadTexture(mMenuBGTexture);

// 退出按钮的贴图
this.mExitTexture = new Texture(256, 256,
TextureOptions.BILINEAR_PREMULTIPLYALPHA);
this.mExitTextureRegion = TextureRegionFactory.createFromAsset(
mExitTexture, this, "menu/menu_exit.png", 0, 0);
this.mEngine.getTextureManager().loadTexture(mExitTexture);

}

protected void createStaticMenuScene() {
this.mStaticMenuScene = new MenuScene(this.mCamera);
final IMenuItem playMenuItem = new ColorMenuItemDecorator(
new TextMenuItem(MENU_PLAY, mfont, "Play Game"), 0.5f, 0.5f,
0.5f, 1.0f, 0.0f, 0.0f);
playMenuItem.setBlendFunction(GL10.GL_SRC_ALPHA,
GL10.GL_ONE_MINUS_SRC_ALPHA);
this.mStaticMenuScene.addMenuItem(playMenuItem);

final IMenuItem scoresMenuItem = new ScaleMenuItemDecorator(
new TextMenuItem(MENU_SCORES, mfont, "Scores"), 1.2f, 1.0f);
scoresMenuItem.setBlendFunction(GL10.GL_SRC_ALPHA,
GL10.GL_ONE_MINUS_SRC_ALPHA);
this.mStaticMenuScene.addMenuItem(scoresMenuItem);

final IMenuItem optionsMenuItem = new ColorMenuItemDecorator(
new ScaleMenuItemDecorator(new TextMenuItem(MENU_OPTIONS,
mfont, "Options"), 1.2f, 1.0f), 0.5f, 0.5f, 0.5f, 1.0f,
1.0f, 1.0f);
optionsMenuItem.setBlendFunction(GL10.GL_SRC_ALPHA,
GL10.GL_ONE_MINUS_SRC_ALPHA);
this.mStaticMenuScene.addMenuItem(optionsMenuItem);

final IMenuItem aboutMenuItem = new TextMenuItem(MENU_ABOUT, mfont,
"Abuot");
aboutMenuItem.setBlendFunction(GL10.GL_SRC_ALPHA,
GL10.GL_ONE_MINUS_SRC_ALPHA);
this.mStaticMenuScene.addMenuItem(aboutMenuItem);

final IMenuItem exitMenuItem = new ScaleMenuItemDecorator(
new SpriteMenuItem(MENU_EXIT, mExitTextureRegion), 1.2f, 1.0f);
exitMenuItem.setBlendFunction(GL10.GL_SRC_ALPHA,
GL10.GL_ONE_MINUS_SRC_ALPHA);
this.mStaticMenuScene.addMenuItem(exitMenuItem);

this.mStaticMenuScene.buildAnimations();
this.mStaticMenuScene.setBackgroundEnabled(false);
this.mStaticMenuScene.setOnMenuItemClickListener(this);
}

@Override
public Scene onLoadScene() {
// TODO Auto-generated method stub
this.mEngine.registerUpdateHandler(new FPSLogger());
this.createStaticMenuScene();
final int centerX = (CAMERA_WIDTH - this.mMenuBGTextureRegion
.getWidth()) / 2;
final int centerY = (CAMERA_HEIGHT - this.mMenuBGTextureRegion
.getHeight()) / 2;
this.mMenuScene = new Scene(1);

final Sprite menubg = new Sprite(centerX, centerY, mMenuBGTextureRegion);
mMenuScene.getLastChild().attachChild(menubg);
mMenuScene.setChildScene(mStaticMenuScene);

return this.mMenuScene;
}

@Override
public void onLoadComplete() {
// TODO Auto-generated method stub

}

@Override
public boolean onMenuItemClicked(MenuScene pMenuScene, IMenuItem pMenuItem,
float pMenuItemLocalX, float pMenuItemLocalY) {
// TODO Auto-generated method stub
switch (pMenuItem.getID()) {
case MENU_PLAY:
Toast.makeText(MainMenu.this, "paly selected", Toast.LENGTH_SHORT)
.show();
return true;

case MENU_SCORES:
Toast.makeText(MainMenu.this, "scores selected", Toast.LENGTH_SHORT)
.show();
return true;

case MENU_OPTIONS:
Toast.makeText(MainMenu.this, "options selected",
Toast.LENGTH_SHORT).show();
return true;

case MENU_ABOUT:
Toast.makeText(MainMenu.this, "about selected", Toast.LENGTH_SHORT)
.show();
return true;

default:
return false;

}

}

}

五、实体Entity

在AndEngine中,我们看到的游戏元素都是Entity的子类,像场景Scene,精灵Sprite,瓦片Tile,图形Texture,粒子Partical,文本等都是Entity对象。Entity对象可以通过修改器Modifier对象来修改。AndEngine在游戏设计上采用了实体/组件设计方法,该方法将所有的物体都看做Entity对象,而不是为每种物体设计一个类。相对于完全的面向对象,这样的好处是代码便于管理,可以更方便的修改。
Entity类:
Entity是包括Scene类内所有可见物体的超类,所以也包括可见物体的公共属性,所以可以设置Modifier来修改。这些属性有:
【】float mX,mY Entity对象当前的位置
【】float mInitialX,mInitialY 对象的初始位置
【】boolean mVisible 对象是否可见  
【】boolean mIgnoredUpdate  对象是否更新
【】int mZindex 对象在显示序列中的位置(比如图层的叠加)
【】IEntity mParent 此对象的上层对象
【】SmartList<IEntity> mChildren 对象的子对象列表
【】float mRotation  对象的旋转角度
【】float   mScale   对象的缩放因子
【】float mAlpha 对象的透明度
【】UpdateHandlerList mUpdateHandlers 应用于此对象的UpdateHandler对象列表

Entity类的构造器和方法:
Entity()
Entity(final float pX,final float pY)

位置相关
float getX() /getY() 返回当前位置的x,y坐标。
float getInitialX() /getIntialY()返回Entity对象的初始x,y坐标
void setPosition(final float px,final float py) 设置Entity对象位置
setPosition(final IEnity pOtherEntity)将传入Entity对象的位置设定为此Entity对象的位置

缩放相关
float isScaled() 如果缩放因子不是1.0f,则返回true
float getScaleX() 返回横向缩放因子
void setScale(final float pScaleX,fnal float pScaleY) 设定两个方向的缩放因子

颜色相关
在AndEnigine中,Entity对象的颜色是一个乘数,相当与在原图上进行叠加染色。
float getRed()...
void setColor(final float pRed,final float pGreen ,final float pBlue,final float pAlpha)

旋转相关
float getRotation()
setRotation(final float pRotation)
获取,设置旋转角度。

管理子对象
    Entity对象通常是分层组织起来的,以便批量修改。如果上层对象被修改了,那么修改的效果会自动应用于他的所有子对象,但是,子对象的修改效果不会传递到上层。
    IEnitity getFirstChild() 
                getLastChild()
   获得此Entity对象的第一个及最后一个子对象。
   void attachChild(final IEntity pEntity)
   将新对象加入到此Entity对象,并作为最后一个子对象。
   IEntity getChild(final int index)
   返回cshu所在位置的子对象
   int getChildCount()
   得到子对象的数目


篇幅过长,加载过慢,分下一篇

地址:http://blog.csdn.net/lan410812571/article/details/9717561


你可能感兴趣的:(android,游戏开发,AndEngine)