Naver Perl Community & Study Cafe


2009.09.23 14:00

Xna Pong Game


XNA 공부를 시작한지 어느정도 지났다...

이리저리 다른일한다고 핑계만 대다가,

기본서인 "실전 예제로 배우는 XNA Game Programming"  를 제대로 보기로 결심하고 천천히 살펴보던 중

이 책의 첫번째 게임 예제는 Pong 게임을 접하게 되었다.



서로 공을 주고 받으며, 대전을 하는 게임인데

공만 주고 받으면 심심하니 변수를 하나 만들어 보았다.


중앙에 운석을 하나 넣어서

그 운석에 맞으면 다른곳으로 튕겨나게....

헙.. 말은 쉽지만 구현하는데는 까다로울 듯 하다.



일단 Content에 Meteo 라는 운석 이미지를 추가를 한 뒤

LoadContent() 함수에 가서 meteorite 이미지를 불러온다.


texmeteo = Content.Load<Texture2D>("meteorite");


그리고 StartNewMeteo 이라는 함수를 만들어 처음 운석의 자리를 정해준다.

public void StartNewMeteo()
{
            MeteoPosition = new Vector2(0.5f, 0.5f);           // 0.5f , 0.5f 는 정 중앙을 뜻한다.
}

그리고 이미지를 출력하기 위해 RenderMeteo 함수도 만들어 준다.

public void RenderMeteo()
{
      RenderSprite(texmeteo, (int)((0.05f + 0.9f * MeteoPosition.X) * 1024) - MeteoRect.Width / 2,
                        (int)((0.02f + 0.96f * MeteoPosition.Y) * 768) - MeteoRect.Height / 2,  MeteoRect);
}





그리고 게임이 그려지는 Draw 함수 안에서

게임이 시작되었을 때 RenderMeteo() 함수만 불러주면 이미지 출력은 손쉽게 이루어진다.



허접하지만 운석그림이 화면에 출력되는것을 확인할 수 있다.


이제부터가 중요한데

Ball 이 저 운석에 충돌할때 되면 다른 방향으로 꺽어지는 부분은 어떻게 하면 좋을까?

일단 Ball 과 운석이 충돌했을때를 먼저 구현해보도록 하자.



이 부분은 Update 함수에서 구현을 하면 되는데,

공과 패들이 충돌할 때와 동일하게 구현하면 손쉽게 처리 할 수 있다.

일단 Meteo의 Size를 구하여, MeteoBox를 먼저 구해놓는다.

Vector2 MeteoSize = new Vector2(MeteoRect.Width / 1024.0f, MeteoRect.Height / 768.0f);

BoundingBox MeteoBox = new BoundingBox(new Vector3(MeteoPosition.X-MeteoSize.X/2, 
                           MeteoPosition.Y-MeteoSize.Y/2, 0),  new Vector3(MeteoPosition.X+MeteoSize.X/2,
                           MeteoPosition.Y+MeteoSize.Y/2, 0));


그 후에 Ball 과 MeteoBox가 충돌했는지의 여부를 파악한다.

if (ballBox.Intersects(MeteoBox)){

          // 출동했을시 실행

}


충돌했을때의 처리가 약간 까다로울텐데,

어디에서 공이 충돌하느냐에 따라 튕겨나가는 방향을 다르게 처리해야한다.

예를들어 운석은 4가지의 방향이 있는데 이 4가지를 모두 처리해보자.



if (ballSpeed.X < 0)
{
         ballSpeed.X = Math.Abs(ballSpeed.X);
}
else if (ballSpeed.X > 0)
{
         ballSpeed.X = -Math.Abs(ballSpeed.X);
}
if (ballSpeed.Y < 0)
{
         ballSpeed.Y = Math.Abs(ballSpeed.Y);
}
else if (ballSpeed.Y > 0)
{
         ballSpeed.Y = -Math.Abs(ballSpeed.Y);
}


나같은 경우에는 이런식으로 처리를 했는데

BallSpeed의 X 와 Y의 값에 따라 패들을 튕기게 만들었다.

실제로 게임 플레이는 잘 되지만 알고리즘상으로 좋은것은 아닐듯.. 그냥 if만 쉐리 박은거라;;



이제 마지막으로 운석을 움직여 보겠다.

 if (MeteoPosition.Y < 0.2f || MeteoPosition.Y > 0.8f)
{
         MeteoSpeed.Y = -MeteoSpeed.Y;
}

if (MeteoPosition.X < 0.2f || MeteoPosition.X > 0.8f)
{
         MeteoSpeed.X = -MeteoSpeed.X;
}

MeteoPosition += MeteoSpeed * moveFactorPerSecond ;


사각의 공간을 만들어 그 공간안에서 운석을 움직여 보았다.

그럼 이제 컴퓨터에게 패들을 맡기고 게임을 구경해보자.





이정도야 ㅋㅋ

신고
Trackback 0 Comment 1