Total587,633
Today2
Yesterday7

카테고리

분류 전체보기 (437)
예찬+상빈 아들만 둘!.. (0)
IT, Gadget (90)
DEV life (30)
테마게시판 (0)
Life (47)
사진이 있는 이야기 (73)
30대의 유희 (196)
오늘뭐먹지 (0)

최근에 받은 트랙백

블로그 이미지
jakesoul
좁지만,제이크씨의문화살롱

달력

« » 2019.8
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

최근에 달린 댓글

Three20

DEV life/DEV.mobile / 2009.09.24 00:53
Joe Hewitt 이라는 사람이 만든 iPhone UI 라이브러리로, 요새 iPhone용 화보 어플을 하나 만들일이 있어서(외주) 쓸만한 샘플 찾다가 발견한 주옥같은 라이브러리다.

http://groups.google.com/group/three20/


원래 Facebook용 어플을 만들기 위한 것이었다는데... 배포되는 소스에 포함된 샘플만으로 이미지/뷰 제어에 대한 거의 완벽한(UI things나 최적화 등을 제외하고) 솔루션에 가깝다. thumbnail이나 table 등은 기본, flickrs에서 url 받아서 이미지 로딩해서 그려줄수도 있고.

appStore에서 비키니 란제리 섹시 등의 키워드(물론 영어로ㅡ,.ㅡ)로 검색하면 핫한 사진을 모아놓은 화보집들이 엄청 나오는데(이미 레드오션) 그중 중국계 개인 개발자가 웹상에 돌아다니는 핫한 사진들을 임의로 모아서 엄청나게 어플을 찍어대고 있는데... 얼핏 봐도 이 왕서방이 쓰는 것이 바로 이 Three20 인듯으로 보인다. 그냥 샘플코드에 사진만 바꿔 넣어도 이미 어플로서의 기능은 완벽하다 이거죠.

하지만 정작 난 이것을 쓰지 않는다.ㅡ,.ㅡ

기본적으로 UIView 등 cocoa에서 제공하는 framework에 기반한 라이브러리라... 기본적인 것들을 바꿀려고 해도 큰(혹은 귀찮은) 작업이 되어버린다. 그냥 opengl-es로 대충 512*512 짜리 Texture 잡아서 뿌려버렸다...ㅡ,.ㅡ


Posted by jakesoul

wipi 규약상, wipi-c (clet)는 메모리 컴팩션을 하도록 되어 있습니다. 따라서 포인터를 직접 사용할 수 없고-컴팩션이 일어날때 마다 메모리 내용이 싹 바뀌니까요-동적으로 할당한 메모리 블럭에 각각 memID를 부여해 그것을 통하여 간접 참조를 하도록 하고 있습니다. 따라서 기존의 c/c++ 개발방식 그대로 만들 수 없다는 문제가 뒤따릅니다. 이는 코드의 이식성과 유연성에 매우 치명적인 결함이며, 솔까말 다 const array로 박아버리고 싶을만큼 할당할 때 마다 귀찮아 죽겠습니다.

 

(그런데 여기서 재미있는 것은 SKT clet은 메모리 컴팩션이 일어나지 않습니다. wipi 규약을 제대로 지켜지 않았지만 그것이 오히려 개발 사이드에서는 장점이군요.)

 

인터넷 검색을 해보면 많은 wipi 개발자들이 이러한 메모리 컴팩션을 일어나지 않게 하는 방법에 대해 여기저기 묻고 다닌 흔적을 쉽게 볼 수 있습니다. 저 역시 그 중 하나였구요.

 

오늘 motive q&a에서 발췌한 하나의 아티클.

 

 

KTF WIPI 1.2 API 에서는 다음의 메모리 관리 API 가 추가되었습니다.
API 문서 4.3메모리 관리 API 를 확인 하세요.
기존 WIPI C 의 메모리 동적 할당 /해제 API 는 Garbage Collection 이나 Memeory
Compaction 에 의해 절대위치가 변경될 수 있으므로, 새롭게 메모리 절대 번지에 접근할수 있도록 하는 API 를 제공하여 기 구현된 C 솔루션들의 WIPI 플랫폼으로의 포팅을 용이하도록 한다.
typedef struct _MC_UserMemInterface
{
    M_Int32 (*memInit)(void* heapBase, M_Int32 size);
    void* (*memAlloc)(void* heapBase, M_Int32 size);
    void* (*memCalloc)(void* heapBase, M_Int32 numMember, M_Int32 size);
    void (*memFree)(void* heapBase, void* memPtr);
}
MC_UserMemInterface;
<사용법>
WIPIHeader.h 파일 MXUserMemMgr.h 을 주석을 풀어준다. 
#include "MXUserMemMgr.h"
//#include "sys/MXUserMemMgr.h"

 

 

'DEV life > DEV.mobile' 카테고리의 다른 글

Three20  (0) 2009.09.24
SKT의 앱스토어, T-STORE 오픈. 그러나..  (0) 2009.09.09
KTF clet 어플 구현시 메모리 컴팩션 방지  (0) 2009.09.08
날로 먹는 iPhone dev 일기 #5  (0) 2009.08.01
날로 먹는 iPhone dev 일기 #4  (0) 2009.06.19
SKT 앱스토어 오픈  (0) 2009.06.09
Posted by jakesoul

궁금하신 분은 없겠지만, 오랜만에 올리는 소리소문없이 제작중인ㅡ,.ㅡ 제 첫번째 app, 코드명 AHR 소식입니다. 이거 뭐 개발한다고 끄적거린지 4개월이 넘었는데... 아직도 런칭을 못시켜서 낯이 뜨겁네요.ㅎㅎ 슬로우스타터라는 말처럼 처음엔 좀 더뎌도 후에 꾸준히 app이 나오면 좋겠습니다.ㅎㅎ



ADC개발자 등록을 마치고, 개발중인 버전을 실기 테스트 해보았습니다. (보안유지한다고 블러처리한 것은 아니고..ㅡ,.ㅡ 5~6년전 개발했던 게임 이미지를 임시로 차용중이라 창피해서 블러를 먹였습니다.)

컨셉이 한손으로 원활히 플레이하도록 하는 것이라, 요새 유행하는 아날로그 스틱형태의 가상 컨트롤러 대신 좌우 버튼을 심었는데... 이것을 좌우 방향 동시에 눌렀을 때 뿌라스 마이너스 되어서 가만히 있는 것보다, pc키보드에서 여러키 누를때의 느낌(A를 누르다가 B를 누르면 A무시되고 B만 찍히는...)을 살려볼려고 간단하게 멀티터치 처리를 해놓았었는데, 그것이 문제가 좀 있네요. 그냥 빼야할 듯.ㅡ,.ㅡ

현재까지의 공정은 기획 90%, 개발 80% 이상이고, 그래픽 외주는 다음주부터 스타트 되어 8월 중순에 끝납니다. 이미지 다 나오면 바로 릴리즈 가능할 듯 하네요. 아, 사운드가 좀 고민입니다. 얼마 안되는 인맥풀을 한번 가동해봐야겠군요.

to do:
  • 사운드 기획
  • 사운드 외주 발주
  • 게임오버 후 랭킹 화면 구현
  • lite-paid version 구분
  • level balance



Posted by jakesoul

본문과 상관 없는 회사에서 진행하는 프로젝트 스샷

게임이건 어플이건 오토바이건 자동차건 아가씨건 총각이건 역시 중요한 것은 look.

디자이너 없이 허접한 이미지 가져다 붙여 쓰다보니 개발하는 입장에서 흥도 안나고, 중간중간 스샷 찍어 포스팅할 수준도 아니고 해서... (자질구레한 update에 대해서는 별도로 트위팅을 하고 있습니다만) 포스트는 참으로 오랜만입니다.

windows + vc로 개발 환경을 옮겼습니다. (opengles -> opengl
이제, 소스 구현을 어느 정도 끝내고 실기 테스트를 할 때 맥을 켜도 될 것 같습니다. =)


어제 국내 모 개발사를 방문해서 이야기를 할 기회가 있었는데 여러가지 생각을 하게 되었습니다.


  • 무료어플의 성공적인 다운로드가, 물론 고무적인 결과이긴하지만, 유료 버전 제품의 마케팅 데이타로 사용될 수 있을까
  • 0.99$, 외국(미국)인들에게 속된말로 껌값과도 같다고 하지만, 맛있는 껌이 저렇게 많은데 맛없는 껌을 누가 먹겠는가
  • 기능성 게임이 제휴 마케팅 혹은 정책적 지원 등을 배제하고 시장에서 성공할 수 있을까? 아, 카테고리를 게임으로 안하면 되려나?
  • 경험, 노하우, 프로세스. 자본보다 사람이 중요한 이유다.



Posted by jakesoul

http://www.mysmart.co.kr/app/index.jsp

  • url이름처럼, wm 어플들뿐이군요. featured-phone용은 다른 url로 팔려는 것인가? 어쨌거나 페이지 전체를 플래쉬로 만들어주는 센스!-,.- (tworld가 이런식이어서 몇년 전에 skt와 다툼이 좀 있었습죠..-,.-)
  • 아직 유료 어플은 두 개뿐이고 나머지는 다 무료 어플입니다. 개인이 만든 것 같은 (아마추어 냄새짙은) 어플 들도 있지만 전체적으로 오픈마켓이라기보다는 기존에 있던 wm 어플을 파는 듯한 느낌인데…
  • 게임 카테고리는 없습니다. 등급심사 문제 때문에 당장 열리긴 쉽지 않을 듯…

근데 국내 스마트폰 사용자가 몇이죠…?-_- 취미로 블랙잭 중고로 하나 사서 개발이나 해볼까 생각이 듭니다.

'DEV life > DEV.mobile' 카테고리의 다른 글

날로 먹는 iPhone dev 일기 #5  (0) 2009.08.01
날로 먹는 iPhone dev 일기 #4  (0) 2009.06.19
SKT 앱스토어 오픈  (0) 2009.06.09
SKT 앱스토어 어플 공모전  (4) 2009.05.11
날로 먹는 iPhone dev 일기 #3  (2) 2009.05.06
SKT의 앱스토어, 성공할까?  (26) 2009.04.14
Posted by jakesoul

★http://developer.itopping.co.kr/contest <- 자세한 것은 이곳을 참고하세요.

참여자 혜택을 보고 알게된 것 :
 - 개발자 등록비를 받는구나
 - 검증 수수료도 받는구나?!!



아무튼, 특별상을 제외하고 총 1억 2천만원의 상금이 52명에게 나눠(?)지네요. 상금 규모가 큰건 아니지만... 경험을 쌓는다 생각하면 한번쯤 도전해도 좋지 않을까 싶네요.

'DEV life > DEV.mobile' 카테고리의 다른 글

날로 먹는 iPhone dev 일기 #4  (0) 2009.06.19
SKT 앱스토어 오픈  (0) 2009.06.09
SKT 앱스토어 어플 공모전  (4) 2009.05.11
날로 먹는 iPhone dev 일기 #3  (2) 2009.05.06
SKT의 앱스토어, 성공할까?  (26) 2009.04.14
2D 프레임버퍼의 제어  (2) 2009.04.07
Posted by jakesoul

근황:

현재 기본적인 어플리케이션 프레임과 각종 필요 API등은 어느 정도 작업이 끝난 상태입니다. (오래 걸렸죠...-_-;;)

이제 보다 근본적인 문제에 부딪혔는데, 그것은 바로 리소스를 가공할 툴을 만드는 것과, 어떻게 프로젝트를 매니징/프로듀스할 것이냐 하는 것들입니다.

필요인력을 수급하고 프로젝트를 관리하는 것은 사실 여기서 다루긴 어려운 문제고,

리소스를 가공할 툴..같은 경우는 cocoa 개발에 대한 소양이 깊지 못한 관계로 천상 wintel 플랫폼에서 작업을 하기로 결정했습니다. 결국 맥을 메인으로 쓰는 것은 또 다시 철회, 한동안 치워두었던 wintel 머신을 다시 들여놨습니다. (cpu가 amdx2 쿠마인데, 한밤중에 작업하고 있으면 지금 내가 시카고행 대한항공 보잉747기 이코노미석에 앉아 있는 느낌도 납니다. 저는 미쿡에 가본적이 없다능)

이왕 맥과 wintel 머신을 병행하기로 한 이상, 장기적으로 windows에 아예 cygwin따위로 iPhone 개발 환경을 구축하는 것도 고려중입니다. 집에 모니터가 달랑 하나라 아무래도 (노트북이 아닌)컴퓨터 두대에서 와리가리 하는 것도 귀찮을 테니까요. 그럼 대체 맥은 왜 산거지...? (-_-)





'DEV life > DEV.mobile' 카테고리의 다른 글

SKT 앱스토어 오픈  (0) 2009.06.09
SKT 앱스토어 어플 공모전  (4) 2009.05.11
날로 먹는 iPhone dev 일기 #3  (2) 2009.05.06
SKT의 앱스토어, 성공할까?  (26) 2009.04.14
2D 프레임버퍼의 제어  (2) 2009.04.07
날로 먹는 iPhone dev 일기 #2  (0) 2009.04.07
Posted by jakesoul
주위에서 관련 질문을 해주신 분이 계셔서... 이전에 포스팅했던 내용을 보여드릴랬더니만, 일전에 포스트가 단체로 안드로메다 사생대회 가는 바람에 다 지워진 모양입니다.

이왕 포스트 하는 김에, 추가로 몇개 더 턱턱 붙여서 올립니다. 이전처럼 자세한 설명은 시간관계상 생략하겠습니다.-_-;; 코드의 세련미, 효율성이나 가독성은 여기서는 고려치 않았습니다.

##화면의 확대
: 화면을 주어진 배율로 확대합니다. 이 때 배율은 1, 2, ..., n 등 정수 뿐만 아니라, x1.2, x1.8, x2.7 등 실수배도 가능토록 합니다. 입력될 배율의 표현은 두개의 정수[int zoom_mul, int zoom_div]로 받겠습니다.

rate = mul / div;

void *frameBuffer;  //#### pointer of frame Buffer
void *destBuffer;   //#### copy of frame Buffer

//#### zoom rate = int zoom_mul / int zoom_div, zoom_div != 0
//#### scrWidth = width of screen
//#### scrHeight = width of screen

//#### Make destBuffer that will contains cropped frameBuffer
//#### ===============================
//#### 현재 frameBuffer의 중앙으로부터, 확대되어 화면에 뿌려질 부분만을 cropping 합니다.

const int DESTBUFFER_START_X_OFFSET
= (scrWidth * zoom_mul / zoom_div - scrWidth) / (2 * zoom_mul / zoom_div);
const int DESTBUFFER_START_Y_OFFSET 
= (scrHeight * zoom_mul / zoom_div - scrHeight) / (2 * zoom_mul / zoom_div);
const int DESTBUFFER_WIDTH = scrWidth * zoom_div / zoom_mul;
const int DESTBUFFER_HEIGHT = scrHeight * zoom_div / zoom_mul;

int offset = 0;
for ( int j = DESTBUFFER_START_Y_OFFSET; 
           j < DESTBUFFER_START_Y_OFFSET + DESTBUFFER_HEIGHT; j ++)
{
for ( int i = DESTBUFFER_START_X_OFFSET;
           i < DESTBUFFER_START_X_OFFSET + DESTBUFFER_WIDTH ; i ++)
{
*(destBuffer + offset ++) = *(frameBuffer + j * scrWidth + i);
}
}

//#### Make destBuffer fit to frameBuffer
for (j = 0; j < scrHeight; j ++)
{
int _j = j * zoom_div / zoom_mul;

for (i = 0; i < scrWidth; i ++)
{
int _i = i * zoom_div / zoom_mul;

*(frameBuffer + j * scrWidth + i) 
= *(destBuffer + _j * DESTBUFFER_WIDTH + _i);
}
}

* 화면을 확대할 때, 원래 배율 화면1에서 확대된 배율 화면 2로 바로 넘어가지 말고, 중간에 한두 프레임정도 화면1과 화면2를 적절한 알파값으로 겹쳐 그리는 것을 삽입하면 적절한 ZOOMING 연출이 됩니다.


## 전체 화면 BLUR 효과
: 현재 frameBuffer를 알파 적용해서 기준 화면에서 x, y 각각의 방향으로 -1, +1 씩 어긋나게 겹쳐 찍습니다. 타겟 디바이스의 퍼포먼스를 고려해서, 얼마나 많이 겹쳐 찍을 것인지-보통 상하좌우 4번이면 적당하지 않을 까요- 또한 그에 따라 겹쳐 찍을 때 알파 값을 어느 정도로 줄 것인지 그래픽 아티스트와 게임 디자이너 등과 조정하면 될 것입니다. 이 소스를 구구절절히 쓰는 것은 패킷의 낭비와도 같으므로 생략합니다.ㅎㅎ


## 전체 화면 모자이크 효과
: 화면을 정해진 크기[int  mosaic_size]의 격자로 나누어, 정해진 정도[int mosaic_degree]로 평균값을 구해서 칠합니다. 이 때, 각 격자 안의 픽셀들의 평균값을 구하는 방식은 여러가지가 있을 수 있는데요, 역시 타겟 디바이스의 퍼포먼스 등을 고려해서 얼마나 디테일하게 평균값을 구할 것인가를 정해야할 것입니다. 

다만, 특정인의 신원을 보호하기 위해, 혹은 성인물 윤리위원회의 심의를 통과하기 위해-_- 모자이크를 하지 않는다면, 모자이크라는 표현 자체가 '원래 이미지를 얼마나 근접하게 재현하는 가' 하는 것은 쥐한테 삽 들려주는 것만큼 가치가 없는 짓거리라는 것은 분명합니다. 

여기서는 격자의 최 좌측 상단의 점부터 시작하여 최 우측 하단의 점까지 mosaic_degree 만큼의 픽셀 값을 읽어 평균을 내도록 합니다.

void *frameBuffer;  //#### pointer of frame Buffer
void *destBuffer;   //#### copy of frame Buffer

//#### int mosaic_size;
//#### int mosaic_degree;
//#### scrWidth = width of screen
//#### scrHeight = width of screen

//#### void BlendPixel( int bg_RGB, int fg_RGB, int alpha );
//#### int getCoordDivByDeg(int mosaic_size, int mosaic_degree, int step);

for (int j = 0; j < scrHeight / mosaic_size; j++)
{
int _j = j * mosaic_size;

for (int i = 0; i < scrWidth / mosaic_size; i ++)
{
int _i = i * mosaic_size;

int rgbValue = *(destBuffer + _j * scrWidth + _i);

//#### Calculate balanced rgb value for the mosaic square
for (int k = 0; k < mosaic_degree; k ++)
{
int currLoc
    = getCoordDivByDeg(mosaic_size, mosaic_degree, k);
int currRGB 
     = *(frameBuffer + (_j + currLoc) * W + _i +  currLoc);
rgbValue 
     = BlendPixel ( 
           rgbValue, currRGB, 256 - 256 / mosaic_degree);
}
*(destBuffer + j * (scrWidth / mosaic_size)  + i) = rgbValue;
}
}

//#### draw
for (int j = 0; j < scrHeight; j ++)
{
int _j = j / mosaic_size;
for (int i = 0; i < scrWidth; i ++)
*(frameBuffer + j * scrWidth + i) 
     = *(destBuffer + _j * (scrWidth / mosaic_size) + i / mosaic_size);
}


##화면의 회전
: 사실 이것을 구현하는 것이 가장 골치 아팠는데, 제가 아는 삼각함수 이론으로 구현하니 한 8% 부족하더군요-_-;; (잘돌다가 갑자기 쿠에르보 더블 턴을 하더군요...) 그래서 다른 멋쟁이 개발자의 소스를 그냥 날로 먹겠습니다 차용해서 구현했습니다. 쎼쎼 아리가또 땡큐.

void *frameBuffer;  //#### pointer of frame Buffer
void *destBuffer;   //#### copy of frame Buffer

//#### int pivotX;
//#### int pivotY;
//#### int angle;
//#### scrWidth = width of screen
//#### scrHeight = width of screen

//#### return value of sin(int angle), cos(int angle) => -0xFF ~ 0xFF

for (int j = 0; j < scrHeight; j ++)
{
int tmpY = j - pivotY;

for (int i = 0; i < scrWidth; i ++)
{
int tmpX = i - pivotX;

int _i = pivotX + (tmpX * cos(angle) - tmpY * sin(angle) >> 8);
int _j = pivotY + (tmpX * sin(angle) + tmpY * cos(angle) >> 8);

if (_i >= scrWidth || _i < 0) continue;
if (_j >= scrHeight || _j < 0) continue;

*(frameBuffer + j * scrWidth + i) = *(destBuffer + _j * scrWidth + _i);
}
}


'DEV life > DEV.mobile' 카테고리의 다른 글

날로 먹는 iPhone dev 일기 #3  (2) 2009.05.06
SKT의 앱스토어, 성공할까?  (26) 2009.04.14
2D 프레임버퍼의 제어  (2) 2009.04.07
날로 먹는 iPhone dev 일기 #2  (0) 2009.04.07
날로 먹는 iPhone dev 일기 #1  (2) 2009.04.01
날로 먹는 iPhone dev 일기 #0  (2) 2009.03.30
Posted by jakesoul
Touch

어떤 형태로건 사용자의 입력이 없다면 그것을 '게임'이라고 부를 수 있을 까요?

사용자의 입력이라는 것이, 일반적인 게임의 조작성에서 조금 멀리 떨어져 있을 수는 있어도-비쥬얼 노블 류 처럼 OK 버튼이나 푹푹 눌러대거나, NDS의 닌텐독스나 대합주에서 처럼 마이크에 소리를 지른다거나 등등등-어찌 되었건 '게임'이라는 어플리케이션을 구성하는데 외부의 조작을 처리하는 것은 반드시 필요한 것이 되겠습니다. 

 iPhone은, 설명할 필요도 없이, 메인 입력으로 터치 인터페이스를 사용하죠. 이것을 처리하기 위해서 필요한 것은, 프로젝트에 UIKit framework가 포함되어 있을 것입니다.


touch를 제어하는 방법을 잘 다룬 예제로는 Apple Sample Codes의 Touches가 있습니다. 코드를 얻은 후, MyView.m 파일 중반을 보시면 touch event 를 다루는 이벤트 핸들러 메소드들이 있습니다.

이를 간단히 정리해보면-

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;


이름을 보니 이놈이 뭐하는 놈인지 설명할 필요가 없어졌습니다.

그래도 간단히 짚고 넘어가죠^^;;


// Handles the start of a touch

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

{

    NSUInteger numTaps = [[touches anyObject] tapCount]; // ==> 현재 터치되어있는 수를 구하는 코드

// ...중략


// Enumerate through all the touch objects.

NSUInteger touchCount = 0;

for (UITouch *touch in touches) {

    // Send to the dispatch method, which will make sure the appropriate subview is acted upon

[self dispatchFirstTouchAtPoint:[touch locationInView:self] forEvent:nil];

// ==> 모든 터치에 대해, 터치 위치와 이벤트 등에 따라 처리해줍니다.

touchCount++;  

}

}


-(void) dispatchFirstTouchAtPoint:(CGPoint)touchPoint forEvent:(UIEvent *)event

{

// ...생략-_-

}


이놈 까지 봤으니 이후는 더더욱 설명할 것이 없을 것입니다.


// Handles the continuation of a touch.

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

{  

// ...생략

// Enumerates through all touch objects

   for (UITouch *touch in touches) {

// Send to the dispatch method, which will make sure the appropriate subview is acted upon

  [self dispatchTouchEvent:[touch view] toPosition:[touch locationInView:self]];

}

// ...생략

}


-(void) dispatchTouchEvent:(UIView *)theView toPosition:(CGPoint)position

{

// ...생략

}


// Handles the end of a touch event.

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

{

    // Enumerates through all touch object

    for (UITouch *touch in touches){

// Sends to the dispatch method, which will make sure the appropriate subview is acted upon

[self dispatchTouchEndEvent:[touch view] toPosition:[touch locationInView:self]];

}

}


-(void) dispatchTouchEndEvent:(UIView *)theView toPosition:(CGPoint)position

{   

// ...생략

}


- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event

{

    // Enumerates through all touch object

    for (UITouch *touch in touches){

// Sends to the dispatch method, which will make sure the appropriate subview is acted upon

[self dispatchTouchEndEvent:[touch view] toPosition:[touch locationInView:self]];

}

}


참 쉽죠잉?-_-  터치의 처리 자체는 간단한 문제지만, 이후 구현하고자 하는 게임의 인터페이스 디자인에 따라 이벤트의 처리를 보다 효율적으로, 그리고 직관적으로 설계하기 위한 연구가 필요할 것입니다. 다음은 사운드 출력 고고싱~

* iPhone Simulator에서의 멀티터치 입력은, option키를 누르면 가능합니다.


'DEV life > DEV.mobile' 카테고리의 다른 글

SKT의 앱스토어, 성공할까?  (26) 2009.04.14
2D 프레임버퍼의 제어  (2) 2009.04.07
날로 먹는 iPhone dev 일기 #2  (0) 2009.04.07
날로 먹는 iPhone dev 일기 #1  (2) 2009.04.01
날로 먹는 iPhone dev 일기 #0  (2) 2009.03.30
게임 플랫폼으로서의 iPhone  (2) 2009.03.24
Posted by jakesoul
Drawing@2D 

애플은 iPhone의 3D API로 openGL | es를 사용합니다. 익히 아시다시피 openGL은 'os비종속적인' 표준 3D 라이브러리죠. 물론 3D뿐만 아니라 2D 이미지를 표시할 때도 Quartz보다 openGL | es 사용이 권장됩니다.

openGL(es)로 2D 이미지를 그리는 것은 개발자 입장에서 썩 효율적인 일은 아닙니다. openGL의 3D 좌표계에서 2D 좌표를 직관적으로 사용할 수 없는 것은 물론이고, 애초에 2D 이미지 = z뎁스 고정된 rect위의 텍스쳐이기 때문에 이미지 크기에 대한 제한(텍스쳐 이미지의 크기는 power of 2이어야 합니다. 32*32, 64*64, 128*128, ...) 등으로 이것 저것 신경써야 할 것이 많습니다.

물론, 어느 개발사건 상용게임 혹은 그에 준하는 게임을 만들 때 openGL (혹은 directX) 만을 가지고 만들지는 않습니다. 라이브러리에서 제공하는 기본 API 자체로는 개발자가 일일이 해야할 것이 많기 때문이죠. 보통 '엔진'으로 불리우는, 보다 하이레벨의 라이브러리 셋을 얹어 쓰게 됩니다.

보통 iPhone 개발용으로 자주 언급되는 엔진으로는 oolong, sio2, cocos2d 등-모두 open source-이 있는데요, 그중 2D 관련해서는 cocos2d 가 가장 많이 다뤄지고 있습니다. 제가 살펴보니 실제 게임을 구현하는데 조금 애매한 부분이 있습니다. 어딘가 불필요한 부분도 많고, 반대로 조금 모자란 부분도 있습니다. 그저 쉽게 이미지 몇장을 화면에 배치하고 이동이나 회전 등의 제어를 하는 것으로 만족한다면 모를까, 이대로는 게임 엔진을 구성할 수는 없는 수준입니다. 결국 많이 손을 보아야하는데, 이미 누군가에 의해 높이 쌓아져 올린 동전 더미를 건드리는 것보다, 새로 동전을 쌓는 것이 수월할 때도 있습니다. 

외국의 dev 포럼을 보면 보통 2D 기반의 작업에 대해서, cocos2d의 texture2D 클래스만 가져와서 개발을 하는 경우를 종종 볼 수 있습니다. texture2D 클래스를 어디서 구할 수 있느냐 물어보는 사람들도 자주 있구요.

컨셉자체가 '날로먹는' 것이므로 자세한 설명과 친절한 예제등은 생략하고 바로 Texture2D를 이용해서 화면에 이미지를 찍어보도록 하겠습니다. 

준비물 : 
1) 애플에서 제공하는 GLSprite 샘플코드
 : Welcome to Xcode 창의 iPhone Dev Center > iPhone Sample Code 섹션에서 찾아들어가시거나, 여기(로그인 필요) 에서 받으면 되겠습니다.

2) Texture2D관련 파일들 - Texture2D.h / Texture2D.m / PVRTexture.h / PVRTexture.m
: cocos2d-for-iphone 소스를 받아서 그 안에서 추출. http://code.google.com/p/cocos2d-iphone/

GLSprite 프로젝트를 열고, Add > Existing Files > 해서 4개의 Texture2D 파일들을 추가합니다. 이 때 필요시 타겟 폴더에 아이템을 복사함Copy items into destination group's folder (if needed)에 체크하세요.


이제 EAGLView.m 을 들여다 보도록 하겠습니다.

살짝 살펴보면,  GLSprite 어플은 
 
어플이 시작되면
(id)initWithCoder:(NSCoder*)coder;
-> [self setupView];
-> [self drawView];

그리고 매 timeout마다
(void)drawView;


이렇게 돌아가는 것을 알 수 있습니다. *한번 돌려 [CMD-R] 보세요. 4각형에 텍스쳐가 매핑되어서 빙글빙글 돌고 있습니다.



- (void)setupView


이곳에서 스프라이트(이미지)의 로딩과 기본적인 openGL|es 세팅이 이루어집니다. 중간에 스프라이트를 읽어오는 부분을 살펴봅니다.

spriteImage = [UIImage imageNamed:@"Sprite.png"].CGImage; 

Sprite.png파일을 UIImage로 읽어서, 그것을 CoreGraphics Image로 가져오는 코드입니다. 하지만 이 때 image 파일들은 8비트, 32비트 rgb(a)칼라여야 하고, power of 2의 사이즈를 가져야 합니다. 이것 저것 따지는 게 많고 귀찮습니다.

이제 Texture2D 클래스를 이용해서 쉽고 편하게 2D이미지를 읽어와서 화면에 뿌려보도록 하죠.

EAGLView.h 에 Texture2D 헤더를 임포트 선언합니다.

#import "Texture2D.h"


그리고 EAGLView 클래스 선언 내부에 Texture2D 객체를 하나 추가해줍니다.

Texture2D *tex;


그리고 원하는 이미지 파일을 Resources 폴더 밑에 추가해줍니다.  Add > Existing Files > 마찬가지로 이 때 필요시 타겟 폴더에 아이템을 복사함Copy items into destination group's folder (if needed) 을 체크.

그리고  - (void)setupView 를 다음과 같이 추가/변경합니다.


그리고 - (void)drawView 를 고쳐 보죠.


이 때, 이미지의 기준 좌표는 좌측 하단이며, 전체 화면은 x: -1.0 ~ 1.0, y: -1.5 ~ 1.5 를 차지하고 있습니다. 대강 감이 오시죠? (-1.0, -1.5) 부터 넓이 2.0, 높이 3.0의 Rect에 텍스쳐를 그리라는 것입니다. 참고로 커멘트 되어있는 부분- [tex drawAtPoint:CGPointMake(-1.0, -1.5)]; 는 한 점CGPoint 위에 텍스쳐를 그리는 것으로, cocos2d 안에 있는 Texture2D소스를 바로 가져왔을 때 한 두라인을 수정해야 화면에 제대로 보입니다. 


제가 넣은 이미지를 띄워보았습니다. =) 

이것으로 화면에 '내가 원하는 이미지'를 '원하는 위치'에 띄우는 것이 가능해졌습니다. 이제 기존에 자신이 쓰던 스프라이트/리소스 툴과 연계하여 보다 편리하고 보다 효율적으로 돌아가는 스프라이트 엔진을 짜는 것이 필요하겠죠.

'DEV life > DEV.mobile' 카테고리의 다른 글

2D 프레임버퍼의 제어  (2) 2009.04.07
날로 먹는 iPhone dev 일기 #2  (0) 2009.04.07
날로 먹는 iPhone dev 일기 #1  (2) 2009.04.01
날로 먹는 iPhone dev 일기 #0  (2) 2009.03.30
게임 플랫폼으로서의 iPhone  (2) 2009.03.24
에리테리아 전설  (6) 2009.03.13
Posted by jakesoul