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

📄 g23-01.cpp

📁 游戏开发数据结构-Data.Structures.for.Game.Programmers
💻 CPP
字号:
// ============================================================================
//  G23-01.cpp
//  Stealth Game Demo
// ============================================================================
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include "SDLHelpers.h"
#include "Array2D.h"
#include "Queue.h"
#include "Stack.h"
#include "Pathfinding.h"


// ============================================================================
//  Global Constants
// ============================================================================
const char PROGRAM_NAME[]   = "Stealth Game Demonstration";
const int WIDTH             = 800;
const int HEIGHT            = 600;
const int MAPX              = 100;
const int MAPY              = 75;


// ============================================================================
//  classes
// ============================================================================


// ============================================================================
//  Global Variables
// ============================================================================
Array2D<Cell> g_map( MAPX, MAPY );


// the stacks that contain all the moves
LStack<int> g_xmovement;
LStack<int> g_ymovement;

// the initial goal and starting cells are invalid
int g_goalx = -1, 
    g_goaly = -1;
int g_currentx = -1,
    g_currenty = -1;

// the player is not moving
bool g_moving = false;


// these are the different tiles:
// 0 - dense forest
// 1 - light forest
// 2 - grass
// 3 - dirt road
// 4 - paved road

SDL_Color DENSEFOREST = { 11, 81, 19, 0 };
SDL_Color LIGHTFOREST = { 33, 155, 44, 0 };
SDL_Color GRASS = { 114, 218, 124, 0 };
SDL_Color DIRTROAD = { 119, 84, 59, 0 };
SDL_Color PAVEDROAD = { 128, 128, 128, 0 };
SDL_Color WALL = BLACK;

// colors of the tiles
SDL_Color TABLE[6];

SDL_Surface* g_window = 0;


int g_timer;


// drawing commands
bool g_mousedown = false;
bool g_walldraw = false;
float g_weight = 1.0f;
bool g_drawing = false;


// ============================================================================
//  Drawing
// ============================================================================
void DrawMap()
{
    int x;
    int y;

    // draw each cell of the map
    for( y = 0; y < MAPY; y++ )
    {
        for( x = 0; x < MAPX; x++ )
        {
            SDLBox( g_window, x * 8, y * 8, 
                    8, 8, TABLE[ (int)(g_map.Get( x, y ).m_weight / 4) - 1] );
        }
    }

    // draw the goal
    SDLBox( g_window, g_goalx * 8, g_goaly * 8, 
            8, 8, BLUE );

    // draw player
    SDLBox( g_window, g_currentx * 8, g_currenty * 8, 
            8, 8, RED );

}





// ============================================================================
//  Other Algorithms
// ============================================================================
void SaveMap()
{
    FILE* f = fopen( "map", "wb" );

    fwrite( g_map.m_array, MAPX * MAPY, sizeof(Cell), f );

    fclose( f );
}



void LoadMap()
{
    FILE* f = fopen( "map", "rb" );

    fread( g_map.m_array, MAPX * MAPY, sizeof(Cell), f );

    fclose( f );
}


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

    //initialize systems
    SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER );
    SDL_EnableUNICODE( true );
    SDL_WM_SetCaption( PROGRAM_NAME, 0);

    // set the video mode.
    g_window = SDL_SetVideoMode( WIDTH, HEIGHT, 0, SDL_ANYFORMAT );

    // fill the color table
    TABLE[0] = DENSEFOREST;
    TABLE[1] = LIGHTFOREST;
    TABLE[2] = GRASS;
    TABLE[3] = DIRTROAD;
    TABLE[4] = PAVEDROAD;
    TABLE[5] = WALL;

    // load the map
    LoadMap();

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

    // declare event variable
    SDL_Event event;

    // 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 );
                g_mousedown = true;
                // see if the user clicked on a square
                x = x / 8;
                y = y / 8;

                // a weight of 24 is the wall.
                if( g_weight == 24.0f )
                    g_walldraw = true;
                else
                    g_walldraw = false;

            }

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

                // see if the user clicked on a square
                x = x / 8;
                y = y / 8;

                // if the drawing mode is on, draw a tile
                if( g_drawing == true )
                {
                    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 );

                // calculate the tile number the mouse is over
                x = x / 8;
                y = y / 8;

                // if drawing mode is on, and the mouse button is down
                if( g_mousedown == true && g_drawing == true )
                {
                    // then draw the current wall state and tile
                    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 <= '5' )
                {
                    g_weight = ((float)(event.key.keysym.unicode - '0') + 1.0f) * 4;
                }

                // toggle the drawing mode
                if( event.key.keysym.unicode == 'd' )
                {
                    g_drawing = !g_drawing;
                }

                // place the start position
                if( event.key.keysym.unicode == 's' )
                {
                    g_moving = false;
                    g_currentx = x / 8;
                    g_currenty = y / 8;
                }

                // place the goal
                if( event.key.keysym.unicode == 'g' )
                {
                    g_moving = false;
                    g_goalx = x / 8;
                    g_goaly = y / 8;
                }

                // start the pathfinding
                if( event.key.keysym.unicode == ' ' )
                {
                    g_moving = true;

                    // empty the movement stacks
                    while ( g_xmovement.Count() != 0 || 
                            g_ymovement.Count() != 0 )
                    {
                        g_xmovement.Pop();
                        g_ymovement.Pop();
                    }

                    // calculate the path through the map
                    PathAStar( g_map, g_currentx, g_currenty, g_goalx, g_goaly );

                    // iterate through the map, and push every cell in the path
                    // onto the movement stacks
                    x = g_goalx;
                    y = g_goaly;
                    while( x != -1 && y != -1 )
                    {
                        g_xmovement.Push( x );
                        g_ymovement.Push( y );
                        t = g_map.Get( x, y ).m_lastx;
                        y = g_map.Get( x, y ).m_lasty;
                        x = t;
                    }

                    // pop the first cell off the stack, since the player is
                    // already on that cell
                    g_xmovement.Pop();
                    g_ymovement.Pop();

                    // reset the timer
                    g_timer = SDL_GetTicks();
                }



            }
        }

        // if 500 milliseconds have passed since the last
        // move, and the player is moving
        if( SDL_GetTicks() - g_timer >= 500 && g_moving == true )
        {
            // record the current time
            g_timer = SDL_GetTicks();

            if( g_xmovement.Count() == 0 )
            {
                // if there are no more moves, then stop moving.
                g_moving = false;
            }
            else
            {
                // get the next cell
                g_currentx = g_xmovement.Top();
                g_currenty = g_ymovement.Top();

                // pop it from the stack
                g_xmovement.Pop();
                g_ymovement.Pop();
            }
        }


        DrawMap();
        SDL_UpdateRect( g_window, 0, 0, 0, 0 );
    }

    SaveMap();
    return 0;
}

⌨️ 快捷键说明

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