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 + -
显示快捷键?