Xcode vs. Visual Studio - SDL C++

Xcode vs. Visual Studio - SDL C++

本文关键字:SDL C++ Studio vs Visual Xcode      更新时间:2023-10-16

我正在使用各种在线教程和几本书自学编程。目前使用的是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中标记的警告是:

switch: '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是以不同的方式建立的?