엄청 많은데 그 때 급급해서 다 못 적어 놓은 것 같다.... 아쉽다


iBatis SqlMap 에서 DOCTYPE root 'null' 발생시..

  • 위에 주석같이 생긴걸 빼먹거나 지우는 경우가 있는 것 같다. 하지만 여기엔 그 주석을 꼭 써주어야 한다. DOCTYPE 을 정의해주기 때문...
  • sqlMapConfig 와 sqlMap 파일 각각 다르기 때문에 따로 적어 줄 것
  • http://www.bywoong.com/?p=1816

Error parsing XPath '/sqlMap/update'. Cause: java.util.NoSuchElementException

  • 조건에 #을 빠뜨린 것
  • 각각의 값에 #이 붙어있는지

Error creating bean with name '-----': Injection of resource fields failed; ....

  • 톰캣을 올리다 에러가 난다
  • Service Interface 를 Implements 한 클래스에 @Service 가 붙어있는지 확인하자


'study > java' 카테고리의 다른 글

java.net.BindException: permission denied: 80  (0) 2013.09.22
간단한 jpg(jpeg) 리사이징하는 java 클래스  (0) 2013.03.12
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
,


친구들이 제 생일이라고 책을 하나 사줬습니다.

정확히는 제가 사달라고 한 책을 사줬습니다. .... ;;;

이자리를 빌어서 감사함을 표합니다 :)

원래 하고자 하는건 C/S 개발이고
그렇게 어리지 않았지만 어렸을 때 꿈은 게임 개발이었고
현재 주 수입원은 프로그래밍 교육이며
제일 많이 경력을 가지고 있는건 웹 객발인 저는 ...

하던걸 해야된다는 옛 어른들(?)의 말씀을 본 받아.. 웹 개발 공부를 또 합니다. :|

지금 안드로이드 공부도 하고 있고, 학교도 다니고 있고, 일도 하고 있지만 ... 뭔가 나태하다는 느낌이 자꾸 듭니다.

HTML5와 웹표준은 피할 수 없는 운명같은 겁니다. 정부는 ActiveX를 없애고 새로운 스마트 사인이라는 신종 강요 정책(-_-;)을 저희에게 선물하려고 하는데 .. 웹표준 정책은 이미 밀어붙여지고 있고 RIA를 쓰지 않는 건 어느샌가 익숙한 일이 될 것 같습니다.

그리고 모바일 플랫폼등을 지원하기 위해서는 확실히 배워 둘 필요가 있구요.


그래서 보고 있습니다.
소감은...

아직요..^^; 1/4도 못 읽었습니다.


그래도 여태까지 가장 감명 깊게 읽고 또 자주 찾아보는 책은



이 책인데 ...

이제 잊을 때가 온 건가... 싶어요..-_ㅜ
Posted by TY
,


프로그래밍을 하다가 주변에 질문을 하게 되면 질문 받은 사람들은 주로 뭐라고 대답을 하나요?

전 주로 두 가지 답변을 합니다.

"소스 줘봐" 혹은 "디버깅 돌려"

첫 번째꺼야 그러려니 해도, 두 번째 이야기를 할 때 난관에 봉착하더군요. 디버깅을 어떻게 하냐던데..

그래서 디버깅에 대해 글을 한 번 써보기로 했습니다.

일단 디버깅이 뭘까요?

Wikipedia에서는 이렇게 설명을 합니다.

" 디버그(debug)는 컴퓨터 프로그램 상의 오류(버그)를 찾아내어 바로잡는 과정을 뜻한다. 디버깅(debugging)이라고도 한다. "

보통 프로그램을 디버깅하게 되는 이유는 논리적 오류(Logical error) 때문입니다.

오류에는 크게 2 종류가 있습니다.

문법적 오류(Syntax error) : 해당 언어의 문법에 적합하지 않아서 컴파일러가 번역을 못하는 경우 컴파일러는 Syntax Error를 많이 겪습니다. 컴파일 하기 전에 오류가 발생하는 경우는 이 경우입니다.

논리적 오류(Logical error) : 논리적으로 발생하는 오류입니다. 문법적으로는 문제가 없으나 실행해보면 문제가 생기는 경우죠. 다음과 같은 경우를 주로 이야기합니다.

int arr[10];

for(int i=0;i<12;i++)
{
	arr[i] = [i];
}

이 소스코드는 int 형 배열 arr[10]의 12번째 원소 arr[11]을 접근하면서 할당되지 않은 메모리 사용이나 범위를 벗어났다고 오류가 발생하게 됩니다. 이런건 간단한 예외(Exception)인데, 논리적 오류는 주로 다음과 같은 것을 일컬습니다.


int a = 0;

while(a < 100)
{
	a = 1;
}

 이 프로그램은 a += 1 을 하려고 했는데 a = 1 으로 한 논리적 오류로 해두겠습니다. 저번에 학생들 수업할 때 진짜 저런 학생이 있었어요. 어쨌든 저 프로그램은 메모리 오류가 나는 것도 아니고 문법적 오류가 있는 것도 아니지만(이클립스에선 잡기도 합니다. 이클립스는 똑똑해요..)  무한 루프에 빠지게 됩니다.

이 정도 소스코드면 딱 보면 누구나 에러를 찾을 수 있으나, 코드가 방대해지면 저와 같은 간단한 논지에서 찾을 수 있는 에러도 찾을 수 없습니다. 게다가 본인이 짠 코드에 대한 확신이 강한 사람은 프로그램이 방대해질 수록 초보적인 실수에 대해 자신은 그러지 않을거란 과신을 갖게 되고 확인을 하지 않게 되죠.

그렇다면 디버깅이란건 뭘까요?

사전적 정의는 위에 언급했고, 흔히 말하는 디버깅 해보라는 이야기는, IDE(Intergrated Development Environment, 통합개발환경)에서 제공해주는 디버거 툴(debugger tools)을 사용해서 디버깅을 진행해보라는 이야기입니다.

디버깅은 주로 소스코드를 인터프리트형식으로 실행하며 line by line으로 현재 메모리에 저장된 변수들의 값을  추적하고 루틴을 살펴보는 방식입니다.

그러면 300줄이면 300번 확인을 해야 하는건데 이런 귀찮은 일을 왜 해야 할까요? 시간 아깝게.

인터넷을 보거나, 주변 사람들을 보면 이런 허탈한 류의 이야기가 많습니다.

"내 코드가 이상해서 12시간동안 봤는데, 변수 하나를 할당을 잘못 해줬지 뭐야 아오 어이없어!"

"내 코드가 실행이 안되는거야. 그래서 봤는데 for문 옆에 세미콜론을 붙였어 3시간이나 보고 있었는데"

라던가.. 이런 류의 이야기들을 많이 보셨거나 들어보셨을 겁니다.

 이게 디버깅을 천천히 해봤으면 어디가 문제인지 쉽게 알 수 있는 일인데 디버깅을 안하면서 생기는 일일 경우가 많습니다. 디버깅은 선택이 아니라 필수적인 습관이라 생각하며 여러분에게 권장하고 싶습니다.

다음 글에서는 Visual Studio에서 디버깅하는 방법을 알아보겠습니다.
Posted by TY
,

 좀 된 이야기지만 SONY, 정확히는 SCE(Sony Computer Entertainment, 국내 지사로는 SCEK)에서 안드로이드에 SONY 인증을 받은 기기에 한해 PS(Play Station) 계열의 컨텐츠를 제공한다고 합니다. 그리고 MS 또한 Windows Phone에서 XBOX 및 Windows 기반의 게임들을 즐길 수 있게 하겠다고 하지요.

 지금의 가정용 콘솔 게임기와 휴대용 콘솔 게임기는 시장을 달리하고 있지만, 처음 예측과는 다른 방향으로 승부하고 있습니다. 초기의 게임 시장에서 PSP와 NDS가 격돌할 때만 하더라도, 휴대용 기기는 게임 호흡이 짧고 중간에 멈춰도 페널티가 크지 않은 캐쥬얼한 게임들에 한정하여 성공할 것이며, 가정용 콘솔 기기는 휴대용 기기에서는 구현할 수 없는 훌륭한 그래픽과 장대한 게임으로 승부를 내려고 했죠. 

 하지만 NDS와 PSP에서 대작 타이틀이 나오면서 오히려 집에서 휴대용 기기를 붙잡고 나오지 않는 - 이것은 저 두 기기의 킬링 타이틀의 게임성이 상당히 훌륭했기 때문에 나온 현상이긴 합니다. - 사람들이 일본에서 사회적 이슈가 될 정도로 기존의 예상을 뒤엎었습니다. 그래서 초기에는 휴대용 게임기의 본질을 살린 숨이 짧고 기기의 특성을 살린 게임들이 많이 발매되었지만, 그 후에는 전 세대의 기종(PS, GC, N64)등의 게임을 컨버팅 및 리메이크해서 나오는 게임들도 상당 수가 되었습니다. WIFI를 이용한 온라인 대전 게임등 어느새 휴대용 콘솔은 가정용 콘솔이 해야 할 자리들을 빼앗기 시작합니다. 가정용 콘솔에게 남은 건 웅장한 그래픽과 용량에 거의 구애받지 않는 대작 게임들이 되버립니다. 

 물론 제작사인 두 회사는 퍼스트 파티뿐만이 아니라 게임을 공급하는 세컨드, 써드 파티에게도 각 기종 게임의 차별성을 요구하게 됩니다. 물론 제작사 측에서도 팀킬을 하는 상황은 원치 않았을 겁니다. 가정용에서 큰 볼륨의 게임을 휴대용에서 외전격이나 그래픽 및 스토리라인을 다운그레이드해서 휴대용으로 발매하는 방식을 이용하기도 하고, 각각 기기의 특성에 맞춘 타이틀의 시리즈를 달리 하기도 했습니다. 그렇게 해서 현재의 시장은 두개 다 갖고 싶은 시장이 되었네요. 

 하지만 스마트폰의 게임기 가능은 이야기가 많이 다릅니다. 휴대용 기기가 가지고 있는 장점은 말 그대로 휴대성인데, 휴대폰에서 그와 같은 수준의 게임이 구동된다면 구지 휴대용 기기가 필요할까요? 피쳐폰 시절부터 휴대폰의 MP3기능이 훌륭해지고 있었고, 그에 따라 MP3 플레이어 시장은 어느샌가 휴대폰 시장과의 잠재적 경쟁 구도를 가지게 되었습니다. MP3 플레이어의 매력을 많이 잃게 되었죠. 같은 맥락의 이야기라고 생각합니다. 저는 신기술이 새로운 시장을 개척하지만, 기존의 시장을 사장시키는 현상이라고 봅니다.


 시대는 계속 새로운 시장을 찾아서 이동하는 걸까요. 테이프는 CD로 넘어왔고, CD는 MP3로 넘어왔지요. 제가 어렸을 때 유명 가수들의 CD 판매량은 100만장을 쉽게 돌파했던 것 같습니다. 하지만 지금은 100만장을 팔면 상당히 기적적인 일이라고 하네요. 2010년 최대 판매 앨범이 모 아이돌의 정규 앨범이었는데, 자체 집계상 20만장 정도가 팔렸다고 하네요. 이렇게 CD가 팔리지 않게 된 것은 작고 고용량인 MP3 플레이어가 아무리 작게 만들어도 CD보다 작을 수 없는 CDP의 상품성과 경쟁력을 넘어섰기 때문이라고 할 수 있는 것 같습니다. 반도체 기술의 발전에 의한 플래시 메모리의 단위 면적당 용량의 상승, 절전 기술의 발전과 베터리의 소형화로 인해 MP3 플레이어는 CDP의 상품성을 넘어서게 되버렸습니다.

 64MB 용량을 가진 MP3가 30만원일 때 사람들은 20만원짜리 MP3CDP(MP3파일을 기록한 것을 재생할 수 있는 CDP)가 더 좋다고 느꼈지만, CD 용량과 흡사하지만 훨씬 작고 베터리도 오래가는 MP3 플레이어들이 가격 경쟁력을 갖추고 발매되면서 MP3 플레이어 시장이 CDP시장을 잠식했다고 생각합니다.

 지금은 초기 단계이니 배터리 문제나 기종별 호환성의 문제등에 많이 부딪힐 거라고 생각합니다. 게임의 호환성 및 이식성, 그리고 최종적으로 게임의 퀄리티 문제에 부딪히지 않을까요? 그동안 통일된 플랫폼에 게임을 제공했던 업체들은 다채로운 기종에 게임이 모두 호환될 수 있게 하는 부분이 상당히 부담스럽고 힘든 문제로 다가오겠지만, 아이폰 개발과 안드로이드 개발이 같은 문제를 안고 있었지만, 지금 보면 안드로이드 시장은 지금 충분히 성장했고 개발자가 얻을 수 있는 피드백또한 두 시장 모두 훌륭히 성장했기에 모바일 플랫폼에서의 정착 또한 시간 문제라고 생각됩니다.

 지금 주위를 둘러보면 MP3 플레이어나 PMP를 조작하고 있는 사람들보다, 스마트폰을 조작하며 같은 기능을 즐기고 있는 사람이 더 많지 않을까요? 언젠가 거기에 휴대용 게임까지 추가될꺼라 봅니다.

 인터넷 기사를 살펴보면 닌텐도의 위기라거나, 애플의 위기라고 일컫습니다. 두 업체의 공통점은 H/W 및 S/W를 자체 개발하는 회사라는 점과 폐쇄적이란 점이 있다고 보는데요. 아이폰 개발 커뮤니티에 보면 '리젝(Reject, 여기서는 개발자가 등록을 하려고 하나 애플측에서 불허하는 것을 이야기함)'의 추억에 대한 이야기도 있고, 닌텐도의 써드 파티가 되고 싶은 회사들도 상당히 무리가 있었다, 라는 이야기를 많이 들어보셨을 겁니다. - 물론 PS계열은 더 만만치 않습니다. 하지만 소니는 핸드폰도 만드니까 저런 일을 하는거겠죠 -

 애플측 또한 소니등과 게임으로 협력할 의향이 없다고 밝혔으며, 닌텐도또한 그러지 않을것이라 생각합니다. 그리고 인터넷 기사에서는 이것이 그들의 패인이 될 것이라고 말하는 것 같습니다.

 과연 어떻게 될까요. 스마트폰은 휴대용 게임기의 시장을 잠식할 수 있을까요? 그거야 업계의 정책에 따라 달린 것이겠지만, GXG나 GPANG이 망했던 것을 생각하면 그들의 사업이 쉽게 성공할 수 있을지 모르겠습니다.

 정작 게임에 돈을 많이 쓰는 사람들은 그렇게 개방적이지 않으니까요 :)
Posted by TY
,

08년에 WEB 2.0에 관해서 세미나? 까진 아니고.. 뭐 발표를 한 번 한 적이 있습니다. 그에 관련된 강연도 참 많이 들었었기에, 준비는 상당히 수월하게 했지만.. 인터넷의 한 기사를 읽으니 그 때 그랬던 기억이 나네요.

제가 그 관련해서 가장 인상 깊었던 것은 옴니아의 외국 버전 광고였습니다. Youtube에서 검색하면 볼 수 있는데, 동영상 자체에서 선택을 통해 마치 비주얼 노벨을 진행하는 듯한 방식으로 광고를 즐길 수 있었죠. 조회수도 상당했고, 국내·외 적으로 상당한 반응을 일으켰던 것으로 알고 있습니다.  WEB 2.0에 부합하는 광고다 라던가 등등의 수식어가 붙었던 걸로 기억합니다. 이걸 세미나에서 처음 볼 때 저도 굉장히 신선하다고 생각했었지요.

물론 블로그도 처음에는 사용자가 자신의 글을 기록하고 개방하여 지식과 경험을 교류하자는 차원에서 나왔지만, 조회수가 높아지거나 특정 분야에 전문성을 가진 블로거들은 어느샌가 상업성의 유혹을 받게 되고, 배너 삽입등을 넘어서서 리뷰를 가장한 광고를 하게 되기도 하죠.

많은 업체들도 인터넷 배너 광고보다는 흔히 '파워 블로거'라고 불리는 집단들이 자신들의 상품을 리뷰하는 것이 더 홍보효과가 좋다고 느끼게 되고, 이들에게 제품을 주고 사용기 등을 작성해 주는 것을 원하게 됩니다.

물론 그로 인해 제품에 대한 정보와 피드백이 많아져서, 댓글 알바등에게 휘둘리지 않고 좋은 상품을 선택할 수 있는 방법의 폭이 더 넓어졌지만 글쎄요... 굉장히 이 이야기를 들으며 씁쓸했던 기억이 나네요.

그리고 그것을 넘어선 이후 기업 자체에서 블로그를 운영하거나, 직원들의 블로그 운영을 장려하는 수준에 이르렀습니다. 마치 일반 유저인 듯 하지만 사실은 해당 기업의 사원이 경우도 적지 않지요. 대표적인 예로는 MS가 있겠네요. MS는 직원들의 블로깅을 종용하는 기업 중에 하나죠.

 이를 넘어서 각 회사에서는 파워블로거를 영입해서 본인들의 회사를 홍보하는 용도 혹은 회사 블로그를 운영하도록 합니다. 그들이 받는 액수는 일반 서무직보다 많고, 더러 기술자보다 많이 받는 경우도 있지요. 글쓰는 기술의 승리라고 할까요? :)

그래서 저도 블로그를 열심히 해보려 했으나, 선천적인 게으름 및 그렇게 남이 혹할만한 주제를 쓴 적이 없어서.. 여태까지 써 본 블로그가 5개 정도 되지만, 최대 투데이가 500을 넘긴 적이 없지요..^^;; 500을 넘긴 건, 그때 한참 이슈인 주제에 대해 큰 태클을 걸어서 그랬던 것 같습니다. 그 전에 블로그에는 거의 와우, 일상, 미스터 블로그씨(?!)에게 시비걸기 등이 내용의 주였습니다.  뭐 간혹가다 게임 개발이나 그런 글을 올릴 때가 있었지요. 정말 심심할 때는 개발툴에 대한 이야기도 썼던 것 같습니다. 그런게 유입 키워드로 적용되서 투데이를 간간히 유지했지요. 지금도 투데이 유지하는 거 보면 'mysql_fetch' 라던가 'MSSQL LIKE', 'css 얻어오기' 등등이네요 :| 그래서 하루에 5명은 들어오는 것 같아요.

어쨌든 뭔가 주제에 벗어난 것 같습니다.. 원래 쓰려고 하던 주제는 이 기사를 보고 쓴거지요.

http://news.mk.co.kr/v3/view.php?year=2011&no=77948

SNS를 이용해서 광고를 한다고 하네요. 거 참...

트위터나 페이스북같은 서비스는 서로 관계되지 않은 사람들끼리도 관계 엮이기가 참 쉽지요. 예를 들자면 연예인들의 경우는 그들의 소식을 궁금해하는 팬 및 기자가 그들을 팔로잉 할 것이며, 유명 기술자나 정치인 같은 경우도 그들의 동향을 궁금해하는 사람들이 많이 팔로잉을 하겠지요. 그 뿐만 아니라 열심히 트위터를 하는 일반인 기술자도 팔로잉 하는 사람이 참 많겠네요..^^;

그런데 그들이 무언가 이 제품에 대해 글을 올려서 링크를 한다면? 그럼 사람들은 휴대기기나 SNS 프로그램으로 접속을 할테고, 그럼 그 상품에 대해 광고가 되겠네요.

하루에 75만원이라는건, 뭐 중학생이 앱 만들어서 대박 부자됨.. 이라는 거랑 다를 바 없는 이야기지만 상당히 많은 이웃을 보유하고 있는 SNS유저들은 혹할 만 하네요. '나정도로 팔로워 있으면 저런걸로 수익을 올릴 수 있지 않을까?' 라는 생각을 이 사람 저 사람, 참 많이 할 것 같네요.

그러다보면 어느새 SNS도 블로그처럼 광고인지 아닌지 구분되지 않는 글들이 많아지겠지요. 뭐 그에 대한 효과는 상호 톡톡히 보겠지만, 정의로운(?) WEB 2.0 발전에 대해서는 별로 도움이 될 것 같지 않네요. 그러다보면 사람들이 아무리 Adsense를 달아도 돈을 많이 못 버는 것 처럼 ..... 그렇게 되겠죠? 사실 잘 모르겠습니다.

어쨌든 좀 씁쓸하네요, 이것 저것 다 돈벌이랑 연관이 되는군요.

'뭐 하나 잘하면 돈을 벌 수 있구나' 라는 생각이 드는게 아니라, '이것까지 돈벌이에 결부되어야 하나' 라는 생각이 듭니다..

함부로 클릭하기 두려워 지겠군요, 광고일까봐 ㅎㅎ 이런 참...
Posted by TY
,