私はcocos2d-androidを学んでいます。私は、Ray WenderlichのiOSチュートリアルの一部をAndroidに移植したチュートリアルに従っています。私は最初のチュートリアルを終え、次のRay Wenderlichチュートリアルを自分自身でAndroidに変えて学習を続けたいと思っています。cocos2d-android(github版)バックグラウンドレイヤーを移動しているときに、プレーヤーのスプライトを画面の中央に維持するにはどうすればよいですか?
元のiOSチュートリアルでは、ここで見つけることができますのhttp:// WWW raywenderlichコム/ 1163 /ハウツー - メイク・タイルベースのゲーム-で、cocos2d
は私がアンドロイドにアプリケーションを変換していますその振る舞いにいくつかの問題を抱えています。
私のコードはここにある:
パブリッククラスGameLayerは、私が最初に私の表示サイズを取得し、私のTMXファイルから私のタイル張りのマップを作成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!"));
}
}
}
}
を拡張します。私は私の背景レイヤーを取得し、それを子供として追加します。次に、私のオブジェクト層をつかみ、私のスポーンポイントオブジェクトをマップから引き出します(テスト目的のためにこのスポーンポイントを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ます。public void(するCGPointのPOS)」メソッドは、プレーヤーと表示位置を扱うが、私は、彼らが正常に働いているとは思いません。
私の友人はiOSプログラミングを行い、彼のiPhoneでアプリケーションを作成しました。予想どおりに動作していますので、cocos2dのアンドロイドポートにバグがあるかどうか疑問に思っています。
私は中に入って、地図上で右または上に移動し続けると、キャラクターが画面の中央にとどまらない理由について誰もが考えていますか?
入力いただきありがとうございます。私はこのことを理解しようと2日間私の机に頭を打っていました。
あなたの提案に感謝しますが、私はあなたが正しいとは思わない。クリックの目的は、プレイヤーとクリックの距離の差ではなく、クリックの方向に1つのマップタイルを移動することです。それが私のしていることです。 "_map.getTileSize()。width"を使用してマップ全体の幅ではなく、マップ上の単一のタイルの幅(32x32ピクセル)を使用しています。いずれにしても、今夜私が帰宅するとき、私はその変更を行い、それが何か変わるかどうかを見ます。ありがとう! – MySkippy
私はあなたの提案を試みたが、私が探していたものではないと思った。あなたのソリューションは、プレイヤーの元の位置とタッチの違いと同じ距離だけプレイヤーを移動させますが、プレイヤーが画面の中央にとどまらないという問題があります。 画面に触れるたびに1タイル(32ピクセル)ずつ移動します。プレイヤーが画面の中央に達すると、彼は画面の中央に位置したままにしておき、1つのマップタイル(32ピクセル)を反対方向に移動して、プレイヤーが移動したことを暗示します。しかし、ありがとう。 – MySkippy