I'm learning how to create games with this great engine and I'm trying to put my knowledge in order to create a simple game. My first goal is to make a Rectangle moving using accelerometer and create levels using xml parser.
Only the second step works. In fact my player rectangle remains stuck on the screen. I noticed that if I put all my code in a BaseActivity class all works fine, but obviously I would to create few classes to make my game organized and to follow object orientation paradigm. Here is my classes and my first "try" level xml layout.
GameActivity:
public class GameActivity extends BaseGameActivity implements IAccelerationListener {
private Camera camera;
private ResourcesManager resourceManager;
static PhysicsWorld mPhysicsWorld;
@Override
public EngineOptions onCreateEngineOptions() {
// TODO Auto-generated method stub
camera = new Camera(0, 0, 800, 480);
EngineOptions engineOptions = new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(800, 480), camera);
mPhysicsWorld = new PhysicsWorld(new Vector2(0, SensorManager.GRAVITY_EARTH), false);
engineOptions.setWakeLockOptions(WakeLockOptions.SCREEN_ON);
return engineOptions;
}
@Override
public void onCreateResources(OnCreateResourcesCallback pOnCreateResourcesCallback) throws Exception {
ResourcesManager.prepareManager(mEngine, this, camera, getVertexBufferObjectManager());
resourceManager = ResourcesManager.getInstance();
pOnCreateResourcesCallback.onCreateResourcesFinished();
}
@Override
public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback)
throws Exception {
SceneManager.getInstance().createGameScene(pOnCreateSceneCallback);
}
@Override
public void onPopulateScene(Scene pScene,
OnPopulateSceneCallback pOnPopulateSceneCallback) throws Exception {
// TODO Auto-generated method stub
}
@Override
public Engine onCreateEngine(EngineOptions pEngineOptions){
return new LimitedFPSEngine(pEngineOptions, 60);
}
@Override
protected void onDestroy(){
super.onDestroy();
if (this.isGameLoaded())
System.exit(0);
}
@Override
public void onAccelerationAccuracyChanged(AccelerationData pAccelerationData) {
// TODO Auto-generated method stub
}
@Override
public void onAccelerationChanged(AccelerationData pAccelerationData) {
final Vector2 gravity = Vector2Pool.obtain(pAccelerationData.getX()*3, pAccelerationData.getY()*3);
this.mPhysicsWorld.setGravity(gravity);
Vector2Pool.recycle(gravity);
}
@Override
public void onResumeGame() {
super.onResumeGame();
this.enableAccelerationSensor(this);
}
@Override
public void onPauseGame() {
super.onPauseGame();
this.disableAccelerationSensor();
}
}
ResourceManager:
public class ResourcesManager {
public static final ResourcesManager INSTANCE = new ResourcesManager();
public Engine engine;
public GameActivity activity;
public Camera camera;
public VertexBufferObjectManager vbom;
public void loadMenuResources(){
loadMenuGraphics();
}
private void loadMenuGraphics() {
}
public void loadGameResources(){
loadGameGraphics();
loadGameFonts();
}
private void loadGameFonts() {
}
private void loadGameGraphics() {
}
public static void prepareManager(Engine engine, GameActivity activity, Camera camera, VertexBufferObjectManager vbom){
getInstance().engine = engine;
getInstance().activity = activity;
getInstance().camera = camera;
getInstance().vbom = vbom;
}
public static ResourcesManager getInstance(){
return INSTANCE;
}
}
SceneManager:
package com.indies.fatescape;
import org.andengine.engine.Engine;
import org.andengine.ui.IGameInterface.OnCreateSceneCallback;
public class SceneManager {
private BaseScene gameScene;
private static SceneManager INSTANCE = new SceneManager();
private SceneType currentSceneType = SceneType.SCENE_GAME;
private BaseScene currentScene;
private Engine engine = ResourcesManager.getInstance().engine;
public enum SceneType {
SCENE_GAME,
}
public void setScene(BaseScene scene){
engine.setScene(scene);
currentScene = scene;
currentSceneType = scene.getSceneType();
}
public void createGameScene(OnCreateSceneCallback pOnCreateSceneCallback){
gameScene = new GameScene();
gameScene.registerUpdateHandler(GameActivity.mPhysicsWorld);
currentScene = gameScene;
pOnCreateSceneCallback.onCreateSceneFinished(gameScene);
}
/*
* setScene(SceneType sceneType) which takes care about displaying another scene and keeping track of it
* by storing references of the displayed scene and its type
*/
public void setScene(SceneType sceneType){
switch (sceneType){
case SCENE_GAME:
setScene(gameScene);
break;
default:
break;
}
}
public static SceneManager getInstance() {
return INSTANCE;
}
public SceneType getCurrentSceneType() {
return currentSceneType;
}
public BaseScene getCurrentScene() {
return currentScene;
}
}
GameScene:
public class GameScene extends BaseScene {
private PhysicsWorld physicsWorld;
private static final String TAG_LEVEL = "level";
private static final String TAG_ENTITY = "entity";
private static final String TAG_ENTITY_ATTRIBUTE_TYPE = "type";
private static final String TAG_ENTITY_ATTRIBUTE_X = "x";
private static final String TAG_ENTITY_ATTRIBUTE_Y = "y";
private static final String TAG_ENTITY_ATTRIBUTE_WIDTH = "width";
private static final String TAG_ENTITY_ATTRIBUTE_HEIGHT = "height";
private static final Object TAG_ENTITY_ATTRIBUTE_TYPE_VALUE_BRICK = "brick";
private static final Object TAG_ENTITY_ATTRIBUTE_TYPE_VALUE_PLAYER = "player";
private Body playerBody;
private Rectangle player;
@Override
public void createScene() {
createPhysics();
createBackground();
loadLevel(1);
}
@Override
public void onBackLeyPressed() {
}
@Override
public SceneType getSceneType() {
return SceneType.SCENE_GAME;
}
@Override
public void disposeScene() {
}
private void createBackground() {
setBackground(new Background(Color.BLUE));
}
private void createPhysics(){
physicsWorld = GameActivity.mPhysicsWorld;
}
private void loadLevel(int id){
final LevelLoader levelLoader = new LevelLoader();
final FixtureDef FIXTURE_DEF = PhysicsFactory.createFixtureDef(0, 0.01f, 0.5f);
levelLoader.registerEntityLoader(TAG_LEVEL, new IEntityLoader() {
@Override
public IEntity onLoadEntity(String pEntityName, Attributes pAttributes) {
return GameScene.this;
}
});
levelLoader.registerEntityLoader(TAG_ENTITY, new IEntityLoader() {
@Override
public IEntity onLoadEntity(String pEntityName, Attributes pAttributes) {
final Rectangle levelObject;
final int x = SAXUtils.getIntAttributeOrThrow(pAttributes, TAG_ENTITY_ATTRIBUTE_X);
final int y = SAXUtils.getIntAttributeOrThrow(pAttributes, TAG_ENTITY_ATTRIBUTE_Y);
final int width = SAXUtils.getIntAttributeOrThrow(pAttributes, TAG_ENTITY_ATTRIBUTE_WIDTH);
final int height = SAXUtils.getIntAttributeOrThrow(pAttributes, TAG_ENTITY_ATTRIBUTE_HEIGHT);
final String type = SAXUtils.getAttributeOrThrow(pAttributes, TAG_ENTITY_ATTRIBUTE_TYPE);
if(type.equals(TAG_ENTITY_ATTRIBUTE_TYPE_VALUE_BRICK)){
levelObject = new Rectangle(x, y, width, height, vbom);
Body body = PhysicsFactory.createBoxBody(physicsWorld, levelObject, BodyType.StaticBody, FIXTURE_DEF);
physicsWorld.registerPhysicsConnector(new PhysicsConnector(levelObject, body, true, false));
return levelObject;
} else if(type.equals(TAG_ENTITY_ATTRIBUTE_TYPE_VALUE_PLAYER)){
player = new Rectangle(x, y, width, height, vbom);
playerBody = PhysicsFactory.createBoxBody(physicsWorld, player, BodyType.DynamicBody, FIXTURE_DEF);
physicsWorld.registerPhysicsConnector(new PhysicsConnector(player, playerBody, true, true));
return player;
} else
throw new IllegalArgumentException();
}
});
try {
levelLoader.loadLevelFromAsset(activity.getAssets(), "level/" + id + ".lvl");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
BaseScene:
public abstract class BaseScene extends Scene {
protected ResourcesManager resourcesManager;
protected Engine engine;
Activity activity;
protected Camera camera;
protected VertexBufferObjectManager vbom;
public BaseScene(){
resourcesManager = ResourcesManager.getInstance();
engine = resourcesManager.engine;
activity = resourcesManager.activity;
camera = resourcesManager.camera;
vbom = resourcesManager.vbom;
createScene();
}
// Abstraction
public abstract void createScene();
public abstract void onBackLeyPressed();
public abstract SceneType getSceneType();
public abstract void disposeScene();
}
Layout:
<?xml version="1.0" encoding="utf-8"?>
<level width="1000" height="780">
<entity x="0" y="0" width="20" height="20" type="player"/>
<entity x="100" y="100" width="100" height="30" type="brick"/>
<entity x="200" y="200" width="50" height="30" type="brick"/>
</level>