⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 isohex19_1.cpp

📁 一個遊戲教程
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//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 + -