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