isohex18_3.cpp
来自「一個遊戲教程」· C++ 代码 · 共 808 行 · 第 1/2 页
CPP
808 行
/*****************************************************************************
IsoHex18_3.cpp
Ernest S. Pazera
09SEPT2000
Start a WIN32 Application Workspace, add in this file
Requires the following libs:
ddraw.lib, dxguid.lib
Requires the following files:
DDFuncs.h.cpp, GDICanvas.h/cpp, IsoMouseMap.h/cpp,
IsoScroller.h/cpp, IsoTilePlotter.h/cpp, IsoTileWalker.h/cpp
TileSet.h/cpp. IsoHexCore.h, IsoHexDefs.h
IsoRenderer.h/cpp
*****************************************************************************/
//////////////////////////////////////////////////////////////////////////////
//INCLUDES
//////////////////////////////////////////////////////////////////////////////
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "DDFuncs.h"
#include "TileSet.h"
#include "IsoHexCore.h"
#include "IsoRenderer.h"
#include <list>
//////////////////////////////////////////////////////////////////////////////
//DEFINES
//////////////////////////////////////////////////////////////////////////////
//name for our window class
#define WINDOWCLASS "ISOHEX18"
//title of the application
#define WINDOWTITLE "IsoHex 18-3"
const int MAPWIDTH=40;
const int MAPHEIGHT=40;
//gamestates
const int GS_IDLE=0;//waits for a keypress
const int GS_STARTTURN=1;//starts a players turn
const int GS_ENDTURN=2;//ends a players turn
const int GS_NEXTUNIT=3;//finds the next unit to move
const int GS_STARTMOVE=4;//starts moving the unit
const int GS_DOMOVE=5;//moves the unit
const int GS_ENDMOVE=6;//ends a unit move
const int GS_NULLMOVE=7;//tells a unit to not move
const int GS_SKIPMOVE=8;//temporarily skip the move
//////////////////////////////////////////////////////////////////////////////
//TYPEDEFS/STRUCTS
//////////////////////////////////////////////////////////////////////////////
struct UnitInfo//unit information structure
{
int iType;//type of unit
int iTeam;//team to which the unit belongs
POINT ptPosition;//map location of the unit
int iMovePoints;//number of movepoints left this turn
};
typedef UnitInfo *PUNITINFO;//pointer type alias for unitinfo
typedef std::list<PUNITINFO> UNITLIST;//list of units
typedef std::list<PUNITINFO>::iterator UNITLISTITER;//iterator for unit list
//////////////////////////////////////////////////////////////////////////////
//PROTOTYPES
//////////////////////////////////////////////////////////////////////////////
bool Prog_Init();//game data initalizer
void Prog_Loop();//main game loop
void Prog_Done();//game clean up
//////////////////////////////////////////////////////////////////////////////
//GLOBALS
//////////////////////////////////////////////////////////////////////////////
HINSTANCE hInstMain=NULL;//main application handle
HWND hWndMain=NULL;//handle to our main window
//game state
int iGameState=GS_IDLE;
int iCurrentTeam=0;//the team whose turn it currently is
//directdraw
LPDIRECTDRAW7 lpdd=NULL;
LPDIRECTDRAWSURFACE7 lpddsMain=NULL;
LPDIRECTDRAWSURFACE7 lpddsBack=NULL;
LPDIRECTDRAWSURFACE7 lpddsFrame=NULL;
//tilesets
CTileSet tsBack;//background
CTileSet tsUnit;//unit
CTileSet tsShield;//shields
//offsets for the shields
POINT ptShieldOffset[2];//one for each unit
//isohexcore components
CTilePlotter TilePlotter;//plotter
CTileWalker TileWalker;//walker
CScroller Scroller;//scroller
CMouseMap MouseMap;//mousemap
CRenderer Renderer;//renderer
POINT ptScroll;//keep track of how quickly we scroll
//map location structure
struct MapLocation
{
UNITLIST ulUnitList;//list of units on this map location
};
MapLocation mlMap[MAPWIDTH][MAPHEIGHT];//map array
UNITLIST MainUnitList;//unit list for all units
UNITLIST TeamUnitList;//unit list for teams(Current Players Turn)
PUNITINFO pCurrentUnit;//current unit being moved
bool bFlash;//controls the flashing of the current unit
ISODIRECTION idMoveUnit;//direction in which the unit will be moved
//rendering functionprototype
void RenderFunc(LPDIRECTDRAWSURFACE7 lpddsDst,RECT* rcClip,int xDst,int yDst,int xMap,int yMap);
//////////////////////////////////////////////////////////////////////////////
//WINDOWPROC
//////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK TheWindowProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
//which message did we get?
switch(uMsg)
{
case WM_KEYDOWN:
{
switch(wParam)
{
case VK_ESCAPE:
{
DestroyWindow(hWndMain);
return(0);
}break;
case VK_SPACE://do not move unit
{
if(iGameState==GS_IDLE) iGameState=GS_NULLMOVE;//only respond when gamestate is GS_IDLE;
return(0);
}break;
case 'W'://wait to move this unit later
{
if(iGameState==GS_IDLE) iGameState=GS_SKIPMOVE;//skip this unit for now
}break;
case VK_NUMPAD8:
case VK_UP:
{
if(iGameState==GS_IDLE)//gamestate must be GS_IDLE
{
idMoveUnit=ISO_NORTH;//move to the north
POINT ptNext=TileWalker.TileWalk(pCurrentUnit->ptPosition,idMoveUnit);//check the next position
if(ptNext.x>=0 && ptNext.y>=0 && ptNext.x<MAPWIDTH && ptNext.y<MAPWIDTH)//bounds checking
{
if(mlMap[ptNext.x][ptNext.y].ulUnitList.empty())//if the map location is empty
{
iGameState=GS_STARTMOVE;//set the unit in motion
}
else
{
UNITLISTITER iter=mlMap[ptNext.x][ptNext.y].ulUnitList.begin();//get the first entry in the list
PUNITINFO pUnitInfo=*iter;//get the unit from the list
if(pUnitInfo->iTeam==pCurrentUnit->iTeam)//must be the same team
{
iGameState=GS_STARTMOVE;
}
}
}
}
}break;
case VK_NUMPAD9:
case VK_PRIOR:
{
if(iGameState==GS_IDLE)//gamestate must be GS_IDLE
{
idMoveUnit=ISO_NORTHEAST;//move to the north
POINT ptNext=TileWalker.TileWalk(pCurrentUnit->ptPosition,idMoveUnit);//check the next position
if(ptNext.x>=0 && ptNext.y>=0 && ptNext.x<MAPWIDTH && ptNext.y<MAPWIDTH)//bounds checking
{
if(mlMap[ptNext.x][ptNext.y].ulUnitList.empty())//if the map location is empty
{
iGameState=GS_STARTMOVE;//set the unit in motion
}
else
{
UNITLISTITER iter=mlMap[ptNext.x][ptNext.y].ulUnitList.begin();//get the first entry in the list
PUNITINFO pUnitInfo=*iter;//get the unit from the list
if(pUnitInfo->iTeam==pCurrentUnit->iTeam)//must be the same team
{
iGameState=GS_STARTMOVE;
}
}
}
}
}break;
case VK_NUMPAD6:
case VK_RIGHT:
{
if(iGameState==GS_IDLE)//gamestate must be GS_IDLE
{
idMoveUnit=ISO_EAST;//move to the north
POINT ptNext=TileWalker.TileWalk(pCurrentUnit->ptPosition,idMoveUnit);//check the next position
if(ptNext.x>=0 && ptNext.y>=0 && ptNext.x<MAPWIDTH && ptNext.y<MAPWIDTH)//bounds checking
{
if(mlMap[ptNext.x][ptNext.y].ulUnitList.empty())//if the map location is empty
{
iGameState=GS_STARTMOVE;//set the unit in motion
}
else
{
UNITLISTITER iter=mlMap[ptNext.x][ptNext.y].ulUnitList.begin();//get the first entry in the list
PUNITINFO pUnitInfo=*iter;//get the unit from the list
if(pUnitInfo->iTeam==pCurrentUnit->iTeam)//must be the same team
{
iGameState=GS_STARTMOVE;
}
}
}
}
}break;
case VK_NUMPAD3:
case VK_NEXT:
{
if(iGameState==GS_IDLE)//gamestate must be GS_IDLE
{
idMoveUnit=ISO_SOUTHEAST;//move to the north
POINT ptNext=TileWalker.TileWalk(pCurrentUnit->ptPosition,idMoveUnit);//check the next position
if(ptNext.x>=0 && ptNext.y>=0 && ptNext.x<MAPWIDTH && ptNext.y<MAPWIDTH)//bounds checking
{
if(mlMap[ptNext.x][ptNext.y].ulUnitList.empty())//if the map location is empty
{
iGameState=GS_STARTMOVE;//set the unit in motion
}
else
{
UNITLISTITER iter=mlMap[ptNext.x][ptNext.y].ulUnitList.begin();//get the first entry in the list
PUNITINFO pUnitInfo=*iter;//get the unit from the list
if(pUnitInfo->iTeam==pCurrentUnit->iTeam)//must be the same team
{
iGameState=GS_STARTMOVE;
}
}
}
}
}break;
case VK_NUMPAD2:
case VK_DOWN:
{
if(iGameState==GS_IDLE)//gamestate must be GS_IDLE
{
idMoveUnit=ISO_SOUTH;//move to the north
POINT ptNext=TileWalker.TileWalk(pCurrentUnit->ptPosition,idMoveUnit);//check the next position
if(ptNext.x>=0 && ptNext.y>=0 && ptNext.x<MAPWIDTH && ptNext.y<MAPWIDTH)//bounds checking
{
if(mlMap[ptNext.x][ptNext.y].ulUnitList.empty())//if the map location is empty
{
iGameState=GS_STARTMOVE;//set the unit in motion
}
else
{
UNITLISTITER iter=mlMap[ptNext.x][ptNext.y].ulUnitList.begin();//get the first entry in the list
PUNITINFO pUnitInfo=*iter;//get the unit from the list
if(pUnitInfo->iTeam==pCurrentUnit->iTeam)//must be the same team
{
iGameState=GS_STARTMOVE;
}
}
}
}
}break;
case VK_NUMPAD1:
case VK_END:
{
if(iGameState==GS_IDLE)//gamestate must be GS_IDLE
{
idMoveUnit=ISO_SOUTHWEST;//move to the north
POINT ptNext=TileWalker.TileWalk(pCurrentUnit->ptPosition,idMoveUnit);//check the next position
if(ptNext.x>=0 && ptNext.y>=0 && ptNext.x<MAPWIDTH && ptNext.y<MAPWIDTH)//bounds checking
{
if(mlMap[ptNext.x][ptNext.y].ulUnitList.empty())//if the map location is empty
{
iGameState=GS_STARTMOVE;//set the unit in motion
}
else
{
UNITLISTITER iter=mlMap[ptNext.x][ptNext.y].ulUnitList.begin();//get the first entry in the list
PUNITINFO pUnitInfo=*iter;//get the unit from the list
if(pUnitInfo->iTeam==pCurrentUnit->iTeam)//must be the same team
{
iGameState=GS_STARTMOVE;
}
}
}
}
}break;
case VK_NUMPAD4:
case VK_LEFT:
{
if(iGameState==GS_IDLE)//gamestate must be GS_IDLE
{
idMoveUnit=ISO_WEST;//move to the north
POINT ptNext=TileWalker.TileWalk(pCurrentUnit->ptPosition,idMoveUnit);//check the next position
if(ptNext.x>=0 && ptNext.y>=0 && ptNext.x<MAPWIDTH && ptNext.y<MAPWIDTH)//bounds checking
{
if(mlMap[ptNext.x][ptNext.y].ulUnitList.empty())//if the map location is empty
{
iGameState=GS_STARTMOVE;//set the unit in motion
}
else
{
UNITLISTITER iter=mlMap[ptNext.x][ptNext.y].ulUnitList.begin();//get the first entry in the list
PUNITINFO pUnitInfo=*iter;//get the unit from the list
if(pUnitInfo->iTeam==pCurrentUnit->iTeam)//must be the same team
{
iGameState=GS_STARTMOVE;
}
}
}
}
}break;
case VK_NUMPAD7:
case VK_HOME:
{
if(iGameState==GS_IDLE)//gamestate must be GS_IDLE
{
idMoveUnit=ISO_NORTHWEST;//move to the north
POINT ptNext=TileWalker.TileWalk(pCurrentUnit->ptPosition,idMoveUnit);//check the next position
if(ptNext.x>=0 && ptNext.y>=0 && ptNext.x<MAPWIDTH && ptNext.y<MAPWIDTH)//bounds checking
{
if(mlMap[ptNext.x][ptNext.y].ulUnitList.empty())//if the map location is empty
{
iGameState=GS_STARTMOVE;//set the unit in motion
}
else
{
UNITLISTITER iter=mlMap[ptNext.x][ptNext.y].ulUnitList.begin();//get the first entry in the list
PUNITINFO pUnitInfo=*iter;//get the unit from the list
if(pUnitInfo->iTeam==pCurrentUnit->iTeam)//must be the same team
{
iGameState=GS_STARTMOVE;
}
}
}
}
}break;
}
}break;
case WM_DESTROY://the window is being destroyed
{
//tell the application we are quitting
PostQuitMessage(0);
//handled message, so return 0
return(0);
}break;
case WM_PAINT://the window needs repainting
{
//a variable needed for painting information
PAINTSTRUCT ps;
//start painting
HDC hdc=BeginPaint(hwnd,&ps);
/////////////////////////////
//painting code would go here
/////////////////////////////
//end painting
EndPaint(hwnd,&ps);
//handled message, so return 0
return(0);
}break;
}
//pass along any other message to default message handler
return(DefWindowProc(hwnd,uMsg,wParam,lParam));
}
//////////////////////////////////////////////////////////////////////////////
//WINMAIN
//////////////////////////////////////////////////////////////////////////////
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
//assign instance to global variable
hInstMain=hInstance;
//create window class
WNDCLASSEX wcx;
//set the size of the structure
wcx.cbSize=sizeof(WNDCLASSEX);
//class style
wcx.style=CS_OWNDC | CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
//window procedure
wcx.lpfnWndProc=TheWindowProc;
//class extra
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?