数组初始化影响看似无关的类C ++ SDL

时间:2013-12-23 05:47:11

标签: c++ arrays class sdl state-machine

所以我差不多用C ++和SDL编写了我的第一个tic tac toe,ad我遇到了一个小问题。我使用状态机从标题屏幕切换到形状选择屏幕,一个或两个播放器到获胜屏幕并返回到选择屏幕等。在选择屏幕上,我有两个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()”,它影响了choice :: render()或choice :: event()类fucntions中的渲染。任何人都可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

导致剪辑问题的错误是sprite_clip的错误声明。你已经宣布它为sprite_clip[10],但你有13个精灵。将其更改为sprite_clip[13]

我注意到的其他事情:

  • 您使用new分配所有这些状态对象,但绝不会delete它们。当你改变状态时,你需要delete他们。否则你会泄漏内存。
  • 字体font.ttf似乎是一种全球资源,但是由全局和本地方法的混合物随意管理。在load_files()中加载一次,然后在clean_up()中将其释放一次。

虽然您的项目可能已完成,但您可能会对其进行修补,并在您有所工作的情况下继续改进实施。 (如果这是一个家庭作业,请保留一份工作版本的副本。;-))

  • 考虑将您的所有全局状态(您的字体,精灵,剪辑数组等)打包到游戏的单个类中。您的init_xxxload_xxx函数将移至其构造函数。你的clean_up移动到它的析构函数。
  • 考虑将动态状态对象转换为静态分配的状态对象。他们甚至可以成为我在上一个项目中提到的同一个全球国家级的成员。现在你已将整个游戏封装在一个类中。
  • 考虑将playerOneplayerTwo合并为一个类。在施工时区分它们,就像使用win(0)win(1)win(2)一样。