2012-02-29 53 views
1

我正在学习cocos2d-android的过程。我一直在遵循一个教程,将Ray Wenderlich的一些iOS教程移植到Android上。我已经完成了第一个教程,并希望继续将下一个Ray Wenderlich教程转换为Android,作为学习练习。cocos2d-android(github版本)如何在移动背景图层的同时在屏幕上保持“player”精灵?

原来的iOS教程可以在这里找到HTTP:// WWW raywenderlich COM/1163 /如何对做-A-瓦制游戏与 - 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处。

当我开始向上或向右移动时,会出现问题。一旦我通过屏幕中心,我希望玩家精灵会保持居中在屏幕上,而背景移动的方向与我继续移动时相反。然而,玩家和背景都会移动,因此最终我的玩家会进入屏幕的右侧或顶部边缘,即使剩下大量地图,我也无法再向上或向右移动。

注意到玩家在地图的左上角。

Player reaching the top of screen and not staying centered as expected

通知玩家在地图的右下角。

Player reaching the right of screen and not staying centered as expected

“公布尔ccTouchesEnded(MotionEvent事件)”方法和“setViewPointCentered公共无效(CGPoint POS)”方法处理球员和观点的定位,但我不认为他们能顺利运作。

我的一个朋友做iOS的编程和创建了他的iPhone应用程序,它的工作如预期,所以我不知道是否有在cocos2d的Android的端口的错误。

有没有人对为什么字符不会停留在屏幕上居中,当我到了中继续移动向右,向上或地图上的任何想法?

感谢您提供任何输入。我一直在我的桌子上敲打我的头两天,试图弄清楚这一点。

回答

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); 

现在我的玩家角色仍除非我到达地图的边缘,否则我四处走动时可以看到屏幕的中心。

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; 
    } 
} 
+0

感谢您的建议,但我不相信你是正确的。点击的目的是在玩家点击的方向上移动玩家单个地图平铺,而不是玩家与点击之间的距离差异。在我看来,这就是我正在做的事情。通过使用“_map.getTileSize()。宽度”我在地图上使用单个拼贴的宽度(32x32像素),而不是整个地图的宽度。无论哪种方式,当我今晚回家时,我会做出改变,看看它是否有任何改变。谢谢! – MySkippy 2012-02-29 14:17:22

+0

我试过了你的建议,但是因为我怀疑这不是我正在寻找的东西。您的解决方案会将玩家移动到与玩家初始位置和触摸之间的距离相同的距离,但仍然存在玩家不能保持居中在屏幕上的问题。 我希望玩家每次触摸屏幕时移动1个地图平铺(32像素)。一旦玩家到达屏幕中间,我希望他保持在屏幕中心的位置,我希望地图移动1个地图块(32像素)的方向相反,以暗示玩家移动。不过谢谢。 – MySkippy 2012-03-01 04:57:33

相关问题