<aside> 💡

GameLoop

  1. Tick 처리
  2. Draw 수행 </aside>

<aside> 💡

플레이어 객체, 적 객체, 배경이미지 등의 리소스들은 초기화 단계에서 생성

</aside>

  1. Tick 처리

    1. 시간처리
  1. 프레임 선형보간
  1. 매 프레임마다 플레이어, 적, 배경이미지 등의 위치값 업데이트

  2. 매 프레임마다 Collision 처리

  3. 매 프레임마다 그 외 게임 로직들 처리

  1. 화면 그리기

    1. BackBuffer에 Lock 수행
    1. 배경이미지 그리기
  1. 0번 압축을 통한 그리기
struct COMPRESSED_LINE
{
	DWORD	dwStreamNum;
	DWORD	dwLineDataSize;
	PIXEL_STREAM*	pPixelStream;
};

struct PIXEL_STREAM
{
	WORD	wPosX;
	WORD	wPixelNum;
	DWORD	dwPixel;
};

// sx, sy : DirectX 스크린 좌표계상에서의 위치
BOOL CDDrawDevice::DrawImageData(int sx, int sy, const CImageData* pImgData)
{
	BOOL	bResult = FALSE;

#ifdef _DEBUG
	if (!m_pWriteBuffer)
		__debugbreak();

#endif

	int iScreenWidth = (int)m_dwWidth;

	int iBitmapWidth = (int)pImgData->GetWidth();
	int iBitmapHeight = (int)pImgData->GetHeight();

	INT_VECTOR2	ivSrcStart = {};
	INT_VECTOR2	ivDestStart = {};

	INT_VECTOR2	ivPos = { sx, sy };
	INT_VECTOR2	ivImageSize = { iBitmapWidth, iBitmapHeight };
	INT_VECTOR2 ivDestSize = {};

	if (!CalcClipArea(&ivSrcStart, &ivDestStart, &ivDestSize, &ivPos, &ivImageSize))
		goto lb_return;

	
	const COMPRESSED_LINE* pLineDesc = pImgData->GetCompressedImage(ivSrcStart.y);
	
	// pDestPerLine는 화면(백버퍼)에서 복사할 행의 시작 주소
	// m_dwWriteBufferPitch는 한 행의 바이트 크기이므로 ivDestStart.y행부터 그리기 시작하게 됨
	
	// ivDestStart는 화면(BackBuffer)에서 이미지가 그려지기 시작하는 좌표
	
	char* pDestPerLine = m_pWriteBuffer + (ivDestStart.y) * m_dwWriteBufferPitch;	
	
	for (int y = 0; y < ivDestSize.y; y++)
	{
		// 한 Line씩 차례대로 처리
		// dwStreamNum = 해당 Line의 압축된 Color 구간(PIXEL_STREAM) 개수
		// PIXEL_STREAM은 여러 개 연속된 Color 정보를 압축한 구조체
		
		for (DWORD i = 0; i < pLineDesc->dwStreamNum; i++)
		{
			PIXEL_STREAM*	pStream = pLineDesc->pPixelStream + i;
			
			// dwPixelColor = 현재 픽셀 색상
			// iPixelNum = 연속된 픽셀 개수
			DWORD	dwPixelColor = pStream->dwPixel;     
			int		iPixelNum = (int)pStream->wPixelNum;
			
			/* 
				wPosX = 각 PIXEL_STREAM의 시작 x좌표 (이미지 좌표계)
							= 연속픽셀이 시작한 x좌표
							
				sx = 화면(BackBuffer) 상에서의 이미지의 좌상단 x좌표
				
				dest_x = 화면(BackBuffer) 상에서의 wPosX의 x좌표
								= sx + wPosX
			*/
			
			
			int dest_x = sx + (int)pStream->wPosX;
			
			// 화면상에서의 wPosX의 x좌표가 화면밖으로 나갔을 시 Clipping 처리
			if (dest_x < 0)
			{
				// dest_x가 음수인 경우이므로, 그려야할 픽셀을 줄이는 효과
				// 화면밖으로 나간 픽셀수만큼은 Draw하면 안됨
				iPixelNum += dest_x;
				dest_x = 0;
			}
			
			// 화면상에서의 wPosX의 x좌표가 화면밖으로 나갔을 시 Clipping 처리
			if (dest_x + iPixelNum > iScreenWidth)
			{
				// 만약 이걸 주석처리할 시 그 다음 Line의 픽셀로 넘어가서 그림
				// 우하단에서 넘어갈 시 메모리범위를 넘어가게 됨
				iPixelNum = iScreenWidth - dest_x;
			}
			
			
			// pDest = 화면(BackBuffer) 상에서 이미지가 그려지기 시작하는 시작주소
			// 픽셀당 4Byte

			char* pDest = pDestPerLine + (DWORD)(dest_x * 4);
			for (int x = 0; x < iPixelNum; x++)
			{
				*(DWORD*)pDest = dwPixelColor;
				pDest += 4;
			}
		}
		
		// 다음 Line에 대한 구조체로 이동
		pLineDesc++;
		
		// 한 행의 크기(m_dwWriteBufferPitch)만큼 증가시켜 다음 행의 시작 주소로 이동
		pDestPerLine += m_dwWriteBufferPitch;
		
	}
}