문제

So I'm nearly done writing my first tic tac toe in C++ and SDL, ad I've run into a slight problem. I use a state machine to switch from title screen to shape choice screen, to player one or two to winning screen and back to the choice screen etc etc. On the choice screen I have two SDL_Rect arrays that act as buttons and the buttons are the X and O sprites I use from my sprite sheet. When the mouse hovers over them, they change colors. Everything is fine and dandy until the game resets to the choice screen after a win lose or tie. When it goes back to the choice screen and the mouse hovers over the button, it does not show the highlighted or mouse hovered sprite it clipped before. I pin pointed this problem to the initialization of my "set_grid_regions()" function. But this array doesn't even interact with the choice screen class in any way. How can this be affecting my hover sprites?

Just so anyone can see, here is the whole of the program:

#include "SDL.h"
#include "SDL_ttf.h"
#include "SDL_image.h"
#include "SDL_mixer.h"
#include <string>
#include <iostream>

//constants
const int SCREEN_HEIGHT = 300;
const int SCREEN_WIDTH = 300;
const int SCREEN_BPP = 32;
const int GRID_WIDTH = 96;
const int GRID_HEIGHT = 96;

//game states
enum States
{
    S_NULL,
    INTRO,
    CHOICE,
    START_O,
    START_X,
    PLAYER_ONE,
    PLAYER_TWO,
    O_win,
    X_win,
    Tie,
    EXIT,
};
// CLASSES //
class GameState
{
public:
    virtual void events() = 0;
    virtual void logic() = 0;
    virtual void render() = 0;
    virtual ~GameState(){};
};

class intro : public GameState
{
private:
    //hover variable
    bool button_hover = NULL;
    //rects and surfaces
    SDL_Rect button;
    SDL_Surface *title_message = NULL;
public:
    void events();
    void logic();
    void render();
    intro();
    ~intro();
};

class choice : public GameState
{
private:
    bool O_hover = NULL;
    bool X_hover = NULL;
    SDL_Rect shape_O_button;
    SDL_Rect shape_X_button;
    SDL_Surface *choice_text = NULL;
public:
    void events();
    void logic();
    void render();
    choice();
    ~choice();
};

class playerOne : public GameState
{

public:
    void events();
    void logic();
    void render();
    playerOne();
    ~playerOne();
};

class playerTwo : public GameState
{
public:
    void events();
    void logic();
    void render();
    playerTwo();
    ~playerTwo();
};

class win : public GameState
{
private:
    int winner = NULL;
    SDL_Surface *Tie = NULL;
    SDL_Surface *X_win = NULL;
    SDL_Surface *O_win = NULL;
public:
    void events();
    void logic();
    void render();
    win(int winner);
    ~win();
};

class Exit : public GameState
{
public:
    void events();
    void logic();
    void render();
    Exit();
    ~Exit();
};

// GLOBALS //
GameState *currentState = NULL;
int stateID = S_NULL;
int nextState = S_NULL;

//event
SDL_Event event;

//surfaces
SDL_Surface *screen = NULL;
SDL_Surface *sprites = NULL;
//ttf
TTF_Font *font = NULL;
SDL_Color color = { 0, 0, 0 };
SDL_Color win_Color = { 0, 100, 0 };
//arrays
int grid_array[9];

//rects
SDL_Rect sprite_clip[10];
SDL_Rect grid_region[9];
int number_elements = sizeof(grid_region) / sizeof(grid_region[0]);

//bools
bool shape = NULL;
bool invalid = NULL;
bool winner = NULL;
//ints
int highlight = NULL;
int shape_winner = NULL;

// FUCNTIONS //
//load image
SDL_Surface *load_image(std::string filename)
{
    //loaded image
    SDL_Surface* loadedImage = NULL;
    //optimized surface
    SDL_Surface* optimizedImage = NULL;
    //load image
    loadedImage = IMG_Load(filename.c_str());
    //if image loaded
    if (loadedImage != NULL)
    {
        //Create optimized image
        optimizedImage = SDL_DisplayFormat(loadedImage);
        //free old image
        SDL_FreeSurface(loadedImage);
        //if optimized
        if (optimizedImage != NULL)
        {
            //map color key
            Uint32 colorkey = SDL_MapRGB(optimizedImage->format, 255, 255, 0);
            //set all pixles of color 0,0,0 to be transparent
            SDL_SetColorKey(optimizedImage, SDL_SRCCOLORKEY, colorkey);
        }
    }
    return optimizedImage;
}

//apply image
void apply_surface(int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL)
{
    //temp rect
    SDL_Rect offset;
    //offsets
    offset.x = x;
    offset.y = y;
    //blit
    SDL_BlitSurface(source, clip, destination, &offset);
}

//initiate SDL etc
bool init()
{
    //initialize all SDL subsystems
    if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
    {
        return false;
    }
    //set up screen
    screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE);
    if (screen == NULL)
    {
        return false;
    }
    //check screen
    if (screen == NULL)
    {
        return false;
    }
    //init TTF
    if (TTF_Init() == -1)
    {
        return false;
    }
    //set window caption
    SDL_WM_SetCaption("Tic-Tac-Toe", NULL);
    //if evetything worked
    return true;
}

//load files
bool load_files()
{
    //sprite sheet
    sprites = load_image("Sprites.png");
    if (sprites == NULL)
    {
        return false;
    }
    font = TTF_OpenFont("font.ttf", 45);
    if (font == NULL)
    {
        return false;
    }
    return true;
}

//quit
void clean_up()
{
    //delete game state
    delete currentState;
    //free image
    SDL_FreeSurface(sprites);
    //quit ttf
    TTF_CloseFont(font);
    TTF_Quit();
    //quit SDL
    SDL_Quit();
}

void set_clip_regions()
{
    //init clip array
    //O
    sprite_clip[0].x = 300;
    sprite_clip[0].y = 0;
    sprite_clip[0].w = 80;
    sprite_clip[0].h = 82;
    //X
    sprite_clip[1].x = 300;
    sprite_clip[1].y = 176;
    sprite_clip[1].w = 80;
    sprite_clip[1].h = 82;
    //grid
    sprite_clip[2].x = 0;
    sprite_clip[2].y = 0;
    sprite_clip[2].w = 300;
    sprite_clip[2].h = 300;
    //highlight
    sprite_clip[3].x = 300;
    sprite_clip[3].y = 82;
    sprite_clip[3].w = 94;
    sprite_clip[3].h = 94;
    //left to right line
    sprite_clip[4].x = 398;
    sprite_clip[4].y = 188;
    sprite_clip[4].w = 234;
    sprite_clip[4].h = 12;
    //diag up
    sprite_clip[5].x = 393;
    sprite_clip[5].y = 0;
    sprite_clip[5].w = 188;
    sprite_clip[5].h = 186;
    //up down line
    sprite_clip[6].x = 591;
    sprite_clip[6].y = 0;
    sprite_clip[6].w = 11;
    sprite_clip[6].h = 208;
    //Diag down line
    sprite_clip[7].x = 0;
    sprite_clip[7].y = 300;
    sprite_clip[7].w = 188;
    sprite_clip[7].h = 186;
    //start button
    sprite_clip[8].x = 202;
    sprite_clip[8].y = 300;
    sprite_clip[8].w = 94;
    sprite_clip[8].h = 32;
    //intro and choice background
    sprite_clip[9].x = 300;
    sprite_clip[9].y = 300;
    sprite_clip[9].w = 300;
    sprite_clip[9].h = 300;
    //start hover
    sprite_clip[10].x = 202;
    sprite_clip[10].y = 332;
    sprite_clip[10].w = 94;
    sprite_clip[10].h = 32;
    //X hover
    sprite_clip[11].x = 202;
    sprite_clip[11].y = 446;
    sprite_clip[11].w = 80;
    sprite_clip[11].h = 82;
    //o hover
    sprite_clip[12].x = 202;
    sprite_clip[12].y = 364;
    sprite_clip[12].w = 80;
    sprite_clip[12].h = 82;
}

void set_grid_regions()
{
    //set regions for images to be applied to
    grid_region[0].x = 3;
    grid_region[0].y = 3;

    grid_region[1].x = 103;
    grid_region[1].y = 3;

    grid_region[2].x = 203;
    grid_region[2].y = 3;

    grid_region[3].x = 3;
    grid_region[3].y = 103;

    grid_region[4].x = 103;
    grid_region[4].y = 103;

    grid_region[5].x = 203;
    grid_region[5].y = 103;

    grid_region[6].x = 3;
    grid_region[6].y = 203;

    grid_region[7].x = 103;
    grid_region[7].y = 203;

    grid_region[8].x = 203;
    grid_region[8].y = 203;
}

void init_grid()
{
    //from left to right top to bottom
    grid_array[0] = 0;
    grid_array[1] = 0;
    grid_array[2] = 0;
    grid_array[3] = 0;
    grid_array[4] = 0;
    grid_array[5] = 0;
    grid_array[6] = 0;
    grid_array[7] = 0;
    grid_array[8] = 0;

}

// STATE MACHINE FUNCTIONS //
void set_next_state(int newState)
{
    if (nextState != EXIT)
    {
        nextState = newState;
    }
}

void change_state()
{
    if (nextState != S_NULL)
    {
        //change state
        switch (nextState)
        {
        case CHOICE:
            currentState = new choice();
            break;
        case PLAYER_ONE:
            currentState = new playerOne();
            break;
        case PLAYER_TWO:
            currentState = new playerTwo();
            break;
        case O_win:
            currentState = new win(0);
            break;
        case X_win:
            currentState = new win(1);
            break;
        case Tie:
            currentState = new win(2);
            break;
        case EXIT:
            currentState = new Exit();
            break;
        }
        //change state
        stateID = nextState;
        //null nextState
        nextState = S_NULL;
    }
}

// CLASS DEFINITIONS //
intro::intro()
{
    //button
    button_hover = false;
    //title
    title_message = TTF_RenderText_Solid(font, "TIC TAC TOE", color);
    //button bounds
    button.x = 102;
    button.y = 180;
    button.w = 94;
    button.h = 32;
}

intro::~intro()
{
    SDL_FreeSurface(title_message);
}

void intro::events()
{
    int x, y;
    //mouse events
    while (SDL_PollEvent(&event))
    {
        if (event.type == SDL_MOUSEMOTION)
        {
            x = event.motion.x;
            y = event.motion.y;
            if ((x > button.x) && (x < button.x + button.w) && (y > button.y) && (y < button.y + button.h))
            {
                button_hover = true;
            }
            else
            {
                button_hover = false;
            }
        }
        if (event.type == SDL_MOUSEBUTTONDOWN)
        {
            if (event.button.button == SDL_BUTTON_LEFT)
            {
                x = event.motion.x;
                y = event.motion.y;
                if ((x > button.x) && (x < button.x + button.w) && (y > button.y) && (y < button.y + button.h))
                {
                    set_next_state(CHOICE);
                }
            }
        }
        if (event.type == SDL_QUIT)
        {
            set_next_state(EXIT);
        }
    }
}

void intro::logic()
{

}

void intro::render()
{
    apply_surface(0, 0, sprites, screen, &sprite_clip[9]);
    apply_surface((SCREEN_WIDTH - title_message->w) / 2, 100, title_message, screen);
    if (button_hover == true)
    {
        apply_surface(102, 180, sprites, screen, &sprite_clip[10]);
    }
    else
    {
        apply_surface(102, 180, sprites, screen, &sprite_clip[8]);
    }
}

choice::choice()
{
    O_hover = false;
    X_hover = false;

    shape_O_button.x = 0;
    shape_O_button.y = 130;
    shape_O_button.w = 80;
    shape_O_button.h = 82;

    shape_X_button.x = 220;
    shape_X_button.y = 130;
    shape_X_button.w = 80;
    shape_X_button.h = 82;

    font = TTF_OpenFont("font.ttf", 34);
    choice_text = TTF_RenderText_Solid(font, "CHOOSE YOUR SHAPE", color);
}

choice::~choice()
{
    SDL_FreeSurface(choice_text);
    O_hover = NULL;
    X_hover = NULL;
}

void choice::events()
{
    int x, y;
    //mouse events
    while (SDL_PollEvent(&event))
    {
        if (event.type == SDL_MOUSEMOTION)
        {
            x = event.motion.x;
            y = event.motion.y;
            if ((x > shape_O_button.x) && (x < shape_O_button.x + shape_O_button.w) && (y > shape_O_button.y) && (y < shape_O_button.y + shape_O_button.h))
            {
                O_hover = true;
            }
            else
            {
                O_hover = false;
            }
            if ((x > shape_X_button.x) && (x < shape_X_button.x + shape_X_button.w) && (y > shape_X_button.y) && (y < shape_X_button.y + shape_X_button.h))
            {
                X_hover = true;
            }
            else
            {
                X_hover = false;
            }
        }
        if (event.type == SDL_MOUSEBUTTONDOWN)
        {
            if (event.button.button == SDL_BUTTON_LEFT)
            {
                x = event.motion.x;
                y = event.motion.y;
                if ((x > shape_O_button.x) && (x < shape_O_button.x + shape_O_button.w) && (y > shape_O_button.y) && (y < shape_O_button.y + shape_O_button.h))
                {
                    shape = false;
                    init_grid();
                    set_next_state(PLAYER_ONE);
                }
                if ((x > shape_X_button.x) && (x < shape_X_button.x + shape_X_button.w) && (y > shape_X_button.y) && (y < shape_X_button.y + shape_X_button.h))
                {
                    shape = true;
                    init_grid();
                    set_next_state(PLAYER_TWO);
                }
            }
        }
        if (event.type == SDL_QUIT)
        {
            set_next_state(EXIT);
        }
    }

}

 void choice::logic()
{

}

 void choice::render()
{
     apply_surface( 0, 0, sprites, screen, &sprite_clip[9]);
     if (O_hover == false)
     {
         apply_surface(shape_O_button.x, shape_O_button.y, sprites, screen, &sprite_clip[0]);
     }
     else
     {
         apply_surface(shape_O_button.x, shape_O_button.y, sprites, screen, &sprite_clip[12]);
     }
     if (X_hover == false)
     {
         apply_surface(shape_X_button.x, shape_X_button.y, sprites, screen, &sprite_clip[1]);
     }
     else
     {
         apply_surface(shape_X_button.x, shape_X_button.y, sprites, screen, &sprite_clip[11]);
     }
     apply_surface((SCREEN_WIDTH - choice_text->w) / 2, 60, choice_text, screen);
}

 //plyer O
 playerOne::playerOne()
 {
     set_grid_regions();
 }

 playerOne::~playerOne()
 {

 }

 void playerOne::events()
 {
     //mouse offsets
     int x = 0, y = 0;
     //if mouse moves
     while (SDL_PollEvent(&event))
     {
         if (event.type == SDL_MOUSEMOTION)
         {
             //get the mouse co-ords
             x = event.motion.x;
             y = event.motion.y;

             for (int grid = 0; grid < number_elements; grid++)
             {

                 if ((x > grid_region[grid].x) && (x < grid_region[grid].x + GRID_WIDTH) && (y > grid_region[grid].y) && (y < grid_region[grid].y + GRID_HEIGHT))
                 {

                     //set highlight region
                     highlight = grid;
                 }
             }
         }
         //when the player clicks on a grid_region
         if (event.type == SDL_MOUSEBUTTONDOWN)
         {
             //mouse co-ordinates
             x = event.motion.x;
             y = event.motion.y;

             if (event.button.button == SDL_BUTTON_LEFT)
             {
                 //iterate
                 for (int grid = 0; grid < number_elements; grid++)
                 {
                     //if in region box
                     if ((x > grid_region[grid].x) && (x < grid_region[grid].x + GRID_WIDTH) && (y > grid_region[grid].y) && (y < grid_region[grid].y + GRID_HEIGHT))
                     {
                         //check region
                         //if O turn
                         if ((grid_array[grid] == 0) && (shape == 0))
                         {
                             //fill region
                             grid_array[grid] = 1;
                             shape = (!shape);
                         }
                         else if (grid_array[grid] != 0)
                         {
                             //raise "error"
                             invalid = true;
                         }
                         //if X turn
                         else if ((grid_array[grid] == 0) && (shape == 1))
                         {
                             if ((grid_array[grid] == 0))
                             {
                                 //fill region
                                 grid_array[grid] = 2;
                                 shape = (!shape);
                             }
                             else if (grid_array[grid] != 0)
                             {
                                 //raise "error"
                                 invalid = true;
                             }
                         }
                     }
                 }
             }
         }
         if (event.type == SDL_QUIT)
         {
             set_next_state(EXIT);
         }
     }
 }

 void playerOne::logic()
 {
     //check O win
     for (int win = 0; win <= 6; win += 3)
     {
         if ((grid_array[win] == 1) && (grid_array[win + 1] == 1) && (grid_array[win + 2] == 1))
         {
             winner = 0;
             set_next_state(O_win);
         }
     }
     for (int win = 0; win < 3; win++)
     {
         if ((grid_array[win] == 1) && (grid_array[win + 3] == 1) && (grid_array[win + 6] == 1))
         {
             winner = 0;
             set_next_state(O_win);
         }
     }
     if ((grid_array[0] == 1) && (grid_array[4] == 1) && (grid_array[8] == 1))
     {
         winner = 0;
         set_next_state(O_win);
     }
     if ((grid_array[2] == 1) && (grid_array[4] == 1) && (grid_array[6] == 1))
     {
         winner = 0;
         set_next_state(O_win);
     }
     //check X's
     for (int win = 0; win <= 6; win += 3)
     {
         if ((grid_array[win] == 2) && (grid_array[win + 1] == 2) && (grid_array[win + 2] == 2))
         {
             winner = 1;
             set_next_state(X_win);
         }
     }
     for (int win = 0; win < 3; win++)
     {
         if ((grid_array[win] == 2) && (grid_array[win + 3] == 2) && (grid_array[win + 6] == 2))
         {
             winner = 1;
             set_next_state(X_win);
         }
     }
     if ((grid_array[0] == 2) && (grid_array[4] == 2) && (grid_array[8] == 2))
     {
         winner = 1;
         set_next_state(X_win);
     }
     if ((grid_array[2] == 2) && (grid_array[4] == 2) && (grid_array[6] == 2))
     {
         winner = 1;
         set_next_state(X_win);
     }
     //check TIE
     if ((grid_array[0] != 0) && (grid_array[1] != 0) && (grid_array[2] != 0) && (grid_array[3] != 0) && (grid_array[4] != 0) && (grid_array[5] != 0) && (grid_array[6] != 0) && (grid_array[7] != 0) && (grid_array[8] != 0) && (winner == NULL))
     {
         set_next_state(Tie);
     }
 }

 void playerOne::render()
 {
     //logic
     //rendering
     //background
     SDL_FillRect(screen, &screen->clip_rect, SDL_MapRGB(screen->format, 0xFF, 0xFF, 0xFF));
     //grid
     apply_surface(0, 0, sprites, screen, &sprite_clip[2]);
     //highlight
     if (highlight != -1)
     {
         apply_surface(grid_region[highlight].x, grid_region[highlight].y, sprites, screen, &sprite_clip[3]);
     }
     //APPLY PLAYER SHAPE
     for (int grid = 0; grid < number_elements; grid++)
     {
         //O's
         if ((grid_array[grid] == 1))
         {
             apply_surface(grid_region[grid].x + 7, grid_region[grid].y + 6, sprites, screen, &sprite_clip[0]);
         }
         else if ((grid_array[grid] == 2))
         {
             //X's
             apply_surface(grid_region[grid].x + 7, grid_region[grid].y + 6, sprites, screen, &sprite_clip[1]);
         }
     }
 }

 playerTwo::playerTwo()
 {
     set_grid_regions();
 }

 playerTwo::~playerTwo()
 {

 }

 void playerTwo::events()
 {
     //mouse offsets
     int x = 0, y = 0;
     //if mouse moves
     while (SDL_PollEvent(&event))
     {
         if (event.type == SDL_MOUSEMOTION)
         {
             //get the mouse co-ords
             x = event.motion.x;
             y = event.motion.y;

             for (int grid = 0; grid < number_elements; grid++)
             {

                 if ((x > grid_region[grid].x) && (x < grid_region[grid].x + GRID_WIDTH) && (y > grid_region[grid].y) && (y < grid_region[grid].y + GRID_HEIGHT))
                 {

                     //set highlight region
                     highlight = grid;
                 }
             }
         }
         //when the player clicks on a grid_region
         if (event.type == SDL_MOUSEBUTTONDOWN)
         {
             //mouse co-ordinates
             x = event.motion.x;
             y = event.motion.y;

             if (event.button.button == SDL_BUTTON_LEFT)
             {
                 //iterate
                 for (int grid = 0; grid < number_elements; grid++)
                 {
                     //if in region box
                     if ((x > grid_region[grid].x) && (x < grid_region[grid].x + GRID_WIDTH) && (y > grid_region[grid].y) && (y < grid_region[grid].y + GRID_HEIGHT))
                     {
                         //check region
                         //if O turn
                         if ((grid_array[grid] == 0) && (shape == 0))
                         {
                             //fill region
                             grid_array[grid] = 1;
                             shape = (!shape);
                         }
                         else if (grid_array[grid] != 0)
                         {
                             //raise "error"
                             invalid = true;
                         }
                         //if X turn
                         else if ((grid_array[grid] == 0) && (shape == 1))
                         {
                             if ((grid_array[grid] == 0))
                             {
                                 //fill region
                                 grid_array[grid] = 2;
                                 shape = (!shape);
                             }
                             else if (grid_array[grid] != 0)
                             {
                                 //raise "error"
                                 invalid = true;
                             }
                         }
                     }
                 }
             }
         }
         if (event.type == SDL_QUIT)
         {
             set_next_state(EXIT);
         }
     }
 }

 void playerTwo::logic()
 {
     //check O win
     for (int win = 0; win <= 6; win += 3)
     {
         if ((grid_array[win] == 1) && (grid_array[win + 1] == 1) && (grid_array[win + 2] == 1))
         {
             winner = 0;
             set_next_state(O_win);
         }
     }
     for (int win = 0; win < 3; win++)
     {
         if ((grid_array[win] == 1) && (grid_array[win + 3] == 1) && (grid_array[win + 6] == 1))
         {
             winner = 0;
             set_next_state(O_win);
         }
     }
     if ((grid_array[0] == 1) && (grid_array[4] == 1) && (grid_array[8] == 1))
     {
         winner = 0;
         set_next_state(O_win);
     }
     if ((grid_array[2] == 1) && (grid_array[4] == 1) && (grid_array[6] == 1))
     {
         winner = 0;
         set_next_state(O_win);
     }
     //check X's
     for (int win = 0; win <= 6; win += 3)
     {
         if ((grid_array[win] == 2) && (grid_array[win + 1] == 2) && (grid_array[win + 2] == 2))
         {
             winner = 1;
             set_next_state(X_win);
         }
     }
     for (int win = 0; win < 3; win++)
     {
         if ((grid_array[win] == 2) && (grid_array[win + 3] == 2) && (grid_array[win + 6] == 2))
         {
             winner = 1;
             set_next_state(X_win);
         }
     }
     if ((grid_array[0] == 2) && (grid_array[4] == 2) && (grid_array[8] == 2))
     {
         winner = 1;
         set_next_state(X_win);
     }
     if ((grid_array[2] == 2) && (grid_array[4] == 2) && (grid_array[6] == 2))
     {
         winner = 1;
         set_next_state(X_win);
     }
     //check TIE
     if ((grid_array[0] != 0) && (grid_array[1] != 0) && (grid_array[2] != 0) && (grid_array[3] != 0) && (grid_array[4] != 0) && (grid_array[5] != 0) && (grid_array[6] != 0) && (grid_array[7] != 0) && (grid_array[8] != 0) && (winner == NULL))
     {
         set_next_state(Tie);
     }
 }

 void playerTwo::render()
 {
     //logic
     //rendering
     //background
     SDL_FillRect(screen, &screen->clip_rect, SDL_MapRGB(screen->format, 0xFF, 0xFF, 0xFF));
     //grid
     apply_surface(0, 0, sprites, screen, &sprite_clip[2]);
     //highlight
     if (highlight != -1)
     {
         apply_surface(grid_region[highlight].x, grid_region[highlight].y, sprites, screen, &sprite_clip[3]);
     }
     //APPLY PLAYER SHAPE
     for (int grid = 0; grid < number_elements; grid++)
     {
         //O's
         if ((grid_array[grid] == 1))
         {
             apply_surface(grid_region[grid].x + 7, grid_region[grid].y + 6, sprites, screen, &sprite_clip[0]);
         }
         else if ((grid_array[grid] == 2))
         {
             //X's
             apply_surface(grid_region[grid].x + 7, grid_region[grid].y + 6, sprites, screen, &sprite_clip[1]);
         }
     }
 }

 win::win(int winner)
 {
    shape_winner = winner;
    font = TTF_OpenFont("font.ttf", 45);
    X_win = TTF_RenderText_Solid(font, "X WINS", win_Color);
    O_win = TTF_RenderText_Solid(font, "O wins", win_Color);
    Tie = TTF_RenderText_Solid(font, "Tie", win_Color);
 }

 win::~win()
 {
     TTF_CloseFont(font);
     SDL_FreeSurface(X_win);
     SDL_FreeSurface(O_win);
 }

 void win::events()
 {
     while (SDL_PollEvent(&event))
     {
         if (event.type == SDL_QUIT)
         {
             set_next_state(EXIT);
         }
     }
 }

 void win::logic()
 {
     if (shape_winner == 3)
     {
         SDL_Delay(2000);
         set_next_state(CHOICE);
         winner = NULL;
     }
 }

 void win::render()
 {
     //background
     SDL_FillRect(screen, &screen->clip_rect, SDL_MapRGB(screen->format, 0xFF, 0xFF, 0xFF));
     //grid
     apply_surface(0, 0, sprites, screen, &sprite_clip[2]);
     //highlight
     if (highlight != -1)
     {
         apply_surface(grid_region[highlight].x, grid_region[highlight].y, sprites, screen, &sprite_clip[3]);
     }
     //APPLY PLAYER SHAPE
     for (int grid = 0; grid < number_elements; grid++)
     {
         //O's
         if ((grid_array[grid] == 1))
         {
             apply_surface(grid_region[grid].x + 7, grid_region[grid].y + 6, sprites, screen, &sprite_clip[0]);
         }
         else if ((grid_array[grid] == 2))
         {
             //X's
             apply_surface(grid_region[grid].x + 7, grid_region[grid].y + 6, sprites, screen, &sprite_clip[1]);
         }
     }
     if (shape_winner == 1)
     {
         apply_surface((SCREEN_WIDTH - X_win->w) / 2, (SCREEN_HEIGHT - X_win->h) / 2, X_win, screen);
         //enable delay and reset
         shape_winner = 3;
     }
     if (shape_winner == 0)
     {
         apply_surface((SCREEN_WIDTH - O_win->w) / 2, (SCREEN_HEIGHT - O_win->h) / 2, O_win, screen);
         //enable delay and reset
         shape_winner = 3;
     }
     if (shape_winner == 2)
     {
         apply_surface((SCREEN_WIDTH - Tie->w) / 2, (SCREEN_HEIGHT - Tie->h) / 2, Tie, screen);
         //enable delay and reset
         shape_winner = 3;
     }
 }

 Exit::Exit()
 {

 }

 Exit::~Exit()
 {

 }

 void Exit::events()
 {

 }

 void Exit::logic()
 {

 }

 void Exit::render()
 {

 }

//MAAAAAAAAAAAAAAAAAAIN//
int main(int argc, char* args[])
{
    //init SDL
    init();
    //load files
    load_files();
    //set clips
    set_clip_regions();
    //set state
    stateID = INTRO;
    //set game object
    currentState = new intro();
    while (stateID != EXIT)
    {
        //handle state events
        currentState->events();
        // do state logic
        currentState->logic();
        //change state if needed
        change_state();
        //render state 
        currentState->render();
        if (SDL_Flip(screen) == -1)
        {
            return 1;
        }
    }
    clean_up();
    return 0;
}

It's pretty strange. But I'm 99% sure that it's the "set_grid_regions()" that is effecting the rendering inside the choice::render() or choice::event() class fucntions. Can anyone help with this?

도움이 되었습니까?

해결책

The error causing the clipping problem is an incorrect declaration for sprite_clip. You've declared it as sprite_clip[10], but you have 13 sprites. Change this to sprite_clip[13].

Other things I noticed:

  • You allocate all these state objects with new, but you never delete them. You need to delete them when you change states. Otherwise you will leak memory.
  • The font font.ttf seems to be a global resource but is haphazardly managed by a mixture of global and local methods. Load it once in load_files() and release it once in clean_up().

While your project may be complete, you might tinker around with it and work on improving the implementation now that you have something working. (If this was a homework, keep a copy of a working version to hand in. ;-) )

  • Consider packaging all of your global state (your fonts, sprites, clipping arrays, etc.) into a single class for the game. Your init_xxx and load_xxx functions move to its constructor. Your clean_up moves to its destructor.
  • Consider converting your dynamic state objects into statically allocated state objects. They could even be members of the same global state class I mentioned in the previous bullet. Now you've encapsulated the whole game in one class.
  • Consider merging playerOne and playerTwo into a single class. Distinguish them at construction time, just as you did with win(0), win(1), win(2).
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top