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

📄 isorenderer.cpp

📁 一個遊戲教程
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	OffsetRect(&rcUpdate,ptPlot.x,ptPlot.y);
	//add to rect list
	AddRect(&rcUpdate);
}

//scroll the frame
void CRenderer::ScrollFrame(int scrollx,int scrolly)
{
	//figure out the actual scrollx and scrolly
	POINT ptAnchorOld;
	//grab the current anchor position
	ptAnchorOld.x=pScroller->GetAnchor()->x;
	ptAnchorOld.y=pScroller->GetAnchor()->y;
	//move the anchor
	pScroller->MoveAnchor(scrollx,scrolly);
	//calculate the actual scrollx and scrolly
	scrollx=pScroller->GetAnchor()->x-ptAnchorOld.x;
	scrolly=pScroller->GetAnchor()->y-ptAnchorOld.y;
	//reset the anchor position
	pScroller->GetAnchor()->x=ptAnchorOld.x;
	pScroller->GetAnchor()->y=ptAnchorOld.y;

	//rectangle for blitting
	RECT rcSrc;//source RECT(frame buffer)
	RECT rcDst;//destination RECT(back buffer)
	RECT rcUpdateX;//update rect
	RECT rcUpdateY;//update rect
	//set both rects to the screen space
	CopyRect(&rcSrc,pScroller->GetScreenSpace());
	CopyRect(&rcDst,pScroller->GetScreenSpace());
	//set both update rects empty
	SetRectEmpty(&rcUpdateX);
	SetRectEmpty(&rcUpdateY);
	//check the sign of scrollx
	//if scrollx is 0, we need do nothing
	if(scrollx)
	{
		//scrollx is non-zero
		if(scrollx<0)
		{
			//positive scrollx
			//scroll direction: to the right
			//set up an update rect for the left side of the screen
			SetRect(&rcUpdateX,rcDst.left,rcDst.top,rcDst.left-scrollx,rcDst.bottom);
			//adjust the blitting rects
			rcDst.left-=scrollx;
			rcSrc.right+=scrollx;
		}
		else
		{
			//negative scrollx
			//scroll direction: to the left
			//set up an update rect for the right side of the screen
			SetRect(&rcUpdateX,rcDst.right-scrollx,rcDst.top,rcDst.right,rcDst.bottom);
			//adjust the blitting rects
			rcDst.right-=scrollx;
			rcSrc.left+=scrollx;
		}
	}
	//check the sign of scrolly
	//if scrolly is 0, we need do nothing
	if(scrolly)
	{
		//scrolly is non-zero
		if(scrolly<0)
		{
			//negative scrolly
			//scroll direction: down
			//set and update rect for the top of the screen
			SetRect(&rcUpdateY,rcDst.left,rcDst.top,rcDst.right,rcDst.top-scrolly);
			//adjust the blitting rects
			rcDst.top-=scrolly;
			rcSrc.bottom+=scrolly;
		}
		else
		{
			//positive scrolly
			//scroll direction: up
			//set an update rect for the bottom of the screen
			SetRect(&rcUpdateY,rcDst.left,rcDst.bottom-scrolly,rcDst.right,rcDst.bottom);
			//adjust the blitting rects
			rcDst.bottom-=scrolly;
			rcSrc.top+=scrolly;
		}
	}
	//perform the blit(bulk scrolling)
	lpddsBackBuffer->BltFast(rcDst.left,rcDst.top,lpddsFrameBuffer,&rcSrc,DDBLTFAST_WAIT);
	//perform the scroll
	pScroller->MoveAnchor(scrollx,scrolly);
	//add the update rects
	AddRect(&rcUpdateX);
	AddRect(&rcUpdateY);
}

//update the frame
void CRenderer::UpdateFrame()
{
	//update rect
	RECT rcUpdate;
	//copy from screenspace
	CopyRect(&rcUpdate,pScroller->GetScreenSpace());

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

	//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(;;)
		{
			//plot the tile
			ptPlot=pTilePlotter->PlotTile(ptCurrent);
			ptPlot=pScroller->WorldToScreen(ptPlot);
			//check that ptcurrent is an actual map location
			if(ptCurrent.x>=0 && ptCurrent.y>=0 && ptCurrent.x<iMapWidth && ptCurrent.y<iMapHeight)
			{
				//is the tile marked?
				if(bMap[ptCurrent.x+ptCurrent.y*iMapWidth])
				{
					//send to rendering function
					RenderFunction(lpddsFrameBuffer,&rcUpdate,ptPlot.x,ptPlot.y,ptCurrent.x,ptCurrent.y);
					//rest to unmarked
					bMap[ptCurrent.x+ptCurrent.y*iMapWidth]=false;
				}
			}

			//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++;
	}

	//render all update rects from frame buffer to back buffer
	for(int iCount=0;iCount<iUpdateRectIndex;iCount++)
	{
		//render update rect
		lpddsBackBuffer->BltFast(rcUpdateList[iCount].left,rcUpdateList[iCount].top,lpddsFrameBuffer,&rcUpdateList[iCount],DDBLTFAST_WAIT);
	}

	//render from back buffer to frame buffer
	lpddsFrameBuffer->BltFast(rcUpdate.left,rcUpdate.top,lpddsBackBuffer,&rcUpdate,DDBLTFAST_WAIT);

	//set rectangle index to 0
	iUpdateRectIndex=0;
}

⌨️ 快捷键说明

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