반응형
음, 안드로이드에서 COCOS2D를 쓰면 쓸수록 삽질을 많이 한다.
특히나 아이폰에 맞춰 만들어진 것을 안드로이드용으로 포팅하면서 많은 문제가 아직 남아있다는 걸 느낀다.
지난 게임 관련 포스팅을 할 때 COCOS2D 안드로이드 엔진에 대한 문제를 몇 가지 적어놓았다.
이번에는 드래그 앤 드랍을 안드로이드용으로 하는 소스를 써보려 한다.
아래 소스를 참조하자.
[1]을 보고 만든 것이다. Objective C를 자바 형태로 센스있게 바꾸면서 작업했다.
Objective C에 있는 메소드나 클래스명이 거의 그대로 자바 엔진에 있었다. 메소드명이나 파라미터 형태가 조금 다른게 몇 개 있었지만 나름 잘 짜여져 있었다.
다만 몇 가지 문제가 있었는데.
문제 1. 아이폰에서는 ccTouchesMoved(드래그중 호출되는 메소드) 메소드에서 UITouch라는 클래스의 객체를 받고 이전 터치값을 받아올 수 있지만 안드로이드에서는 이게 빠져있다. 그래서 이전 값을 갖는 부분과 계산해주는 방법을 추가해주었다.
문제 2. Sprite 드래그 앤 드랍을 잘 되었다. 그러나 배경 드래그를 할 때는 좌표값 계산에 문제가 생긴다. 화면위치와 현재 드래그 위치를 계산해주는 convertTouchToNodeSpace 메소드에 문제가 있는 것으로 생각되어서 직접 이 메소드를 구현해 보았지만 웃기게도 똑같은 결과가 나온다. 이 문제는 좌표 계산한 결과값이 오차가 크게 나오면서 배경을 드래그 할 때 배경 위치값이 왔다갔다하면서 화면이 치직거리는듯한 모양을 보여줘버린다.
그래서 이 것을 해결하기 위해서 배경을 드래그 할 떄는 MotionEvent의 값만을 사용해서 계산했다.
힘들게 만든 후에 너무 짜증나서 포스팅하고 싶은 마음도 없었지만, 나 같이 안드로이드이서 COCOS2D 사용하느랴고 고생하는 사람들을 배려하기 위해 포스팅을 한다. 안드로이드 COCOS2D 개발 문서는 정말 너무 없으니까 말이다.
추가로 자체적으로 만들어본 convertMyTouchToNodeSpace메소드. ( convertTouchToNodeSpace와 결과가 같기에 별로 쓸 필요는 없다;)
Reference
[1] iPhone COCOS2D 드래그 앤 드랍 ( http://www.raywenderlich.com/2343/how-to-drag-and-drop-sprites-with-cocos2d )
특히나 아이폰에 맞춰 만들어진 것을 안드로이드용으로 포팅하면서 많은 문제가 아직 남아있다는 걸 느낀다.
지난 게임 관련 포스팅을 할 때 COCOS2D 안드로이드 엔진에 대한 문제를 몇 가지 적어놓았다.
이번에는 드래그 앤 드랍을 안드로이드용으로 하는 소스를 써보려 한다.
아래 소스를 참조하자.
[1]을 보고 만든 것이다. Objective C를 자바 형태로 센스있게 바꾸면서 작업했다.
Objective C에 있는 메소드나 클래스명이 거의 그대로 자바 엔진에 있었다. 메소드명이나 파라미터 형태가 조금 다른게 몇 개 있었지만 나름 잘 짜여져 있었다.
다만 몇 가지 문제가 있었는데.
문제 1. 아이폰에서는 ccTouchesMoved(드래그중 호출되는 메소드) 메소드에서 UITouch라는 클래스의 객체를 받고 이전 터치값을 받아올 수 있지만 안드로이드에서는 이게 빠져있다. 그래서 이전 값을 갖는 부분과 계산해주는 방법을 추가해주었다.
문제 2. Sprite 드래그 앤 드랍을 잘 되었다. 그러나 배경 드래그를 할 때는 좌표값 계산에 문제가 생긴다. 화면위치와 현재 드래그 위치를 계산해주는 convertTouchToNodeSpace 메소드에 문제가 있는 것으로 생각되어서 직접 이 메소드를 구현해 보았지만 웃기게도 똑같은 결과가 나온다. 이 문제는 좌표 계산한 결과값이 오차가 크게 나오면서 배경을 드래그 할 때 배경 위치값이 왔다갔다하면서 화면이 치직거리는듯한 모양을 보여줘버린다.
그래서 이 것을 해결하기 위해서 배경을 드래그 할 떄는 MotionEvent의 값만을 사용해서 계산했다.
힘들게 만든 후에 너무 짜증나서 포스팅하고 싶은 마음도 없었지만, 나 같이 안드로이드이서 COCOS2D 사용하느랴고 고생하는 사람들을 배려하기 위해 포스팅을 한다. 안드로이드 COCOS2D 개발 문서는 정말 너무 없으니까 말이다.
import java.util.ArrayList;
import org.cocos2d.actions.base.CCRepeatForever;
import org.cocos2d.actions.interval.CCRotateBy;
import org.cocos2d.actions.interval.CCRotateTo;
import org.cocos2d.actions.interval.CCSequence;
import org.cocos2d.events.CCTouchDispatcher;
import org.cocos2d.layers.CCColorLayer;
import org.cocos2d.nodes.CCDirector;
import org.cocos2d.nodes.CCSprite;
import org.cocos2d.types.CGPoint;
import org.cocos2d.types.CGRect;
import org.cocos2d.types.CGSize;
import org.cocos2d.types.ccColor4B;
import android.view.MotionEvent;
public class GameLayer extends CCColorLayer {
private CCSprite background;
private CCSprite selSprite;
private ArrayList<CCSprite> movableSprites;
private CGPoint oldTouchLocation = CGPoint.zero();
private CGSize winSize;
GameLayer(ccColor4B color) {
super(color);
// get View Size
winSize = CCDirector.sharedDirector().winSize();
// set Background
background = CCSprite.sprite("bg_game.jpg");
background.setAnchorPoint(CGPoint.make(0.0F, 0));
background.setPosition(0, 0);
this.addChild(background, 0);
// init
movableSprites = new ArrayList<CCSprite>();
//
for(int i=1; i < 5; i++) {
CCSprite sprite = CCSprite.sprite("icon.png");
sprite.setAnchorPoint(CGPoint.zero());
sprite.setPosition(i * 100, winSize.height/2);
this.addChild(sprite, 1);
movableSprites.add(sprite);
}
this.setIsTouchEnabled(true);
CCTouchDispatcher.sharedDispatcher().addTargetedDelegate(this, 0, true);
}
public void selectSpriteForTouch(CGPoint touchLocation) {
CCSprite newSprite = null;
for (CCSprite sprite : movableSprites) {
if (CGRect.containsPoint(sprite.getBoundingBox(), touchLocation)) {
newSprite = sprite;
break;
}
}
if (newSprite != selSprite) {
if(selSprite != null) {
selSprite.stopAllActions();
selSprite.runAction(CCRotateTo.action(0.1F, 0));
}
if(newSprite != null) {
CCRotateBy rotLeft = CCRotateBy.action(0.1F, -4.0F);
CCRotateBy rotCenter = CCRotateBy.action(0.1F, 0.0F);
CCRotateBy rotRight = CCRotateBy.action(0.1F, 4.0F);
CCSequence rotSeq = CCSequence.actions(rotLeft, rotCenter, rotRight, rotCenter);
newSprite.runAction(CCRepeatForever.action(rotSeq));
}
selSprite = newSprite;
}
}
public CGPoint boundLayerPos(CGPoint newPos) {
CGSize winSize = CCDirector.sharedDirector().winSize();
CGPoint retval = newPos;
retval.x = Math.min(retval.x, 0);
retval.x = Math.max(retval.x, - background.getContentSize().width+winSize.width);
retval.y = this.position_.y;
return retval;
}
public void panForTranslation(CGPoint translation) {
if (selSprite != null) {
CGPoint newPos = CGPoint.ccpAdd(selSprite.getPosition(), translation);
selSprite.setPosition(newPos);
} else {
CGPoint newPos = CGPoint.ccpAdd(this.position_, translation);
this.setPosition(boundLayerPos(newPos));
}
}
@Override
public boolean ccTouchesMoved(MotionEvent event) {
CGPoint touchLocation, translation;
if(selSprite == null) {
// background
touchLocation = CGPoint.ccp(event.getX(), event.getY());
} else {
// sprite
touchLocation = convertTouchToNodeSpace(event);
}
translation = CGPoint.ccpSub(touchLocation, oldTouchLocation);
panForTranslation(translation);
oldTouchLocation = touchLocation;
return true;
}
@Override
public boolean ccTouchesBegan(MotionEvent event) {
CGPoint touchLocation = this.convertTouchToNodeSpace(event);
selectSpriteForTouch(touchLocation);
if(selSprite == null) {
oldTouchLocation.set(event.getX(), event.getY());
} else {
oldTouchLocation.set(selSprite.getPosition().x, selSprite.getPosition().y);
}
return true;
}
}
GameLayer.java
추가로 자체적으로 만들어본 convertMyTouchToNodeSpace메소드. ( convertTouchToNodeSpace와 결과가 같기에 별로 쓸 필요는 없다;)
private CGPoint convertMyTouchToNodeSpace(MotionEvent event) {
CGPoint eventPoint = CGPoint.ccp(event.getX(), winSize.height - event.getY());
CGPoint curPoint = getPosition();
curPoint.set(-curPoint.x, curPoint.y);
return CGPoint.ccpAdd(curPoint, eventPoint);
}
Reference
[1] iPhone COCOS2D 드래그 앤 드랍 ( http://www.raywenderlich.com/2343/how-to-drag-and-drop-sprites-with-cocos2d )
반응형
'Devlopment > Mobile' 카테고리의 다른 글
COCOS2D-X 윈도우에서 신규 솔루션으로 만들기 (0) | 2012.02.03 |
---|---|
COCOS2D-X 설치 (윈도우) (4) | 2012.02.03 |
[안드로이드 게임 개발] 1. 시작과 시행착오 (6) | 2012.01.27 |
Cocos2d를 이용하영 FPS 출력하는 기본 소스 (0) | 2012.01.25 |
안드로이드(Android) OnGestureListener 사용법 (0) | 2011.12.27 |
안드로이드에서 OpenGL ES를 사용하는 GLSurfaceView의 기본 골격 (0) | 2011.12.27 |
안드로이드 View, SurffaceView를 사용하는 기본 골격 (0) | 2011.12.18 |
안드로이드 게임 엔진 (1) | 2011.12.01 |
안드로이드 앱 'SD 카드로 이동', '디바이스로 이동' 기능 (0) | 2011.10.14 |
안드로이드 여러 버전의 APK 배포 (0) | 2011.10.14 |