작업의 막바지를 향해 가던 도중... 맵 정보를 바깥으로 빼야한다는 것을 깨달았다.

아 그랬다.. 나는 XNA에서 파일을 입력 받아야 하는 것이었다. .. -_-

어떻게 하는지 모르겠고 예제는 안돌아가고 감도 안 잡히고 해서 .. 나는 지인에게 물어봤다. 본격 징징..

이자리를 빌어 다람군에게 감사를... 왠지 실명을 안쓰니 갑자기 내가 덕이 충만해진 것 같아 조금 슬프다.

 지인은 나에게 컨텐츠 파이프라인을 추가하면 된다고 했다. 

그래서 좀 인터넷좀 뒤지고 하다보니 모르겠따. 몹시 닥달을 해서 알아냈다.

그래서 해봤는데 안된다. 왜 안될까?

나는 무수히 삽질을 하고 인터넷도 뒤져보고 보내준 지인의 소스와 나의 소스를 꼼꼼히 비교하며 스펠링 하나하나의 개연성에 대해 연구를 하기 시작했다.

그러다가 내 파일과 지인의 파일의 속성을 한 글자씩 읽어가고 있었다.

이럴쑤가... 아..

파일 속성에 보면 ..

고급 - 빌드 작업

이라는 부분이 있다(영어는 모름^^)

나는 '내용'으로 되어있고 지인의 것은 '컴파일'로 되어있었다.

이것을 바꾸었더니 나의 1시간 대소문자 비교 행위는 끝이 났다.

아....

이제 제대로 적용을 할 때가 왔다...




잠을 다섯시간만 자고 일어나야지 한 후에 2시간 동안 잠 못자다가 이러다간 세시간만 자려다가 실패할 것 같아서 포기하고 지금 한 시간동안 컴터와 씨름을 했다.

언제쯤 나는 아침형 인간이 될 수 있을지 의문이다. 
Posted by TY
,

오늘 조나 비싼 24인치 모니터만한 인튜오스로 그린 타블렛으로 그린 나의 초 명작 뱀 ( - -;) 게임 계획서에 넣으려고 그렸다. 누구 나에게 그림 그려 줄 사람 없습니까 ㅜㅜ

1. ArrayList 와 List<T>
 나는 java를 쓰던 버릇이 있어서 ArrayList 를 구지 System.Collections 에서 꺼내서 썼었다. 하면서 왜 Generic이 안되지? 라고 매번 생각했었는데.. 그냥 List는 System.Collections.Generic에 있다. 나는 아무 생각 없이 안 썼는데 생각해보면 왜 안 썼는지 모르겠다. 앞으로 List를 애용해야지... 인터넷 검색 찬스를 좀 써봤지만 이런 글을 얻었다.
http://bytes.com/topic/c-sharp/answers/643286-arraylist-vs-list
하.. 더 이상 예외 처리를 하기 위해 대입을 해서 할 필요가 없다는 것을 깨달았다. 그냥 Generic을 써서 간단하게 해야겠다.
마치 구시대의 유물을 고집하던 놈이 된 것 같아 찝찝하지만 나의 영어로 해석할 수 없는 심오한 뜻이 있어서 사람들이 ArrayList를 쓴다고 생각하고 싶다. 어쨌든 난 이제 List를 써야겠다.

2. Initialize() 와 LoadContent()
 아무 생각 없이 초기화가 데이터를 불러오는 것 보다 먼저이지 않을까 생각했는데, 오늘 List를 넣어서 코딩을 하다가 깨달았다. 정확히 말하면 에러가 났다. 그 이유를 보니..
 LoadContent 가 Initialize 보다 먼저 실행된다. 중요한 것을 깨달은 듯

3. static class 와 interface
 나는 java에서 상수를 관리할 때 늘상 Interface 에 final을 붙이며 썼다. 그리고 C#에서는 static class 를 만들어서 const 를 붙여서 썼다. 근데 최근에 java 코딩을 좀 많이 해서 아무 생각 없이 C#에서 interface를 만들어서 하려는데 음 왠지 안되는 것 같다. 쿨하게 포기하고 static class로 전환했다. IConstants 등으로 안 만들고 Constants로 만든 나에게 왠지 모르게 감사했다.


요즘은 왠지 모르게 깨달은게 많은데 아무데도 남겨두지 않았다.

이 기회에 좀 적어놔야 되지 싶은데 시간 되면 저번에 했던 Spring 이랑 iBatis랑 JSON이랑 등등 좀 정리해서 블로그 같은데 올려놔야겠다, 라는 생각이 들었다.

 우선 MSSQL 이랑 Oracle 까는 숙제부터 해야지...--;
Posted by TY
,

제가 중요한 글을 까먹고 있었던 것 같습니다.



이 문서는 다음과 같은 서적, 사이트들을 참고하여 작성하고 있습니다.

- 서적 -

Windows Phone 7 프로그래밍 멘토: 윈도우 폰 7 프로그래밍 가이드(이수겸 저/삼정데이타서비스/ISBN-13:9788964860113)

실버라이트 부분과 WP7의 기본 개념을 잡는데 많은 도움을 주었습니다.

XNA를 이용한 Windows Phone 7 게임 프로그래밍(이승훈, 김대호, 김응두, 임준철, 정병근 공저 / 비제이퍼블릭 / ISBN-13: 9788994774015)

XNA 부분에 대해 관련된 많은 도움을 받고 있습니다.

- 사이트 -

Microsoft APP HUB(http://create.msdn.com/en-US/)

MS의 공식 WP7(?) 사이트입니다. 많은 정보를 여기서 참고합니다.

- 도움 주신분 -

성함(소속) 순입니다. 가나다 순으로 정렬됩니다. 본인 희망대로 작성합니다.

신동림(대한민국)
주병진(노예)



 제 블로그에 기재된 자료에 대해 저작권에 문제가 있다고 생각되시는 분들은 저에게 연락을 주시며 조속한 조치를 취하도록 하겠습니다.

 제 연락처는 아래의 링크된 글 최하단에서 확인하실 수 있습니다.

http://oddly.tistory.com/2

만약 관련된 문제로 인해서 미리 생길지 모르는 저에 대한 불만이나 기분 상하셨을 분들에 대해 미리 죄송한 마음을 표합니다. 공부하던 것을 널리 알리고자 하다보니 그럴 수도 있다는 너그러운 마음으로 이해해 주시면 감사하겠습니다..^^;
Posted by TY
,

SpriteBatch

Draw Class에 보면 최 상단에 SpriteBatch.Begin 메서드가 있고 SpriteBatch.End 메서드가 있다. 두 메서드 사이에 SpriteBatch를 이용해 그려지는 (DrawString, Draw 등의 메서드) 등은 SpriteBatch의 설정을 모두 이어받는다.

환경 설정은 SpriteBatch.Begin 메서드는 다수의 메서드로 오버로딩 되어있는데 각각 알아보자.

 

SpriteBatch.Begin()
SpriteBatch.Begin(SpriteSortMode, BlendState)
SpriteBatch.Begin(SpriteSortMode, BlendState, SamplerState, DepthStencilState, RasterizerState)
SpriteBatch.Begin(SpriteSortMode, BlendState, SamplerState, DepthStencilState, RasterizerState,Effect)
SpriteBatch.Begin(SpriteSortMode, BlendState, SamplerState, DepthStencilState, RasterizerState,Effect, Matrix)

어차피 생성자를 재 호출 하고 추가된 기능만 수정되지 싶으니 인자의 역할을 하나하나 살펴보자.

SpriteSortMode – 이미지 출력 순서를 결정

Deferred / Immediate / Texture / BackToFront / FrontToBack

의 속성들을 갖고 있는데 각각에 대해 간단히 알아보겟다.

Deferred – SpriteBatch.End() 가 호출되기 전까지 스프라이트를 화면에 출력하지 않으며, 호출될 때 호출된 순서대로 출력. 가장 기본적인 처리 방식이다

Immediate – Draw 메서드 호출시 즉각적으로 화면에 출력한다.가장 빠르지만 한 번에 SpriteBatch 메서드 밖에 활성화 시킬 수 없는 문제가 있다.

Texture – 텍스쳐 우선순위 별로 정렬하여 마지막에 모아서 그린다.

* 텍스쳐 우선순위 : Draw 메서드는 여러 개의 오버로딩 함수가 있다(MSDN을 참조해보면 7개 정도 있는 것 같다)  여기서Draw Order란 항목이 있다고 하는데 이것에 따라 출력됨을 원칙으로 한다.

BackToFront – Deferred모드와 동일하지만 호출 순서의 반대로 출력이 된다. (즉 마지막에 호출된 Draw가 가장 앞에 출력이 된다)

FrontToBack – Layer Depth 인자를 이용하여 그에 따라 출력을 한다. 생각하기에 Deferred 와 함께 개인적으로 많이 쓸 방식이 아닌가 싶다.

BlendState – 이미지 출력시 색상 혼합이 일어나는 방식을 결정하기 위해 사용.

AlphaBlend/Additive/NonePremultiplied/Opaque

의 속성들을 갖고 있다.

Alphablend -  알다시피 알파블렌딩이다. 알파 값을 조절해 겹치게 하는 것.

Additive – 색상 혼합

NonePremultiplied – 아무런 처리를 하지 않고 그냥 출력

Opaque – 불투명 처리를 통해 알파 값을 무시하고 이미지를 그대로 출력

SamplerState – Clamp 와 Wrap 모드로 나뉘며 그에 따라 필터링 방식이 세분화된다.

Clamp 모드는 텍스쳐의 경계에 위치한 가장자리 픽셀을 사용해 범위에 벗어난 부분을 표현한다.

Warp 모드는 범위를 벗어난 부분에 대해 텍스쳐를 반복해서 출력한다.(타일 형식으로 부어버림)

필터링은 Point, Linear, Anisotropic 세 가지 방식을 지원한다. Point 방식은 해당 지점에 가까운 텍스쳐를 그대로 사용하여 처리 시간이 짧고, Linear 방식은 해당 지점과 가까운 텍스처의 주변 색상을 선형 보간을 통해 출력 색상을 결정한다. Anisotropic 방식은 비등방성 필터링을 이야기한다.

DepthStencilState – 장치의 깊이 버퍼의 사용 방식을 결정한다. DepthBufferEnable / DepthBufferWriteEnable의 설정값이 자동으로 변경이 된다.

DepthBufferEnable – Pixel Buffer에 객체를 그릴 때 깊이 버퍼의 값을 비교해 객체의 출력 여부를 결정한다.

DepthBufferWriteEnable – 객체를 픽셀 버퍼에 그릴 때 객체의 깊이 값을 깊이 버퍼에 저장할 것인지 결정

DepthStencilState의 설정 가능 목록은 다음과 같다.

Default / DepthRead / None 이 있다.

RasterizerState – 벡터 정보를 레스터 정보로 어떻게 변환할 것인지 처리한다.

여기서 3D쪽에 많이 나오는 CW,CCW가 나온다.

CullClockWise – 시계방향으로 앞면을 판별, 뒷면 미출력

CullCounterClockWise – 반시계방향으로 앞면을 판별, 뒷면 미출력

CullNoneNone – 앞면, 뒷면 모두 출력

Effect – Begin과 End 사이에 그려지는 3D 객체들에 대해 쉐이더 효과를 지정한다.  WP7에서는 성능 저하를 막기 위해 간단한 5가지 이펙트를 쓸 수 있다. 그 목록은 다음과 같다.

BasicEffect / AlphaTestEffect / DualTextureEffect / EnvironmentMapEffect / SkinnedEffect

BasicEffect – 기본 제공 이펙트

AlphaTestEffect – 투명 효과에 특화되어있는 이펙트

DualTextureEffect - 2개 이상의 텍스쳐를 사용할 수 있는 이펙트

EnvironmentMapEffect – 객체 주변의 환경을 반영할 수 있는 이펙트

SkinnedEffect – 스키닝 애니메이션을 모델에 적용 가능한 Effect

Matrix – 구조체를 이용해 회전이나 반전 등을 사용할 수 있다.

여기까지가 Begin의 인자들의 설명이다. 사실 이런거 알아서 뭐하나~ 싶은데 ………. 개인적으로 이런 거 잘 몰라서 고생한 기억도 있고, 알아두면 나중에 다 뼈가 되고 살이 된다고 생각한다.

SpriteBatch.End()

Begin, End 사이에서 사용된 출력 대상을 화면에 반영하고 출력 환경을 복원한다. Begin과 End 메서드 사이에 다른 SpirteBatch 클래스의 Begin 과 End를 사용할 수 없다(runtime error발생). 또한 짝을 잘 맞춰서 사용해야 한다.

 

SpriteBatch.Draw()

이 메서드는 2D 이미지를 화면에 출력할 수 있다. 오버로딩된 함수의 목록은 다음과 같다.

SpriteBatch.Draw(Texture2D, Rectangle, Color)
SpriteBatch.Draw(Texture2D, Rectangle, Nullable<Rectangle>, Color)
SpriteBatch.Draw(Texture2D, Rectangle, Nullable<Rectangle>, Color, float, Vector2, SpriteEffects, float)
SpriteBatch.Draw(Texture2D,  Vector2, Color)
SpriteBatch.Draw(Texture2D, Vector2, Nullable<Rectangle>, Color)
SpriteBatch.Draw(Texture2D, Vector2, Nullable<Rectangle>, Color, float, Vector2, float, SpriteEffects, float)
SpriteBatch.Draw(Texture2D, Vector2, Nullable<Rectangle>, Color, float, Vector2, Vector2, SpriteEffects, float)

각각의 매개변수의 역할은 다음과 같다.

Texture2D texture: 이미지

Vector2 position: 화면 출력 위치 좌표 지정

Rectangle destinationRectangle: 화면 출력 rect 지정. 자동으로 이미지를 확대, 축소해 영역에 맞춘다.

Nullable<Rectangle> sourceRectangle: 이미지 자산 중 출력하고 싶은 부분을 지정

Color color: 이미지 자산과 색상 혼합. Color.White를 사용지 원 이미지 그대로 표현 가능

float rotation: 이미지 회전 상태 지정. radian 형식의 값 사용

Vector2 origin: 이미지 출력 기준 위치 지정. 회전 상태, 출력 위치 등에 영향을 준다.

float scale: 이미지 확대 축소 비율 지정. 가로, 세로 방향 동일

Vector2 scale: 이미지 확대 축소 비율 지정. 가로, 세로 방향 다르게 사용 가능.

SpriteEffects effects: 이미지 좌우, 상하 반전 효과 지정

float layerDepth: 출력 순서 지정

Draw 메서드를 사용해서 화면에 출력시 어떻게 내부에서 처리되는 과정을 이해한다면 매개변수 설정에 따라 어떤 결과가 나올 것인지 예상할 수 있다. 

현재 공식적으로 내부 처리 과정에 대해 설명한 자료가 없으므로 이는 출력 결과를 바탕으로 예상한 내용이라는 것에 주의해야 한다.

우선 이미지에서 많이 쓰이는 두가지 좌표계에 알아 둘 필요가 있을 것 같다. 간단히 그림으로 설명하면 다음과 같다.

위 그림은 정점 좌표계에 대해 이야기한다. 정점 좌표계에선 축을 지칭할 때 가로를 x축, 세로를 y축으로 한다.

그리고 해당 이미지의 좌측 끝 좌표를 Left, 우측 끝 좌표를 Right라고 한다. 최상단을 Top, 최하단을 Bottom이라고 칭한다. 그래서 이를 기준으로 4 꼭지점에 대한 좌표를 정의하면 위의 그림에도 보이듯이 다음과 같이 이야기한다.

좌측 상단: (Left, Top)

우측 상단: (Right, Top)

좌측 하단: (Left, Bottom)

우측 하단: (Right, Bottom)

위의 그림은 UV좌표계를 이야기한다. UV좌표는 텍스쳐의 좌표를 설정해 출력할 이미지에 대한 조작을 가한다.

텍스쳐 좌표 설정시 영향을 주는 요소는 잘라내기 영역과 좌우, 상하 반전 효과이다. 텍스쳐 좌표는 텍스쳐가 변경되어도 그 크기에 상관없이 텍스쳐 좌표를 계속 사용할 수 있도록 실수로 표현한다.

Left = 0, Right = 1, Top = 0, Bottom = 1 과 같은 개념으로 생각하면 되겠다. Right를 Texture.Width와 같게 표현한다고 볼 수 있으며, Bottom을 Texture.Height와 같게  표현한다고 볼 수 있다.

잘라내기 영역이 이 텍스쳐 좌표를 결정하는데 중요한 영향을 미치는데 별도로 설정하지 않는 경우에는 일반적으로 모두 다 표기되게 처리를 하나 만약 잘라내기 영역을 설정할 경우, 각각 left,right,top,bottom에 잘라낼 비율을 설정할 수 있다.(쉽게 sourceRectangle.Left / texture.Width 와 같은 형식으로 비율을 맞춰 출력을 하게 된다.)

Left와 Right, Top과 Bottom의 위치가 바뀔 경우 좌우, 상하 반전 효과를 적용할 수 있게 된다.

destinationRectangle 매개변수를 전달받은 메서드들은 축소 비율을 무시하고 destinationRectangle에서 받은 값으로 처리를 하게 된다.이것은

scale 인자는 2종류가 있는데, 하나는 float이고 하나는 Vector2 형식이다. float형식은 가로, 세로를 동일한 비율로 바꿔주게 되고, Vector2는 각각 설정이 가능하다.

이에 대해 자세히 알아보고 싶으면 MSDN을 참조하기 바란다. Matrix부분에 대한 것은 본인이 3D에 대한 지식이 미약하여 헛된 정보를 전하지 않을까 하여 생략하도록 하겠다.^^;

다음에는 문자 출력에 대해 한 번 자세히 알아보도록 하겠다.^^

Posted by TY
,

우선 전에 언급했다시피 WP7의 라이브러리는 WP7 Framework 아래에 Silverlight, XNA로 나누어진다. 전에 내용을 유심히 읽어봤거나 관심이 있다면 알겠지만 XNA가 게임 개발을 하는데 필요한 주요 클래스 라이브러리이다. WP7에 탑재된 XNA 라이브러리 목록들은 다음과 같다.

 

 

명칭 객체의 위치 설명
Input Microsofot.Xna.Framework.Input XBOX 360 컨트롤러 장치, 키보드, 마우스의 입력을 받을 수 있는 함수와 클래스 제공
Media Microsofot.Xna.Framework.Media 음악과 앨범, 재생 목록, 사진 등의 자료 재생 및 접근과 관련된 클래스를 제공
Content Microsofot.Xna.Framework.Content 콘텐츠 파이프라인을 통해 게임에서 사용하는 자원들을 각 파일 포맷에 따라 관리하고 유지하는데 필요한 클래스 제공
GameServices Microsofot.Xna.Framework.GameServices XBOX LIVE와 관련된 기능을 담당. LIVE 관련 GUI포함되어있다. 게이머의 데이터와 직접 통신하거나 선택을 반영할 수 있는 API 제공
Graphics Microsofot.Xna.Framework.Graphics 3D 오브젝트를 표시하는 하드웨어 가속 기능과 렌더링을 포함하는 낮은 수준의 응용 프로그램 인터페이스를 제공
Audio Microsofot.Xna.Framework.Audio XACT로 만든 프로젝트 및 콘텐츠 오디오 파일을 재생하고 낮은 수준의 인터페이스 방식에서 조작할 수 있는 클래스 제공
Touch Microsofot.Xna.Framework.Input.Touch 터치 기반 입력 장치를 활성화하는 클래스를 제공
Network Microsofot.Xna.Framework.Net XNA 프레임워크 게임상에서 XBOX Live 멀티 플레이어 지원 및 네트워킹을 구현하는 클래스를 제공
Storage Microsofot.Xna.Framework.Storage 저장장소의 파일 입출력을 담당

VS 2010에 많은 템플릿이 있는데, 우리가 개발할 WP7에 관련된 템플릿은 Windows Phone Game과 Windows Phone Game Library이다. Content Pipeline Extension Library 템플릿은 기본적으로 제공되는 콘텐츠 파이프라인이 지원하지 않는 형식의 파일을 사용하거나 콘텐츠 정보를 임의로 변경하고 싶은 경우 같은 것을 위한 기본틀을 제공한다.

한 번 Windows Phone Game 템플릿을 생성해보자. 역시나 메뉴에서 Device를 Windows Phone 7 Emulator로 바꾸고 실행해보자.

그러면 아무것도 없는 마치 9x계열 커널을 처음 깔았을 때나 보일법한 새파란 화면이 보인다.. 만약 실행이 안된다면 이전에 설명했던 최저사양을 만족하지 못하는 PC임을 알 수 있을 것이다.

간단히 소스를 살펴보자.

Program.CS

C#에서 WF를 해본 사람이라면 느낌이 오겠지만 Program.cs는 작업하는데 그리 중요한 파일이 아니다 (물론 중요하지만 별 내용이 없다……… 나도 여기다가 별 짓을 다해봤기 때문에 중요하지 않다곤 말 할 수 없겠다^^; )

그냥 단지 이 프로그램을 구동하기 위한 파일이다.

 

  1: using System;
  2: 
  3: namespace HelloXNA4
  4: {
  5: #if WINDOWS || XBOX
  6:     static class Program
  7:     {
  8:         /// <summary>
  9:         /// The main entry point for the application.
 10:         /// </summary>
 11:         static void Main(string[] args)
 12:         {
 13:             using (Game1 game = new Game1())
 14:             {
 15:                 game.Run();
 16:             }
 17:         }
 18:     }
 19: #endif
 20: }

진짜 별 것 없다.

Game.cs

나는 초기화나 이런 것을 굉장히 중요하다고 생각하는 사람이다. 자세히 알아볼 가치가 있다.

  1: using System;
  2: using System.Collections.Generic;
  3: using System.Linq;
  4: using Microsoft.Xna.Framework;
  5: using Microsoft.Xna.Framework.Audio;
  6: using Microsoft.Xna.Framework.Content;
  7: using Microsoft.Xna.Framework.GamerServices;
  8: using Microsoft.Xna.Framework.Graphics;
  9: using Microsoft.Xna.Framework.Input;
 10: using Microsoft.Xna.Framework.Input.Touch;
 11: using Microsoft.Xna.Framework.Media;
 12: 
 13: namespace HelloXNA4
 14: {
 15:     /// <summary>
 16:     /// This is the main type for your game
 17:     /// </summary>
 18:     public class Game1 : Microsoft.Xna.Framework.Game
 19:     {
 20:         GraphicsDeviceManager graphics;
 21:         SpriteBatch spriteBatch;
 22: 
 23:         public Game1()
 24:         {
 25:             graphics = new GraphicsDeviceManager(this);
 26:             Content.RootDirectory = "Content";
 27: 
 28:             // Frame rate is 30 fps by default for Windows Phone.
 29:             TargetElapsedTime = TimeSpan.FromTicks(333333);
 30:         }
 31: 
 32:         /// <summary>
 33:         /// Allows the game to perform any initialization it needs to before starting to run.
 34:         /// This is where it can query for any required services and load any non-graphic
 35:         /// related content.  Calling base.Initialize will enumerate through any components
 36:         /// and initialize them as well.
 37:         /// </summary>
 38:         protected override void Initialize()
 39:         {
 40:             // TODO: Add your initialization logic here
 41: 
 42:             base.Initialize();
 43:         }
 44: 
 45:         /// <summary>
 46:         /// LoadContent will be called once per game and is the place to load
 47:         /// all of your content.
 48:         /// </summary>
 49:         protected override void LoadContent()
 50:         {
 51:             // Create a new SpriteBatch, which can be used to draw textures.
 52:             spriteBatch = new SpriteBatch(GraphicsDevice);
 53: 
 54:             // TODO: use this.Content to load your game content here
 55:         }
 56: 
 57:         /// <summary>
 58:         /// UnloadContent will be called once per game and is the place to unload
 59:         /// all content.
 60:         /// </summary>
 61:         protected override void UnloadContent()
 62:         {
 63:             // TODO: Unload any non ContentManager content here
 64:         }
 65: 
 66:         /// <summary>
 67:         /// Allows the game to run logic such as updating the world,
 68:         /// checking for collisions, gathering input, and playing audio.
 69:         /// </summary>
 70:         /// <param name="gameTime">Provides a snapshot of timing values.</param>
 71:         protected override void Update(GameTime gameTime)
 72:         {
 73:             // Allows the game to exit
 74:             if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
 75:                 this.Exit();
 76: 
 77:             // TODO: Add your update logic here
 78: 
 79:             base.Update(gameTime);
 80:         }
 81: 
 82:         /// <summary>
 83:         /// This is called when the game should draw itself.
 84:         /// </summary>
 85:         /// <param name="gameTime">Provides a snapshot of timing values.</param>
 86:         protected override void Draw(GameTime gameTime)
 87:         {
 88:             GraphicsDevice.Clear(Color.CornflowerBlue);
 89: 
 90:             // TODO: Add your drawing code here
 91: 
 92:             base.Draw(gameTime);
 93:         }
 94:     }
 95: }
 96: 

 

간단히 각 메서드의 역할에 대해 알아보자.

Initialize는 게임이 실행 될 때 Device관련된 초기화를 해주는 함수임을 알 수 있다. Android도 처음에 상속을 받아서 Initialize를 진행하게 되는데 그것과 같은 방식임을 알 수 있다. 여기다가 나중에 첫 구동시 필요한 것들을 적으면 되겠다. base.Initialize는 WF의 InitializeComponent 메서드의 개념 정도가 되는 것 같다.

* 아 혹시 base가 뭔지 가물가물한 분들을 위해 , base는 JAVA의 super와 같은 개념이다.(즉 자식 클래스가 부모 클래스의 메서드등을 이용할 때 쓴다는 이야기)

 

LoadContent 메서드는 이미지, 모델, 음원등의 컨텐츠를 사용하기 위한 역할을 수행한다. 프로젝트에 추가된 컨텐츠들은 빌드시 알아서 XNB 파일로 변환되어 저장되고, 저장된 파일을 읽어들이는 역할을 한다.

Update 메서드는 WIN32API의 WM_TIMER(?) 정도의 느낌이라고 할 까.  1초에 30번 실행되는 사실상 게임에서의 동적인 모든 것들을 처리하기 위한 메서드이다.

Draw 메서드는 이미지와 모델 텍스트등을 출력하는 메서드이다. WP7의 해상도에 맞게 알아서 출력이 됨이 참 기특한 메서드이다.

UnloadContent 메서드는 LoadContent에서 로드한 컨텐츠들을 해제하는 역할을 게임 종료 또는 장치가 변경되거나 할 때 수행된다.(소멸자 정도로 생각해도 되겠다)

이것을 그래픽으로 표현하면 다음과 같이 볼 수 있다.

그럼 여기에 간단히 텍스트와 이미지를 하나씩 출력해보겠다.

Solution Explorer를 보면 최하단에 프로젝트명Contents(Content) 라는 프로젝트가 있을 것이다. 우클릭을 하여 Add->New Item을 해보자.(한글로는 추가 –> 새 항목이다. 만약 그림이 필요하다면 좀 더 IDE에 익숙해질 필요가 있겠다ㅜㅜ)

우선 글자를 추가해보자. Sprite Font를 선택하자.

생성했더니 뭔가 소스가 많이 나온다 –_- 억… 자 이것은 일단 나중에 필요할 때 자세히 알아보기로 하고 넘어가자. 사실 살펴봐도 XML파일인 것 같은데 인코딩 형식, 끌어와야 할 네임스페이스, 폰트명, 글자크기, 자간이 있는 것 같은데 UseKerning과 Style을 잘 모르겠는데 인터넷으로 알아본 바 UseKerning은 단어간 간격이고 Style은 아마 Bold Italic등을 지정하는게 아닌가 추측해본다. Character Region이야 국가코드명이 아닐까?(무책임…)

일단 이 놈을 써보자.

Game1.cs 파일로 돌아가 Game1 생성자 전에 다음과 같은 내용을 추가해보자.

뭐라고 쓰던 자유지만 본인은 이렇게 선언을 해 보았다. (text는 구지 영어 한글 구분해 본 이유는 에뮬레이터에서 한글이 잘 되나 궁금했던 것 뿐이다. 안되면……………………… 비트맵으로 완성형 한글을 써야 하나?^^; )

  1: SpriteFont spriteFont;
  2: String messageTextKor = "뭐임마 깝ㄴㄴ요";
  3: String messageTextEng = "You don't know me? shut up boy";

 

그 후 LoadContent메서드에서 Load 메서드를 이용해 한번 로딩을 해보자. 아래와 같이 쓰면 된다.

  1: protected override void LoadContent()
  2:         {
  3:             // Create a new SpriteBatch, which can be used to draw textures.
  4:             spriteBatch = new SpriteBatch(GraphicsDevice);
  5: 
  6:             // TODO: use this.Content to load your game content here
  7:             spriteFont = Content.Load<SpriteFont>("SpriteFont1");
  8:         }

 

소스에서 보이는 성의 없는 객체 생성… 만약 아까 새 항목에서 이름을 지었다면 큰따옴표 안에 자신이 만든 항목의 이름을 적어주면 되겠다. 그 후 Draw 메서드에 글자 출력을 넣어보자.

  1:         protected override void Draw(GameTime gameTime)
  2:         {
  3:             GraphicsDevice.Clear(Color.CornflowerBlue);
  4: 
  5:             // TODO: Add your drawing code here
  6: 
  7:             spriteBatch.Begin();
  8: 
  9:             spriteBatch.DrawString(spriteFont, messageTextEng, Vector2.Zero, Color.Black);
 10: 
 11:             spriteBatch.End();
 12: 
 13:             base.Draw(gameTime);
 14:         }

저렇게 치면 일단 글자가 나오는데 이게 가로로 놓을 때 기준인 것 같다(뭐 게임 만들 때 난 이렇게 만들꺼니 상관 없지만…)

아 그리고 한글로 바꿔보자.

아, 에러 난다. … 망했네. 라는 생각을 가져본다.

인터넷의 수많은 LocalizationPipeline.dll 파일을 써서 하는 무언가를 살펴봤는데.. 어… 난 컴파일이 안된다. 전생에 지은 죄가 많은가? 아.. 현생에도 지은 죄는 많다..ㅜㅜ 어쨌든 남따라 해도 안되는 나는 예제를 또 분석한다.

http://create.msdn.com/en-US/education/catalog/sample/localization

여기에 보면 4.0용 예제가 있는데 XBOX360용이랑 윈도우 용 밖에 없다. 그래도 한 번 해보자. .NET은 그래서 있는거니까! 입을 벌리고 하하하

우선 Content 쪽 참조를 보니

우선 using부터 살펴보면 기본 프로젝트보다 한 줄이 추가된다.

using System.Globalization;

바로 임마인데.. 임마를 일단 추가하자.

내리다보면 내가 싫어하는 템플릿-_-을 쓰는 함수가 하나 있다. LoadLocalizedAsset이라는 함수인데 쭈욱 훑어보면 현재 프레임웍에서 인지하고 있는 언어를 언어의 정보를 얻어와서 매칭을 시켜주는 것 같다.

그리고 Draw함수를 살펴보자.

아.. 뭐야 안되잖아.

XBOX용 예제에는 Strings 라는 클래스인지 네임스페이스가 있는 것 같은데 WP에는 없다. 참조가 다른건지 뭔지 아 지친다. 그래서 인터넷에서 본 걸 따라해봐야겠다고 생각했다.

안된 이유는 Pipeline(WP에서는 Content)의 bin/Windows Phone/Debug 폴더에 dll 파일을 넣어야 된다는 것이었다. 일단 이것을 넣고..

http://blog.naver.com/windoxpxp/10101609237

이 링크를 참조했다.

텍스트를 직접 입력해도 되는데 사용할 한글 문자가  Resx파일에 있어야 한다. –_-.. 나중에 유니코드 홈페이지 들어가서 한번 긁어야겠단 생각이 들었다.

와 2시간간의 삽질을 끝내고 한글을 출력하니 너무 행복하다 ^^;; 이제 이미지를 넣어보자.

자 그 전에 해결할 것이 화면 해상도를 알아야한다.

에뮬을 실행하면 자동으로 눕혀서(480*800)에서 나오는데, 이게 가로로 될 수도 있는데 그런 것을 처리해야한다.

우선 이미지 표시되는 형식을 보면 너무나도 익숙하게도 Back Buffer와 Front Buffer가 있다. 이것을 Flip하면서 그려주는 형태인데… 즉 Back Buffer에 다 그리고 Front Buffer로 그림을 옮긴단 이야기가 된다.

우선 가로로 한다는 가정하에 버퍼 크기를 설정한다. 이것은 생성자에서 처리를 해주면 된다.

생성자를 다음과 같이 수정하자.

 

  1: public Game1()
  2:         {
  3:             graphics = new GraphicsDeviceManager(this);
  4:             Content.RootDirectory = "Content";
  5: 
  6:             // Frame rate is 30 fps by default for Windows Phone.
  7:             TargetElapsedTime = TimeSpan.FromTicks(333333);
  8: 
  9:             graphics.PreferredBackBufferWidth = 480;
 10:             graphics.PreferredBackBufferHeight = 800;
 11:         }

graphics는 GraphicsDeviceManager 클래스고 그 속성에 후면 버퍼의 가로 세로 길이를 정할 수 있다. 원하는 값을 넣으면 바뀌게 된다. 물론 WP7에 자동 하드웨어 스케일링 기능이 있어서 화면을 알아서 늘리거나 줄여서 표기가 되고 프로그램의 성능에는 영향을 미치지 않는다(하드웨어가 지원하므로)

프로그램의 화면 회전을 고정시킬 필요가 있는데, 그럴땐 GraphicsDevice 클래스의 SupportedOrientations 속성을 사용하면 된다.

DisplayOrientation 열거형 멤버를 참조해보자.

  1:     public enum DisplayOrientation
  2:     {
  3:         Default = 0,
  4:         LandscapeLeft = 1,
  5:         LandscapeRight = 2,
  6:         Portrait = 4,
  7:     }

이렇게 4개로 구성되어있는데, Default는 그냥 세운 상태, LandscapeLeft와 right는 좌, 우로 가로로 둔 상태, Portrait는 뒤집어 둔 상태라고 생각하면 된다. 나는 넓은 화면만 지원할 것이므로 다음과 같이 작성해본다.

graphics.SupportedOrientations = DisplayOrientation.LandscapeLeft | DisplayOrientation.LandscapeRight;

화면이 어느 쪽으로 돌아가는 보통 긴 축이 X로 표기되지만, Portrait 형을 포함할 경우 짧은 축이 X축을 갖게 된다. 이 점 유의하자.

풀스크린 모드를 이용할 수 있는데 위의 통신사나 핸드폰의 상태를 표기하는 부분을 가리게 된다. GraphicsDevice의 IsFullScreen 옵션을 이용하면 된다.

자.. 기본적인 상황은 이 쯤으로 알아두고 이제 정말 그림을 띄워보자.

지원 포멧은 겁나 많다. 일반적인건 다 된다고 생각하면 된다. 물론 3ds 같은건 안된다^^; 그 이외에도 등록이 가능하나 역시나 작업을 좀 해야 한다.

추가한 이미지의 속성을 좀 보면 다음과 같다.

AssetName – 이름 정도라고 생각하면 된다.

Build Action – 굳이 바꾸지 않았으면 한다. 책에 적혀있는 건데 리소스가 많이 필요한 프로그램은 미리 컨버팅을 해두면 컴파일 시간을 줄일 수 있다고 한다.

Xontent Importer는 파일 형식이다. 이것도 굳이 건드릴 필요는 없을 것 같다.

Content Processor 처리 방식을 선택하는 건데, 이 또한 지금은 굳이 건드릴 필요가 없지 싶다.

Color Key  Color가 있는데 선택한 색상을 투명으로 처리하는 것이다. 컬러키라는 개념에 익숙한 분들은 잘 알 것이라 믿는다. 

Color Key Enable은 컬러키로 설정한 색상을 투명 처리할 것인가 말 것인가 이다.

Generate Mipmaps 밉맵 생셩 여부를 결정하는데 사용된다.

Permutiply Alpha – 알파 값을 색상에 곱하여 저장하는 방식으로 색상 정보를 압축할 때 쓰인다

Resize to Power of Two - 2의 승수로 파일의 가로 세로 길이를 조정할 것인지를 묻는다. True로 바꿀 경우 알아서 커지기 때문에 애초에 2의 승수로 만들던지 False로 쓰기를 추천한다.

Texture Format – XNB로 변경할 때 어떤 방식으로 저장할지를 결정한다. NoChange는 그대로, Color는 XNA 색상 형식으로 저장, DxtCompressed는 DX의 텍스쳐 형식으로 저장을 한다. 크기가 많이 작아지나, 2의 승수여야만 한다.

출력 디렉토리로 복사 – 이름 그대로.

파일 이름 – 콘텐츠 파이프라인에 등록된 리소스 파일의 이름을 결정한다.

 

자… 이제 이미지를 로드해보자.

우선 생성자 위에 또 선언을 해보자.

Texture2D texture;

라고..

그리고 생성자를 수정하자. 나는 아까 내가 원하는 것들을 적절히 조합했고 풀스크린 옵션은 기본으로 쓰기로 해서 안 설정했다.

  1: public Game1()
  2:         {
  3:             graphics = new GraphicsDeviceManager(this);
  4:             Content.RootDirectory = "Content";
  5: 
  6:             // Frame rate is 30 fps by default for Windows Phone.
  7:             TargetElapsedTime = TimeSpan.FromTicks(333333);
  8: 
  9:             graphics.PreferredBackBufferWidth = 480;
 10:             graphics.PreferredBackBufferHeight = 800;
 11: 
 12:             graphics.SupportedOrientations = DisplayOrientation.LandscapeLeft | DisplayOrientation.LandscapeRight;
 13:         }

그 후, LoadContent부분을 수정한다.

texture = Content.Load<Texture2D>("Leva");

이 문구를 수정하자. 나는 이미지의 AssatName이 Leva라서 저렇게 해놨다. 왜 저런 이름인지는 곧 알게 됨.

그 후 Draw 함수에 아까 글자 출력을 넣던 위치에 다음 줄을 넣어보자.

spriteBatch.Draw(texture, new Rectangle(0, 0, 480, 800), Color.White);

 

그리고 이쯤이면 다들 눈치챘겠지만 Content.Load 함수는 템플릿.. 그렇다. C#에서는 제네릭 형식으로 콘텐츠 파이프라인이 지원하는 형식이면 모두다 넣을 수 있다.

그래서 난 성공했다.

 

다음엔 스프라이트에 대해 알아보도록 하겠다.

Posted by TY
,

Windows phone 7 개발하기

  1. 다운로드
    1. Windows Phone developer tools

      http://msdn.microsoft.com/en-us/library/ff402530(v=VS.92).aspx 에서 다운로드

      Windows Phone Developer Tools

      Windows Phone Developer Tools January 2011 Update

      개를 다운로드 받는다.

      현재 영어, 불어, 독어, 이탈리아어, 스페인어밖에 Localizing 되어있지 않다. ( 영어로 해야 한다는 이야기 --.. 4개중에 영어보다 잘하는 있는 사람은 위의 4 개를 이용하는 것도 좋을 같다.)

      XNA Game Studio 4.0, Silverlight 4 for Windows Phone 툴에 모두 통합되어 있다. (Visual Studio 2010 Express for Windows Phone 또한 포함되어 있기 때문에 원한다면 설치할 있다)

    2. WP Emulator의 최저 사양
      1. Windows Vista, 7 32bit & 64 bit

        XP, Server 제품 군, 가상 머신은 지원하지 않는다. 2008, XP에서도 개발할 수 있으나 특정 기능이 지원하지 않을 수도 있다.

      2. 2G 이상의 램(그리고 1.5GB 이상의 여유공간이 있어야 한다 – 한 마디로 4G 정도는 되야 에뮬레이터를 돌릴만한 이야기)
      3. XNA Frameworks기반으로 작성된 프로그램을 구동시키기 위해서는 DirectX10 이나 11 이상을 지원하는 그래픽카드, 드라이버가 WDDM 1.1 혹은 그 이상의 버전의 드라이버로 작성되어있어야 함
      4. Blur나 Drop shadow는 에뮬레이터에서는 지원하지 않는다
      5. mouse로는 멀티터치를 지원할 수 없다. 사용자의 기기가 멀티 터치를 지원하는 입력기기를 가지고 있다면 지원 가능.
      6. 가속센서, GPS, 카메라는 아직 에뮬레이터에서 지원하지 않는다.
  2. Silverlight와 XNA를 선택하는 기준

Silverlight를 사용할 때

XNA를 사용할 때

XAML기반의 event driven application framework 개발을 원할 때

높은 퍼포먼스의 게임 제작을 원할 때

인터넷에서 사용하는 형식의 어플리케이션을 빠르게 개발하고 싶을 때

다중 화면의 2D-3D 게임 개발을 원할 때

WP7에서 지원하는 UI를 쓰려 할 때

XNA 컨텐츠 파이프라인을 이용하려 할 때

model,mesh,texture,effect,terrain,animation등

동영상 재생을 하려고 할 때

 

HTML 웹 브라우저 컨트롤을 쓰려 할 때

 

 

  1. 개발 환경
    1. 해상도: 800*480, 480*320 2가지 해상도가 존재한다.
    2. CPU: 1Ghz 이상의 ARM v7 "Coretex/Scorpion" (Apple 의 A4는 Coretex A8이고, 이 또한 ARM v7계열이다)
    3. GPU: DX9이상 렌더링이 가능한 GPU – 이것은 XNA 게임을 구동할 수 있는 디바이스가 되기 위함이다.
    4. 메모리: 256MB 이상의 램과 8G이상의 플래시 메모리를 탑재하여야 한다. 현재 마이크로 소프트는 WP7에 SD카드를 허용하지 않고 있다.
    5. 센서: 가속 센서, 컴퍼스, 조도, 근접, 카메라, GPS를 갖고 있다
    6. FM: WP7은 FM 라디오를 지원한다
  2. 개발 도구 소개
    1. Visual Studio 2010 - 개발을 할 때 쓰이는 IDE
    2. Windows Phone Emulator Resources – 핸드폰 에뮬레이터
    3. Silverlight 4 Tools For Visual Studio – XAML 기반의 RIA 형식 개발을 하고자 할 때
    4. XNA Game Studio 4.0 – 게임 개발을 위해
    5. Microsoft Expression Blend for Windows Phone – 최적화된 Silverlight
  3. 설치하기
    1. vm_web.exe를 실행한다
    2. 모두 설치한다
    3. WindowsPhoneDeveloperResources_en-US_Patch1.msp를 설치한다. 확인 문구 등이 안 나와서 설치가 다 된 건지 의아할 수 있으나, 다 된 거다.
    4. 그 다음 VS10-KB2486994-x86.exe를 설치한다.
  4. 첫 구동
    1. 한글 VS 2010에서는 WP7의 프로젝트가 보이지 않는다
    2. http://kenial.tistory.com/739 사이트를 참조하자 :)
    3. 메뉴 바에 있는 Windows Phone 7 Devices 를 Windows Phone 7 Emulator 로 바꾸고 컴파일 한다.
    4. 와 된다!
Posted by TY
,