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

📄 main.cpp

📁 A Star 算法 的C++实现, 有很好的类实现
💻 CPP
字号:
/*
NOTE: This code was written using Microsoft's Visual C++ v 6.0.
I don't know how well it will work with other compilers.

You also will need the Direct X 7.0 SDK, and to install the lib
and include files from the SDK to your C++ lib and include
folders. You can get the DirectX 7.0 SDK (large!) here:
http://download.microsoft.com/download/win98SE/SDK/7.0/W9X/EN-US/dx7sdk-700.1.exe


========================
A* Pathfinder - The Maze
========================
By Patrick Lester, pwlester@policyalmanac.org

A fuller implementation than the Basics demo. This is the 
template you will want to work from if you want to write or
customize your own version of A*.

Instructions
------------
- Press enter to start pathfinding mode
- left or right click anywhere on the map to make the smiley
  go there.
- search times are printed in the upper left hand coner
- map may be edited by pressing enter button to toggle to
  map editing mode and left clicking on the map.

*/

#define WINDOW_NAME "Program" //Visible when game is minimized
#include "../common/launchWindows.h"
#include "../common/dxLibrary.h"
#include "aStarLibrary.h"

//-----------------------------------------------------------------------------
// Global variables and constants
//-----------------------------------------------------------------------------
cImage* wallImage; cImage* mapImage;
cImage* mousePointer; 
cImage* smiley; cImage* chaser;
char smileyActivated = 0;
int xLoc [4]; int yLoc [4]; int speed [4];
int searchTime, g_showDirections=0; 


//-----------------------------------------------------------------------------
// Function Prototypes: where necessary
//-----------------------------------------------------------------------------
void CheckUserInput (void);
void CreateMapImage (void);
void CreateWallImage (void);
void DrawMap (void);
void EditMap (void);
void LoadGraphics (void);
void LoadMapData (void);
void LoadUnitData (void);
void MoveChaser (int ID);
void MoveSmiley (void);
void MoveSprite(int ID);
void RenderScreen (void);
void SaveMapData (void);
void ShowDirections (void);


//-----------------------------------------------------------------------------
// Name: GameMain
// Desc: Launch and run game.
//-----------------------------------------------------------------------------
void GameMain (HWND hwnd)
{
	Graphics (800,600,16,hwnd);
	LoadMapData();
	LoadUnitData();
	LoadGraphics();
	InitializePathfinder();

	//Main game loop
    while (!KeyDown(27)) //While escape key not pressed
    {
		CheckUserInput();

		//Move smiley
		if (smileyActivated == 1) MoveSmiley();
	
		//Move chasers
		if (smileyActivated == 1)  
			for (int ID = 2; ID <= 3; ID++) 
				MoveChaser(ID);

		RenderScreen(); //draw stuff on screen
		CheckWinMessages();
	}	

	SaveMapData();
	EndPathfinder();
	EndGraphics();
	return;
}


//-----------------------------------------------------------------------------
// Name: CheckUserInput
// Desc: Process key and mouse presses.
//-----------------------------------------------------------------------------
void CheckUserInput (void) 
{
	if (KeyHit(13))
	{
		smileyActivated = 1 - smileyActivated;
		if (smileyActivated == 1) CreateMapImage();
	}
	if (smileyActivated == 0) EditMap();

	//Show/hide directions by pressing space bar.
	if (KeyHit(32)) g_showDirections = 1-g_showDirections;
}


//-----------------------------------------------------------------------------
// Name: CreateMapImage
// Desc: Creates the map image
//-----------------------------------------------------------------------------
void CreateMapImage (void) 
{
	FreeImage(mapImage);
	mapImage = CreateImage(800,600); //create a new map image.
	SetBuffer (0,mapImage);
	Color(0,0,255);//set default color to blue
	for (int x = 0; x <= 79; x++){
		for (int y = 0; y <= 59; y++){

		//Draw blue walls
		if (walkability[x][y] == unwalkable) 
			Rect(x*10,y*10,10,10,1);
		
	}}		
	SetBuffer (2);
	Color(255,255,255);//set default color to white
}


//-----------------------------------------------------------------------------
// Name: CreateWallImage
// Desc: Creates a blue 10x10 wall block image
//-----------------------------------------------------------------------------
void CreateWallImage (void) 
{
	wallImage = CreateImage(10,10); //create a new map image.
	SetBuffer (0,wallImage);
	Color(0,0,255);//set default color to blue
	Rect(0,0,10,10,1);
	SetBuffer (2);
	Color(255,255,255);//set default color to white
}


//-----------------------------------------------------------------------------
// Name: DrawMap
// Desc: Edit the map by left clicking while in edit mode.
//-----------------------------------------------------------------------------
void DrawMap(void)
{
	if (smileyActivated == 1) 
		DrawBlock (mapImage,0,0);
	else
	{
		for (int x = 0; x <= 79; x++){
		for (int y = 0; y <= 59; y++){

			//Draw blue walls
			if (walkability[x][y] == unwalkable) 
				DrawBlock (wallImage,x*10,y*10);
		}}
	}
}


//-----------------------------------------------------------------------------
// Name: EditMap
// Desc: Edit the map by left clicking while in edit mode.
//-----------------------------------------------------------------------------
void EditMap (void)
{
	if (MouseHit(1))
	{
		int x = MouseX()/10;
		int y = MouseY()/10;
		walkability[x][y] = 1-walkability[x][y];
	}
}


//-----------------------------------------------------------------------------
// Name: LoadGraphics
// Desc: Loads graphics
//-----------------------------------------------------------------------------
void LoadGraphics (void)
{
	SetFont("Arial",14);
	CreateWallImage();
	CreateMapImage();
	mousePointer = LoadImage("../../Graphics/red_pointer.bmp");
	MaskImage (mousePointer, 255,255,255);

	AutoMidHandle(true);
	smiley = LoadImage("../../Graphics/smiley x 10.bmp");
	MaskImage (smiley, 0,0,0);

	chaser = LoadImage("../../Graphics/ghost x 10.bmp");
	MaskImage (chaser, 0,0,0);
}


//-----------------------------------------------------------------------------
// Name: LoadMapData
// Desc: Load any pre-existing map when launching the program.
//-----------------------------------------------------------------------------
void LoadMapData (void)
{
	ifstream filein;
	filein.open("myTerrainData.dat",ios::nocreate);
	if (filein)
	{
		for (int x = 0; x <= 79; x++){
			for (int y = 0; y <= 59; y++){
			filein >> walkability [x][y];//or filein.read(buffer,length)
			if (walkability [x][y] > 1) walkability [x][y] = 0;
		}}
		filein.close();	
	}
	else //initialize the map to completely walkable
	{
		for (int x = 0; x <= 79; x++){
			for (int y = 0; y <= 59; y++){
				walkability [x][y] = walkable;
		}}
	}
}


//-----------------------------------------------------------------------------
// Name: LoadUnitData
// Desc: Initialize unit-related data
//-----------------------------------------------------------------------------
void LoadUnitData (void) 
{
	xLoc[1] = 125 ; yLoc[1] = 325; //initial smiley location
	xLoc[2] = 725 ; yLoc[2] = 325; //initial chaser location
	xLoc[3] = 465 ; yLoc[3] = 145; //initial chaser location	
	speed[1] = 5;//smiley speed
	speed[2] = 3;//chaser
	speed[3] = 2;//chaser
}


//-----------------------------------------------------------------------------
// Name: MoveChaser
// Desc: This subroutine moves the chasers/ghosts around on the screen.
//	In this case the findPath function is accessed automatically when
//	a chaser reaches the end of his current path. The path info
//	is also updated occasionally.
//-----------------------------------------------------------------------------
void MoveChaser (int ID)  
{
	int targetID = 1; //ID of target (the smiley)

//1. Find Path: If smiley and chaser are not at the same location on the 
//	screen and no path is currently active, find a new path.
	if (xLoc[ID] != xLoc[targetID] || yLoc[ID] != yLoc[targetID]) 
	{
	//If no path has been generated, generate one. Update it when
	//the chaser reaches its fifth step on the current path.	
	if (pathStatus[ID] == notStarted || pathLocation[ID] == 5)
	{
		//Generate a new path. Enter coordinates of smiley sprite (xLoc(1)/
		//yLoc(1)) as the target.
		pathStatus[ID] = FindPath(ID,xLoc[ID],yLoc[ID],
			xLoc[targetID],yLoc[targetID]);
		
	}} 

//2.Move chaser.
	if (pathStatus[ID] == found) MoveSprite(ID);
}


//-----------------------------------------------------------------------------
// Name: MoveSmiley
// Desc: This subroutine moves the smiley around on the screen. In
//	this case the findPath function is accessed via mouse clicks.
//-----------------------------------------------------------------------------
void MoveSmiley (void)  
{
	int ID = 1; //ID of smiley sprite

//1.Find Path: If smiley is active, any left or right click 
//	on the map will find a path and make him go there.
	if (MouseHit(1) || MouseHit(2))
	{	
		//Call the findPath function.
		int time1 = timeGetTime();
		pathStatus[ID] = FindPath(ID,xLoc[ID],yLoc[ID],MouseX(),MouseY());
		int time2 = timeGetTime();
		searchTime = time2-time1;
	}

//2.Move smiley.
	if (pathStatus[ID] == found) MoveSprite(ID);	
}


//-----------------------------------------------------------------------------
// Name: MoveSprite
// Desc: Moves the sprites around on the screen.
//-----------------------------------------------------------------------------
void MoveSprite(int ID)
{
//1.Read path information
	ReadPath(ID,xLoc[ID],yLoc[ID],speed[ID]);

//2.Move sprite. xLoc/yLoc = current location of sprite. xPath and
//	yPath = coordinates of next step on the path that were/are
//	read using the readPath function.
	if (xLoc[ID] > xPath[ID]) xLoc[ID] = xLoc[ID] - speed[ID];
	if (xLoc[ID] < xPath[ID]) xLoc[ID] = xLoc[ID] + speed[ID];
	if (yLoc[ID] > yPath[ID]) yLoc[ID] = yLoc[ID] - speed[ID];		
	if (yLoc[ID] < yPath[ID]) yLoc[ID] = yLoc[ID] + speed[ID];
	
//3.When sprite reaches the end location square	(end of its current
//	path) ...		
	if (pathLocation[ID] == pathLength[ID]) 
	{
//		Center the chaser in the square (not really necessary, but 
//		it looks a little better for the chaser, which moves in 3 pixel
//		increments and thus isn't always centered when it reaches its
//		target).
		if (abs(xLoc[ID] - xPath[ID]) < speed[ID]) xLoc[ID] = xPath[ID];
		if (abs(yLoc[ID] - yPath[ID]) < speed[ID]) yLoc[ID] = yPath[ID];
	}
}	


//-----------------------------------------------------------------------------
// Name: RenderScreen
// Desc: Draws stuff on screen
//-----------------------------------------------------------------------------
void RenderScreen (void) 
{
	Cls();
	DrawMap();

	DrawImage (smiley,xLoc[1],yLoc[1]);
	for (char ID = 2; ID <= 3; ID++)
		DrawImage (chaser,xLoc[ID],yLoc[ID]);

	//Show directions
	if (g_showDirections != 0) 
		ShowDirections();
	else
	{
		SetFont("Arial",14);
		Text(0,0,"Press space bar for directions");
	}

	if (smileyActivated == 0) 
	{
		SetFontColor (255,0,0);
		Text (0,20,"Map Edit Mode");
		SetFontColor (255,255,255);
	}
	else
		Text (0,20,combine "Search Time = " + searchTime + " ms");

	DrawImage (mousePointer,MouseX(),MouseY());
	Flip();
}


//-----------------------------------------------------------------------------
// Name: SaveMapData
// Desc: Saves the map when exiting the program.
//-----------------------------------------------------------------------------
void SaveMapData (void) 
{
	ofstream fileout;
	fileout.open("myTerrainData.dat");
	for (int x = 0; x <= 79; x++){
		for (int y = 0; y <= 59; y++){
		if (walkability [x][y] != 1) walkability [x][y] = 0;
		fileout << walkability [x][y];
	}}
	fileout.close();
}


//-----------------------------------------------------------------------------
// Name: ShowDirections
// Desc: Shows directions when the space bar has been hit.
//-----------------------------------------------------------------------------
void ShowDirections(void)
{
	SetBrush(0,0,0);
	SetPen(255,0,0);	
	Rect(100,100,600,401,1);
	SetFont("Arial",16,1,0,1);
	Text(125,130,"Directions");
	SetFont("Arial",16);

	Text(125,150,"- Press the space bar to hide or show these directions.");
	Text(125,170,"- Press enter to start pathfinding mode. Press enter again to toggle back");
	Text(125,190,"  to map-editing mode.");
	Text(125,210,"- When in pathfinding mode, left or right click anywhere on the map to"); 
	Text(125,230,"  make the smiley go there.");
	Text(125,250,"- When in map edit mode, draw blue walls by left clicking on the screen.");
	Text(125,270,"- Erase blue walls by left clicking on them.");

	Text(125,310,"Press escape to exit the program.");
	SetFont("Arial",14);
}

⌨️ 快捷键说明

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