2013-01-18 3 views
1

저는 다양한 온라인 자습서와 몇 권의 책을 사용하여 프로그래밍을 배우고 있습니다. 현재 C++입니다. 지난 며칠 동안 OpenGL과 SDL을 조금 했어요.Xcode vs. Visual Studio - SDL C++

작은 사각형이 통과하지 못하도록 벽을 만드는 작은 프로그램이 있습니다.

// 
    // main.cpp 
    // SDL_Template 
    // 

    // The headers 
    #include <stdlib.h> 
    #include <string> 

    // SDL headers 
    #include <SDL/SDL.h> 
    #include "SDL_image/SDL_image.h" 
    //#include "SDL/SDL_ttf.h" 
    //#include "SDL/SDL_mixer.h" 

    // Other headers 
    #include <OpenGL/gl3.h> 


    // Screen attributes 
    const int SCREEN_WIDTH = 640; 
    const int SCREEN_HEIGHT = 480; 
    const int SCREEN_BPP = 32; 

    // The frame rate 
    const int FRAMES_PER_SECOND = 20; 

    // The attributes of the square 
    const int SQUARE_WIDTH = 20; 
    const int SQUARE_HEIGHT = 20; 

    // The surfaces 
    SDL_Surface *square = NULL; 
    SDL_Surface *screen = NULL; 

    // The event structure 
    SDL_Event event; 

    // The wall 
    SDL_Rect wall; 

    // The square 
    class Square 
    { 
     private: 
      // The collision box of the square 
      SDL_Rect box; 

      // The velocity of the square 
      int xVel, yVel; 

     public: 
      // Initializes the variables 
      Square(); 

      // Takes key presses and adjusts the square's velocity 
      void handle_input(); 

      // Moves the square 
      void move(); 

      // Shows the square on the screen 
      void show(); 
    }; 

    //The timer 
    class Timer 
    { 
     private: 
      // The clock time when the timer started 
      int startTicks; 

      // The ticks stored when the timer was paused 
      int pausedTicks; 

      // The timer status 
      bool paused; 
      bool started; 

     public: 
      // Initializes variables 
      Timer(); 

      // The various clock actions 
      void start(); 
      void stop(); 
      void pause(); 
      void unpause(); 

      // Gets the timer's time 
      int get_ticks(); 

      // Checks the status of the timer 
      bool is_started(); 
      bool is_paused(); 
    }; 

    SDL_Surface *load_image(std::string filename) 
    { 
     // The image that's loaded 
     SDL_Surface* loadedImage = NULL; 

     // The optimized surface that will be used 
     SDL_Surface* optimizedImage = NULL; 

     // Load the image 
     loadedImage = IMG_Load(filename.c_str()); 

     // If the image loaded 
     if (loadedImage != NULL) 
     { 
      // Create an optimized surface 
      optimizedImage = SDL_DisplayFormat(loadedImage); 

      // Free the old surface 
      SDL_FreeSurface(loadedImage); 

      // If the surface was optimized 
      if (optimizedImage != NULL) 
      { 
       // Color key surface 
       SDL_SetColorKey(optimizedImage, SDL_SRCCOLORKEY, SDL_MapRGB(optimizedImage->format, 0, 0xFF, 0xFF)); 
      } 
     } 

     // Return the optimized surface 
     return optimizedImage; 
    } 

    void apply_surface(int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL) 
    { 
     // Holds offsets 
     SDL_Rect offset; 

     // Get offsets 
     offset.x = x; 
     offset.y = y; 

     // Blit 
     SDL_BlitSurface(source, clip, destination, &offset); 
    } 

    bool check_collision(SDL_Rect A, SDL_Rect B) 
    { 
     // The sides of the rectangles 
     int leftA, leftB; 
     int rightA, rightB; 
     int topA, topB; 
     int bottomA, bottomB; 

     // Calculate the sides of rect A 
     leftA = A.x; 
     rightA = A.x + A.w; 
     topA = A.y; 
     bottomA = A.y + A.h; 

     // Calculate the sides of rect B 
     leftB = B.x; 
     rightB = B.x + B.w; 
     topB = B.y; 
     bottomB = B.y + B.h; 

     // If any of the sides from A are outside of B 
     if(bottomA <= topB) 
     { 
      return false; 
     } 

     if(topA >= bottomB) 
     { 
      return false; 
     } 

     if(rightA <= leftB) 
     { 
      return false; 
     } 

     if(leftA >= rightB) 
     { 
      return false; 
     } 

     // If none of the sides from A are outside B 
     return true; 
    } 

    bool init() 
    { 
     // Initialize all SDL subsystems 
     if (SDL_Init(SDL_INIT_EVERYTHING) == -1) 
     { 
      return false; 
     } 

     // Set up the screen 
     screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE); 

     // If there was an error in setting up the screen 
     if (screen == NULL) 
     { 
      return false; 
     } 

     // Set the window caption 
     SDL_WM_SetCaption("Move the Square", NULL); 

     // If everything initialized fine 
     return true; 
    } 

    bool load_files() 
    { 
     // Load the square image 
     square = load_image("square.bmp"); 

     // If there was a problem in loading the square 
     if (square == NULL) 
     { 
      return false; 
     } 

     // If everything loaded fine 
     return true; 
    } 

    void clean_up() 
    { 
     // Free the surface 
     SDL_FreeSurface(square); 

     // Quit SDL 
     SDL_Quit(); 
    } 

    Square::Square() 
    { 
     // Initialize the offsets 
     box.x = 0; 
     box.y = 0; 

     // Set the square's dimentions 
     box.w = SQUARE_WIDTH; 
     box.h = SQUARE_HEIGHT; 

     // Initialize the velocity 
     xVel = 0; 
     yVel = 0; 
    } 

    void Square::handle_input() 
    { 
     // If a key was pressed 
     if (event.type == SDL_KEYDOWN) 
     { 
      //Adjust the velocity 
      switch (event.key.keysym.sym) 
      { 
       case SDLK_UP: yVel -= SQUARE_HEIGHT/2; break; 
       case SDLK_DOWN: yVel += SQUARE_HEIGHT/2; break; 
       case SDLK_LEFT: xVel -= SQUARE_WIDTH/2; break; 
       case SDLK_RIGHT: xVel += SQUARE_WIDTH/2; break; 
      } 
     } 
     // If a key was released 
     else if (event.type == SDL_KEYUP) 
     { 
      //Adjust the velocity 
      switch (event.key.keysym.sym) 
      { 
       case SDLK_UP: yVel += SQUARE_HEIGHT/2; break; 
       case SDLK_DOWN: yVel -= SQUARE_HEIGHT/2; break; 
       case SDLK_LEFT: xVel += SQUARE_WIDTH/2; break; 
       case SDLK_RIGHT: xVel -= SQUARE_WIDTH/2; break; 
      } 
     } 
    } 

    void Square::move() 
    { 
     // Move the square left or right 
     box.x += xVel; 

     // If the square went too far to the left or right or has collided with the wall 
     if ((box.x < 0) || (box.x + SQUARE_WIDTH > SCREEN_WIDTH) || (check_collision(box, wall))) 
     { 
      // Move back 
      box.x -= xVel; 
     } 

     // Move the square up or down 
     box.y += yVel; 

     // If the square went too far up or down or has collided with the wall 
     if ((box.y < 0) || (box.y + SQUARE_HEIGHT > SCREEN_HEIGHT) || (check_collision(box, wall))) 
     { 
      // Move back 
      box.y -= yVel; 
     } 
    } 

    void Square::show() 
    { 
     // Show the square 
     apply_surface(box.x, box.y, square, screen); 
    } 

    Timer::Timer() 
    { 
     // Initialize the variables 
     startTicks = 0; 
     pausedTicks = 0; 
     paused = false; 
     started = false; 
    } 

    void Timer::start() 
    { 
     // Start the timer 
     started = true; 

     // Unpause the timer 
     paused = false; 

     // Get the current clock time 
     startTicks = SDL_GetTicks(); 
    } 

    void Timer::stop() 
    { 
     // Stop the timer 
     started = false; 

     // Unpause the timer 
     paused = false; 
    } 

    void Timer::pause() 
    { 
     // If the timer is running and isn't already paused 
     if ((started == true) && (paused == false)) 
     { 
      // Pause the timer 
      paused = true; 

      // Calculate the paused ticks 
      pausedTicks = SDL_GetTicks() - startTicks; 
     } 
    } 

    void Timer::unpause() 
    { 
     // If the timer is paused 
     if (paused == true) 
     { 
      // Unpause the timer 
      paused = false; 

      // Reset the starting ticks 
      startTicks = SDL_GetTicks() - pausedTicks; 

      // Reset the paused ticks 
      pausedTicks = 0; 
     } 
    } 

    int Timer::get_ticks() 
    { 
     // If the timer is running 
     if (started == true) 
     { 
      // If the timer is paused 
      if (paused == true) 
      { 
       // Return the number of ticks when the timer was paused 
       return pausedTicks; 
      } 
      else 
      { 
       // Return the current time minus the start time 
       return SDL_GetTicks() - startTicks; 
      } 
     } 

     // If the timer isn't running 
     return 0; 
    } 

    bool Timer::is_started() 
    { 
     return started; 
    } 

    bool Timer::is_paused() 
    { 
     return paused; 
    } 

    int main(int argc, char* args[]) 
    { 
     // Quit flag 
     bool quit = false; 

     // The square 
     Square mySquare; 

     // The frame rate regulator 
     Timer fps; 

     // Initialize 
     if(init() == false) 
     { 
      return 1; 
     } 

     // Load the files 
     if (load_files() == false) 
     { 
      return 1; 
     } 

     // Set the wall 
     wall.x = 300; 
     wall.y = 40; 
     wall.w = 40; 
     wall.h = 400; 

     // While the user hasn't quit 
     while (quit == false) 
     { 
      // Start the frame timer 
      fps.start(); 

      // While there are events to handle 
      while (SDL_PollEvent(&event)) 
      { 
       // Handle events for the square 
       mySquare.handle_input(); 

       // If the user has Xed out the window 
       if (event.type == SDL_QUIT) 
       { 
        // Quit the program 
        quit = true; 
       } 
      } 

      // Move the square 
      mySquare.move(); 

      // Fill the screen white 
      SDL_FillRect(screen, &screen->clip_rect, SDL_MapRGB(screen->format, 0xFF, 0xFF, 0xFF)); 

      // Show the wall 
      SDL_FillRect (screen, &wall, SDL_MapRGB(screen->format, 0x77, 0x77, 0x77)); 

      // Show the square on the screen 
      mySquare.show(); 

      // Update the screen 
      if (SDL_Flip(screen) == -1) 
      { 
       return 1; 
      } 

      // Cap the frame rate 
      if (fps.get_ticks() < 1000/FRAMES_PER_SECOND) 
      { 
       SDL_Delay((1000/FRAMES_PER_SECOND) - fps.get_ticks()); 
      } 
     } 

     // Clean up 
     clean_up(); 

     return 0; 
    } 

나는 완전히이 사이트의 작동 방식을 이해하고, 그래서 당신이 내 코드를 확인하라는 게 아니에요 :

여기 내 코드입니다. 내 코드는 Xcode 4.5와 Visual Studio 2010 모두에서 컴파일됩니다. Xcode에서는 컴파일되지만 일부 경고가 표시되지만 실행될 때는 아무 것도 발생하지 않습니다. 그러나 Visual Studio 2012에서는 경고없이 컴파일되고 성공적으로 실행됩니다.

여기서는 C++/SDL 포럼/도움말 페이지를 검색했지만 비슷한 사례는 찾지 못했습니다.

왜 이런가요? 이 비주얼 스튜디오 2010에서 실행되는 것 같다, 내가 만일 당신이 엑스 코드에서 플래그 경고를 궁금해

... 그것은 코드가 아닙니다 확신은 있습니다

229 열거 값에 처리되지 스위치 : 'SDLK_UNKNOWN', 'SDLK_BACKSPACE', 'SDLK_TAB은'...

이 코드의 switch (event.key.keysym.sym) 줄에 강조 표시됩니다.

그래서 제 질문은 다음과 같습니다

  • 은 어떤 종류의 문제가이 경고 오류를 구분 수 있을까?

  • Visual Studio에서 작동하며 Xcode가 아닌 프로그램에서 일반적으로 알려진 문제점이 있습니까?

나는 (내가 그것에 대해 아무것도 찾을 수없는 것) 내가 발견되지 않았 음을 어딘가에 설정 같은데요 ...

나는이 길이 드려 죄송합니다.

+0

디버거를 사용하여 코드를 단계별로 실행하여 'false'를 반환하거나 인쇄 문을 추가하십시오 . –

+0

나는 xCode에서 디버깅하는 방법에 대해 완전히 모르겠다는 것을 인정해야한다. 감사. – Reanimation

답변

5

switch 문에서 가능한 모든 선택을 처리하지 않습니다. 다음과 같은 기본 경우를 사용하여 경고를 제거 할 수 있습니다.

+0

아 물론. 나는 그것을 놓친다 고 나는 믿을 수 없다. 시간을내어 주셔서 감사합니다. 경고가 이제 사라졌습니다 :) 이제 실행되지 않는 이유를 알아내는 중 ... – Reanimation

1

Xcode는 단순히 event.key.keysym.sym 열거 형의 모든 가능한 값을 처리하지 않는다고 경고합니다. 나는 언젠가는 다른 종류의 키 프레스를 다룰 생각이 없기 때문에 이것은 문제가되지 않습니다. 아마도 경고 수준을 낮추어 이러한 경고를 억제 할 수 있는지 알 수있을 것입니다.

Xcode로 빌드했을 때 프로그램이 성공적으로 실행되지 않는 것으로 알고 있습니다. 아마도 SDL은 다른 방식으로 설정 되었습니까?

+0

감사합니다.위의 Charvak가 나머지 스위치를 다루기 위해 제안한대로'default : break; '를 추가했습니다. 더 이상의 경고는 없습니다. 예, 저는 XCode가 SDL을 채택하는 방법과 관련이 있다고 생각하기 시작했습니다. – Reanimation