📄 main.cpp
字号:
g_pd3dDevice,
szTileName,
&g_pTexture[ i ] ) ) ) {
return;
}
}
// Load the rabbit textures
for( i = 0; i < 8; i++ ) {
// Set the name
sprintf( szTileName, "rabbit%d.tga", i );
// Load it
if( FAILED( D3DXCreateTextureFromFile(
g_pd3dDevice,
szTileName,
&g_pRabbitTextures[ i ] ) ) ) {
return;
}
}
// Load the arrow textures
for( i = 0; i < 8; i++ ) {
// Set the name
sprintf( szTileName, "arrow%d.tga", i );
// Load it
if( FAILED( D3DXCreateTextureFromFile(
g_pd3dDevice,
szTileName,
&g_pArrowTextures[ i ] ) ) ) {
return;
}
}
// Text Font
hFont = CreateFont(
16, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, PROOF_QUALITY,
0, "fixedsys" );
// Create the Direct3D Font
D3DXCreateFont( g_pd3dDevice, hFont, &pD3DXFont );
};
//--------------------------------------------------------------------------------------
//
// Function to draw a 3D object in 2D space
//
// iXPos = x-position in screen-space of the top-left corner of the object
// iYPos = y-position in screen-space of the top-left corner of the object
// fXSize = Width of the object in screen-space (pixels)
// fYSize = Height of the object in screen-space (pixels)
// iTexture = Index into the texture array of object to draw
//
//--------------------------------------------------------------------------------------
void vDrawInterfaceObject( int iXPos, int iYPos, float fXSize, float fYSize, LPDIRECT3DTEXTURE9 tex )
{
D3DXMATRIX matWorld, matRotation, matTranslation, matScale;
float fXPos, fYPos;
// Set default position,scale,rotation
D3DXMatrixIdentity( &matTranslation );
// Scale the sprite
D3DXMatrixScaling( &matScale, fXSize, fYSize, 1.0f );
D3DXMatrixMultiply( &matTranslation, &matTranslation, &matScale );
// Rotate the sprite
D3DXMatrixRotationZ( &matRotation, 0.0f );
D3DXMatrixMultiply( &matWorld, &matTranslation, &matRotation );
// Calculate the position in screen-space
fXPos = (float)(-(g_iWindowWidth/2)+iXPos);
fYPos = (g_iWindowHeight/2)-fYSize-iYPos;
// Move the sprite
matWorld._41 = fXPos; // X
matWorld._42 = fYPos; // Y
// Set matrix
g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
g_pd3dDevice->SetTexture( 0, tex );
g_pd3dDevice->SetStreamSource( 0, g_pVBInterface, 0, sizeof( CUSTOMVERTEX ) );
g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
// Dereference texture
g_pd3dDevice->SetTexture(0, NULL);
}
//--------------------------------------------------------------------------------------
//
// Function to initialize the map
//
//--------------------------------------------------------------------------------------
void vInitMap( void )
{
int i, j;
// Clear the map
for( i = 0; i < g_iMapWidth * g_iMapHeight; i++ ) {
// Base layer gets water
g_iTileMap[ i ][ 0 ] = 1;
// Other layers get 0
for( j = 1; j < 4; j++ ) {
g_iTileMap[ i ][ j ] = 0;
}
}
// Clear the arrow map, it uses -1 for the
// "blank" tile
for( i = 0; i < g_iMapWidth * g_iMapHeight; i++ ) {
g_iArrowMap[ i ] = -1;
}
}
//-----------------------------------------------------------------------------
//
// Creates the command toolbar
//
// Commands
// --------
// Load - Loads a map created with the D3D_MapEditorLayers program
// Go - Calculates and executes the path to solve the map loaded
//
//-----------------------------------------------------------------------------
void vCreateToolbar(HWND hwnd, HINSTANCE hinst)
{
WNDCLASSEX wcToolBar;
// Set up and register toolbar window class
wcToolBar.cbSize = sizeof(wcToolBar);
wcToolBar.style = CS_HREDRAW | CS_VREDRAW;
wcToolBar.lpfnWndProc = fnMessageProcessor;
wcToolBar.cbClsExtra = 0;
wcToolBar.cbWndExtra = 0;
wcToolBar.hInstance = hinst;
wcToolBar.hIcon = LoadIcon( NULL, IDI_APPLICATION );
wcToolBar.hCursor = LoadCursor( NULL, IDC_ARROW );
wcToolBar.hbrBackground = (HBRUSH) GetStockObject (COLOR_BACKGROUND);
wcToolBar.lpszMenuName = NULL;
wcToolBar.lpszClassName = "ToolBar"; // Registered Class Name
wcToolBar.hIconSm = LoadIcon( NULL, IDI_APPLICATION );
RegisterClassEx(&wcToolBar);
// Create toolbar window
hWndToolBar = CreateWindowEx (
WS_EX_LEFT|WS_EX_TOPMOST|WS_EX_TOOLWINDOW,
"ToolBar", "Command Bar",
WS_BORDER | WS_VISIBLE | WS_CAPTION | WS_MINIMIZEBOX,
g_iWindowWidth-100, g_iYOffset, 100, 80, hwnd, NULL, hinst, NULL);
// Load Button
hBUTTON_LOAD = CreateWindow(
"BUTTON", "Load",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
5, 5, 85, 20, hWndToolBar, (HMENU)ID_BUTTON_LOAD, hinst, NULL);
// Go Button
hBUTTON_GO = CreateWindow(
"BUTTON", "Go",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
5, 35, 85, 20, hWndToolBar, (HMENU)ID_BUTTON_GO, hinst, NULL);
// Activate edit area
SetActiveWindow( g_hWnd );
}
//-----------------------------------------------------------------------------
//
// Loads the tile map from a binary file.
//
//-----------------------------------------------------------------------------
void vLoadMap( char *szMapName )
{
FILE *fp;
OPENFILENAME fileStruct;
char szFileName[ 512 ];
char szFilter[ 32 ];
char szExtension[ 32 ];
int iRet;
// Clear out maps prior to loading
vInitMap();
// Clear buffer to receive file name
memset( szFileName, 0x00, 512 );
// Create file filter
memset( szFilter, 0x00, 32 );
strcpy( szFilter, "*.dat" );
// Create file extension
memset( szExtension, 0x00, 32 );
strcpy( szExtension, "dat" );
//
// Setup the file dialog box
//
if( szMapName == NULL ) {
// Clear file dialog structure
memset( &fileStruct, 0x00, sizeof( OPENFILENAME ) );
// Initialize structure
fileStruct.hInstance = g_hInstance;
fileStruct.hwndOwner = g_hWnd;
fileStruct.lpstrDefExt = szExtension;
fileStruct.lpstrFileTitle = szFileName;
fileStruct.lpstrFilter = szFilter;
fileStruct.nMaxFileTitle = 512;
fileStruct.lStructSize = sizeof( OPENFILENAME );
// Retrieve the filename
iRet = GetOpenFileName( &fileStruct );
// Exit out on failure
if( !iRet ) {
return;
}
}
else {
strcpy( szFileName, szMapName );
}
// Open the tile file
fp = fopen( szFileName, "rb" );
// Return if no file to load
if( fp == NULL ) {
return;
}
// Read the tile buffer
fread( g_iTileMap, 40000, sizeof(int), fp );
// Close the tile file
fclose( fp );
// Play sound to indicate action
PlaySound("button.wav",NULL,SND_FILENAME|SND_ASYNC);
}
//------------------------------------------------------------------------
//
// PATH FINDING FUNCTIONS
//
//------------------------------------------------------------------------
//
// Function to get the map cost
//
// >0 = passable
// -1 = blocked
//
int iGetMapCost( int iX, int iY )
{
// If out of horizontal bounds return impassable
if( iX < 0 || iX >= g_iTilesWide )
return( -1 );
// If out of vertical bounds return impassable
if( iY < 0 || iY >= g_iTilesHigh )
return( -1 );
// Return impassable if not the 0 tile
if( g_iTileMap[ iX+(iY*g_iMapWidth) ][ 1 ] != 0 ) {
return( -1 );
}
// Return tile value for anything else
else {
return( g_iTileMap[ iX+(iY*g_iMapWidth) ][ 1 ] );
}
}
//
// Initialize the path and follow it
//
void vInitPathing( void )
{
bool bRet;
int iTempX;
int iTempY;
int iDir;
// Start & End map positions
int iNodeStartX;
int iNodeStartY;
int iNodeEndX;
int iNodeEndY;
// Timers
DWORD dwStartTime;
DWORD dwTotalTime;
// Path class object
CPathFinder pathMyPath;
// Clear the arrow map
// Use it later to show the path
for( int i = 0; i < g_iMapWidth * g_iMapHeight; i++ ) {
g_iArrowMap[ i ] = -1;
}
//
// Set rabbit start pos
//
// Search the map for a "start" tile
for( int y = 0; y < g_iMapHeight; y++ ) {
for( int x = 0; x < g_iMapWidth; x++ ) {
if( g_iTileMap[ x+(y*g_iMapWidth) ][ 0 ] == 19 ) {
g_iRabbitXPos = x;
g_iRabbitYPos = y;
// Create a start state
iNodeStartX = g_iRabbitXPos;
iNodeStartY = g_iRabbitYPos;
break;
}
}
}
//
// Set rabbit end pos
//
// Search the map for a "end" tile
for( y = 0; y < g_iMapHeight; y++ ) {
for( int x = 0; x < g_iMapWidth; x++ ) {
if( g_iTileMap[ x+(y*g_iMapWidth) ][ 0 ] == 20 ) {
iNodeEndX = x;
iNodeEndY = y;
break;
}
}
}
// Update rendered message
sprintf( g_szPathStatus, "CALCULATING PATH" );
vRender();
// Setup the cost function
pathMyPath.vSetCostFunction( iGetMapCost );
// Start the timer
dwStartTime = timeGetTime();
// Setup the start and end
pathMyPath.vSetStartState( iNodeStartX, iNodeStartY, iNodeEndX, iNodeEndY );
// Find the path - 300 maximum nodes
bRet = pathMyPath.bFindPath( 300 );
// Stop the timer
dwTotalTime = timeGetTime()-dwStartTime;
// Exit on failure
if( !bRet ) {
// Update rendered message
sprintf( g_szPathStatus,
"FAILED, OPEN = %d, CLOSED = %d, TIME = %ld",
pathMyPath.m_iActiveOpenNodes,
pathMyPath.m_iActiveClosedNodes,
dwTotalTime );
return;
}
else {
// Update rendered message
sprintf( g_szPathStatus,
"COMPLETE, OPEN = %d, CLOSED = %d, TIME = %ld",
pathMyPath.m_iActiveOpenNodes,
pathMyPath.m_iActiveClosedNodes,
dwTotalTime );
}
// Follow the path now
CPathNode *GoalNode = pathMyPath.m_CompletePath->m_Path[ 0 ];
int iTotalNodes = 0;
// Set temp position to figure out direction arrow
iTempX = GoalNode->m_iX;
iTempY = GoalNode->m_iY;
// Start at position 1 not 0
iTotalNodes++;
GoalNode = pathMyPath.m_CompletePath->m_Path[ iTotalNodes ];
// Loop through the path and follow it
// Draw an arrow for each step
while( iTotalNodes < pathMyPath.m_CompletePath->m_iNumNodes ) {
// Figure out direction
iDir = vFindDirection( iTempX, iTempY, GoalNode->m_iX, GoalNode->m_iY );
// Set arrow on arrow map
g_iArrowMap[ GoalNode->m_iX+(GoalNode->m_iY*g_iMapWidth) ] = iDir;
// Render the scene
vRender();
// Set temp position to figure out direction arrow
iTempX = GoalNode->m_iX;
iTempY = GoalNode->m_iY;
// Increment node count
iTotalNodes++;
// Get next node
GoalNode = pathMyPath.m_CompletePath->m_Path[ iTotalNodes ];
};
}
//
// Figure out which direction to face when moving
// from a start position to an end position
//
int vFindDirection( int iStartX, int iStartY, int iEndX, int iEndY )
{
int iDir;
if( iEndX > iStartX ) {
if( iEndY > iStartY ) {
iDir = 3;
}
else if ( iEndY == iStartY ) {
iDir = 2;
}
else if ( iEndY < iStartY ) {
iDir = 1;
}
}
else if( iEndX < iStartX ) {
if( iEndY > iStartY ) {
iDir = 5;
}
else if ( iEndY == iStartY ) {
iDir = 6;
}
else if ( iEndY < iStartY ) {
iDir = 7;
}
}
if( iEndX == iStartX ) {
if( iEndY > iStartY ) {
iDir = 4;
}
else if ( iEndY == iStartY ) {
iDir = 2;
}
else if ( iEndY < iStartY ) {
iDir = 0;
}
}
return( iDir );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -