1

私はcocos2d-androidを学習中です。Ray Wenderlich の iOS チュートリアルの一部を Android に移植したチュートリアルに従っています。私は最初のチュートリアルを完了しました。次の Ray Wenderlich チュートリアルを学習の演習として自分で Android に変換して続行したいと考えていました。

元の iOS チュートリアルは、http://www raywenderlich com/1163/how-to-make-a-tile-based-game-with-cocos2d にあります。

アプリケーションを Android に変換しましたが、動作に問題があります。

私のコードはここにあります:

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 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("TileMap.tmx");
    _background = _map.layerNamed("Background");
    _objects = _map.objectGroupNamed("Objects");

    // Add my background layer
    // TODO: Position layer in the correct spot.
    addChild(_background);

    _spawnPoint = _objects.objectNamed("SpawnPoint");

    _player = CCSprite.sprite("Player3.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!"));
        }
    }
}

}

まず、表示サイズを取得し、TMX ファイルからタイル マップを作成します。背景レイヤーを取得し、子として追加します。次に、オブジェクト レイヤーを取得し、スポーン ポイント オブジェクトをマップから引き出します (テスト目的で、このスポーン ポイントを 100、100 でオーバーライドします)。プレイヤー スプライトをつかみ、プレイヤーの位置を 100, 100 座標に設定します。次に、プレーヤーを子として追加します。

次に、setViewPointCentered を呼び出して、プレイヤーの位置に基づいてマップを適切な位置に移動します。この部分は問題なく動作し、マップは左下隅 (0,0) が画面の左下隅 (0,0) に配置され、キャラクターは画面の中心からわずかに左と下の 100,100 に配置されます。 .

問題は、上または右に移動し始めたときに発生します。画面の中心を通過すると、プレーヤーのスプライトが画面の中心に留まり、移動を続けると背景が反対方向に移動することが期待されます。ただし、プレーヤーと背景の両方が移動するため、最終的にプレーヤーが画面の右端または上端に移動し、マップがたくさん残っているにもかかわらず、上または右に移動できなくなります。

マップの左上隅にいるプレイヤーに注目してください。

プレーヤーが画面の上部に到達し、期待どおりに中央に留まらない

マップの右下隅にいるプレイヤーに注目してください。

プレーヤーが画面の右側に到達し、期待どおりに中央に留まらない

「public boolean ccTouchesEnded(MotionEvent event)」メソッドと「public void setViewPointCentered(CGPoint pos)」メソッドは、プレーヤーとビューの位置を処理しますが、正しく機能しているとは思いません。

私の友人は iOS プログラミングを行っており、彼の iPhone でアプリを作成しましたが、期待どおりに動作しているので、cocos2d の Android ポートにバグがあるのではないかと思っています。

中央に到達してマップ上で右または上に移動し続けると、キャラクターが画面の中央に留まらない理由について何か考えがある人はいますか?

ご提供いただけるご意見をお寄せいただきありがとうございます。私はこれを理解しようとして、2日間机に頭をぶつけてきました。

4

2 に答える 2

1

OK私はそれを理解しました。

このコードでは、次のようになります。

// Get TMX Map and associated layers/groups
_map = CCTMXTiledMap.tiledMap("TileMap.tmx");
_background = _map.layerNamed("Background");
_objects = _map.objectGroupNamed("Objects");

// Add my background layer
// TODO: Position layer in the correct spot.
addChild(_background);

_backgroundレイヤーを追加していますが、本当にやりたいのは、代わりに_mapを追加することです。

// Get TMX Map and associated layers/groups
_map = CCTMXTiledMap.tiledMap("TileMap.tmx");
_background = _map.layerNamed("Background");
_objects = _map.objectGroupNamed("Objects");

// Add my background layer
// TODO: Position layer in the correct spot.
addChild(_map);

これで、マップの端に到達しない限り、歩き回っている間、プレイヤーキャラクターは表示可能な画面の中央に留まります。

于 2012-03-02T04:59:31.003 に答える
0

タッチが終了するたびに、プレイヤーは mapWidth または height だけ移動します。diffで位置を移動する必要があります。試す

CGPoint diff = CGPoint.ccpSub(touchLocation, playerPosition);

if (Math.abs(diff.x) > Math.abs(diff.y)) {
    if (diff.x > 0) {
        playerPosition.x += diff.x;
    } else {
        playerPosition.x -= diff.x;
    }
} else {
    if (diff.y > 0) {
        playerPosition.y += diff.y;
    } else {
        playerPosition.y -= diff.y;
    }
}
于 2012-02-29T06:12:11.427 に答える