📄 isohex19_1.cpp
字号:
//MAIN GAME LOOP
//////////////////////////////////////////////////////////////////////////////
void Prog_Loop()
{
switch(iGameState)
{
case GS_STARTTURN://start the current team's turn
{
PUNITINFO pUnitInfo;//variable to check for the team's units
UNITLISTITER iter;//iterator for the main unit list
for(iter=MainUnitList.begin();iter!=MainUnitList.end();iter++)//iterate through the main unit list
{
pUnitInfo=*iter;//grab the unit from the list
if(pUnitInfo->iTeam==iCurrentTeam)//does this unit belong to the current team?
{
//give the unit a movement point
pUnitInfo->iMovePoints=1+pUnitInfo->iType;
//add this unit to the team list
TeamUnitList.push_back(pUnitInfo);
}
}
//set moved unit flag to false
bMovedUnit=false;
//set the next gamestate
iGameState=GS_NEXTUNIT;
}break;
case GS_NEXTUNIT://select the next unit as the current unit
{
//set current unit to NULL
pCurrentUnit=NULL;
if(TeamUnitList.empty())//if the team unit list is empty
{
//if a unit has been moved, send to end of turn
if(bMovedUnit)
{
iGameState=GS_ENDTURN;//end the turn
}
else
{
//send to GS_IDLE
iGameState=GS_IDLE;//send to idle state
}
}
else
{
//turn is not over
UNITLISTITER iter=TeamUnitList.begin();//get the first unit in the team list
pCurrentUnit=*iter;//grab the unit from the list
TeamUnitList.pop_front();//remove the unit from the list
//check to see if this unit is holding position
if(pCurrentUnit->bHolding) return;//go to next unit
mlMap[pCurrentUnit->ptPosition.x][pCurrentUnit->ptPosition.y].ulUnitList.remove(pCurrentUnit);//remove the unit from the map location
mlMap[pCurrentUnit->ptPosition.x][pCurrentUnit->ptPosition.y].ulUnitList.push_front(pCurrentUnit);//place unit at the top of the map locations unit list
POINT ptPlot=TilePlotter.PlotTile(pCurrentUnit->ptPosition);//plot the unit's location
POINT ptScreen=Scroller.WorldToScreen(ptPlot);//translate into screen coordinates
if(!PtInRect(Scroller.GetScreenSpace(),ptScreen))//check to see if point is within screenspace
{
//not on screen
ptPlot.x-=(Scroller.GetScreenSpaceWidth()/2);
ptPlot.y-=(Scroller.GetScreenSpaceHeight()/2);
//set the anchor
Scroller.SetAnchor(&ptPlot);
Renderer.AddRect(Scroller.GetScreenSpace());
}
iGameState=GS_IDLE;//set to idling gamestate
}
}break;
case GS_ENDTURN://end of a player's turn
{
//clear out team unit list(just to be sure)
TeamUnitList.clear();
//change team
iCurrentTeam=1-iCurrentTeam;
iGameState=GS_STARTTURN;//set gamestate to start next turn
}break;
case GS_NULLMOVE://do not move the current unit
{
//set the moved flag to true
bMovedUnit=true;
//set movement points to 0
pCurrentUnit->iMovePoints=0;
//don't really do anything, just go to the next unit
pCurrentUnit=NULL;
iGameState=GS_NEXTUNIT;
}break;
case GS_SKIPMOVE://skip this unit for now
{
//put unit at end of team unit list
TeamUnitList.push_back(pCurrentUnit);
pCurrentUnit=NULL;//set current unit to NULL
iGameState=GS_NEXTUNIT;//select the next unit
}break;
case GS_HOLDPOSITION://tell unit to hold position
{
//set holding flag
pCurrentUnit->bHolding=true;
//show the holding unit
Renderer.AddTile(pCurrentUnit->ptPosition.x,pCurrentUnit->ptPosition.y);
pCurrentUnit=NULL;
bFlash=true;
//set next gamestate
iGameState=GS_NEXTUNIT;
DWORD dwTimeStart=GetTickCount();//get the frame start time
//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);
//wait until 500 ms have passed
while(GetTickCount()-dwTimeStart<500);
}break;
case GS_STARTMOVE:
{
//set the moved flag to true
bMovedUnit=true;
//remove the unit from the map location
mlMap[pCurrentUnit->ptPosition.x][pCurrentUnit->ptPosition.y].ulUnitList.remove(pCurrentUnit);
Renderer.AddTile(pCurrentUnit->ptPosition.x,pCurrentUnit->ptPosition.y);
//set next gamestate
iGameState=GS_DOMOVE;
}break;
case GS_DOMOVE:
{
//move the unit
pCurrentUnit->ptPosition=TileWalker.TileWalk(pCurrentUnit->ptPosition,idMoveUnit);
//set next gamestate
iGameState=GS_ENDMOVE;
}break;
case GS_ENDMOVE:
{
//place the unit on its new map location
mlMap[pCurrentUnit->ptPosition.x][pCurrentUnit->ptPosition.y].ulUnitList.push_front(pCurrentUnit);
Renderer.AddTile(pCurrentUnit->ptPosition.x,pCurrentUnit->ptPosition.y);
//subtract a movement point
pCurrentUnit->iMovePoints--;
//check to see if this unit is finished moving
if(pCurrentUnit->iMovePoints==0)
{
//done moving
pCurrentUnit=NULL;
//set next gamestate
iGameState=GS_NEXTUNIT;
}
else
{
//not done moving
iGameState=GS_IDLE;
}
bFlash=true;
DWORD dwTimeStart=GetTickCount();//get the frame start time
//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);
//wait until 500 ms have passed
while(GetTickCount()-dwTimeStart<500);
}break;
case GS_IDLE://the game is idling, update the frame, but thats about it.
{
DWORD dwTimeStart=GetTickCount();//get the frame start time
//scroll the frame (0,0)
Renderer.ScrollFrame(0,0);
//toggle unit flash
bFlash=!bFlash;
//if the current unit is not null
if(pCurrentUnit!=NULL)
{
//add the tile in which the current unit lives
Renderer.AddTile(pCurrentUnit->ptPosition.x,pCurrentUnit->ptPosition.y);
}
//update the frame
Renderer.UpdateFrame();
//if the current unit IS null
if(pCurrentUnit==NULL)
{
//show the end of turn marker if bflash is true
if(bFlash) tsPressEnter.PutTile(lpddsBack,0,0,iCurrentTeam);
}
//flip to show the back buffer
lpddsMain->Flip(0,DDFLIP_WAIT);
//wait until 200 ms have passed
while(GetTickCount()-dwTimeStart<200);
}break;
case GS_CLICKSELECT:
{
//check map location for emptiness
if(mlMap[ptClick.x][ptClick.y].ulUnitList.empty())
{
//map location is empty
iGameState=GS_CLICKCENTER;//we want to center on this map location
}
else
{
//map location is not empty
//look at top of list
UNITLISTITER iter=mlMap[ptClick.x][ptClick.y].ulUnitList.begin();
PUNITINFO pUnitInfo=*iter;
//check that if this unit belongs to the current team
if(pUnitInfo->iTeam==iCurrentTeam)
{
//belongs to current team
//one unit?
if(mlMap[ptClick.x][ptClick.y].ulUnitList.size()==1)
{
//a single unit(already contained in pUnitInfo)
//is this the current unit?
if(pUnitInfo==pCurrentUnit)
{
//this is the current unit
iGameState=GS_IDLE;//return to the neutral gamestate
}
else
{
//this is not the current unit
//does this unit have any movement points left?
if(pUnitInfo->iMovePoints>0)
{
//has movement points left
//push the current unit to front of team list
if(pCurrentUnit) TeamUnitList.push_front(pCurrentUnit);
pCurrentUnit=NULL;
//set holding to false for the new unit
pUnitInfo->bHolding=false;
//remove new unit from team list
TeamUnitList.remove(pUnitInfo);
//put new unit in front of team list
TeamUnitList.push_front(pUnitInfo);
//go to gs_nextunit
iGameState=GS_NEXTUNIT;
}
else
{
//does not have movement points left
//go back to gs_idle
iGameState=GS_IDLE;
}
}
}
else
{
//place the current unit at the front of the list
if(pCurrentUnit) TeamUnitList.push_front(pCurrentUnit);
//a stack of units
iGameState=GS_CLICKSTACK;
}
}
else
{
//does not belong to current team
iGameState=GS_CLICKCENTER;//we want to center on this map location
}
}
}break;
case GS_CLICKCENTER:
{
//center on clicked tile
POINT ptPlot=TilePlotter.PlotTile(ptClick);//plot tile
ptPlot.x-=(Scroller.GetScreenSpaceWidth()/2);//adjust by half screenspace
ptPlot.y-=(Scroller.GetScreenSpaceHeight()/2);
Scroller.SetAnchor(&ptPlot);//set anchor
Renderer.AddRect(Scroller.GetScreenSpace());
//return to GS_IDLE
iGameState=GS_IDLE;
}break;
case GS_CLICKSTACK:
{
//prepare the stack
int count;
for(count=0;count<20;count++)//clear out the list
SelectUnitList[count]=NULL;
//reset count to 0
count=0;
//iterate through the list of units at the current map location
UNITLISTITER iter;//iterator
PUNITINFO pUnitInfo;//unit info
for(iter=mlMap[ptClick.x][ptClick.y].ulUnitList.begin();count<20 && iter!=mlMap[ptClick.x][ptClick.y].ulUnitList.end();iter++)//iterate through list
{
pUnitInfo=*iter;//grab the unit
//place unit in list
SelectUnitList[count]=pUnitInfo;
//add 1 to count
count++;
}
//send to next gamestate
iGameState=GS_PICKUNIT;
}break;
case GS_PICKUNIT:
{
//no scrolling
Renderer.ScrollFrame(0,0);
//update frame
Renderer.UpdateFrame();
//place select window onto display
DDBLTFX ddbltfx;
DDBLTFX_Clear(&ddbltfx);
ddbltfx.dwFillColor=dwSelectWindowColor;
lpddsBack->Blt(&rcSelectWindow,NULL,NULL,DDBLT_WAIT | DDBLT_COLORFILL,&ddbltfx);
//show the units
int cellx,celly;//cell position
int cellnum;//number of the cell
int pixelx,pixely;//pixel position
for(celly=0;celly<4;celly++)
{
for(cellx=0;cellx<5;cellx++)
{
cellnum=cellx+celly*5;//calculate the cell number
//check that the unit exists
if(SelectUnitList[cellnum])
{
//calculate pixel position
pixelx=rcSelectWindow.left+ptCellSize.x*cellx;
pixely=rcSelectWindow.top+ptCellSize.y*celly;
//plot the units position
pixelx+=ptUnitOffset.x;
pixely+=ptUnitOffset.y;
//put the unit
tsUnit.PutTile(lpddsBack,pixelx,pixely,SelectUnitList[cellnum]->iType);
//move the pixel to place shielf
pixelx+=ptShieldOffset[SelectUnitList[cellnum]->iType].x;
pixely+=ptShieldOffset[SelectUnitList[cellnum]->iType].y;
//place appropriate shield
if(SelectUnitList[cellnum]->bHolding)
{
//unit is holding
tsShield.PutTile(lpddsBack,pixelx,pixely,iCurrentTeam*2+4);
}
else
{
//unit is not holding
if(SelectUnitList[cellnum]->iMovePoints)
{
//unit has movement points left
tsShield.PutTile(lpddsBack,pixelx,pixely,iCurrentTeam*2);
}
else
{
//unit does not have movememtn points left
tsShield.PutTile(lpddsBack,pixelx,pixely,iCurrentTeam*2+8);
}
}
}
}
}
//flip
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 an empty list
if(!mlMap[xMap][yMap].ulUnitList.empty())
{
//list is not empty
UNITLISTITER iter=mlMap[xMap][yMap].ulUnitList.begin();//get iterator to beginning of list
PUNITINFO pUnitInfo=*iter;//grab the item
//if this is the current unit
if(pUnitInfo==pCurrentUnit)
{
//this is the current unit
if(!bFlash) return;//if flash is "off" dont render
}
tsUnit.ClipTile(lpddsDst,rcClip,xDst,yDst,pUnitInfo->iType);//place the unit
iter++;//move to the next item in the list
if(iter==mlMap[xMap][yMap].ulUnitList.end())//if the end of the list, this is a single unit
{
if(pUnitInfo->bHolding)//if holding position
{//holding
tsShield.ClipTile(lpddsDst,rcClip,xDst+ptShieldOffset[pUnitInfo->iType].x,yDst+ptShieldOffset[pUnitInfo->iType].y,pUnitInfo->iTeam*2+4);//place the shield
}
else
{//not holding
tsShield.ClipTile(lpddsDst,rcClip,xDst+ptShieldOffset[pUnitInfo->iType].x,yDst+ptShieldOffset[pUnitInfo->iType].y,pUnitInfo->iTeam*2);//place the shield
}
}
else//more than one unit... this is a stack
{
if(pUnitInfo->bHolding)//if holding position
{//holding
tsShield.ClipTile(lpddsDst,rcClip,xDst+ptShieldOffset[pUnitInfo->iType].x,yDst+ptShieldOffset[pUnitInfo->iType].y,pUnitInfo->iTeam*2+5);//place the shield
}
else
{//not holding
tsShield.ClipTile(lpddsDst,rcClip,xDst+ptShieldOffset[pUnitInfo->iType].x,yDst+ptShieldOffset[pUnitInfo->iType].y,pUnitInfo->iTeam*2+1);//place the shield
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -