Я в процессе изучения cocos2d-android. Я следовал учебному пособию, которое портировало некоторые учебники Рэя Вендерлиха по iOS на Android. Я закончил первые уроки и хотел продолжить, преобразовав следующий урок Рэя Вендерлиха в Android самостоятельно в качестве упражнения для обучения.
Оригинальное руководство по iOS можно найти здесь http: // www raywenderlich com / 1163 / Как сделать игру на основе плитки с 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)" и метод "public void setViewPointCentered (CGPoint pos)" управляют игроком и позиционированием вида, но я не думаю, что они работают правильно.
Мой друг занимается программированием iOS и создал приложение на своем iPhone, и оно работает, как и ожидалось, поэтому мне интересно, есть ли ошибка в порте android cocos2d.
У кого-нибудь есть идеи о том, почему персонаж не будет оставаться в центре экрана, когда я доберусь до середины и продолжу двигаться вправо или вверх по карте?
Спасибо за любой вклад, который вы можете предоставить. Я два дня бился головой о стол, пытаясь понять это.