AndEngine の作業を開始し、多くのことを学びましたが、自分のゲームのレベル セレクターの作成に行き詰まっています。ITextureRegion をスプライト オブジェクトにアタッチしようとしたときにこれを経験したので、これは getTextureManager() と関係があることを知っていますが、今回は最終日にどこにも行きません。
mainActivity.java
import org.andengine.engine.camera.Camera;
import org.andengine.engine.options.EngineOptions;
import org.andengine.engine.options.ScreenOrientation;
import org.andengine.engine.options.WakeLockOptions;
import org.andengine.engine.options.resolutionpolicy.FillResolutionPolicy;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.scene.background.Background;
import org.andengine.opengl.font.FontFactory;
import org.andengine.opengl.texture.ITexture;
import org.andengine.opengl.texture.TextureManager;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.andengine.opengl.texture.atlas.bitmap.BuildableBitmapTextureAtlas;
import org.andengine.opengl.texture.atlas.bitmap.source.IBitmapTextureAtlasSource;
import org.andengine.opengl.texture.atlas.buildable.builder.BlackPawnTextureAtlasBuilder;
import org.andengine.opengl.texture.atlas.buildable.builder.ITextureAtlasBuilder.TextureAtlasBuilderException;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.opengl.texture.region.TextureRegion;
import org.andengine.ui.activity.SimpleBaseGameActivity;
import org.andengine.util.color.Color;
import android.graphics.Typeface;
import android.util.Log;
public class Main_Activity extends SimpleBaseGameActivity {
EngineOptions engine;
Camera mCamera;
private static final int WIDTH = 800;
private static final int HEIGHT = 480;
LevelSelector ls;
Scene mScene;
public org.andengine.opengl.font.Font mFont;
ITextureRegion mTextureRegion;
@Override
public EngineOptions onCreateEngineOptions() {
mCamera = new Camera(0, 0, WIDTH, HEIGHT);
engine = new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new FillResolutionPolicy(), mCamera);
engine.setWakeLockOptions(WakeLockOptions.SCREEN_ON);
return engine;
}
@Override
protected void onCreateResources() {
BuildableBitmapTextureAtlas mBitmapTextureAtlas = new BuildableBitmapTextureAtlas(this.getTextureManager() ,32 , 32);
mTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(mBitmapTextureAtlas, this, "marble.png");
try {
mBitmapTextureAtlas.build(new BlackPawnTextureAtlasBuilder<IBitmapTextureAtlasSource, BitmapTextureAtlas>(0, 1, 1));
mBitmapTextureAtlas.load();
} catch (TextureAtlasBuilderException e) {
Log.e("", ""+e);
}
this.mFont = FontFactory.create(this.getFontManager(), this.getTextureManager(), 256, 256, Typeface.create(Typeface.DEFAULT, Typeface.BOLD), 32);
this.mFont.load();
}
@Override
protected Scene onCreateScene() {
mScene = new Scene();
mScene.setBackground(new Background(0.09804f, 0.6274f, 0.8784f));
ls = new LevelSelector(5, 2, WIDTH, HEIGHT, mScene, mEngine);
ls.createTiles(mTextureRegion, mFont);
ls.show();
return mScene;
}
}
LayerSelector.java
import org.andengine.engine.options.EngineOptions;
import org.andengine.entity.Entity;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.sprite.Sprite;
import org.andengine.entity.text.Text;
import org.andengine.input.touch.TouchEvent;
import org.andengine.opengl.font.Font;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.opengl.texture.region.TextureRegion;
import android.service.wallpaper.WallpaperService.Engine;
public class LevelSelector extends Entity {
/* Level selector layer properties */
private final int COLUMNS = 6;
private final int ROWS = 6;
/* Level selector tile properties */
private final int TILE_DIMENSION = 50;
private final int TILE_PADDING = 15;
private final Scene mScene;
private final org.andengine.engine.Engine mEngine;
/*
* The mChapter variable can allow each LevelSelector object to contain
* level tiles which begin levels in different chapters.
*/
private final int mChapter;
/* Variable containing the current max level unlocked */
private final int mMaxLevel;
/* Camera width and height are needed for the layout */
private final int mCameraWidth;
private final int mCameraHeight;
/* Initial x/y coordinates used for tile positioning */
private final float mInitialX;
private final float mInitialY;
/*
* Variable which defines whether the LevelSelector is hidden or visible
*/
private boolean mHidden = true;
/**
* The LevelSelector object can be used to display a grid of level tiles for
* user selection.
*
* @param pMaxLevel
* Current max unlocked level.
* @param pChapter
* Chapter/world number of this particular LevelSelector.
* @param pCameraWidth
* Camera object's width value.
* @param pCameraHeight
* Camera object's height value.
* @param pScene
* The Scene in which the LevelSelector will be displayed on.
* @param pEngine
* AndEngine's mEngine object.
*/
public LevelSelector(final int pMaxLevel, final int pChapter,
final int pCameraWidth, final int pCameraHeight,
final Scene pScene, final org.andengine.engine.Engine pEngine) {
/* Initialize member variables */
this.mScene = pScene;
this.mEngine = pEngine;
this.mChapter = pChapter;
this.mMaxLevel = pMaxLevel;
this.mCameraWidth = pCameraWidth;
this.mCameraHeight = pCameraHeight;
/*
* Obtain the initial tile's X coordinate by subtracting half of the
* entire level selector width including all tiles and padding from the
* center of the Scene
*/
final float halfLevelSelectorWidth = ((TILE_DIMENSION * COLUMNS) + TILE_PADDING
* (COLUMNS - 1)) * 0.5f;
this.mInitialX = (this.mCameraWidth * 0.5f) - halfLevelSelectorWidth;
/* Same math as above applies to the Y coordinate */
final float halfLevelSelectorHeight = ((TILE_DIMENSION * ROWS) + TILE_PADDING
* (ROWS - 1)) * 0.5f;
this.mInitialY = (this.mCameraHeight * 0.5f) + halfLevelSelectorHeight;
mEngine.getTextureManager();
}
/**
* Create the level tiles with a customized ITextureRegion representation as
* well as a customized Font.
*
* @param pTextureRegion
* The ITextureRegion to supply each of the level tiles.
* @param pFont
* The Font to be displayed by Text written on the tiles,
* specifying tile level number for example.
*/
public void createTiles(final ITextureRegion pTextureRegion,
final org.andengine.opengl.font.Font pFont) {
/* Temp coordinates for placing level tiles */
float tempX = this.mInitialX + TILE_DIMENSION * 0.5f;
float tempY = this.mInitialY - TILE_DIMENSION * 0.5f;
/* Current level of the tile to be placed */
int currentTileLevel = 1;
/*
* Loop through the Rows, adjusting tempY coordinate after each
* iteration
*/
for (int i = 0; i < ROWS; i++) {
/*
* Loop through the column positions, placing a LevelTile in each
* column
*/
for (int o = 0; o < COLUMNS; o++) {
final boolean locked;
/* Determine whether the current tile is locked or not */
if (currentTileLevel <= mMaxLevel) {
locked = false;
} else {
locked = true;
}
/* Create a level tile */
LevelTile levelTile = new LevelTile(tempX, tempY, locked,
currentTileLevel, pTextureRegion, pFont);
/*
* Attach the level tile's text based on the locked and
* currentTileLevel variables pass to its constructor
*/
levelTile.attachText();
/* Register & Attach the levelTile object to the LevelSelector */
mScene.registerTouchArea(levelTile);
this.attachChild(levelTile);
/* Increment the tempX coordinate to the next column */
tempX = tempX + TILE_DIMENSION + TILE_PADDING;
/* Increment the level tile count */
currentTileLevel++;
}
/* Reposition the tempX coordinate back to the first row (far left) */
tempX = mInitialX + TILE_DIMENSION * 0.5f;
/* Reposition the tempY coordinate for the next row to apply tiles */
tempY = tempY - TILE_DIMENSION - TILE_PADDING;
}
}
/**
* Display the LevelSelector on the Scene.
*/
public void show() {
/* Register as non-hidden, allowing touch events */
mHidden = false;
/* Attach the LevelSelector the the Scene if it currently has no parent */
if (!this.hasParent()) {
mScene.attachChild(this);
}
/* Set the LevelSelector to visible */
this.setVisible(true);
}
/**
* Hide the LevelSelector on the Scene.
*/
public void hide() {
/* Register as hidden, disallowing touch events */
mHidden = true;
/* Remove the LevelSelector from view */
this.setVisible(false);
}
public class LevelTile extends Sprite {
/*
* The LevelTile should keep track of level number and lock status. Feel
* free to add additional data within level tiles
*/
private final boolean mIsLocked;
private final int mLevelNumber;
private final org.andengine.opengl.font.Font mFont;
private Text mTileText;
/*
* Each level tile will be sized according to the constant
* TILE_DIMENSION within the LevelSelector class
*/
public LevelTile(float pX, float pY, boolean pIsLocked,
int pLevelNumber, ITextureRegion pTextureRegion, org.andengine.opengl.font.Font pFont) {
super(pX, pY, LevelSelector.this.TILE_DIMENSION,
LevelSelector.this.TILE_DIMENSION, pTextureRegion,
LevelSelector.this.mEngine.getVertexBufferObjectManager());
/* Initialize the necessary variables for the LevelTile */
this.mFont = pFont;
this.mIsLocked = pIsLocked;
this.mLevelNumber = pLevelNumber;
}
/* Method used to obtain whether or not this level tile represents a
* level which is currently locked */
public boolean isLocked() {
return this.mIsLocked;
}
/* Method used to obtain this specific level tiles level number */
public int getLevelNumber() {
return this.mLevelNumber;
}
/*
* Attach the LevelTile's text to itself based on whether it's locked or
* not. If not, then the level number will be displayed on the level
* tile.
*/
public void attachText() {
String tileTextString = null;
/* If the tile's text is currently null... */
if (this.mTileText == null) {
/*
* Determine the tile's string based on whether it's locked or
* not
*/
if (this.mIsLocked) {
tileTextString = "Locked";
} else {
tileTextString = String.valueOf(this.mLevelNumber);
}
/* Setup the text position to be placed in the center of the tile */
final float textPositionX = LevelSelector.this.TILE_DIMENSION * 0.5f;
final float textPositionY = textPositionX;
/* Create the tile's text in the center of the tile */
this.mTileText = new Text( textPositionX,
textPositionY, this.mFont,
tileTextString, tileTextString.length(),
LevelSelector.this.mEngine
.getVertexBufferObjectManager());
/* Attach the Text to the LevelTile */
this.attachChild(mTileText);
}
}
@Override
public boolean onAreaTouched(TouchEvent pSceneTouchEvent,
float pTouchAreaLocalX, float pTouchAreaLocalY) {
/* If the LevelSelector is not hidden, proceed to execute the touch
* event */
if (!LevelSelector.this.mHidden) {
/* If a level tile is initially pressed down on */
if (pSceneTouchEvent.isActionDown()) {
/* If this level tile is locked... */
if (this.mIsLocked) {
/* Tile Locked event... */
LevelSelector.this.mScene.getBackground().setColor(
org.andengine.util.color.Color.RED);
} else {
/* Tile unlocked event... This event would likely prompt
* level loading but without getting too complicated we
* will simply set the Scene's background color to green */
LevelSelector.this.mScene.getBackground().setColor(
org.andengine.util.color.Color.GREEN);
/**
* Example level loading:
* LevelSelector.this.hide();
* SceneManager.loadLevel(this.mLevelNumber);
*/
}
return true;
}
}
return super.onAreaTouched(pSceneTouchEvent, pTouchAreaLocalX,
pTouchAreaLocalY);
}
}
}
参考までに、このコードは AndEngine クックブックを使用した Android ゲーム開発のコード バンドルに属します。font や engine などの変数をいくつか編集しましたが、プログラムのロジックやフローは変更していません。
これを実行すると、以下の画面が表示されます