2012-02-29 44 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

相關問題