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,但在其行为方式上遇到了一些问题。

我的代码在这里:

公共类 GameLayer 扩展 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 端口中是否存在错误。

有没有人知道为什么当我到达中间并继续在地图上向右或向上移动时角色不会保持在屏幕中央?

感谢您提供的任何意见。两天来,我一直在用头撞桌子,试图弄清楚这一点。

4

2 回答 2

1

好的,我想通了。

在这段代码中:

// 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 回答