isohex13_4.cpp

来自「一個遊戲教程」· C++ 代码 · 共 671 行 · 第 1/2 页

CPP
671
字号

//////////////////////////////////////////////////////////////////////////////
//MAIN GAME LOOP
//////////////////////////////////////////////////////////////////////////////
void Prog_Loop()
{
	//clear out back buffer
	DDBLTFX ddbltfx;
	DDBLTFX_ColorFill(&ddbltfx,0);
	lpddsBack->Blt(NULL,NULL,NULL,DDBLT_WAIT | DDBLT_COLORFILL,&ddbltfx);

	//scroll the map
	ptScreenAnchor.x+=ptScreenAnchorScroll.x;
	ptScreenAnchor.y+=ptScreenAnchorScroll.y;
	ClipScreenAnchor();

	//show the board
	DrawMap();

	//show the cursor
	ShowIsoCursor();

	//flip
	lpddsMain->Flip(NULL,DDFLIP_WAIT);
}

POINT StagMap_TilePlotter(POINT ptMap,int iTileWidth,int iTileHeight)
{
	POINT ptReturn;
	//calculate pixel position for the map position given
	ptReturn.x=ptMap.x*iTileWidth+(ptMap.y & 1)*iTileWidth/2;
	ptReturn.y=ptMap.y*iTileHeight/2;
	//return calculate point
	return(ptReturn);
}

void SetUpMap()
{
	//randomly set up the map
	for(int x=0;x<MAPWIDTH;x++)
	{
		for(int y=0;y<MAPHEIGHT;y++)
		{
			iTileMap[x][y]=rand()%(tsIso.GetTileCount());
		}
	}
}

void DrawMap()
{
	POINT ptTile;//tile pixel coordinate
	POINT ptMap;//map coordinate
	//the y loop is outside, because we must blit in horizontal rows
	for(int y=0;y<MAPHEIGHT;y++)
	{
		for(int x=0;x<MAPWIDTH;x++)
		{
			//get pixel coordinate for map position
			ptMap.x=x;
			ptMap.y=y;
			ptTile=StagMap_TilePlotter(ptMap,mmMouseMap.ptSize.x,mmMouseMap.ptSize.y);
			//plot the tile(adjust for anchor)
			tsIso.PutTile(lpddsBack,ptTile.x-ptScreenAnchor.x,ptTile.y-ptScreenAnchor.y,iTileMap[x][y]);
		}
	}
}

void SetUpSpaces()
{
	//set up screen space
	SetRect(&rcScreenSpace,0,0,640,480);
	
	//grab tile rectangle from tileset
	RECT rcTile1;
	RECT rcTile2;
	POINT ptPlot;
	POINT ptMap;

	//grab tiles from extents
	CopyRect(&rcTile1,&tsIso.GetTileList()[0].rcDstExt);
	CopyRect(&rcTile2,&tsIso.GetTileList()[0].rcDstExt);

	//move first tile to upper left position
	ptMap.x=0;
	ptMap.y=0;
	ptPlot=StagMap_TilePlotter(ptMap,mmMouseMap.ptSize.x,mmMouseMap.ptSize.y);
	OffsetRect(&rcTile1,ptPlot.x,ptPlot.y);

	//move first tile to lower right position
	ptMap.x=MAPWIDTH-1;
	ptMap.y=MAPHEIGHT-1;
	ptPlot=StagMap_TilePlotter(ptMap,mmMouseMap.ptSize.x,mmMouseMap.ptSize.y);
	OffsetRect(&rcTile2,ptPlot.x,ptPlot.y);

	//combine these two tiles into world space
	UnionRect(&rcWorldSpace,&rcTile1,&rcTile2);

	//copy worldspace to anchor space
	CopyRect(&rcAnchorSpace,&rcWorldSpace);

	//subtract out screenspace
	//adjust right edge
	rcAnchorSpace.right-=(rcScreenSpace.right-rcScreenSpace.left);
	//make sure right not less than left
	if(rcAnchorSpace.right<rcAnchorSpace.left) rcAnchorSpace.right=rcAnchorSpace.left;
	//adjust bottom edge
	rcAnchorSpace.bottom-=(rcScreenSpace.bottom-rcScreenSpace.top);
	//make sure bottom not less than top
	if(rcAnchorSpace.bottom<rcAnchorSpace.top) rcAnchorSpace.bottom=rcAnchorSpace.top;

	//adjust edges of anchorspace for "no jaggies"
	//add 1/2 height to top
	rcAnchorSpace.top+=(mmMouseMap.ptSize.y/2);
	//subtract 1/2 height from bottom
	rcAnchorSpace.bottom-=(mmMouseMap.ptSize.y/2);
	//add 1/2 width to left
	rcAnchorSpace.left+=(mmMouseMap.ptSize.x/2);
	//subtract 1/2 width from right
	rcAnchorSpace.right-=(mmMouseMap.ptSize.x/2);

	//initialize screen anchor
	ptScreenAnchor.x=rcAnchorSpace.left;
	ptScreenAnchor.y=rcAnchorSpace.top;

	//initialize cursor
	ptCursor.x=0;
	ptCursor.y=0;
}

POINT StagMap_TileWalker(POINT ptStart, IsoDirection Dir)
{
	//depending on direction, move the point
	switch(Dir)
	{
	case ISO_NORTH:
		{
			ptStart.y-=2;
		}break;
	case ISO_NORTHEAST:
		{
			ptStart.x+=(ptStart.y&1);
			ptStart.y--;
		}break;
	case ISO_EAST:
		{
			ptStart.x++;
		}break;
	case ISO_SOUTHEAST:
		{
			ptStart.x+=(ptStart.y&1);
			ptStart.y++;
		}break;
	case ISO_SOUTH:
		{
			ptStart.y+=2;
		}break;
	case ISO_SOUTHWEST:
		{
			ptStart.x+=((ptStart.y&1)-1);
			ptStart.y++;
		}break;
	case ISO_WEST:
		{
			ptStart.x--;
		}break;
	case ISO_NORTHWEST:
		{
			ptStart.x+=((ptStart.y&1)-1);
			ptStart.y--;
		}break;
	}
	//return the point
	return(ptStart);
}

void ShowIsoCursor()
{
	//copy cursor position
	POINT ptMap=ptCursor;

	//plot cursor position
	POINT ptPlot=StagMap_TilePlotter(ptMap,mmMouseMap.ptSize.x,mmMouseMap.ptSize.y);
	
	//put the cursor image
	tsCursor.PutTile(lpddsBack,ptPlot.x-ptScreenAnchor.x,ptPlot.y-ptScreenAnchor.y,0);
}

void LoadMouseMap(CMouseMap* pmm,LPCTSTR lpszfilename)
{
	//create canvas
	CGDICanvas gdic;
	//load file
	gdic.Load(NULL,lpszfilename);
	//assign width/height
	pmm->ptSize.x=gdic.GetWidth();
	pmm->ptSize.y=gdic.GetHeight();
	//allocate space for the lookup table
	pmm->mmdLookUp= new
		MouseMapDirection[gdic.GetWidth()*gdic.GetHeight()];
	//colorref values for filling lookup
	COLORREF crNW=GetPixel(gdic,0,0);
	COLORREF crNE=GetPixel(gdic,gdic.GetWidth()-1,0);
	COLORREF crSW=GetPixel(gdic,0,gdic.GetHeight()-1);
	COLORREF crSE=GetPixel(gdic,gdic.GetWidth()-1, gdic.GetHeight()-1);
	//test pixel color
	COLORREF crTest;
	//scan convert bitmap into lookup values
	for(int y=0;y<gdic.GetHeight();y++)
	{
		for(int x=0;x<gdic.GetWidth();x++)
		{
			//grab test pixel
			crTest=GetPixel(gdic,x,y);
			//set lookup to default
			pmm->mmdLookUp[x+y*pmm->ptSize.x]=MM_CENTER;
			//check colors
			if(crTest==crNW)
				pmm->mmdLookUp[x+y*pmm->ptSize.x]=MM_NW;
			if(crTest==crNE)
				pmm->mmdLookUp[x+y*pmm->ptSize.x]=MM_NE;
			if(crTest==crSW)
				pmm->mmdLookUp[x+y*pmm->ptSize.x]=MM_SW;
			if(crTest==crSE)
				pmm->mmdLookUp[x+y*pmm->ptSize.x]=MM_SE;
		}
	}
}

void ClipScreenAnchor()
{
	//clip to left
	if(ptScreenAnchor.x<rcAnchorSpace.left) ptScreenAnchor.x=rcAnchorSpace.left;
	//clip to top
	if(ptScreenAnchor.y<rcAnchorSpace.top) ptScreenAnchor.y=rcAnchorSpace.top;
	//clip to right
	if(ptScreenAnchor.x>=rcAnchorSpace.right) ptScreenAnchor.x=rcAnchorSpace.right-1;
	//clip to bottom
	if(ptScreenAnchor.y>=rcAnchorSpace.bottom) ptScreenAnchor.y=rcAnchorSpace.bottom-1;
}

POINT StagMap_MouseMapper(POINT ptMouse,CMouseMap* pmm)
{
	//step1:screen to world
	ptMouse.x+=ptScreenAnchor.x;
	ptMouse.y+=ptScreenAnchor.y;

	//step2:relative world coordinates
	ptMouse.x-=pmm->ptRef.x;
	ptMouse.y-=pmm->ptRef.y;

	//step3:mousemap coords
	POINT ptMouseMapCoarse;
	POINT ptMouseMapFine;
	//coarse mousemap coords
	ptMouseMapCoarse.x=ptMouse.x/pmm->ptSize.x;
	ptMouseMapCoarse.y=ptMouse.y/pmm->ptSize.y;
	//fine mousemap coords
	ptMouseMapFine.x=ptMouse.x%pmm->ptSize.x;
	ptMouseMapFine.y=ptMouse.y%pmm->ptSize.y;
	//adjust for negative fine coordinates
	if(ptMouseMapFine.x<0)
	{
		ptMouseMapFine.x+=pmm->ptSize.x;
		ptMouseMapCoarse.x--;
	}
	if(ptMouseMapFine.y<0)
	{
		ptMouseMapFine.y+=pmm->ptSize.y;
		ptMouseMapCoarse.y--;
	}

	//step4:coarse tilewalk
	POINT ptMap;
	ptMap.x=0;
	ptMap.y=0;
	//move north
	while(ptMouseMapCoarse.y<0)
	{
		ptMouseMapCoarse.y++;
		ptMap=StagMap_TileWalker(ptMap,ISO_NORTH);
	}
	//move south
	while(ptMouseMapCoarse.y>0)
	{
		ptMouseMapCoarse.y--;
		ptMap=StagMap_TileWalker(ptMap,ISO_SOUTH);
	}
	//move east
	while(ptMouseMapCoarse.x>0)
	{
		ptMouseMapCoarse.x--;
		ptMap=StagMap_TileWalker(ptMap,ISO_EAST);
	}
	//move west
	while(ptMouseMapCoarse.x<0)
	{
		ptMouseMapCoarse.x++;
		ptMap=StagMap_TileWalker(ptMap,ISO_WEST);
	}

	//step5:fine tilewalk
	//get lookup value
	MouseMapDirection mmd=pmm->mmdLookUp[ptMouseMapFine.x+ptMouseMapFine.y*pmm->ptSize.x];
	switch(mmd)
	{
	case MM_CENTER:
		{
			//do nothing
		}break;
	case MM_NW:
		{
			//move northwest
			ptMap=StagMap_TileWalker(ptMap,ISO_NORTHWEST);
		}break;
	case MM_NE:
		{
			//move northeast
			ptMap=StagMap_TileWalker(ptMap,ISO_NORTHEAST);
		}break;
	case MM_SW:
		{
			//move southwest
			ptMap=StagMap_TileWalker(ptMap,ISO_SOUTHWEST);
		}break;
	case MM_SE:
		{
			//move southeast
			ptMap=StagMap_TileWalker(ptMap,ISO_SOUTHEAST);
		}break;
	}

	//return map coordinate
	return(ptMap);
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?