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

📄 tileset.cpp

📁 一個遊戲教程
💻 CPP
字号:
// TileSet.cpp: implementation of the CTileSet class.
//
//////////////////////////////////////////////////////////////////////

#include "TileSet.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CTileSet::CTileSet()
{
	//set all members to 0 or NULL
	dwTileCount=0;
	ptiTileList=NULL;
	lpddsTileSet=NULL;
	lpszReload=NULL;
}

CTileSet::~CTileSet()
{
	//unload the tileset
	Unload();
}

//load(initializer)
void CTileSet::Load(LPDIRECTDRAW7 lpdd,LPSTR lpszLoad)
{
	//unload any currently loaded tileset
	Unload();

	//copy filename
	lpszReload=strdup(lpszLoad);

	//load in the tileset
	lpddsTileSet=LPDDS_LoadFromFile(lpdd,lpszReload);


	//retrieve DDSURFACEDESC2 from surface
	DDSURFACEDESC2 ddsd;
	DDSD_Clear(&ddsd);
	lpddsTileSet->GetSurfaceDesc(&ddsd);

	//copy width and height
	int iWidth=ddsd.dwWidth;
	int iHeight=ddsd.dwHeight;

	//temporary variables for cell walls
	int* HCellWall=NULL;
	int HCellWallCount=0;
	int* VCellWall=NULL;
	int VCellWallCount=0;
	int xCount=0;
	int yCount=0;

	//grab the DC from the surface
	HDC hdc;
	lpddsTileSet->GetDC(&hdc);

	//temp variables for control colors
	COLORREF crTransparent=GetPixel(hdc,iWidth-1,0);
	COLORREF crWall=GetPixel(hdc,iWidth-1,1);
	COLORREF crAnchor=GetPixel(hdc,iWidth-1,2);
	COLORREF crInside=GetPixel(hdc,iWidth-1,3);
	COLORREF crInsideAnchor=GetPixel(hdc,iWidth-1,4);
	COLORREF crTest=RGB(0,0,0);

	//count the number of vertical cell walls
	//by scanning the top pixel row
	VCellWallCount=0;
	for(xCount=0;xCount<iWidth;xCount++)
	{
		//retrieve the pixel
		crTest=GetPixel(hdc,xCount,0);

		//test for transparent color
		if(crTest==crTransparent)
		{
			//increase wall counter
			VCellWallCount++;
		}
	}

	//allocate the vertical cell wall list
	VCellWall=new int[VCellWallCount];
	
	//find vertical cell walls
	VCellWallCount=0;
	for(xCount=0;xCount<iWidth;xCount++)
	{
		//retrieve the pixel
		crTest=GetPixel(hdc,xCount,0);

		//test for transparent color
		if(crTest==crTransparent)
		{
			//add x value to the list
			VCellWall[VCellWallCount]=xCount;

			//increase wall counter
			VCellWallCount++;
		}
	}

	//count the number of vertical cell walls
	//by scanning the top pixel row
	HCellWallCount=0;
	for(yCount=0;yCount<iHeight;yCount++)
	{
		//retrieve the pixel
		crTest=GetPixel(hdc,0,yCount);

		//test for transparent color
		if(crTest==crTransparent)
		{
			//increase wall counter
			HCellWallCount++;
		}
	}

	//allocate the vertical cell wall list
	HCellWall=new int[HCellWallCount];
	
	//find vertical cell walls
	HCellWallCount=0;
	for(yCount=0;yCount<iHeight;yCount++)
	{
		//retrieve the pixel
		crTest=GetPixel(hdc,0,yCount);

		//test for transparent color
		if(crTest==crTransparent)
		{
			//add x value to the list
			HCellWall[HCellWallCount]=yCount;

			//increase wall counter
			HCellWallCount++;
		}
	}

	//calculate number of rows, number of columns, and number of tiles
	int tilerows=HCellWallCount-1;
	int tilecolumns=VCellWallCount-1;
	int tilenum=0;
	dwTileCount=tilerows*tilecolumns;

	//allocate tile list
	ptiTileList=new TILEINFO[dwTileCount];

	//scan all tiles
	for(int rowcount=0;rowcount<tilerows;rowcount++)
	{
		for(int columncount=0;columncount<tilecolumns;columncount++)
		{
			//tile number
			tilenum=columncount+rowcount*tilecolumns;

			//temporary flag variable
			bool found=false;

			//scan top
			yCount=HCellWall[rowcount];

			//scan top for anchor
			found=false;
			for(xCount=VCellWall[columncount]+1;(!found)&&(xCount<VCellWall[columncount+1]-1);xCount++)
			{
				//grab pixel
				crTest=GetPixel(hdc,xCount,yCount);

				//check pixel for anchor
				if((crTest==crAnchor) || (crTest==crInsideAnchor))
				{
					found=true;
					ptiTileList[tilenum].ptAnchor.x=xCount;
				}
			}

			//scan top for first inside pixel
			found=false;
			for(xCount=VCellWall[columncount]+1;(!found)&&(xCount<VCellWall[columncount+1]-1);xCount++)
			{
				//grab pixel
				crTest=GetPixel(hdc,xCount,yCount);

				//check pixel for anchor
				if((crTest==crInside) || (crTest==crInsideAnchor))
				{
					found=true;
					ptiTileList[tilenum].rcSrc.left=xCount;
				}
			}

			//not found, use default
			if(!found)
			{
				ptiTileList[tilenum].rcSrc.left=VCellWall[columncount]+1;
			}

			//scan top for last inside pixel
			found=false;
			for(xCount=VCellWall[columncount+1]-1;(!found)&&(xCount>=VCellWall[columncount]+1);xCount--)
			{
				//grab pixel
				crTest=GetPixel(hdc,xCount,yCount);

				//check pixel for anchor
				if((crTest==crInside) || (crTest==crInsideAnchor))
				{
					found=true;
					ptiTileList[tilenum].rcSrc.right=xCount+1;
				}
			}

			//not found, use default
			if(!found)
			{
				ptiTileList[tilenum].rcSrc.left=VCellWall[columncount+1];
			}

			//scan left
			xCount=VCellWall[columncount];

			//scan left for anchor
			found=false;
			for(yCount=HCellWall[rowcount]+1;(!found)&&(yCount<HCellWall[rowcount+1]-1);yCount++)
			{
				//grab pixel
				crTest=GetPixel(hdc,xCount,yCount);

				//check pixel for anchor
				if((crTest==crAnchor) || (crTest==crInsideAnchor))
				{
					found=true;
					ptiTileList[tilenum].ptAnchor.y=yCount;
				}
			}

			//scan left for first inside pixel
			found=false;
			for(yCount=HCellWall[rowcount]+1;(!found)&&(yCount<HCellWall[rowcount+1]-1);yCount++)
			{
				//grab pixel
				crTest=GetPixel(hdc,xCount,yCount);

				//check pixel for anchor
				if((crTest==crInside) || (crTest==crInsideAnchor))
				{
					found=true;
					ptiTileList[tilenum].rcSrc.top=yCount;
				}
			}

			//not found, use default
			if(!found)
			{
				ptiTileList[tilenum].rcSrc.top=HCellWall[rowcount]+1;
			}

			//scan left for last inside pixel
			found=false;
			for(yCount=HCellWall[rowcount+1]-1;(!found)&&(yCount>=HCellWall[rowcount]+1);yCount--)
			{
				//grab pixel
				crTest=GetPixel(hdc,xCount,yCount);

				//check pixel for anchor
				if((crTest==crInside) || (crTest==crInsideAnchor))
				{
					found=true;
					ptiTileList[tilenum].rcSrc.bottom=yCount+1;
				}
			}

			//not found, use default
			if(!found)
			{
				ptiTileList[tilenum].rcSrc.bottom=HCellWall[rowcount+1];
			}

			//calculate the destination extents
			CopyRect(&ptiTileList[tilenum].rcDstExt,&ptiTileList[tilenum].rcSrc);
			OffsetRect(&ptiTileList[tilenum].rcDstExt,-ptiTileList[tilenum].ptAnchor.x,-ptiTileList[tilenum].ptAnchor.y);

		}
	}

	//release the dc of the surface
	lpddsTileSet->ReleaseDC(hdc);

	//set the transparent color
	LPDDS_SetSrcColorKey(lpddsTileSet,ConvertColorRef(crTransparent,&ddsd.ddpfPixelFormat));
}

//reload(restore)
void CTileSet::Reload()
{
	//reload image
	LPDDS_ReloadFromFile(lpddsTileSet,lpszReload);
}

//unload(uninitializer)
void CTileSet::Unload()
{
	//safely release the tile list
	if(ptiTileList)
	{
		delete [] ptiTileList;
		ptiTileList=NULL;
		dwTileCount=0;
	}

	//release the surface
	LPDDS_Release(&lpddsTileSet);

	//release the file name
	if(lpszReload)
	{
		free(lpszReload);
		lpszReload=NULL;
	}
}

//get number of tiles
DWORD CTileSet::GetTileCount()
{
	//return the tile count
	return(dwTileCount);
}

//get tile list
TILEINFO* CTileSet::GetTileList()
{
	//return the beginning of the tile list
	return(ptiTileList);
}

//get surface
LPDIRECTDRAWSURFACE7 CTileSet::GetDDS()
{
	//return the source surface
	return(lpddsTileSet);
}

//retrieve filename
LPSTR CTileSet::GetFileName()
{
	//return the file name
	return(lpszReload);
}

//blit a tile
void CTileSet::PutTile(LPDIRECTDRAWSURFACE7 lpddsDst,int xDst,int yDst,int iTileNum)
{
	//offset the desired tile's extent
	OffsetRect(&ptiTileList[iTileNum].rcDstExt,xDst,yDst);
	//blit the tile
	lpddsDst->Blt(&ptiTileList[iTileNum].rcDstExt,lpddsTileSet,&ptiTileList[iTileNum].rcSrc,DDBLT_WAIT | DDBLT_KEYSRC,NULL);
	//offset the desired tile's extent back
	OffsetRect(&ptiTileList[iTileNum].rcDstExt,-xDst,-yDst);
}

//put a tile with clipping
void CTileSet::ClipTile(LPDIRECTDRAWSURFACE7 lpddsDst,RECT* prcClip,int xDst,int yDst,int iTileNum)
{
	//source and dest rects
	RECT rcSrc;
	RECT rcDst;
	//changex and changey
	int changeX;
	int changeY;
	//get the destination rectangle
	CopyRect(&rcDst,&GetTileList()[iTileNum].rcDstExt);
	OffsetRect(&rcDst,xDst,yDst);
	//calculate changex and changey
	changeX=GetTileList()[iTileNum].rcSrc.left-rcDst.left;
	changeY=GetTileList()[iTileNum].rcSrc.top-rcDst.top;
	//clip the destination rect to the clipping rect
	IntersectRect(&rcDst,&rcDst,prcClip);
	//check to see if the destination rectangle is not empty
	if(!IsRectEmpty(&rcDst))
	{
		//copy dest rect to source
		CopyRect(&rcSrc,&rcDst);
		//offset the source rect by changex/y
		OffsetRect(&rcSrc,changeX,changeY);
		//do the bltfast
		lpddsDst->BltFast(rcDst.left,rcDst.top,GetDDS(),&rcSrc,DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT);
	}
}

⌨️ 快捷键说明

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