【Android】基于andengine游戏引擎的简单游戏实现(模拟控制器、tiledmap地图)

       此程序是在看了AndEngineExamples-GLES2中的几个简单的sample后写的,这是我的第一个博客,有问题的地方,希望大家能指出来。

    程序中使用了tiledmap地图、DigitalOnScreenControl模拟控制器,实现了tiledmap地图的障碍物,通过模拟控制器来控制player行走,没有其他的实现了。适合andengine的初学者来看,直接贴出代码吧,里面已经添加了必要的解释。完整程序代码请到http://download.csdn.net/detail/zaijianluoye110/5600855下载。

package com.example.mygame;

import org.andengine.engine.camera.BoundCamera;
import org.andengine.engine.camera.hud.controls.AnalogOnScreenControl;
import org.andengine.engine.camera.hud.controls.BaseOnScreenControl;
import org.andengine.engine.camera.hud.controls.AnalogOnScreenControl.IAnalogOnScreenControlListener;
import org.andengine.engine.camera.hud.controls.DigitalOnScreenControl;
import org.andengine.engine.options.EngineOptions;
import org.andengine.engine.options.ScreenOrientation;
import org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.andengine.entity.modifier.ScaleModifier;
import org.andengine.entity.modifier.SequenceEntityModifier;
import org.andengine.entity.primitive.Rectangle;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.sprite.AnimatedSprite;
import org.andengine.entity.util.FPSLogger;
import org.andengine.extension.physics.box2d.PhysicsConnector;
import org.andengine.extension.physics.box2d.PhysicsFactory;
import org.andengine.extension.physics.box2d.PhysicsWorld;
import org.andengine.extension.tmx.TMXLayer;
import org.andengine.extension.tmx.TMXLoader;
import org.andengine.extension.tmx.TMXObject;
import org.andengine.extension.tmx.TMXObjectGroup;
import org.andengine.extension.tmx.TMXTiledMap;
import org.andengine.extension.tmx.util.exception.TMXLoadException;
import org.andengine.opengl.texture.TextureOptions;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.opengl.texture.region.TiledTextureRegion;
import org.andengine.ui.activity.SimpleBaseGameActivity;
import org.andengine.util.debug.Debug;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import android.opengl.GLES20;

public class MainActivity extends SimpleBaseGameActivity {
// ===========================================================
// Constants
// ===========================================================

private static final int CAMERA_WIDTH = 480;
private static final int CAMERA_HEIGHT = 320;

// ===========================================================
// Fields
// ===========================================================

private BoundCamera mBoundChaseCamera;
private PhysicsWorld mPhysicsWorld;
private Scene mScene;

private AnimatedSprite mPlayer;
private Body mPlayerBody;

private Direction mDirection;
private BitmapTextureAtlas mBitmapTextureAtlas;
private TiledTextureRegion mPlayerTextureRegion;
private TMXTiledMap mTMXTiledMap;

private BitmapTextureAtlas mOnScreenControlTexture;
private ITextureRegion mOnScreenControlBaseTextureRegion;
private ITextureRegion mOnScreenControlKnobTextureRegion;

// ===========================================================
// Constructors
// ===========================================================

// ===========================================================
// Getter & Setter
// ===========================================================

// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================

@Override
public EngineOptions onCreateEngineOptions() {
this.mBoundChaseCamera = new BoundCamera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);

return new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), this.mBoundChaseCamera);
}

@Override
public void onCreateResources() {
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");
mDirection=Direction.NONE;
this.mBitmapTextureAtlas = new BitmapTextureAtlas(this.getTextureManager(), 72, 128, TextureOptions.DEFAULT);
this.mPlayerTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "player.png", 0, 0, 3, 4);
this.mBitmapTextureAtlas.load();

this.mOnScreenControlTexture = new BitmapTextureAtlas(this.getTextureManager(), 256, 128, TextureOptions.BILINEAR);
this.mOnScreenControlBaseTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mOnScreenControlTexture, this, "onscreen_control_base.png", 0, 0);
this.mOnScreenControlKnobTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mOnScreenControlTexture, this, "onscreen_control_knob.png", 128, 0);
this.mOnScreenControlTexture.load();
}

@Override
public Scene onCreateScene() {
this.mEngine.registerUpdateHandler(new FPSLogger());

this.mScene = new Scene();
//创建虚拟物理世界
this.mPhysicsWorld =  new PhysicsWorld(new Vector2(0, 0), false);
//注册PhysicsWorld
this.mScene.registerUpdateHandler(mPhysicsWorld);
//加载tmx文件--地图
try {
final TMXLoader tmxLoader = new TMXLoader(this.getAssets(), this.mEngine.getTextureManager(), TextureOptions.BILINEAR_PREMULTIPLYALPHA, this.getVertexBufferObjectManager());
this.mTMXTiledMap = tmxLoader.loadFromAsset("tmx/desert.tmx");
} catch (final TMXLoadException e) {
Debug.e(e);
}
//把非wall的图层直接attach到mScene中
for(int i=0;i<this.mTMXTiledMap.getTMXLayers().size();i++){
TMXLayer layer = this.mTMXTiledMap.getTMXLayers().get(i);
if(!layer.getTMXLayerProperties().containsTMXProperty("wall", "true")){
mScene.attachChild(layer);
}
}
//创建wall的层---player不能走入的区域
this.createUnwalkableObjects(this.mTMXTiledMap);
TMXLayer tmxLayer = this.mTMXTiledMap.getTMXLayers().get(0);

/* Make the camera not exceed the bounds of the TMXEntity. */
this.mBoundChaseCamera.setBounds(0, 0, tmxLayer.getHeight(), tmxLayer.getWidth());
this.mBoundChaseCamera.setBoundsEnabled(true);
//为地图添加边界限制
this.addBounds(tmxLayer.getWidth(), tmxLayer.getHeight());

/* Calculate the coordinates for the face, so its centered on the camera. */
final float centerX = (CAMERA_WIDTH - this.mPlayerTextureRegion.getWidth()) / 2;
final float centerY = (CAMERA_HEIGHT - this.mPlayerTextureRegion.getHeight()) / 2;

/* Create the sprite and add it to the scene. */
mPlayer = new AnimatedSprite(centerX, centerY, this.mPlayerTextureRegion, this.getVertexBufferObjectManager());
final FixtureDef playerFixtureDef = PhysicsFactory.createFixtureDef(0, 0, 0.5f);
mPlayerBody = PhysicsFactory.createBoxBody(this.mPhysicsWorld, mPlayer, BodyType.DynamicBody, playerFixtureDef);
this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(this.mPlayer,this.mPlayerBody,true,false){
@Override
public void onUpdate(float pSecondsElapsed) {
// TODO Auto-generated method stub
super.onUpdate(pSecondsElapsed);
//貌似没用
MainActivity.this.mBoundChaseCamera.updateChaseEntity();
}
});
//设置Camera的chase对象为player
this.mBoundChaseCamera.setChaseEntity(mPlayer);
mScene.attachChild(mPlayer);

//实例化模拟控制器
final DigitalOnScreenControl analogOnScreenControl = new DigitalOnScreenControl(0, CAMERA_HEIGHT - this.mOnScreenControlBaseTextureRegion.getHeight(), this.mBoundChaseCamera, this.mOnScreenControlBaseTextureRegion, this.mOnScreenControlKnobTextureRegion, 0.1f, this.getVertexBufferObjectManager(), new IAnalogOnScreenControlListener() {
@Override
public void onControlChange(final BaseOnScreenControl pBaseOnScreenControl, final float pValueX, final float pValueY) {
Direction dir=mDirection;
if(pValueX < 0){
//mPlayer.animate(new long[]{300, 300, 300}, 9, 11, true);
dir=Direction.LEFT;
}else if(pValueX > 0){
//mPlayer.animate(new long[]{200, 200, 200}, 3, 5, true);
dir = Direction.RIGHT;
}
if(pValueY < 0){
//mPlayer.animate(new long[]{200, 200, 200}, 0, 2, true);
dir = Direction.UP;
}else if(pValueY > 0){
//mPlayer.animate(new long[]{200, 200, 200}, 6, 8, true);
dir = Direction.DOWN;
}
if(dir!=mDirection){
mDirection = dir;
switch(mDirection){
case UP:
mPlayer.animate(new long[]{200, 200, 200}, 0, 2, true);
break;
case DOWN:
mPlayer.animate(new long[]{200, 200, 200}, 6, 8, true);
break;
case LEFT:
mPlayer.animate(new long[]{300, 300, 300}, 9, 11, true);
break;
case RIGHT:
mPlayer.animate(new long[]{200, 200, 200}, 3, 5, true);
break;
}
}
MainActivity.this.mPlayerBody.setLinearVelocity(pValueX * 2, pValueY * 2);
}

@Override
public void onControlClick(final AnalogOnScreenControl pAnalogOnScreenControl) {
mPlayer.registerEntityModifier(new SequenceEntityModifier(new ScaleModifier(0.25f, 1, 1.5f), new ScaleModifier(0.25f, 1.5f, 1)));
}
});
analogOnScreenControl.getControlBase().setBlendFunction(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
analogOnScreenControl.getControlBase().setAlpha(0.5f);
analogOnScreenControl.getControlBase().setScaleCenter(0, 128);
analogOnScreenControl.getControlBase().setScale(1.25f);
analogOnScreenControl.getControlKnob().setScale(1.25f);
analogOnScreenControl.refreshControlKnobPosition();

mScene.setChildScene(analogOnScreenControl);
return mScene;
}

// ===========================================================
// Methods
// ===========================================================
/**
* @param map
* @author gengliming
*
* 创建player不能进入的区域
*/
private void createUnwalkableObjects(TMXTiledMap map){
for(final TMXObjectGroup group : this.mTMXTiledMap.getTMXObjectGroups()){
if(group.getTMXObjectGroupProperties().containsTMXProperty("wall", "true")){
for(final TMXObject object : group.getTMXObjects()){
final Rectangle rect = new Rectangle(object.getX(),object.getY(),object.getWidth(),object.getHeight(), this.getVertexBufferObjectManager());
final FixtureDef boxFixtureDef = PhysicsFactory.createFixtureDef(0, 0, 1f);
PhysicsFactory.createBoxBody(this.mPhysicsWorld, rect, BodyType.StaticBody,boxFixtureDef);
rect.setVisible(false);
this.mScene.attachChild(rect);
}
}
}
}
/**
*
* @param width
* @param height
* 为地图添加边界
*/
private void addBounds(float width,float height){
final Rectangle bottom = new Rectangle(0,height-2,width,2,this.getVertexBufferObjectManager());
bottom.setVisible(false);
final Rectangle top = new Rectangle(0,0,width,2,this.getVertexBufferObjectManager());
top.setVisible(false);
final Rectangle left = new Rectangle(0,0,2,height,this.getVertexBufferObjectManager());
left.setVisible(false);
final Rectangle right = new Rectangle(width-2,0,2,height,this.getVertexBufferObjectManager());
right.setVisible(false);

final FixtureDef wallFixtureDef = PhysicsFactory.createFixtureDef(0,0,1f);
PhysicsFactory.createBoxBody(this.mPhysicsWorld, bottom, BodyType.StaticBody, wallFixtureDef);
PhysicsFactory.createBoxBody(this.mPhysicsWorld, top, BodyType.StaticBody, wallFixtureDef);
PhysicsFactory.createBoxBody(this.mPhysicsWorld, left, BodyType.StaticBody, wallFixtureDef);
PhysicsFactory.createBoxBody(this.mPhysicsWorld, right, BodyType.StaticBody, wallFixtureDef);

this.mScene.attachChild(bottom);
this.mScene.attachChild(top);
this.mScene.attachChild(right);
this.mScene.attachChild(left);
}
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值