如何使用cocos2d-android.jar在Cocos2d Android中加载.TMX文件

时间:2013-08-10 10:26:43

标签: android cocos2d-iphone tile tmx

这是我的第一个问题,我在SO中彻底搜索以找到问题的解决方案。但我得到它。 我正在使用cocos2d-android.jar(Cococs2d而不是Cocos2d-x)在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加载和移动Tiled地图的源/链接也很受欢迎。

1 个答案:

答案 0 :(得分:0)

要解决此问题,请从https://github.com/ZhouWeikuan/cocos2d.git获取最新版本的库,构建它或查找已构建的jar。

这是https://code.google.com/p/cocos2d-android-1/issues/detail?id=50解决的问题 干杯! PZ