isohex18_2.cpp
来自「一個遊戲教程」· C++ 代码 · 共 692 行 · 第 1/2 页
CPP
692 行
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
//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()
{
switch(iGameState)
{
case GS_STARTMOVE:
{
//remove the unit from the old position
mlMap[ptUnitOld.x][ptUnitOld.y].bUnit=false;
//calculate new position(virtual new position)
switch(idMoveUnit)
{
case ISO_NORTH:
case ISO_NORTHEAST:
case ISO_NORTHWEST:
case ISO_WEST:
{
//move ptUnit
ptUnit=TileWalker.TileWalk(ptUnit,idMoveUnit);
//set the offset
ptUnitOffset.x=0;
ptUnitOffset.y=0;
//place unit at old position
mlMap[ptUnitOld.x][ptUnitOld.y].bUnit=true;
}break;
case ISO_EAST:
{
//move ptUnit
ptUnit=TileWalker.TileWalk(ptUnit,idMoveUnit);
//set the offset
ptUnitOffset.x=-64;
ptUnitOffset.y=0;
//place unit at new position
mlMap[ptUnit.x][ptUnit.y].bUnit=true;
}break;
case ISO_SOUTHEAST:
{
//move ptUnit
ptUnit=TileWalker.TileWalk(ptUnit,idMoveUnit);
//set the offset
ptUnitOffset.x=-32;
ptUnitOffset.y=-16;
//place unit at new position
mlMap[ptUnit.x][ptUnit.y].bUnit=true;
}break;
case ISO_SOUTHWEST:
{
//move ptUnit
ptUnit=TileWalker.TileWalk(ptUnit,idMoveUnit);
//set the offset
ptUnitOffset.x=32;
ptUnitOffset.y=-16;
//place unit at new position
mlMap[ptUnit.x][ptUnit.y].bUnit=true;
}break;
case ISO_SOUTH:
{
//move ptUnit
ptUnit=TileWalker.TileWalk(ptUnit,idMoveUnit);
//set the offset
ptUnitOffset.x=0;
ptUnitOffset.y=-32;
//place unit at new position
mlMap[ptUnit.x][ptUnit.y].bUnit=true;
}break;
}
//set unit frame to 0
iUnitFrame=0;
//set the next gamestate
iGameState=GS_DOMOVE;
}break;
case GS_DONEMOVE:
{
//finish the move, make sure the unit is positioned correctly
switch(idMoveUnit)
{
case ISO_NORTH:
case ISO_NORTHEAST:
case ISO_NORTHWEST:
case ISO_WEST:
{
//remove from old position
mlMap[ptUnitOld.x][ptUnitOld.y].bUnit=false;
//place on new position
mlMap[ptUnit.x][ptUnit.y].bUnit=true;
}break;
}
//plot new tile's position
POINT ptPlot=TilePlotter.PlotTile(ptUnit);
ptPlot=Scroller.WorldToScreen(ptPlot);
//set scrolling to 0,0
ptScroll.x=0;
ptScroll.y=0;
//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 frame
Renderer.ScrollFrame(ptScroll.x,ptScroll.y);
//add update tiles
Renderer.AddTile(ptUnitOld.x,ptUnitOld.y);
Renderer.AddTile(ptUnit.x,ptUnit.y);
//set ptUnitOffset to (0,0)
ptUnitOffset.x=0;
ptUnitOffset.y=0;
//set the old unit position to the current unit position
ptUnitOld=ptUnit;
//go to idling gamestate
iGameState=GS_IDLE;
//update the frame
Renderer.UpdateFrame();
//flip
lpddsMain->Flip(0,DDFLIP_WAIT);
}break;
case GS_DOMOVE:
{
//move the unit offset
switch(idMoveUnit)
{
case ISO_NORTH:
{
//change offset
ptUnitOffset.x+=0;
ptUnitOffset.y-=8;
}break;
case ISO_NORTHEAST:
{
//change offset
ptUnitOffset.x+=8;
ptUnitOffset.y-=4;
}break;
case ISO_EAST:
{
//change offset
ptUnitOffset.x+=16;
ptUnitOffset.y+=0;
}break;
case ISO_SOUTHEAST:
{
//change offset
ptUnitOffset.x+=8;
ptUnitOffset.y+=4;
}break;
case ISO_SOUTH:
{
//change offset
ptUnitOffset.x+=0;
ptUnitOffset.y+=8;
}break;
case ISO_SOUTHWEST:
{
//change offset
ptUnitOffset.x-=8;
ptUnitOffset.y+=4;
}break;
case ISO_WEST:
{
//change offset
ptUnitOffset.x-=16;
ptUnitOffset.y+=0;
}break;
case ISO_NORTHWEST:
{
//change offset
ptUnitOffset.x-=8;
ptUnitOffset.y-=4;
}break;
}
//grab the update RECTs
RECT rcUpdate1,rcUpdate2;
CopyRect(&rcUpdate1,&Renderer.rcExtent);
CopyRect(&rcUpdate2,&Renderer.rcExtent);
//plot the position of the units old position
POINT ptPlot=TilePlotter.PlotTile(ptUnitOld);
ptPlot=Scroller.WorldToScreen(ptPlot);
OffsetRect(&rcUpdate1,ptPlot.x,ptPlot.y);
//plot the position of the unit's new position
ptPlot=TilePlotter.PlotTile(ptUnit);
ptPlot=Scroller.WorldToScreen(ptPlot);
OffsetRect(&rcUpdate2,ptPlot.x,ptPlot.y);
//scroll the frame (0,0)
Renderer.ScrollFrame(0,0);
//merge the two update RECTS
UnionRect(&rcUpdate1,&rcUpdate1,&rcUpdate2);
//send update rect to the renderer
Renderer.AddRect(&rcUpdate1);
//update the frame
Renderer.UpdateFrame();
//flip to show the back buffer
lpddsMain->Flip(0,DDFLIP_WAIT);
//increase the unit frame counter
iUnitFrame++;
//check for done with gamestate
if(iUnitFrame==4)
{
//set to the next gamestate
iGameState=GS_DONEMOVE;
}
}break;
case GS_IDLE://the game is idling, update the frame, but thats about it.
{
//scroll the frame (0,0)
Renderer.ScrollFrame(0,0);
//update the frame
Renderer.UpdateFrame();
//flip to show the back buffer
lpddsMain->Flip(0,DDFLIP_WAIT);
}break;
}
}
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+ptUnitOffset.x,yDst+ptUnitOffset.y,0);
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?