Your First Game: Microsoft XNA Game Studio Express in 2D XNA 튜토리얼

2006/12/26 00:59

http://blog.naver.com/jaco200/30012498500

  이번 튜토리얼은 2D 이미지를 스크린에 그리고 움직이는 것으로 XNA를 Install 하면  볼 수 있는 'XNA Game Studio Express Documentation'의 내용을 참고로 제작한 것이다.


1. 프로그램을 제작하기 전에 필요한 프로그램을 Install 했는지 확인!!(XNA Express v1.0 정식 버전과 Visual C# 2005 Express)


2. 새 프로젝트 만들기


<XNA 실행>


  정상적으로 Install 했다면 시작 프로그램에서 확인할 수 있다.

  시작->프로그램->Microsoft XNA Game Studio Express->XNA Game Studio Express를 클릭하여 XNA 프로그램을 시작한다.


사용자 삽입 이미지

<XNA 실행 화면>


  XNA를 실행하면 위와 같은 시작 화면이 나타난다. 새로운 프로젝트를 만들기 위해 File->New Project를 클릭하거나 단축키 'Ctrl+Shitf+N'을 클릭한다.


사용자 삽입 이미지

<New Project>


  만들 수 있는 프로젝트 스타일이 여러개 보인다. 윈도우 버젼의 게임을 만들것이므로 Window Game을 선택, Name란에는 MyFirstXNAGame이란 제목을 넣어주고 OK를 클릭한다.


사용자 삽입 이미지

<프로젝트 실행 화면>


  새 프로젝트를 만들어 실행한 화면이다. 프로그래머가 아닌 사람들에게는 난해하게 보일 수 도 있겠지만 실제 코드는 몇 줄 안되고 설명(주석)들이 주로 이루고 있다. 우측창(Solution Explorer)에 보이는 Game1.cs라는 파일의 내용들이다.(어려울 거 없다. 그냥 텍스트 파일이다.)


3. 코드 보기

  게임 프로그램은 일반적으로 다음의 다섯가지 단계에 따라 순차적으로 진행이 된다. ( Game1.cs 파일의 내용들이 바로 이러한 내용들을 적어 놓은 것이다. )


사용자 삽입 이미지
 
<게임 프로그램 실행 구조>

Initialize --> 초기화 단계, 게임의 로직과 관련된 수치들을 초기화 값으로 채워 넣는다. (캐릭터 정보 값과 같은 것들로 그래픽 리소스와는 별개이다.)


LoadGraphicsContent --> 그래픽 리소스들을 읽어 들인다. 캐릭터 이미지 같은 것들을 읽어 들인다.


  위의 두 단계를 거쳐 다음 두 단계에서는 루프를 돌며 게임이 끝날때까지 Update와 Draw를 반복한다.(우리가 흔히 게임 프레임이 60프레임이라고 하는 것도 이 루프가 1초에 60번 돈다고 생각하면 쉽게 이해가 갈 것이다.)


Update --> 키보드/마우스 등의 입력을 받고 게임 내 모든 오브젝트들의 상태를 업데이트한다. 예를 들어 주인공 캐릭터를 동쪽으로 1초 동안 2타일 만큼 움직이고 쉽다면 매 프레임마다 이 곳에서 입력을 받아 캐릭터 좌표의 상태값을 변경시켜 주는 것이다.


Draw --> Update 뒤에는 항상 그려주기(Draw)가 따라 온다. Update가 컴퓨터 내부적으로 계산되는 보이지 않는 단계라면 우리는 Draw라는 단계를 거쳐서 원하는 데로 캐릭터가 이동하는 지를 확인할 수 있다.


UnloadGraphicsContent --> 유저가 더 이상 게임을 하고 싶지 않아 게임을 종료하고 타이틀 화면으로 나가거나 윈도우 화면으로 나간다면 그 때까지 메모리에 담고 있던 이미지나 사운드 파일들을 해제해 줘야 한다.(그렇지 않다면 RAM이 가득 차서 문제가 생길테니까)


  게임 기획자로서 이정도만 이해하고 있어도 여러모로 도움이 될 듯 싶어 조금 설명을 길게 했다. 게임 프로그래머라면 너무나 뻔할 것이다.^^ 게다가 Direct X까지 다루었다면 너무나 익숙한 내용들일테니...


  먼저 아무런 코드의 추가없이 실행해보자.

  메뉴의 build -> build solution을 클릭(F6)해 빌드한 뒤, debug -> start debugging을 클릭(F5) 해 실행한다.


사용자 삽입 이미지

<실행 화면>


  아무 것도 그려지는 것 없이 파란색을 배경으로 한 창만 덩그러니 떠 있다. 이제부터 여기다 스프라이트를 그려 볼 것이다.


4. 스트라이트 더하기

  우측의 Solution Explorer 창에 마우스 오른쪽을 클릭해 Add -> existing item을 클릭한다.

사용자 삽입 이미지

<스프라이트 더하기-1>


  파일 열기 창이 나타나면 자신이 추가하고자 하는 이미지(jpg, bmp 등)를 선택한다. 여기서는 smile.jpg를 선택했다.

사용자 삽입 이미지
<스프라이트 더하기-2>
 
  Solution Explorer 창에 smile.jpg가 추가된 것을 볼 수 있다. 아래에는 해당 이미지의 속성창이 보인다.(만약 보이지 않는다면 F4 키를 눌러본다.) 아래 속성창에서 asset name이라는 것을 기억해라. 이미지를 로드할 때 이 이름이 필요하다.(asset name은 임의 변경 가능)
사용자 삽입 이미지
<스프라이트 더하기-3>
 
  자 이제부터 추가해야 할 코드들을 분석해 보자.
 
// 사용할 텍스쳐 클래스를 선언한다.
Texture2D myTexture;

// 스프라이트를 그릴 스크린 상의 좌표이다. vector2.zero를 통해 스크린 상의 (0, 0)부터 이미지를
// 그릴 것이다.
Vector2 spritePosition = Vector2.Zero;

// 사용할 스프라이트 오브젝트를 선언한다.
SpriteBatch spriteBatch;

// 그려질 이미지를 로드한다. 위에서 추가한 'smile.jpg'를 로드하는 것이다.
protected override void LoadGraphicsContent(bool loadAllContent)
{
    if (loadAllContent)
    {
        //assetname 'smile'에 맞추어 이미지를 로드한다.
        myTexture = content.Load<Texture2D>("smile");
        // 스프라이트 오브젝트를 생성한다.
        spriteBatch = new SpriteBatch(graphics.GraphicsDevice);
    }
}
 
  이미지가 실제로 그려지는 루틴인 Draw 부분이다.
 
protected override void Draw(GameTime gameTime)
{
    // 배경색을 CornflowerBlue로 채워준다.
    graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

    // Begin은 그리기의 시작을 알리고 End는 그리기의 끝을 알린다.
    // myTexture는 smile.jpg 이미지이고 spritePosition은 좌표 (0, 0)을 말한다.
    spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
    spriteBatch.Draw(myTexture, spritePosition, Color.White);
    spriteBatch.End();

    base.Draw(gameTime);
}
 
  이 상태까지 입력한 뒤 실행해 본다.(빌드(F6) 뒤에 실행(F5))
 

사용자 삽입 이미지

<실행화면>


  아까와는 다르게 스마일 이미지가 스크린 좌표 (0, 0) 부터 그려져 있다.(아무 움직임은 없다.)


5. 스트라이트 움직이기

  이제 상태값을 변화시켜 주는 코드를 추가해 보자. 이 루틴을 통해서 정지해 있던 이미지가 45도 방향으로 움직이며 벽에 닿으면 튕겨나가는 것을 확인할 수 있을 것이다.


// Vector2를 이용해 sprite의 이동속도 값을 담을 구조체를 선언한다.
Vector2 spriteSpeed = new Vector2(50.0f, 50.0f);

// Draw 루틴과 함께 가장 중요한 게임 내 오브젝트들의 상태값을 변경시켜 주는 루틴이다.

protected override void Update(GameTime gameTime)
{
    // 게임 플레이 중에 나가는(exit) 것과 관련된 루틴이다. 아직은 중요치 않으니 그냥 넘어가자.
    if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
        this.Exit();

    // UpdateSprite라는 함수 루틴을 호출한다.
    UpdateSprite(gameTime);

    base.Update(gameTime);
}


void UpdateSprite(GameTime gameTime)
{
    // elapsed time을 기준으로 매 프레임마다 스프라이트의 포지션에 값을 더해준다.

    // elapsed time이란 프레임에서 다음 프레임까지의 시간을 나타낸다. 이 시간은 Update와

    // Draw 루틴의 계산 양이나 PC의 사양에 따라 서로 다른 값을 갖는다.
    spritePosition += spriteSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds;

    // 스프라이트 이미지가 화면상에서 움직일 수 있는 최대치의 값과 최소값을 얻어낸다.

    // Viewport란 스크린 크기를 말한다.

    int MaxX = graphics.GraphicsDevice.Viewport.Width - myTexture.Width;
    int MinX = 0;
    int MaxY = graphics.GraphicsDevice.Viewport.Height - myTexture.Height;
    int MinY = 0;

    // 이미지가 이동을 하다 최대값이나 최소값에 도달하면 방향과 각도를 바꿔서 이동하게 한다.
    if (spritePosition.X > MaxX)
    {
        spriteSpeed.X *= -1;
        spritePosition.X = MaxX;
    }

    else if (spritePosition.X < MinX)
    {
        spriteSpeed.X *= -1;
        spritePosition.X = MinX;
    }

    if (spritePosition.Y > MaxY)
    {
        spriteSpeed.Y *= -1;
        spritePosition.Y = MaxY;
    }

    else if (spritePosition.Y < MinY)
    {
        spriteSpeed.Y *= -1;
        spritePosition.Y = MinY;
    }



Posted by BAGE