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

📄 gd23-02.cpp

📁 游戏开发数据结构-Data.Structures.for.Game.Programmers
💻 CPP
📖 第 1 页 / 共 2 页
字号:
            // quit out if the goal has been reached.
            if( x == p_gx && y == p_gy )
                break;

            // loop through each direction.
            for( dir = 0; dir < 8; dir++ )
            {
                // retrieve the coordinates of the current adjacent cell
                ax = x + DIRTABLE[dir][0];
                ay = y + DIRTABLE[dir][1];

                // check to see if the adjacent cell is a valid index, 
                // passable, and not marked.
                if( ax >= 0 && ax < p_map.Width() && 
                    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 = SimpleHeuristic( 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 = SimpleHeuristic( 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;

    PathSimpleHeuristic( 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 + -