isohex18_1.cpp
来自「一個遊戲教程」· C++ 代码 · 共 492 行
CPP
492 行
/*****************************************************************************
IsoHex18_1.cpp
Ernest S. Pazera
17AUG2000
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"
//////////////////////////////////////////////////////////////////////////////
//DEFINES
//////////////////////////////////////////////////////////////////////////////
//name for our window class
#define WINDOWCLASS "ISOHEX18"
//title of the application
#define WINDOWTITLE "IsoHex 18-1"
const int MAPWIDTH=200;
const int MAPHEIGHT=400;
//////////////////////////////////////////////////////////////////////////////
//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
//directdraw
LPDIRECTDRAW7 lpdd=NULL;
LPDIRECTDRAWSURFACE7 lpddsMain=NULL;
LPDIRECTDRAWSURFACE7 lpddsBack=NULL;
LPDIRECTDRAWSURFACE7 lpddsFrame=NULL;
//tilesets
CTileSet tsBack;//background
CTileSet tsTree;//tree foreground
CTileSet tsUnit;//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
//keep track of unit location
POINT ptUnit;//current position of the unit
POINT ptUnitOld;//last position of the unit
ISODIRECTION idMoveUnit;//direction of movement
bool bMoveUnit;//the unit should be moved
//map location structure
struct MapLocation
{
bool bTree;//false=no tree; true=tree
bool bUnit;//false=no unit; true=unit;
};
MapLocation mlMap[MAPWIDTH][MAPHEIGHT];//map array
//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_NUMPAD1:
{
idMoveUnit=ISO_SOUTHWEST;
bMoveUnit=true;
}break;
case VK_NUMPAD2:
{
idMoveUnit=ISO_SOUTH;
bMoveUnit=true;
}break;
case VK_NUMPAD3:
{
idMoveUnit=ISO_SOUTHEAST;
bMoveUnit=true;
}break;
case VK_NUMPAD4:
{
idMoveUnit=ISO_WEST;
bMoveUnit=true;
}break;
case VK_NUMPAD6:
{
idMoveUnit=ISO_EAST;
bMoveUnit=true;
}break;
case VK_NUMPAD7:
{
idMoveUnit=ISO_NORTHWEST;
bMoveUnit=true;
}break;
case VK_NUMPAD8:
{
idMoveUnit=ISO_NORTH;
bMoveUnit=true;
}break;
case VK_NUMPAD9:
{
idMoveUnit=ISO_NORTHEAST;
bMoveUnit=true;
}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
wcx.cbClsExtra=0;
//window extra
wcx.cbWndExtra=0;
//application handle
wcx.hInstance=hInstMain;
//icon
wcx.hIcon=LoadIcon(NULL,IDI_APPLICATION);
//cursor
wcx.hCursor=LoadCursor(NULL,IDC_ARROW);
//background color
wcx.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
//menu
wcx.lpszMenuName=NULL;
//class name
wcx.lpszClassName=WINDOWCLASS;
//small icon
wcx.hIconSm=NULL;
//register the window class, return 0 if not successful
if(!RegisterClassEx(&wcx)) return(0);
//create main window
hWndMain=CreateWindowEx(0,WINDOWCLASS,WINDOWTITLE, WS_POPUP | WS_VISIBLE,0,0,320,240,NULL,NULL,hInstMain,NULL);
//error check
if(!hWndMain) return(0);
//if program initialization failed, then return with 0
if(!Prog_Init()) return(0);
//message structure
MSG msg;
//message pump
for(;;)
{
//look for a message
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
//there is a message
//check that we arent quitting
if(msg.message==WM_QUIT) break;
//translate message
TranslateMessage(&msg);
//dispatch message
DispatchMessage(&msg);
}
//run main game loop
Prog_Loop();
}
//clean up program data
Prog_Done();
//return the wparam from the WM_QUIT message
return(msg.wParam);
}
//////////////////////////////////////////////////////////////////////////////
//INITIALIZATION
//////////////////////////////////////////////////////////////////////////////
bool Prog_Init()
{
//create IDirectDraw object
lpdd=LPDD_Create(hWndMain,DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWREBOOT);
//set display mode
lpdd->SetDisplayMode(640,480,16,0,0);
//create primary surface
lpddsMain=LPDDS_CreatePrimary(lpdd,1);
//get back buffer
lpddsBack=LPDDS_GetSecondary(lpddsMain);
//create the frame buffer
lpddsFrame=LPDDS_CreateOffscreen(lpdd,640,480);
//load in the mousemap
MouseMap.Load("MouseMap.bmp");
//set up the tile plotter
TilePlotter.SetMapType(ISOMAP_DIAMOND);//diamond mode
TilePlotter.SetTileSize(MouseMap.GetWidth(),MouseMap.GetHeight());//grab width and height from mousemap
//set up tile walker to diamond mode
TileWalker.SetMapType(ISOMAP_DIAMOND);
//set up screeen space
RECT rcTemp;
SetRect(&rcTemp,0,0,640,480);
Scroller.SetScreenSpace(&rcTemp);
//load in tiles and cursor
tsBack.Load(lpdd,"backgroundts.bmp");
tsTree.Load(lpdd,"treets.bmp");
tsUnit.Load(lpdd,"unit_warrior.bmp");
//grab tile extent from tileset
CopyRect(&rcTemp,&tsBack.GetTileList()[0].rcDstExt);
//calculate the worldspace
Scroller.CalcWorldSpace(&TilePlotter,&rcTemp,MAPWIDTH,MAPHEIGHT);
//calculate the mousemap reference point
MouseMap.CalcReferencePoint(&TilePlotter,&rcTemp);
//calculate anchor space
Scroller.CalcAnchorSpace();
//set wrap modes for scroller
Scroller.SetHWrapMode(WRAPMODE_CLIP);
Scroller.SetVWrapMode(WRAPMODE_CLIP);
//set scroller anchor to (0,0)
Scroller.GetAnchor()->x=0;
Scroller.GetAnchor()->y=0;
//attach scrolelr and tilewalker to mousemap
MouseMap.SetScroller(&Scroller);
MouseMap.SetTileWalker(&TileWalker);
//set up the map to a random tilefield
for(int x=0;x<MAPWIDTH;x++)
{
for(int y=0;y<MAPHEIGHT;y++)
{
mlMap[x][y].bTree=((rand()%2)==1);//random tree
mlMap[x][y].bUnit=false;//no unit
}
}
//calculate the extent rect
RECT rcExtent;
CopyRect(&rcExtent,&tsBack.GetTileList()[0].rcDstExt);//set to background extent
UnionRect(&rcExtent,&rcExtent,&tsTree.GetTileList()[0].rcDstExt);//union with tree extent
UnionRect(&rcExtent,&rcExtent,&tsUnit.GetTileList()[0].rcDstExt);//union with unit extent
//set up the renderer
Renderer.SetBackBuffer(lpddsBack);
Renderer.SetExtentRect(&rcExtent);
Renderer.SetFrameBuffer(lpddsFrame);
Renderer.SetMapSize(MAPWIDTH,MAPHEIGHT);
Renderer.SetMouseMap(&MouseMap);
Renderer.SetPlotter(&TilePlotter);
Renderer.SetRenderFunction(RenderFunc);
Renderer.SetScroller(&Scroller);
Renderer.SetUpdateRectCount(100);
Renderer.SetWalker(&TileWalker);
//set the position of the unit
ptUnit.x=rand()%MAPWIDTH;
ptUnit.y=rand()%MAPHEIGHT;
ptUnitOld=ptUnit;//set the old position to the same position
mlMap[ptUnit.x][ptUnit.y].bUnit=true;//set the unit on the map
bMoveUnit=false;//set unit movement to false
//plot the position of the unit
POINT ptPos=TilePlotter.PlotTile(ptUnit);
ptPos.x-=(Scroller.GetScreenSpaceWidth()/2);//center the unit horizontally
ptPos.y-=(Scroller.GetScreenSpaceHeight()/2);//center the unit vertically
//set the anchor
Scroller.SetAnchor(&ptPos);
Scroller.WrapAnchor();
//update the entire screenspace
Renderer.AddRect(Scroller.GetScreenSpace());
return(true);//return success
}
//////////////////////////////////////////////////////////////////////////////
//CLEANUP
//////////////////////////////////////////////////////////////////////////////
void Prog_Done()
{
//release frame buffer
LPDDS_Release(&lpddsFrame);
//release main/back surfaces
LPDDS_Release(&lpddsMain);
//release directdraw
LPDD_Release(&lpdd);
}
//////////////////////////////////////////////////////////////////////////////
//MAIN GAME LOOP
//////////////////////////////////////////////////////////////////////////////
void Prog_Loop()
{
//set scroll to 0,0
ptScroll.x=0;
ptScroll.y=0;
//if we are to move the unit
if(bMoveUnit)
{
//calculate the next position of the unit
POINT ptNextPos=TileWalker.TileWalk(ptUnit,idMoveUnit);
//bounds checking
if(ptNextPos.x<0) bMoveUnit=false;
if(ptNextPos.y<0) bMoveUnit=false;
if(ptNextPos.x>=MAPWIDTH) bMoveUnit=false;
if(ptNextPos.y>=MAPHEIGHT) bMoveUnit=false;
//are we still moving the unit?
if(bMoveUnit)
{
//set the unit position to ptnextpos
ptUnit=ptNextPos;
//plot the units next position
POINT ptPlot=TilePlotter.PlotTile(ptUnit);
//translate plot position into screen coordinates
ptPlot=Scroller.WorldToScreen(ptPlot);
//check for scrolling
if(ptPlot.x<0) ptScroll.x=-320;
if(ptPlot.y<0) ptScroll.y=-240;
if(ptPlot.x>640) ptScroll.x=320;
if(ptPlot.y>480) ptScroll.y=240;
}
}
//scroll the map
Renderer.ScrollFrame(ptScroll.x,ptScroll.y);
//if we are still moving the unit
if(bMoveUnit)
{
//reset the old position
mlMap[ptUnitOld.x][ptUnitOld.y].bUnit=false;
//set the new position
mlMap[ptUnit.x][ptUnit.y].bUnit=true;
//add update tiles to renderer
Renderer.AddTile(ptUnitOld.x,ptUnitOld.y);
Renderer.AddTile(ptUnit.x,ptUnit.y);
//set moveunit to false
bMoveUnit=false;
//set old position to current position
ptUnitOld=ptUnit;
}
//update the frame
Renderer.UpdateFrame();
//flip to show the back buffer
lpddsMain->Flip(0,DDFLIP_WAIT);
}
void RenderFunc(LPDIRECTDRAWSURFACE7 lpddsDst,RECT* rcClip,int xDst,int yDst,int xMap,int yMap)
{
//put background tile
tsBack.ClipTile(lpddsDst,rcClip,xDst,yDst,0);
//check for a tree
if(mlMap[xMap][yMap].bTree)
{
//put tree
tsTree.ClipTile(lpddsDst,rcClip,xDst,yDst,0);
}
//check for the unit
if(mlMap[xMap][yMap].bUnit)
{
//put unit
tsUnit.ClipTile(lpddsDst,rcClip,xDst,yDst,0);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?