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

📄 astarex.cpp

📁 类AStarPathFinder实现方块状网格上的A*算法
💻 CPP
字号:
//------------------------------------------------------------------------------
// PROJECT: Class A* Pathfinder Example Program
// OVERVIEW:
//    Link astar.cpp cdx.lib ddraw.lib dinput.lib dxguid.lib winmm.lib
// Revision: 1.0
// Last Update: 11.08.97
// FILE:   ASTAREX.CPP
// AUTHOR: pat@das-netz.de Germany
//------------------------------------------------------------------------------

#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <CDX.h>
#include "ASTAR.H"

CDXInput Input;    // The input object
CDXScreen* Screen; // The screen object
CDXTile* Tiles;    // The map tiles
CDXMap* Map;       // The scrolling map object
CDXSprite* Cursor; // The mousecursor
CDXSprite* Virus;  // The virus

AstarPathfinder* Astar; // The A* object

BOOL bActive = TRUE; // Is the program running?


////////////////////////////////////////////////////////////////////////////////
//                         Check for sprite-tile collosion                    //
////////////////////////////////////////////////////////////////////////////////

BOOL TileHit(int x, int y)
{
	Virus->MoveTo(x - Map->m_PosX,
   				  y - Map->m_PosY);

	for (int i = 0; i < 4; i++) // for all forbidden Tiles
       if ( Virus->TileHit(Map, i) ) //check Hit
          return TRUE;

	return FALSE;
}

////////////////////////////////////////////////////////////////////////////////
//                                   WinProc                                  //
////////////////////////////////////////////////////////////////////////////////

long PASCAL WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch( message )
	{
		case WM_ACTIVATEAPP:
      	    bActive = wParam;
		break;

		case WM_KEYDOWN:
			switch(wParam)
			{
				case VK_ESCAPE:
					PostMessage(hWnd, WM_CLOSE, 0, 0);
				break;
			}
		break;

		case WM_DESTROY:
     		PostQuitMessage(0);
		break;
	}

	return DefWindowProc(hWnd, message, wParam, lParam);
}

////////////////////////////////////////////////////////////////////////////////
//              InitApp - Create the window and the objects                   //
////////////////////////////////////////////////////////////////////////////////

BOOL InitApp(HINSTANCE hInst, int nCmdShow)
{
	HWND hWnd;
	WNDCLASS WndClass;

	WndClass.style = CS_HREDRAW | CS_VREDRAW;
	WndClass.lpfnWndProc = WinProc;
	WndClass.cbClsExtra = 0;
	WndClass.cbWndExtra = 0;
	WndClass.hInstance = hInst;
	WndClass.hIcon = LoadIcon(0, IDI_APPLICATION);
	WndClass.hCursor = LoadCursor(0, IDC_ARROW);
	WndClass.hbrBackground = GetStockObject(BLACK_BRUSH);
	WndClass.lpszMenuName = 0;
	WndClass.lpszClassName = "AstarEx";
	RegisterClass(&WndClass);

	hWnd = CreateWindowEx(
		WS_EX_TOPMOST,
		"AstarEx",
		"AstarEx",
		WS_POPUP,
		0,0,
		GetSystemMetrics(SM_CXSCREEN),
		GetSystemMetrics(SM_CYSCREEN),
		NULL,
		NULL,
		hInst,
		NULL);

	if ( !hWnd ) return FALSE;

	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	// Create the CDXSreen object
	Screen = new CDXScreen();
	Screen->CreateFullScreen(hWnd, 640, 480, 8);

	// Load the palette
	Screen->LoadPalette("VIRUS.BMP");

	// Load the tiles
	Tiles = new CDXTile(Screen, "MAPTILES.BMP", 64, 64, 5);

	// Create and load the map
	Map = new CDXMap(Tiles, Screen);
	Map->Load("CDX.MAP");
	Map->MoveTo(0,0);

   // Create and init the astar object with the CDXMmap object
	Astar = new AstarPathfinder(Map, 4);  // 4 forbidden tiles

	// Load cursor sprite
	Cursor = new CDXSprite(Screen, "MOUSE.BMP", 32, 32, 1);
	Cursor->SetFrame(0);
	Cursor->ColorKey(0);

	// Load virus sprite
	Virus = new CDXSprite(Screen, "VIRUS.BMP", 24, 24, 40);
	Virus->ColorKey(215);

    // Create input devices
	Input.Create(hInst, hWnd);

	return TRUE;
}

////////////////////////////////////////////////////////////////////////////////
//                                     WinMain                                //
////////////////////////////////////////////////////////////////////////////////

int PASCAL WinMain(HINSTANCE hInst, HINSTANCE hPrevInst,
						 LPSTR lpCmdLine, int nCmdShow)
{
	MSG msg;
	static int MouseX;
	static int MouseY;
	int destX = 32, destY = 32,
		posX = 32, posY = 32;
	int curFrame = 0;
   
	if ( !InitApp(hInst, nCmdShow) ) return FALSE;

	while ( 1 )  // Mainloop
	{
		if ( PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) )
		{
			if ( !GetMessage(&msg, NULL, 0, 0) ) return msg.wParam;
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else if ( bActive )
		{
         Input.Update();  // refresh the input devices

         // check for mousecursor collosion

         MouseX += Input.Mouse.x;
         if ( MouseX < 1 )
         	MouseX = 1;
         else if ( MouseX > 608 )
         	MouseX = 608;

         MouseY += Input.Mouse.y;
         if ( MouseY < 1 )
         	MouseY = 1;
         else if ( MouseY > 420 )
         	MouseY = 420;

         Cursor->MoveTo(MouseX, MouseY);

         // perform the map with mouse

         if( MouseY == 1 )    Map->ScrollUp(4);
			if( MouseX == 1 )    Map->ScrollLeft(4);
         if( MouseY == 420 )  Map->ScrollDown(4);
			if( MouseX == 608 )  Map->ScrollRight(4);

         // ------------------------   A* 's stuff   ------------------------ //

         if ( Input.MouseLB &&     // NewPath() must be called and be true before any other A* calls.
         	  Astar->NewPath(posX, posY, MouseX+Map->m_PosX,     // Except Astar->ReachedGoal()
										 MouseY+Map->m_PosY) )   // it returns true if path is false
         {
            Astar->PathNextNode();   // point to next node = next tile on path
            destX = Astar->NodeGetX();  // get the positions from current node
      	  	destY = Astar->NodeGetY();  // and set the new destination
         }

                                    // first we wait until reached next tile, performed below
         if ( !Astar->ReachedGoal() && (destX==posX)&&(destY==posY) )
         {
         	Astar->PathNextNode();   // point to next node
            destX = Astar->NodeGetX(); // get the positions from current node
      		destY = Astar->NodeGetY();
         }

         // ----------------------------------------------------------------- //
         
         // perform moves from tile to tile

			if ( destX > posX ) posX++;       // it is a right event?
			if ( TileHit(posX,posY) ) posX--;

    		if ( destY > posY ) posY++;       // it is a down event?
    	  	if ( TileHit(posX,posY) ) posY--;

    		if ( destX < posX ) posX--;
    	  	if ( TileHit(posX,posY) ) posX++; // it is a left event?

    		if ( destY < posY ) posY--;
    	  	if ( TileHit(posX,posY) ) posY++; // it is an up event?

         // set the virus sprite

         if ( curFrame > 39 ) curFrame = 0;
         Virus->SetFrame(curFrame++);
         Virus->MoveTo(posX - Map->m_PosX,
					   posY - Map->m_PosY);

         // draw all

         Screen->Fill(0);
         Map->Draw(Screen->GetBack());
         Virus->DrawClipped(Screen->GetBack());
         Cursor->DrawTrans(Screen->GetBack());

         Screen->Flip();  // then display
		}
		else WaitMessage();
	}
}


⌨️ 快捷键说明

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