簡體   English   中英

Xcode與Visual Studio-SDL C ++

[英]Xcode vs. Visual Studio - SDL C++

我正在使用各種在線教程和幾本書進行自學編程。 當前是C ++。 在過去的幾天中,我做了一些OpenGL和SDL。

我有一個小程序,該程序創建一堵牆以阻止小正方形穿過它。

這是我的代碼:

    //
    //  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論壇/幫助頁面中進行了搜索,但是沒有發現任何類似的情況。

為什么會這樣呢? 似乎它可以在Visual Studio 2010中運行,我相信它不是代碼。

如果您想知道Xcode中標記的警告是:

開關中未處理229個枚舉值:'SDLK_UNKNOWN','SDLK_BACKSPACE','SDLK_TAB'...

這在代碼的switch (event.key.keysym.sym)行上突出顯示。

所以我的問題是:

  • 什么樣的問題可以解決此警告錯誤?

  • 在Visual Studio中而不是Xcode中可以正常使用程序嗎?

我猜(似乎我什么都找不到)這是我沒發現的地方...

抱歉,敬請諒解。

您未在switch語句中處理所有可能的選擇。 如果這是您的預期目的,則可以使用以下默認情況來消除警告:

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;
     default: break;
}

Xcode只是警告您,您不會處理event.key.keysym.sym枚舉的所有可能值。 由於我懷疑您是否想處理任何一種不同類型的按鍵,所以這不是問題,因為我可能會看看是否可以降低警告級別來抑制這些警告。

至於由Xcode生成的程序未成功運行,我不知道。 也許以其他方式設置了SDL?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM