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

📄 isorenderer.cpp

📁 一個遊戲教程
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//IsoRenderer.cpp

#include "IsoRenderer.h"
#include "DDFuncs.h"

//constructor
CRenderer::CRenderer()
{
	//blank
}

CRenderer::~CRenderer()
{
	//deallocate rectangle list
	delete rcUpdateList;
	//deallocate update map
	delete bMap;
}

//surfaces
void CRenderer::SetBackBuffer(LPDIRECTDRAWSURFACE7 lpdds)
{
	//set the back buffer
	lpddsBackBuffer=lpdds;
}

void CRenderer::SetFrameBuffer(LPDIRECTDRAWSURFACE7 lpdds)
{
	//set the frame buffer
	lpddsFrameBuffer=lpdds;
}

//isohexcore components
void CRenderer::SetPlotter(CTilePlotter* pPlotter)
{
	//set the plotter
	pTilePlotter=pPlotter;
}

void CRenderer::SetWalker(CTileWalker* pWalker)
{
	//set the tile walker
	pTileWalker=pWalker;
}

void CRenderer::SetMouseMap(CMouseMap* pMMap)
{
	//set the mousemap
	pMouseMap=pMMap;
}

void CRenderer::SetScroller(CScroller* pScroll)
{
	//set the scroller
	pScroller=pScroll;
}

//update list
void CRenderer::SetUpdateRectCount(int iMaxRects)//sets up the rectangle list
{
	//set the max number of rectangles
	iUpdateRectCount=iMaxRects;
	//allocate the rectangle list
	rcUpdateList=new RECT[iMaxRects];
	//set the index to 0
	iUpdateRectIndex=0;
}

//update map
void CRenderer::SetMapSize(int MapWidth,int MapHeight)//sets up the update map
{
	//allocate a new map
	bMap=new bool[MapWidth*MapHeight];

	//set the map width and height
	iMapWidth=MapWidth;
	iMapHeight=MapHeight;
}

//rendering functions
void CRenderer::SetRenderFunction(RENDERFN RendFunc)
{
	//set the rendering function
	RenderFunction=RendFunc;
}

//extent rect
void CRenderer::SetExtentRect(RECT* rcExt)
{
	CopyRect(&rcExtent,rcExt);
}

//add rect to list
void CRenderer::AddRect(RECT* prcAdd)
{
	//if there is no more room in the rectangle list, return
	if(iUpdateRectIndex>=iUpdateRectCount) return;

	//copy rect
	RECT rcUpdate;
	IntersectRect(&rcUpdate,prcAdd,pScroller->GetScreenSpace());
	//if the update rect is empty, return
	if(IsRectEmpty(&rcUpdate)) return;

	//clear out the frame buffer with black in the update region
	DDBLTFX ddbltfx;
	DDBLTFX_ColorFill(&ddbltfx,0);
	lpddsFrameBuffer->Blt(&rcUpdate,NULL,NULL,DDBLT_WAIT | DDBLT_COLORFILL,&ddbltfx);

	//add the rect to the list
	CopyRect(&rcUpdateList[iUpdateRectIndex],&rcUpdate);
	iUpdateRectIndex++;//add one to the index

	//temp variables for calculations
	POINT ptTemp;
	POINT ptCoarse;
	POINT ptMap;

	//calculate the corner points
	POINT ptCornerUpperLeft;
	POINT ptCornerUpperRight;
	POINT ptCornerLowerLeft;
	POINT ptCornerLowerRight;

	//upper left
	ptTemp.x=rcUpdate.left;
	ptTemp.y=rcUpdate.top;
	//screen->world
	ptTemp=pScroller->ScreenToWorld(ptTemp);
	//subtract mousemap reference point
	ptTemp.x-=pMouseMap->GetReferencePoint()->x;
	ptTemp.y-=pMouseMap->GetReferencePoint()->y;
	//calculate coarse coordinates
	ptCoarse.x=ptTemp.x/pMouseMap->GetWidth();
	ptCoarse.y=ptTemp.y/pMouseMap->GetHeight();
	//calculate fine cordinates
	ptTemp.x%=pMouseMap->GetWidth();
	ptTemp.y%=pMouseMap->GetHeight();
	//check for negative fine coordinates
	if(ptTemp.x<0) ptCoarse.x--;
	if(ptTemp.y<0) ptCoarse.y--;
	//reset map point
	ptMap.x=0;
	ptMap.y=0;
	//move to the east
	ptMap=pTileWalker->TileWalk(ptMap,ISO_EAST);
	//assign the corner point
	ptCornerUpperLeft.x=ptMap.x*ptCoarse.x;
	ptCornerUpperLeft.y=ptMap.y*ptCoarse.x;
	//reset map point
	ptMap.x=0;
	ptMap.y=0;
	//move to the south
	ptMap=pTileWalker->TileWalk(ptMap,ISO_SOUTH);
	ptCornerUpperLeft.x+=(ptMap.x*ptCoarse.y);
	ptCornerUpperLeft.y+=(ptMap.y*ptCoarse.y);

	//upper right
	ptTemp.x=rcUpdate.right;
	ptTemp.y=rcUpdate.top;
	//screen->world
	ptTemp=pScroller->ScreenToWorld(ptTemp);
	//subtract mousemap reference point
	ptTemp.x-=pMouseMap->GetReferencePoint()->x;
	ptTemp.y-=pMouseMap->GetReferencePoint()->y;
	//calculate coarse coordinates
	ptCoarse.x=ptTemp.x/pMouseMap->GetWidth();
	ptCoarse.y=ptTemp.y/pMouseMap->GetHeight();
	//calculate fine cordinates
	ptTemp.x%=pMouseMap->GetWidth();
	ptTemp.y%=pMouseMap->GetHeight();
	//check for negative fine coordinates
	if(ptTemp.x<0) ptCoarse.x--;
	if(ptTemp.y<0) ptCoarse.y--;
	//reset map point
	ptMap.x=0;
	ptMap.y=0;
	//move to the east
	ptMap=pTileWalker->TileWalk(ptMap,ISO_EAST);
	//assign the corner point
	ptCornerUpperRight.x=ptMap.x*ptCoarse.x;
	ptCornerUpperRight.y=ptMap.y*ptCoarse.x;
	//reset map point
	ptMap.x=0;
	ptMap.y=0;
	//move to the south
	ptMap=pTileWalker->TileWalk(ptMap,ISO_SOUTH);
	ptCornerUpperRight.x+=(ptMap.x*ptCoarse.y);
	ptCornerUpperRight.y+=(ptMap.y*ptCoarse.y);

	//lower left
	ptTemp.x=rcUpdate.left;
	ptTemp.y=rcUpdate.bottom;
	//screen->world
	ptTemp=pScroller->ScreenToWorld(ptTemp);
	//subtract mousemap reference point
	ptTemp.x-=pMouseMap->GetReferencePoint()->x;
	ptTemp.y-=pMouseMap->GetReferencePoint()->y;
	//calculate coarse coordinates
	ptCoarse.x=ptTemp.x/pMouseMap->GetWidth();
	ptCoarse.y=ptTemp.y/pMouseMap->GetHeight();
	//calculate fine cordinates
	ptTemp.x%=pMouseMap->GetWidth();
	ptTemp.y%=pMouseMap->GetHeight();
	//check for negative fine coordinates
	if(ptTemp.x<0) ptCoarse.x--;
	if(ptTemp.y<0) ptCoarse.y--;
	//reset map point
	ptMap.x=0;
	ptMap.y=0;
	//move to the east
	ptMap=pTileWalker->TileWalk(ptMap,ISO_EAST);
	//assign the corner point
	ptCornerLowerLeft.x=ptMap.x*ptCoarse.x;
	ptCornerLowerLeft.y=ptMap.y*ptCoarse.x;
	//reset map point
	ptMap.x=0;
	ptMap.y=0;
	//move to the south
	ptMap=pTileWalker->TileWalk(ptMap,ISO_SOUTH);
	ptCornerLowerLeft.x+=(ptMap.x*ptCoarse.y);
	ptCornerLowerLeft.y+=(ptMap.y*ptCoarse.y);

	//lower right
	ptTemp.x=rcUpdate.right;
	ptTemp.y=rcUpdate.bottom;
	//screen->world
	ptTemp=pScroller->ScreenToWorld(ptTemp);
	//subtract mousemap reference point
	ptTemp.x-=pMouseMap->GetReferencePoint()->x;
	ptTemp.y-=pMouseMap->GetReferencePoint()->y;
	//calculate coarse coordinates
	ptCoarse.x=ptTemp.x/pMouseMap->GetWidth();
	ptCoarse.y=ptTemp.y/pMouseMap->GetHeight();
	//calculate fine cordinates
	ptTemp.x%=pMouseMap->GetWidth();
	ptTemp.y%=pMouseMap->GetHeight();
	//check for negative fine coordinates
	if(ptTemp.x<0) ptCoarse.x--;
	if(ptTemp.y<0) ptCoarse.y--;
	//reset map point
	ptMap.x=0;
	ptMap.y=0;
	//move to the east
	ptMap=pTileWalker->TileWalk(ptMap,ISO_EAST);
	//assign the corner point
	ptCornerLowerRight.x=ptMap.x*ptCoarse.x;
	ptCornerLowerRight.y=ptMap.y*ptCoarse.x;
	//reset map point
	ptMap.x=0;
	ptMap.y=0;
	//move to the south
	ptMap=pTileWalker->TileWalk(ptMap,ISO_SOUTH);
	ptCornerLowerRight.x+=(ptMap.x*ptCoarse.y);
	ptCornerLowerRight.y+=(ptMap.y*ptCoarse.y);

	//move the corners away from screenspace one step
	ptCornerUpperLeft=pTileWalker->TileWalk(ptCornerUpperLeft,ISO_NORTHWEST);
	ptCornerUpperRight=pTileWalker->TileWalk(ptCornerUpperRight,ISO_NORTHEAST);
	ptCornerLowerLeft=pTileWalker->TileWalk(ptCornerLowerLeft,ISO_SOUTHWEST);
	ptCornerLowerRight=pTileWalker->TileWalk(ptCornerLowerRight,ISO_SOUTHEAST);

	//move the left corners to the west
	ptCornerUpperLeft=pTileWalker->TileWalk(ptCornerUpperLeft,ISO_WEST);
	ptCornerLowerLeft=pTileWalker->TileWalk(ptCornerLowerLeft,ISO_WEST);

	//move the bottom corners to the south
	ptCornerLowerLeft=pTileWalker->TileWalk(ptCornerLowerLeft,ISO_SOUTH);
	ptCornerLowerRight=pTileWalker->TileWalk(ptCornerLowerRight,ISO_SOUTH);

	//scan through the tiles
	POINT ptRowStart=ptCornerUpperLeft;
	POINT ptRowEnd=ptCornerUpperRight;
	POINT ptCurrent=ptRowStart;
	DWORD dwRowCount=0;
	for(;;)
	{
		//set current point to rowstart
		ptCurrent=ptRowStart;

		//render a row of tiles
		for(;;)
		{
			//check that ptcurrent is an actual map location
			if(ptCurrent.x>=0 && ptCurrent.y>=0 && ptCurrent.x<iMapWidth && ptCurrent.y<iMapHeight)
			{
				//mark tile for updating
				bMap[ptCurrent.x+ptCurrent.y*iMapWidth]=true;
			}

			//is this the last tile in the row?
			if(ptCurrent.x==ptRowEnd.x && ptCurrent.y==ptRowEnd.y) break;

			//walk to the east
			ptCurrent=pTileWalker->TileWalk(ptCurrent,ISO_EAST);

		}

		//check to see if this is the last row
		if(ptRowStart.x==ptCornerLowerLeft.x && ptRowStart.y==ptCornerLowerLeft.y) break;

		//move down a row
		if(dwRowCount&1)
		{
			//odd row
			//move outward
			ptRowStart=pTileWalker->TileWalk(ptRowStart,ISO_SOUTHWEST);
			ptRowEnd=pTileWalker->TileWalk(ptRowEnd,ISO_SOUTHEAST);
		}
		else
		{
			//even row
			//move inward
			ptRowStart=pTileWalker->TileWalk(ptRowStart,ISO_SOUTHEAST);
			ptRowEnd=pTileWalker->TileWalk(ptRowEnd,ISO_SOUTHWEST);
		}

		//add one to the row count
		dwRowCount++;
	}
}

void CRenderer::AddTile(int mapx,int mapy)
{
	//put x and y into a point
	POINT ptMap;
	ptMap.x=mapx;
	ptMap.y=mapy;
	//plot the map coord
	POINT ptPlot=pTilePlotter->PlotTile(ptMap);
	//convert to screen coords
	ptPlot=pScroller->WorldToScreen(ptPlot);
	//get ext rect
	RECT rcUpdate;
	CopyRect(&rcUpdate,&rcExtent);
	//offset by plotted point

⌨️ 快捷键说明

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