⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gd04-01.cpp

📁 游戏开发数据结构-Data.Structures.for.Game.Programmers
💻 CPP
字号:
// ============================================================================
//  GD04-01.cpp
//  Bitvector Graphical Demonstration.
// ============================================================================
#include "SDLGUI.h"
#include "Bitvector.h"
#include <stdlib.h>
#include <time.h>



// ============================================================================
//  Global Constants
// ============================================================================
const char PROGRAM_NAME[]   = "Bitvector Graphical Demonstration";
const int WIDTH             = 640;
const int HEIGHT            = 480;
const int ITEMS             = 32;
const int ARIAL             = 0;



// ============================================================================
//  Demo States
// ============================================================================
enum bitvectorstate
{
    // nothing happening.
    NOSTATE,

    // find the correct cell to modify
    FINDCELL,

    // find the correct bit to mofify
    FINDBIT,

    // move up a one into the correct position
    MOVEUPBIT,

    // logically not the modifier
    NOT,

    // logically and the mofifier
    AND,

    // logically or the modifier
    OR
};


// ============================================================================
//  Global Variables
// ============================================================================
SDLGUI* g_gui;

// this is the bitvector that we will use in the demo
Bitvector g_vector( 64 );

// this is the bit-modifier. It will be used to modify cells
// within the bitvector.
unsigned long int g_bitmodifier;

// holds the current index in the vector.
int g_current = 0;

// used for counting.
int g_index;


// since the set and clear operations
// are almost identical, we'll use
// a boolean to determine which operation
// we are doing. 1 = clear, 0 = set.
bool g_isclear;

// holds the last known time.
Uint32 g_time;

// the current animation state.
bitvectorstate g_state = NOSTATE;


// small boxes
SDL_Surface* g_s1box;
SDL_Surface* g_s0box;
SDL_Surface* g_sr1box;
SDL_Surface* g_sr0box;

// large boxes
SDL_Surface* g_l1box;
SDL_Surface* g_l0box;
SDL_Surface* g_lr1box;
SDL_Surface* g_lr0box;

// text
SDL_Surface* g_statustext = 0;

// arrow
SDL_Surface* g_downarrow;




// ============================================================================
//  Draw Algorithms
// ============================================================================
void DrawBitVector( Bitvector& p_vec,          // the vector to draw
                    int p_x, int p_y,          // x+y coords
                    int p_current,             // the current index.
                    bool p_horizontal )        // horizontal or vertical?
{
    int index;
    // draw the vector.
    for( index = 0; index < p_vec.Size(); index++ )
    {
        // draw the box
        if( index != p_current )
        {
            // draw the normal boxes
            if( p_vec[index] == true )
                g_gui->Blit( g_s1box, p_x, p_y );
            else
                g_gui->Blit( g_s0box, p_x, p_y );
        }
        else
        {
            // draw the red boxes
            if( p_vec[index] == true )
                g_gui->Blit( g_sr1box, p_x, p_y );
            else
                g_gui->Blit( g_sr0box, p_x, p_y );
        }


        if( p_horizontal == true )
            p_x += g_s1box->w;
        else
            p_y += g_s1box->h;
    }
}


void DrawCell( unsigned long int p_cell,   // the cell to draw
               int p_x, int p_y,           // coords
               int p_current,              // the current index.
               bool p_horizontal )         // horizontal or vertical?
{
    int index;
    unsigned long int currentcell = 1;

    // draw the cell.
    for( index = 0; index < 32; index++, currentcell <<= 1 )
    {
        // draw the box
        if( index != p_current )
        {
            // draw the normal boxes
            if( (p_cell & currentcell) != 0 )
                g_gui->Blit( g_l1box, p_x, p_y );
            else
                g_gui->Blit( g_l0box, p_x, p_y );
        }
        else
        {
            // draw the red boxes
            if( (p_cell & currentcell) != 0 )
                g_gui->Blit( g_lr1box, p_x, p_y );
            else
                g_gui->Blit( g_lr0box, p_x, p_y );
        }


        if( p_horizontal == true )
            p_x += g_l1box->w;
        else
            p_y += g_l1box->h;
    }
}




// ============================================================================
//  Button Callbacks
// ============================================================================
void Set()
{
    // create the status string
    char tempstring[80];
    sprintf( tempstring, "index = %d, cell = %d / 32 = %d", 
             g_current, g_current, g_current / 32 );
    g_statustext = TTF_RenderText_Shaded( g_gui->GetFont(ARIAL), tempstring, 
                                          BLACK, WHITE );
       
    g_isclear = false;
    g_state = FINDCELL;
    g_gui->GetItem( 3 )->SetVisibility( true );
    g_gui->GetItem( 2 )->SetVisibility( true );
    g_gui->GetItem( 0 )->SetVisibility( false );
    g_gui->GetItem( 1 )->SetVisibility( false );
    g_gui->GetItem( 9 )->SetVisibility( false );
};

void Clear()
{
    // create the status string
    char tempstring[80];
    sprintf( tempstring, "index = %d, cell = %d / 32 = %d", 
             g_current, g_current, g_current / 32 );
    g_statustext = TTF_RenderText_Shaded( g_gui->GetFont(ARIAL), tempstring, 
                                        BLACK, WHITE );

    g_isclear = true;
    g_state = FINDCELL;
    g_gui->GetItem( 3 )->SetVisibility( true );
    g_gui->GetItem( 2 )->SetVisibility( true );
    g_gui->GetItem( 0 )->SetVisibility( false );
    g_gui->GetItem( 1 )->SetVisibility( false );
    g_gui->GetItem( 9 )->SetVisibility( false );
};

void Continue() 
{ 
    // a temporary string to print status messages to.
    char tempstring[80];

    // hide the continue button.
    g_gui->GetItem( 2 )->SetVisibility( false );

    // determine which state to go to next.
    switch( g_state )
    {
    case FINDCELL:
        g_state = FINDBIT;

        SDL_FreeSurface( g_statustext );
        sprintf( tempstring, "bit = %d mod 32 = %d", g_current, g_current % 32 );
        g_statustext = TTF_RenderText_Shaded( g_gui->GetFont(ARIAL), tempstring, 
                                              BLACK, WHITE );

        g_gui->GetItem( 3 )->SetVisibility( false );
        g_gui->GetItem( 4 )->SetVisibility( true );
        g_gui->GetItem( 2 )->SetVisibility( true );
        break;
    case FINDBIT:
        g_state = MOVEUPBIT;
        SDL_FreeSurface( g_statustext );
        g_bitmodifier = 1;
        g_time = SDL_GetTicks();
        g_gui->GetItem( 4 )->SetVisibility( false );
        g_gui->GetItem( 5 )->SetVisibility( true );
        break;
    case MOVEUPBIT:
        g_gui->GetItem( 5 )->SetVisibility( false );
        g_gui->GetItem( 2 )->SetVisibility( true );
        if( g_isclear == true )
        {
            g_state = NOT;
            g_gui->GetItem( 6 )->SetVisibility( true );
            g_bitmodifier = ~g_bitmodifier;
        }
        else
        {
            g_state = OR;
            g_gui->GetItem( 8 )->SetVisibility( true );
            g_vector.Set( g_current, true );
        }
        break;
    case NOT:
        g_state = AND;
        g_gui->GetItem( 6 )->SetVisibility( false );
        g_gui->GetItem( 7 )->SetVisibility( true );
        g_gui->GetItem( 2 )->SetVisibility( true );
        g_vector.Set( g_current, false );
        break;
    case AND:
        g_state = NOSTATE;
        g_gui->GetItem( 7 )->SetVisibility( false );
        g_gui->GetItem( 0 )->SetVisibility( true );
        g_gui->GetItem( 1 )->SetVisibility( true );
        g_gui->GetItem( 2 )->SetVisibility( false );
        g_gui->GetItem( 9 )->SetVisibility( true );
        break;
    case OR:
        g_state = NOSTATE;
        g_gui->GetItem( 8 )->SetVisibility( false );
        g_gui->GetItem( 0 )->SetVisibility( true );
        g_gui->GetItem( 1 )->SetVisibility( true );
        g_gui->GetItem( 2 )->SetVisibility( false );
        g_gui->GetItem( 9 )->SetVisibility( true );
        break;
    }

};



// ============================================================================
//  Main
// ============================================================================
int main( int argc, char* argv[] )
{
    int x;
    int y;
    int index;

    // initialise the bitvector
    g_vector.ClearAll();
    g_current = 0;

    for( index = 0; index < 64; index++ )
        g_vector.Set( index, rand()%2 );

    srand( time(0) );

    //initialize systems
    SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER );
    SDL_WM_SetCaption( "Array Graphical Demonstration", 0); 
    TTF_Init();
    g_gui = new SDLGUI( WIDTH, HEIGHT, ITEMS, WHITE );
    g_gui->SetFont( "arial.ttf", ARIAL, 26, TTF_STYLE_NORMAL );


    // add the buttons to the g_gui
    g_gui->AddButton( 0, 0, "gbup.bmp", "gbdown.bmp", "set bit", 
                       ARIAL, BLACK, WHITE, Set );
    g_gui->AddButton( 128, 0, "gbup.bmp", "gbdown.bmp", "clear bit", 
                       ARIAL, BLACK, WHITE, Clear );
    g_gui->AddButton( 256, 0, "gbup.bmp", "gbdown.bmp", "continue", 
                       ARIAL, BLACK, WHITE, Continue );

    g_gui->AddLabel( 0, 400, "First, you need to find the correct cell.", 
                      ARIAL, BLACK, WHITE );
    g_gui->AddLabel( 0, 400, "then find which bit to modify in that cell.", 
                      ARIAL, BLACK, WHITE );
    g_gui->AddLabel( 0, 400, "Now make an int with the 1 in the correct index", 
                      ARIAL, BLACK, WHITE );
    g_gui->AddLabel( 0, 400, "Negate the integer", ARIAL, BLACK, WHITE );
    g_gui->AddLabel( 0, 400, "Finally, logically AND them together.", 
                      ARIAL, BLACK, WHITE );
    g_gui->AddLabel( 0, 400, "Finally, logically OR them together.", 
                      ARIAL, BLACK, WHITE );
    g_gui->AddLabel( 0, 400, "Click on a box to select the g_current bit.", 
                      ARIAL, BLACK, WHITE );

    // set all the captions to be invisisble.
    g_gui->GetItem( 2 )->SetVisibility( false );
    g_gui->GetItem( 3 )->SetVisibility( false );
    g_gui->GetItem( 4 )->SetVisibility( false );
    g_gui->GetItem( 5 )->SetVisibility( false );
    g_gui->GetItem( 6 )->SetVisibility( false );
    g_gui->GetItem( 7 )->SetVisibility( false );
    g_gui->GetItem( 8 )->SetVisibility( false );

    // set our at exit function
    atexit( SDL_Quit ) ;

    // create the BMP's that we need.
    g_s1box = SDL_LoadBMP( "s1box.bmp" );
    g_s0box = SDL_LoadBMP( "s0box.bmp" );
    g_sr1box = SDL_LoadBMP( "sr1box.bmp" );
    g_sr0box = SDL_LoadBMP( "sr0box.bmp" );
    g_l1box = SDL_LoadBMP( "l1box.bmp" );
    g_l0box = SDL_LoadBMP( "l0box.bmp" );
    g_lr1box = SDL_LoadBMP( "lr1box.bmp" );
    g_lr0box = SDL_LoadBMP( "lr0box.bmp" );
    g_downarrow = SDL_LoadBMP( "downarrow.bmp" );

    // declare event variable
    SDL_Event event;

    g_gui->Draw();
    g_gui->Update();

    // loop until we get a quit message.
    while( 1 )
    {
        //look for an event
        if( SDL_PollEvent( &event ) )
        {
            //an event was found
            if( event.type == SDL_QUIT ) 
                break;

            // mouse button was pressed
            if( event.type == SDL_MOUSEBUTTONDOWN ) 
            {
                // get the mouse g_state.
                SDL_GetMouseState( &x, &y );

                // tell the GUI that a button has been pressed
                g_gui->MouseDown( x, y );

                // check to see if user clicked on a cell
                if( g_state == NOSTATE )
                {
                    if( y >= 300 && 
                        y < 308 && 
                        x >= 64 && 
                        x < (8 * g_vector.Size() + 64) )
                    {
                        g_current = (x - 64) / 8;
                    }
                }
            }

            // mouse button was released
            if( event.type == SDL_MOUSEBUTTONUP ) 
            {
                // get the mouse state.
                SDL_GetMouseState( &x, &y );

                // tell the GUI that a button has been released
                g_gui->MouseUp( x, y );
            }

            if( event.type == SDL_KEYDOWN )
            {
                // a key was pressed.
                if( event.key.keysym.sym == SDLK_ESCAPE )
                {
                    // if ESC was pressed, quit the program.
                    SDL_Event quit;
                    quit.type = SDL_QUIT;
                    SDL_PushEvent( &quit );
                }

                // tell the GUI that a key was pressed.
                g_gui->KeyDown( event.key.keysym.sym, 
                                event.key.keysym.mod,
                                event.key.keysym.unicode );
            }
        }

        // draw the g_gui at the end of each loop.
        g_gui->Draw();

        // draw the bitvector and the separator between the two cells.
        g_gui->Line( 319, 296, 319, 312, BLACK );
        g_gui->Line( 320, 296, 320, 312, BLACK );
        DrawBitVector( g_vector, 64, 300, g_current, true );

        if( g_state == FINDBIT || g_state == MOVEUPBIT ||
            g_state == NOT || g_state == AND || g_state == OR )
        {
            // draw the blown up version of the current cell.
            DrawCell( g_vector.GetCell( g_current / 32 ), 64, 200, g_current % 32, true );

            // draw lines depicting where the current cell came from
            g_gui->ArrowLine( 64, 216, g_current/32 * 256 + 64, 300, 
                               0, 0, true, false, BLACK );
            g_gui->ArrowLine( 576, 216, g_current/32 * 256 + 320, 300, 
                               0, 0, true, false, BLACK );
        }
        if( g_state == FINDCELL )
        {
            g_gui->Blit( g_statustext, 20, 100 );
            g_gui->Blit( g_downarrow, 192 + ((g_current/32) * 256) - (g_downarrow->w/2), 230 );
        }
        if( g_state == FINDBIT )
        {
            g_gui->Blit( g_statustext, 20, 100 );
        }
        if( g_state == MOVEUPBIT )
        {
            index = (SDL_GetTicks() - g_time) / 300;
            if( index > (g_current % 32) )
            {
                index = g_current % 32;
                g_gui->GetItem( 2 )->SetVisibility( true );
            }
            g_bitmodifier = 1 << index;
        }
        if( g_state == MOVEUPBIT || g_state == NOT || g_state == AND || g_state == OR )
        {
            DrawCell( g_bitmodifier, 64, 160, -1, true );
        }

        g_gui->Update();
    }

    return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -