📄 gd05-01.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 + -