C++ 클론코딩 무작정 따라서 만들어보기 2탄

Junghwan Kim·2023년 5월 25일
0

오늘은 자전거 게임의 코드를 분석해보면서 코드를 이해하고 알아가는 시간을 가져보려한다. 물론 당연히 내가직접 이 프로젝트의 코드를 따라서쳐보면서 실행화면까지 띄워보면서 했었더라면 더 좋은 성과,성취도를 낼수있었겠지만 1탄을 보면 알수있듯이 그렇다... 실행화면을 띄우는데엔 실패를 하고말았다. 아쉬운대로 코드분석을 해가면서 최대한 이 자전거게임을 이해하고 분석하고 기존에 있던 실행파일이 있으니 이걸가지고 프로그램을 이해해나가는 시간을 가지는수밖에...
우선 이 게임의 핵심이라 볼수있는 main.cpp의 코드는 다음과 같이 되어있다.

#include <iostream>
using namespace std;
#include <sstream>
#include <SDL/SDL.h>
#include "SDL/SDL_image.h
#include "SDL/SDL_ttf.h"
#include "constants.h"
#include "string"
#include "coardinate.h"
#include "variable.h"
#include "init.h"
#include "function.h"
#include "collision.h"
#include "process.h"
#include "menu.h"


int main(int ch,char *cha[])
{
     if(!init_all())
     return 0;

     if(!load_files())
     return 0;

     int opt=start_menu();


     return 1;
}

SDL라이브러리 그리고 프로젝트에서 미리 만들어놓았던 헤더파일들을 메인쪽에 인클루드 시켜서 int형 변수 opt에 start_menu()를 호출하여 저장하고 1을 반환하여 프로그램을 실행시키는 방식인듯 하다.
다음으로는 variable.h의 코드를 살펴보도록 하겠다.

 SDL_Surface *screen=NULL;
     SDL_Surface *back[2]={NULL,NULL};       //Holds three background..
     SDL_Surface *upback=NULL;
     SDL_Surface *bike=NULL;
     SDL_Surface *obs_wall[2]={NULL,NULL};
     SDL_Surface *menu_pic=NULL;
     SDL_Surface *play_menu=NULL;
     SDL_Surface *instruction_menu=NULL;
     SDL_Surface *quit_menu=NULL;

     TTF_Font *font=NULL;

     SDL_Surface *times=NULL;
     SDL_Surface *time_limit=NULL;
     SDL_Surface *die=NULL;


     SDL_Color textColor={225,0,0};
     SDL_Event event;                             //For checking the event happen...
     Uint8 *keystate=SDL_GetKeyState(NULL);       //for check key event keys..

//Variable for background...
     background bg[2];

//variable for time..
     int start_time;
     int end_time;
     int time_gap;

     int speed;

     int jump_state=0;
     int max_limit=200;



//variable for bike..
     int bike_stand=LAYER_Y;
     int bike_x=START_BIKE_X;
     int bike_y;
//Variable for wall...
     wall w1[SMAX_WALL];
     wall w2[BMAX_WALL];

//Game states..
     int game_on=1;

메인파일에서 각종 SDL라이브러리들을 인쿨루드 시켜주었기에 별다른 문제없이 SDL라이브러리 형식의 변수들을 선언할수 있었고 자전거에 들어갈 변수 벽 플레이메뉴 종료메뉴 등등 게임이 실행될때 나오는 초기화면은 전부 SDL Surface형 변수로 선언을 해주는것을 알수있었다. 그리고 나중에 여기에서 만들어진 변수들이 각각 또다른 헤더파일들에서 쓰여진다는것을 클론코딩을 통하여 알수있었다. 여기서 이제 간단하게 몇개정도 짚고 넘어갈게 있다면 SDL Surface란 소프트웨어를 blitting할때 사용되는 픽셀들을 모아놓은 집합(컬렉션)을 포함하고있는 구조체 라고 한다. 그외에도 SDL_Color,SDL_Event 등등 각종 SDL선언 형식이 궁금하신 분들은 https://wiki.libsdl.org/SDL2/FrontPage 이 링크로 들어가서 정보를 찾으면 쉽게 알수있을것이다. 다음으로는 메뉴를 구성하고있는 메뉴헤더파일을 살펴보겠다.

int start_menu()
{
     bool running=true;
     int x,y;

     bike_process bk;
//https://www.willusher.io/sdl2%20tutorials/2013/08/20/lesson-4-handling-events
     while(running)
     while(SDL_PollEvent( &event ) )
     {
          if(event.type == SDL_MOUSEMOTION)
          {
               cerr<<"inside"<<endl;
               x = event.motion.x;
               y = event.motion.y;
               if((x>594) && (x<756) && (y>340) && (y<357))
               {
                    apply_surface(0,0,play_menu,screen);
               }
               else if((x>572) && (x<778) && (y>414) && (y<431))
               {
                    apply_surface(0,0,instruction_menu,screen);
               }
               else if((x>641) && (x<708) && (y>490) && (y<506))
               {
                    apply_surface(0,0,quit_menu,screen);
               }
               else
               apply_surface(0,0,menu_pic,screen);
               SDL_Flip(screen);

        }
        else
          apply_surface(0,0,menu_pic,screen);
          SDL_Flip(screen);
        if(event.type == SDL_MOUSEBUTTONDOWN)
          {
               x = event.motion.x;
               y = event.motion.y;
               if((x>594) && (x<756) && (y>340) && (y<357))
               {
                    while(bk.process())
                    {
                         SDL_Flip(screen);
                    }
               }
               else if((x>572) && (x<778) && (y>414) && (y<431))
               {
                    apply_surface(0,0,instruction_menu,screen);
               }
               else if((x>641) && (x<708) && (y>490) && (y<506))
               {
                    return 0;
               }
          }
     }

     return 0;
}

여기서부턴 코드를 분석하는데 좀더 난이도가 높아진 느낌이 든다. bool형 변수인 running이 true 상태일때
SDL_PollEvent( &event ) 함수가 호출되는데 아직 처리되지않은 이벤트를 가져올때 사용되는 함수이고 매개변수로 event변수의 주소가 들어간다. 그리고 event의 type이 SDL_MOUSEMOTION일경우 if문을 실행하는데 이말은 마우스가 움직일때 이벤트가 일어나면 이라는 걸로 이해를 하면 된다.
그럴경우 x와 y변수에 마우스의 좌표값을 받아와서 x값과 y값의 범위가 if문에 주어진 조건에 충족을하면 apply_surface함수를 호출하는데 이 함수는 원래 있던 함수가 아닌 사용자가 임의로 정의한 함수이기에 나중에 따로 알아보도록 하고 이런식으로 함수를 계속해서 호출해 사용하다가 마지막줄에 SDL_Flip(screen)함수를 호출하고서 else문으로 넘어가는데 SDL_Flip함수는 버퍼를 바꿔치기할때 사용되는 함수이다. 다음으로 살펴볼 함수는 SDL_MOUSEBUTTONDOWN 이다. 마우스의 왼쪽혹은 오른쪽 버튼을 눌렀을때 발생하는 type이고 마찬가지로 그런경우 x와y변수에 마우스커서의 위치정보를 넣어주고서 bk.process()함수일동안 버퍼를 계속 바꿔치기 해준다.
bk.process는 나중에 헤더파일들을 좀더 분석해보고 하다보면 좀더 자세하게 알수있을듯 하다.
나머지 코드들 같은경우에는 그외의 경우 다시 메뉴화면을 띄워주거나 마우스 커서가 조건을 벗어나버리면 종료가되게 만들게끔 해주는 코드인듯 하다.
3탄에서 계속...

profile
안녕하세요~

0개의 댓글