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

📄 gd05-01.cpp

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


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

const int ARIAL             = 0;




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

        // resizing
        MOVEARRAYLEFT,
        DETERMINESIZE,
        FILLARRAY,
        MOVEARRAYBACK
};




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

// the state
Array2DState g_state = NOSTATE;

// the current selected cell in the array
int g_x;
int g_y;

// height and width vars, used for resizing.
int g_w = 6;
int g_h = 6;

// holds the last marked time.
Uint32 g_time;

// used to hold the current position of the array when filling.
int g_px;
int g_py;

// min variables, used in resizing the array.
int g_xmin;
int g_ymin;


// boxes
SDL_Surface* g_blackbox;
SDL_Surface* g_redbox;
SDL_Surface* g_greybox;
SDL_Surface* g_bluebox;

Array2D<int> g_array( 6, 6 );
Array2D<int> g_temparray( 6, 6 );


// ============================================================================
//  Draw Algorithms
// ============================================================================
void DrawArray2D( Array2D<int>& p_array,            // the array to draw
                  int p_x,                          // x and y coords.
                  int p_y,
                  int p_currentw, int p_currenth,   // the current index.
                  int p_bluex, int p_bluey )        // the "blue" indexes.
{
    static SDL_Surface* text;
    static char number[3] = "00";

    int sx = p_x;     // the starting x coordinate.
    int ix, iy;     // the index coordinates.
    int item;       // this will cache the current item in the array

    // draw the array.
    for( iy = 0; iy < p_array.Height(); iy++ )
    {
        for( ix = 0; ix < p_array.Width(); ix++ )
        {
            // cache the current item.
            item = p_array.Get( ix, iy );

            // draw the box
            if( ix < p_bluex && iy < p_bluey )
            {
                g_gui->Blit( g_bluebox, p_x, p_y );
            }
            else if( ix != p_currentw || iy != p_currenth )
            {
                g_gui->Blit( g_blackbox, p_x, p_y );
            }
            else
            {
                g_gui->Blit( g_redbox, p_x, p_y );
            }

            // draw the contents of the box.
            if( item < 0 || item > 99 )
            {
                // invalid number, render a red 'x'
                text = TTF_RenderText_Shaded( g_gui->GetFont(ARIAL), "x", RED, WHITE );
            }
            else
            {
                // render the number.
                sprintf( number, "%d", item );
                text = TTF_RenderText_Shaded( g_gui->GetFont(ARIAL), number, BLACK, WHITE );
            }

            // draw the number or 'x'.
            g_gui->Blit( text, (g_blackbox->w - text->w) / 2 + p_x, 
                                (g_blackbox->h - text->h) / 2 + p_y );
            SDL_FreeSurface( text );

            // move the x coordinate forward.
            p_x += (g_blackbox->w - 1);
        }
        // move the y coordinate down and reset x.
        p_y += (g_blackbox->h - 1);
        p_x = sx;
    }
}



void DrawGrid( int p_x, int p_y,        // x and y coords
               int p_w, int p_h )       // width and height
{

    int sx = p_x;     // the starting x coordinate.
    int ix, iy;     // the index coordinates.

    // draw the array.
    for( iy = 0; iy < p_h; iy++ )
    {
        for( ix = 0; ix < p_w; ix++ )
        {
            // draw the box
            g_gui->Blit( g_greybox, p_x, p_y );

            // move the x coordinate forward.
            p_x += (g_greybox->w - 1);
        }
        // move the y coordinate down and reset x.
        p_y += (g_greybox->h - 1);
        p_x = sx;
    }
}




// ============================================================================
//  Callbacks
// ============================================================================
void Resize()
{
    g_state = MOVEARRAYLEFT;
    g_gui->GetItem( 0 )->SetVisibility( false );
    g_gui->GetItem( 6 )->SetVisibility( false );
    g_time = SDL_GetTicks();
}

void Continue()
{
    if( g_state == DETERMINESIZE )
    {
        g_state = FILLARRAY;
        g_time = SDL_GetTicks();
        g_gui->GetItem( 1 )->SetVisibility( false );
        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_temparray.Resize( g_w, g_h );
        int x;
        int y;
        for( y = 0; y < g_h; y++ )
        {
            for( x = 0; x < g_w; x++ )
            {
                g_temparray.Get( x, y ) = -1;
            }
        }

        // set the current fill-index to 0,0
        g_px = 0;
        g_py = 0;
        g_xmin = (g_array.Width() < g_w ? g_array.Width() : g_w );
        g_ymin = (g_array.Height() < g_h ? g_array.Height() : g_h );
    }

}

void Randomize()
{
    int x, y;
    for( y = 0; y < g_array.Height(); y++ )
    {
        for( x = 0; x < g_array.Width(); x++ )
        {
            g_array.Get( x, y ) = rand() % 100;
        }
    }
}


void ArrowUp()
{
    g_h--;
    if( g_h < 1 )
        g_h = 1;
}
void ArrowDown()
{
    g_h++;
    if( g_h > 6 )
        g_h = 6;
}
void ArrowLeft()
{
    g_w--;
    if( g_w < 1 )
        g_w = 1;
}
void ArrowRight()
{
    g_w++;
    if( g_w > 6 )
        g_w = 6;
}


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

    srand( time( 0 ) );
 
    // initialise the array
    for( y = 0; y < g_array.Height(); y++ )
    {
        for( x = 0; x < g_array.Width(); x++ )
        {
            g_array.Get( x, y ) = rand() % 100;
        }
    }


    // declare event holder
    SDL_Event event;

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

    //initialize systems
    SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER );
    TTF_Init();

    // create the GUI and set the caption.
    g_gui = new SDLGUI( WIDTH, HEIGHT, ITEMS, WHITE );
    SDL_WM_SetCaption( PROGRAM_NAME, 0); 

    // add the font
    g_gui->SetFont( "arial.ttf", ARIAL, 22, TTF_STYLE_NORMAL );

    
    // load the bmps
    g_blackbox = SDL_LoadBMP( "boxblack.bmp" );
    g_redbox =   SDL_LoadBMP( "boxred.bmp" );
    g_greybox =  SDL_LoadBMP( "boxgrey.bmp" );
    g_bluebox =  SDL_LoadBMP( "boxblue.bmp" );

    // add your GUI items here.
    g_gui->AddButton( 0, 0, "gbup.bmp", "gbdown.bmp", "Resize", 
                       ARIAL, BLACK, WHITE, Resize );
    g_gui->AddButton( 256, 0, "gbup.bmp", "gbdown.bmp", "Continue", 
                       ARIAL, BLACK, WHITE, Continue );

    g_gui->GetItem( 1 )->SetVisibility( false );

    // add the arrow buttons
    g_gui->AddButton( 583, 0, "sarrowup-up.bmp", "sarrowup-down.bmp", 
                       " ", ARIAL, BLACK, BLACK, ArrowUp );
    g_gui->AddButton( 583, 57, "sarrowdown-up.bmp", "sarrowdown-down.bmp", 
                       " ", ARIAL, BLACK, BLACK, ArrowDown );
    g_gui->AddButton( 551, 32, "sarrowleft-up.bmp", "sarrowleft-down.bmp", 
                       " ", ARIAL, BLACK, BLACK, ArrowLeft );
    g_gui->AddButton( 608, 32, "sarrowright-up.bmp", "sarrowright-down.bmp", 
                       " ", ARIAL, BLACK, BLACK, ArrowRight );

    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->AddButton( 128, 0, "gbup.bmp", "gbdown.bmp", "Randomize", 
                       ARIAL, BLACK, WHITE, Randomize );


    // main message loop.
    while( 1 )
    {
        //look for an event
        if( SDL_PollEvent( &event ) )
        {
            //an event was found
            if( event.type == SDL_QUIT ) 
                break;
            if( event.type == SDL_MOUSEBUTTONDOWN ) 
            {
                // get the mouse state.
                SDL_GetMouseState( &x, &y );

                // tell the GUI that a button has been pressed
                g_gui->MouseDown( x, y );
            }
            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 );

                // determine if the user clicked on a cell
                if( g_state == NOSTATE )
                {
                    int px, py;     // used for finding pixel coords.
                    int pw, ph;

                    // find the width and the height of the array.
                    pw = g_array.Width() * (g_blackbox->w - 1);
                    ph = g_array.Height() * (g_blackbox->h - 1);

                    // find the left and the top of the array.
                    px = (WIDTH - pw) / 2;
                    py = 100;

                    // determine if the x,y coords are on the array
                    if( x >= px && 
                        x < px + pw && 
                        y >= py && 
                        y < py + ph )
                    {
                        // find which cell the user clicked on.
                        g_x = (x - px) / (g_blackbox->w - 1);
                        g_y = (y - py) / (g_blackbox->h - 1);
                    }

                }
            }
            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 );
            }
        }   // end event loop.

        // do all game-related stuff here.



        // tell the GUI to redraw itself
        g_gui->Draw();


        if( g_state == NOSTATE )
        {
            x = (WIDTH - (g_array.Width() * (g_blackbox->w - 1))) / 2;
            DrawArray2D( g_array, x, 100, g_x, g_y, 0, 0 );
        }
        if( g_state == MOVEARRAYLEFT )
        {
            x = (WIDTH - (g_array.Width() * (g_blackbox->w - 1))) / 2;
            x = (int)((float)x - (float)(SDL_GetTicks() - g_time) * 0.2f);
            if( x < 10 )
            {
                x = 10;
                g_state = DETERMINESIZE;
                g_gui->GetItem( 1 )->SetVisibility( true );
                g_gui->GetItem( 2 )->SetVisibility( true );
                g_gui->GetItem( 3 )->SetVisibility( true );
                g_gui->GetItem( 4 )->SetVisibility( true );
                g_gui->GetItem( 5 )->SetVisibility( true );
            }
            DrawArray2D( g_array, x, 100, g_x, g_y, 0, 0 );
        }
        if( g_state == DETERMINESIZE )
        {
            DrawArray2D( g_array, 10, 100, g_x, g_y, g_w, g_h );
            DrawGrid( 330, 100, g_w, g_h );
        }
        if( g_state == FILLARRAY )
        {
            if( (SDL_GetTicks() - g_time) > 500 )
            {
                g_temparray.Get( g_px, g_py ) = g_array.Get( g_px, g_py );
                g_px++;
                if( g_px == g_xmin )
                {
                    g_px = 0;
                    g_py++;
                }
                g_time = SDL_GetTicks();
            }
            DrawArray2D( g_array, 10, 100, g_x, g_y, g_xmin, g_ymin );
            DrawArray2D( g_temparray, 330, 100, -1, -1, g_xmin, g_ymin );
            if( g_py == g_ymin )
            {
                // actually resize the array now.
                g_array.Resize( g_w, g_h );
                g_state = MOVEARRAYBACK;
                g_time = SDL_GetTicks();
            }
        }
        if( g_state == MOVEARRAYBACK )
        {
            y = (WIDTH - (g_array.Width() * (g_blackbox->w - 1))) / 2;
            x = (int)(320.0f - (float)(SDL_GetTicks() - g_time) * 0.2f);
            if( x < y )
            {
                x = y;
                g_state = NOSTATE;
                g_gui->GetItem( 0 )->SetVisibility( true );
                g_gui->GetItem( 6 )->SetVisibility( true );
            }
            DrawArray2D( g_array, x, 100, g_x, g_y, 0, 0 );
        }


        // tell the GUI to update itself
        g_gui->Update();

    }
  
    // done
    return 0;
}

⌨️ 快捷键说明

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