?? gd23-04.cpp
字號:
ay >= 0 && ay < p_map.Height() &&
p_map.Get( ax, ay ).m_passable == true &&
p_map.Get( ax, ay ).m_marked == false )
{
// calculate the distance to get into this cell.
// this is calulated as:
// distance of the current cell plus
// the weight of the adjacent cell times the distance
// of the cell.
// diagonal cell's cost is around 1.4 times the cost of
// a horizontal or vertical cell.
distance = p_map.Get( x, y ).m_distance +
p_map.Get( ax, ay ).m_weight * DISTTABLE[dir];
// check if the node has already been calculated before
if( p_map.Get( ax, ay ).m_lastx != -1 )
{
// the node has already been calculated, see if the
// new distance is shorter. If so, update the links.
if( distance < p_map.Get( ax, ay ).m_distance )
{
// the new distance is shorter, update the links
p_map.Get( ax, ay ).m_lastx = x;
p_map.Get( ax, ay ).m_lasty = y;
p_map.Get( ax, ay ).m_distance = distance;
// add the cell to the queue.
c.x = ax;
c.y = ay;
c.heuristic = distance +
AStarHeuristic( x, y,
p_gx, p_gy,
dir );
queue.Enqueue( c );
com.c = CHANGEPOINTER;
com.x = ax;
com.y = ay;
com.newx = x;
com.newy = y;
g_queue.Enqueue( com );
}
}
else
{
// set the links and the distance
p_map.Get( ax, ay ).m_lastx = x;
p_map.Get( ax, ay ).m_lasty = y;
p_map.Get( ax, ay ).m_distance = distance;
// add the cell to the queue.
c.x = ax;
c.y = ay;
c.heuristic = distance +
AStarHeuristic( x, y,
p_gx, p_gy,
dir );
queue.Enqueue( c );
com.c = ENQUEUE;
com.x = ax;
com.y = ay;
g_queue.Enqueue( com );
com.c = CHANGEPOINTER;
com.newx = x;
com.newy = y;
g_queue.Enqueue( com );
}
}
}
}
}
}
// ============================================================================
// Button Callbacks
// ============================================================================
void Go()
{
if( g_startx == -1 || g_starty == -1 || g_goalx == -1 || g_goaly == -1 )
return;
PathAStar( g_map, g_startx, g_starty, g_goalx, g_goaly );
ClearMarks();
g_done = false;
g_processing = true;
g_timer = SDL_GetTicks();
}
void ClearMap()
{
if( g_processing == true )
return;
ClearCells( g_map );
g_done = false;
}
void Slower()
{
if( g_timeLength < 0 )
g_timeLength++;
else
g_timeLength += 50;
}
void Faster()
{
if( g_timeLength > 0 )
g_timeLength -= 50;
else
g_timeLength--;
}
// ============================================================================
// Main
// ============================================================================
int main( int argc, char* argv[] )
{
int x;
int y;
Command c;
//initialize systems
SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER );
SDL_EnableUNICODE( true );
SDL_WM_SetCaption( PROGRAM_NAME, 0);
TTF_Init();
g_gui = new SDLGUI( WIDTH, HEIGHT, ITEMS, WHITE );
g_gui->SetFont( "arial.ttf", ARIAL, 18, TTF_STYLE_NORMAL );
g_gui->AddButton( 0, HEIGHT - 64, "gbup.bmp", "gbdown.bmp", "Go!",
ARIAL, BLACK, WHITE, Go );
g_gui->AddButton( 128, HEIGHT - 64, "gbup.bmp", "gbdown.bmp", "Slower",
ARIAL, BLACK, WHITE, Slower );
g_gui->AddButton( 256, HEIGHT - 64, "gbup.bmp", "gbdown.bmp", "Faster",
ARIAL, BLACK, WHITE, Faster );
g_gui->AddButton( 384, HEIGHT - 64, "gbup.bmp", "gbdown.bmp", "Clear",
ARIAL, BLACK, WHITE, ClearMap );
// load the bmps
g_blackbox = SDL_LoadBMP( "boxblack.bmp" );
g_redbox = SDL_LoadBMP( "boxred.bmp" );
g_greenbox = SDL_LoadBMP( "boxgreen.bmp" );
g_bluebox = SDL_LoadBMP( "boxblue.bmp" );
g_wallbox = SDL_LoadBMP( "boxwall.bmp" );
g_start = SDL_LoadBMP( "start.bmp" );
g_goal = SDL_LoadBMP( "goal.bmp" );
// set the color keys of the BMPs
SDL_SetColorKey( g_blackbox, SDL_SRCCOLORKEY,
SDL_MapRGB( g_blackbox->format, 255, 255, 255 ));
SDL_SetColorKey( g_redbox, SDL_SRCCOLORKEY,
SDL_MapRGB( g_redbox->format, 255, 255, 255 ));
SDL_SetColorKey( g_greenbox, SDL_SRCCOLORKEY,
SDL_MapRGB( g_greenbox->format, 255, 255, 255 ));
SDL_SetColorKey( g_bluebox, SDL_SRCCOLORKEY,
SDL_MapRGB( g_bluebox->format, 255, 255, 255 ));
SDL_SetColorKey( g_wallbox, SDL_SRCCOLORKEY,
SDL_MapRGB( g_wallbox->format, 255, 255, 255 ));
SDL_SetColorKey( g_start, SDL_SRCCOLORKEY,
SDL_MapRGB( g_start->format, 255, 255, 255 ));
SDL_SetColorKey( g_goal, SDL_SRCCOLORKEY,
SDL_MapRGB( g_goal->format, 255, 255, 255 ));
Clear();
ClearCells( g_map );
//RandomizeWeights();
// set our at exit function
atexit( SDL_Quit ) ;
// 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 );
g_mousedown = true;
// see if the user clicked on a square
x = x / 24;
y = y / 24;
if( x < MAPX && y < MAPY )
{
if( g_weight == 10 )
g_walldraw = true;
else
g_walldraw = false;
}
}
// 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 );
g_mousedown = false;
// see if the user clicked on a square
x = x / 24;
y = y / 24;
if( x < MAPX && y < MAPY && g_processing == false )
{
// flip the drawing state
g_map.Get( x, y ).m_passable = !g_walldraw;
g_map.Get( x, y ).m_weight = (float)g_weight;
}
}
if( event.type == SDL_MOUSEMOTION )
{
// get the mouse state.
SDL_GetMouseState( &x, &y );
// see if the user is over a square
x = x / 24;
y = y / 24;
if( x < MAPX && y < MAPY && g_mousedown == true && g_processing == false )
{
// draw the current wall state
g_map.Get( x, y ).m_passable = !g_walldraw;
g_map.Get( x, y ).m_weight = (float)g_weight;
}
}
if( event.type == SDL_KEYDOWN )
{
// get the mouse state.
SDL_GetMouseState( &x, &y );
// 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 );
}
if( event.key.keysym.unicode >= '0' &&
event.key.keysym.unicode <= '9' )
{
g_weight = (float)(event.key.keysym.unicode - '0') + 1.0f;
}
if( event.key.keysym.sym == SDLK_g )
{
x = x / 24;
y = y / 24;
if( x < MAPX && y < MAPY )
{
// if the program isn't processing, set the goal
if( g_processing == false && g_done == false )
{
if( g_map.Get( x, y ).m_passable != false )
{
g_goalx = x;
g_goaly = y;
}
}
}
}
if( event.key.keysym.sym == SDLK_s )
{
x = x / 24;
y = y / 24;
if( x < MAPX && y < MAPY )
{
// if the program isn't processing, set the goal
if( g_processing == false && g_done == false )
{
if( g_map.Get( x, y ).m_passable != false )
{
g_startx = x;
g_starty = y;
}
}
}
}
// tell the GUI that a key was pressed.
g_gui->KeyDown( event.key.keysym.sym,
event.key.keysym.mod,
event.key.keysym.unicode );
}
}
// figure out the number of repetitions to make
x = 0;
if( g_timeLength < 0 )
{
x = -g_timeLength;
}
else if( SDL_GetTicks() - g_timer >= g_timeLength )
{
g_timer = SDL_GetTicks();
x = 1;
}
if( g_processing == true )
{
for( y = 0; y < x; y++ )
{
if( g_queue.Count() == 0 )
{
g_processing = false;
g_done = true;
}
else
{
c = g_queue.Front();
g_queue.Dequeue();
if( c.c == ENQUEUE )
{
g_map.Get( c.x, c.y ).m_inQueue = true;
}
else if( c.c == DEQUEUE )
{
g_map.Get( c.x, c.y ).m_inQueue = false;
g_map.Get( c.x, c.y ).m_marked = true;
}
else
{
g_map.Get( c.x, c.y ).m_lastx = c.newx;
g_map.Get( c.x, c.y ).m_lasty = c.newy;
}
}
}
}
// draw the g_gui at the end of each loop.
g_gui->Draw();
DrawMap();
g_gui->Update();
}
return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -