これは私の最初の質問であり、問題の解決策を見つけるために SO を徹底的に検索しました。しかし、私はそれを理解していません。cocos2d-android.jar (Cocos2d-x ではなく Cococs2d) を使用して Android でデモ ゲームを開発しています。以下は、TMX ファイルをロードするための私の Java コードです。
public class GameLayer extends CCLayer {
private CGSize _winSize;
protected ArrayList<CCSprite> _targets;
protected ArrayList<CCSprite> _projectiles;
protected int _projectilesDestroyed;
protected CCSprite _player;
protected CCSprite _nextProjectile;
protected CCTMXTiledMap _map;
protected CCTMXLayer _background;
protected CCTMXLayer _foreground;
protected CCTMXLayer _meta;
protected CCTMXObjectGroup _objects;
protected HashMap<String, String> _spawnPoint;
protected GameLayer() {
super();
_winSize = CCDirector.sharedDirector().displaySize();
_targets = new ArrayList<CCSprite>();
_projectiles = new ArrayList<CCSprite>();
_projectilesDestroyed = 0;
// Get TMX Map and associated layers/groups
_map = CCTMXTiledMap.tiledMap("MyTiledMap.tmx"); // The app is crashing at this line
_background = _map.layerNamed("Background");
_foreground = _map.layerNamed("Foreground");
_meta = _map.layerNamed("Meta");
_meta.setVisible(false);
_objects = _map.objectGroupNamed("Objects");
if(_objects == null){
Log.e("BoxAway", "Tile map has no objects..");
}
// Add my background layer
// TODO: Position layer in the correct spot.
// addChild(_background);
addChild(_map);
_spawnPoint = _objects.objectNamed("SpawnPoint");
_player = CCSprite.sprite("player.png");
setPlayerPosition(CGPoint.ccp(100.0f, 100.0f));
addChild(_player);
setViewPointCentered(_player.getPosition());
Context context = CCDirector.sharedDirector().getActivity();
/*SoundEngine.sharedEngine().preloadEffect(context, R.raw.pew_pew_lei);
SoundEngine.sharedEngine().playSound(context,
R.raw.background_music_aac, true);*/
this.setIsTouchEnabled(true);
this.schedule("update");
}
public void setViewPointCentered(CGPoint pos) {
float x = 0.0f;
float y = 0.0f;
x = Math.max(pos.x, _winSize.width / 2);
y = Math.max(pos.y, _winSize.height / 2);
x = Math.min(x, (_map.getMapSize().width * _map.getTileSize().width)
- _winSize.width / 2);
y = Math.min(y, (_map.getMapSize().height * _map.getTileSize().height)
- _winSize.height / 2);
CGPoint actualPos = CGPoint.ccp(x, y);
CGPoint centerOfView = CGPoint.ccp(_winSize.width / 2,
_winSize.height / 2);
CGPoint viewPoint = CGPoint.ccpSub(centerOfView, actualPos);
_background.setPosition(viewPoint);
}
public static CCScene scene() {
CCScene scene = CCScene.node();
CCLayer layer = new GameLayer();
scene.addChild(layer);
return scene;
}
@Override
public boolean ccTouchesBegan(MotionEvent event) {
return true;
}
void setPlayerPosition(CGPoint position) {
_player.setPosition(position);
}
@Override
public boolean ccTouchesEnded(MotionEvent event) {
// Choose one of the touches to work with
CGPoint touchLocation = CGPoint.ccp(event.getX(), event.getY());
touchLocation = CCDirector.sharedDirector().convertToGL(touchLocation);
touchLocation = this.convertToNodeSpace(touchLocation);
CGPoint playerPosition = _player.getPosition();
CGPoint diff = CGPoint.ccpSub(touchLocation, playerPosition);
if (Math.abs(diff.x) > Math.abs(diff.y)) {
if (diff.x > 0) {
playerPosition.x += _map.getTileSize().width;
} else {
playerPosition.x -= _map.getTileSize().width;
}
} else {
if (diff.y > 0) {
playerPosition.y += _map.getTileSize().height;
} else {
playerPosition.y -= _map.getTileSize().height;
}
}
if (playerPosition.x <= (_map.getMapSize().width * _map.getTileSize().width)
&& playerPosition.y <= (_map.getMapSize().height * _map
.getTileSize().height)
&& playerPosition.y >= 0
&& playerPosition.x >= 0) {
setPlayerPosition(playerPosition);
}
setViewPointCentered(_player.getPosition());
return true;
}
public void finishShoot() {
addChild(_nextProjectile);
_projectiles.add(_nextProjectile);
}
public void update(float dt) {
ArrayList<CCSprite> projectilesToDelete = new ArrayList<CCSprite>();
for (CCSprite projectile : _projectiles) {
CGRect projectileRect = CGRect.make(projectile.getPosition().x
- (projectile.getContentSize().width / 2.0f),
projectile.getPosition().y
- (projectile.getContentSize().height / 2.0f),
projectile.getContentSize().width,
projectile.getContentSize().height);
ArrayList<CCSprite> targetsToDelete = new ArrayList<CCSprite>();
for (CCSprite target : _targets) {
CGRect targetRect = CGRect.make(target.getPosition().x
- (target.getContentSize().width),
target.getPosition().y
- (target.getContentSize().height),
target.getContentSize().width,
target.getContentSize().height);
if (CGRect.intersects(projectileRect, targetRect)) {
targetsToDelete.add(target);
}
}
for (CCSprite target : targetsToDelete) {
_targets.remove(target);
removeChild(target, true);
}
if (targetsToDelete.size() > 0) {
projectilesToDelete.add(projectile);
}
}
/*for (CCSprite projectile : projectilesToDelete) {
_projectiles.remove(projectile);
removeChild(projectile, true);
if (++_projectilesDestroyed > 30) {
_projectilesDestroyed = 0;
CCDirector.sharedDirector().replaceScene(
GameOverLayer.scene("You Win!"));
}
}*/
}
以下は私の「MyTiledMap.tmx」ファイルです。
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.0" orientation="orthogonal" width="50" height="20" tilewidth="32" tileheight="32">
<tileset firstgid="1" name="tmw_desert_spacing" tilewidth="32" tileheight="32" spacing="1" margin="1">
<image source="tmw_desert_spacing.png" width="265" height="199"/>
</tileset>
<tileset firstgid="49" name="meta_tiles" tilewidth="32" tileheight="32" spacing="1" margin="1">
<image source="meta_tiles.png" width="67" height="34"/>
<tile id="0">
<properties>
<property name="Collidable" value="True"/>
</properties>
</tile>
<tile id="1">
<properties>
<property name="Collectable" value="True"/>
</properties>
</tile>
</tileset>
<layer name="Background" width="50" height="20">
<data encoding="base64" compression="zlib">
eJzjZ2Bg4B/Fo3gUj+JRPIpH8SgexaOYAOaC4oF2B739QYp6LjLMH6r+wCVPSJ8eheZgEyeklhb+UBrFo5gGGACGu0Ur
</data>
</layer>
<objectgroup name="Objects" width="50" height="20">
<object name="SpawnPoint" x="1578" y="519"/>
</objectgroup>
<layer name="Foreground" width="50" height="20">
<data encoding="base64" compression="zlib">
eJztzKERAAAIAkA3cf8t7SaCZ/qPwFEFAADwq8PsYru7ZJN+wqUBEIEBGA==
</data>
</layer>
<layer name="Meta" width="50" height="20">
<data encoding="base64" compression="zlib">
eJzt0EsKACAIRVG3pPtfXJMGEYoKUQT3wJukfUwEAAAAyOnM77pzdPpV7v3T6zmievUec/ptqWfrnd69Fu2tvMs7m5BTGRCqJSw=
</data>
</layer>
</map>
プロジェクトを実行すると、次の Logcat スタック トレースでクラッシュします。
08-10 15:38:27.433: E/AndroidRuntime(500): FATAL EXCEPTION: main
08-10 15:38:27.433: E/AndroidRuntime(500): java.lang.RuntimeException: Unable to start activity ComponentInfo{application.pidex.src.boxaway/application.pidex.src.boxaway.MainActivity}: java.lang.IndexOutOfBoundsException
08-10 15:38:27.433: E/AndroidRuntime(500): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
08-10 15:38:27.433: E/AndroidRuntime(500): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
08-10 15:38:27.433: E/AndroidRuntime(500): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
08-10 15:38:27.433: E/AndroidRuntime(500): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
08-10 15:38:27.433: E/AndroidRuntime(500): at android.os.Handler.dispatchMessage(Handler.java:99)
08-10 15:38:27.433: E/AndroidRuntime(500): at android.os.Looper.loop(Looper.java:123)
08-10 15:38:27.433: E/AndroidRuntime(500): at android.app.ActivityThread.main(ActivityThread.java:3683)
08-10 15:38:27.433: E/AndroidRuntime(500): at java.lang.reflect.Method.invokeNative(Native Method)
08-10 15:38:27.433: E/AndroidRuntime(500): at java.lang.reflect.Method.invoke(Method.java:507)
08-10 15:38:27.433: E/AndroidRuntime(500): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
08-10 15:38:27.433: E/AndroidRuntime(500): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
08-10 15:38:27.433: E/AndroidRuntime(500): at dalvik.system.NativeStart.main(Native Method)
08-10 15:38:27.433: E/AndroidRuntime(500): Caused by: java.lang.IndexOutOfBoundsException
08-10 15:38:27.433: E/AndroidRuntime(500): at java.nio.IntToByteBufferAdapter.get(IntToByteBufferAdapter.java:147)
08-10 15:38:27.433: E/AndroidRuntime(500): at org.cocos2d.layers.CCTMXLayer.setupTiles(CCTMXLayer.java:310)
08-10 15:38:27.433: E/AndroidRuntime(500): at org.cocos2d.layers.CCTMXTiledMap.parseLayer(CCTMXTiledMap.java:212)
08-10 15:38:27.433: E/AndroidRuntime(500): at org.cocos2d.layers.CCTMXTiledMap.<init>(CCTMXTiledMap.java:143)
08-10 15:38:27.433: E/AndroidRuntime(500): at org.cocos2d.layers.CCTMXTiledMap.tiledMap(CCTMXTiledMap.java:115)
08-10 15:38:27.433: E/AndroidRuntime(500): at application.pidex.src.boxaway.GameLayer.<init>(GameLayer.java:44)
08-10 15:38:27.433: E/AndroidRuntime(500): at application.pidex.src.boxaway.GameLayer.scene(GameLayer.java:101)
08-10 15:38:27.433: E/AndroidRuntime(500): at application.pidex.src.boxaway.MainActivity.onStart(MainActivity.java:45)
08-10 15:38:27.433: E/AndroidRuntime(500): at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1129)
08-10 15:38:27.433: E/AndroidRuntime(500): at android.app.Activity.performStart(Activity.java:3791)
08-10 15:38:27.433: E/AndroidRuntime(500): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1620)
08-10 15:38:27.433: E/AndroidRuntime(500): ... 11 more
誰かが私を正しい方向に向けることができますか? Android で cocos2d を使用したタイル マップの読み込みと移動を示す他のソース/リンクも歓迎します。