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