Инициализация массива, влияющая на казалось бы не связанные классы C ++ SDL

0

Поэтому я почти закончил писать свой первый трек tic tac в C++ и SDL, и у меня возникла небольшая проблема. Я использую конечный автомат, чтобы переключиться с экрана заголовка на экран выбора формы, на игрока один или два на выигрышный экран и обратно на экран выбора и т.д. И т.д. На экране выбора у меня есть два массива SDL_Rect, которые действуют как кнопки, а кнопки - X и O спрайты, которые я использую из моего листа спрайтов. Когда мышь нависает над ними, они меняют цвета. Все отлично и денди, пока игра не сбрасывается на экран выбора после того, как победа проиграет или завяжется. Когда он возвращается к экрану выбора, и мышь наводится над кнопкой, он не показывает выделенный или наведенный на мышь спрайт, который он обрезал раньше. Я указываю эту проблему на инициализацию моей функции "set_grid_regions()". Но этот массив даже не взаимодействует с классом экрана выбора. Как это может повлиять на мои спрайты?

Именно так каждый может видеть, вот и вся программа:

#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;
}

Это довольно странно. Но я на 99% уверен, что это "set_grid_regions()", который выполняет рендеринг внутри объектов выбора: render() или option :: event(). Может кто-нибудь помочь с этим?

  • 0
    Хм .... я не вижу delete . change_state должно быть утечка памяти. Не проблема, с которой вы сейчас сталкиваетесь, а потенциальная проблема. Действительно, разве эти состояния не должны быть статически распределены, и вы переключаете указатели на статически распределенные состояния?
  • 0
    Эмм. Можете ли вы привести пример того, что вы имеете в виду во втором бите? И да, проблема кажется очень туманной.
Показать ещё 10 комментариев
Теги:
class
arrays
sdl
state-machines

1 ответ

0
Лучший ответ

Ошибка, вызывающая проблему отсечения, является неправильным объявлением для sprite_clip. Вы объявили его как sprite_clip[10], но у вас есть 13 спрайтов. Измените это на sprite_clip[13].

Другие вещи, которые я заметил:

  • Вы выделяете все эти объекты состояния new, но вы никогда не delete их. Вам нужно delete их, когда вы меняете состояния. В противном случае произойдет утечка памяти.
  • Шрифт font.ttf, по-видимому, является глобальным ресурсом, но беспорядочно управляется сочетанием глобальных и локальных методов. Загрузите его один раз в load_files() и выпустите его один раз в clean_up().

Хотя ваш проект может быть завершен, вы можете поработать с ним и работать над улучшением реализации теперь, когда у вас что-то работает. (Если это была домашняя работа, сохраните копию рабочей версии, чтобы ее можно было использовать. ;-))

  • Рассмотрите возможность упаковки всего вашего глобального состояния (ваши шрифты, спрайты, отсечения массивов и т.д.) В один класс для игры. init_xxx и load_xxx переходят к его конструктору. Ваш clean_up переходит к своему деструктору.
  • Подумайте о преобразовании объектов динамического состояния в статически назначенные объекты состояния. Они могут даже быть членами одного и того же глобального класса, о котором я упоминал в предыдущем выпуске. Теперь вы инкапсулировали всю игру в один класс.
  • Рассмотрите возможность слияния playerOne и playerTwo в один класс. Выделите их во время строительства, как и вы с win(0), win(1), win(2).

Ещё вопросы

Сообщество Overcoder
Наверх
Меню