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

📄 gamewnd.c

📁 俄罗斯方块的整套源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
		pthis->m_eGameState = eGameState_GAME;
		CleanDeleteImage(pthis->m_pimgGameIn);
		//pthis->m_pimgGameBGLeft = ISHELL_LoadResImage(pthis->pMe->a.m_pIShell, RUSSDMD_RES_FILE, IMG_GAME_BG_LEFT);
		//pthis->m_pimgGameBGRight = ISHELL_LoadResImage(pthis->pMe->a.m_pIShell, RUSSDMD_RES_FILE, IMG_GAME_BG_RIGHT);
		GameWnd_DrawContainer(pthis);
		GameWnd_DrawBlockInGame(pthis);
		GameWnd_DrawStatus(pthis);
		//IDISPLAY_DrawRect(pthis->pMe->a.m_pIDisplay, &pthis->m_rectBorder, RGB_WHITE, NULL, IDF_RECT_FRAME);
		return FALSE;
	}
	else if (pthis->pMe->keyFlag & kKeypad_Up)
	{
		pthis->m_nPauseIndex = 0;	// pause
	}
	else if (pthis->pMe->keyFlag & kKeypad_Down)
	{
		pthis->m_nPauseIndex = 1;	// exit
	}
	else if (pthis->pMe->keyFlag & kKeypad_Select)
	{
		if (pthis->m_nPauseIndex == 0)
		{
			CleanDeleteImage(pthis->m_pimgGameIn);
			//pthis->m_pimgGameBGLeft = ISHELL_LoadResImage(pthis->pMe->a.m_pIShell, RUSSDMD_RES_FILE, IMG_GAME_BG_LEFT);
			//pthis->m_pimgGameBGRight = ISHELL_LoadResImage(pthis->pMe->a.m_pIShell, RUSSDMD_RES_FILE, IMG_GAME_BG_RIGHT);
			GameWnd_DrawContainer(pthis);
			GameWnd_DrawBlockInGame(pthis);
			GameWnd_DrawStatus(pthis);
#ifdef ENABLE_MUSIC
			GameWnd_PlayMusic(pthis);
#endif
			pthis->m_eGameState = eGameState_GAME;
		}
		else
			RussDmdApp_SetActiveWnd(pthis->pMe, IDW_MAINMENU);
		return FALSE;
	}
	return TRUE;
}

void GameWnd_Pause_Draw(GameWnd* pthis)
{
	AEERect rc;
	//IDISPLAY_FillRect(pthis->pMe->a.m_pIDisplay, NULL, RGB_BLACK);
	GameWnd_DrawContainer(pthis);
	GameWnd_DrawBlockInGame(pthis);
	GameWnd_DrawStatus(pthis);
	// 画一个暂停对话框
	IIMAGE_Draw(pthis->m_pimgGameIn, (pthis->pMe->screenWidth - pthis->m_pi.cx) >> 1, (pthis->pMe->screenHeight - pthis->m_pi.cy) >> 1);

	// 画选中信息
	SETAEERECT(	&rc, 
				(pthis->pMe->screenWidth - 38) >> 1, 
				((pthis->pMe->screenHeight - 16) >> 1) + pthis->m_nPauseIndex * 18 - 9, 
				38, 16);
	IDISPLAY_DrawRect(pthis->pMe->a.m_pIDisplay, &rc, RGB_WHITE, NULL, IDF_RECT_FRAME);

	//IDISPLAY_DrawText(	pthis->pMe->a.m_pIDisplay, AEE_FONT_BOLD, pthis->m_pszText + 2, 4, 
	//					0, pthis->pMe->screenHeight / 2 - FONT_HEIGHT - 1, NULL, 
	//					IDF_ALIGN_CENTER | (pthis->m_nPauseIndex ? IDF_TEXT_TRANSPARENT : IDF_TEXT_INVERTED));
	//IDISPLAY_DrawText(	pthis->pMe->a.m_pIDisplay, AEE_FONT_BOLD, pthis->m_pszText + 10, 4, 
	//					0, pthis->pMe->screenHeight / 2 + 1, NULL, 
	//					IDF_ALIGN_CENTER | (pthis->m_nPauseIndex ? IDF_TEXT_INVERTED : IDF_TEXT_TRANSPARENT));
}

boolean GameWnd_End_Compute(GameWnd* pthis)
{
	if (pthis->pMe->keyFlag & kKeypad_Select)
	{
		pthis->pMe->score.m_bAddToList = TRUE;
//#ifdef ENABLE_MUSIC
//        GameWnd_CloseMusic(pthis);
//#endif
		RussDmdApp_SetActiveWnd(pthis->pMe, IDW_SCORELIST);
		return FALSE;
	}
	return TRUE;
}

void GameWnd_End_Draw(GameWnd* pthis)
{
	//IDISPLAY_FillRect(pthis->pMe->a.m_pIDisplay, NULL, RGB_BLACK);
	GameWnd_DrawContainer(pthis);
	GameWnd_DrawBlockInGame(pthis);
	GameWnd_DrawStatus(pthis);

	// 画一个失败对话框
	IIMAGE_Draw(pthis->m_pimgGameIn, (pthis->pMe->screenWidth - pthis->m_pi.cx) >> 1, (pthis->pMe->screenHeight - pthis->m_pi.cy) >> 1);
	//IDISPLAY_DrawText(	pthis->pMe->a.m_pIDisplay, AEE_FONT_BOLD, pthis->m_pszText + 6, 4, 
	//					0, 0, NULL, IDF_ALIGN_CENTER | IDF_ALIGN_MIDDLE | IDF_TEXT_INVERTED);
}

void GameWnd_InitData(GameWnd* pthis)
{
	MEMSET(pthis->m_pContainerData, 0, pthis->m_nContainerWidth * pthis->m_nContainerHeight);
	GameWnd_GetRandomBlock(pthis, &pthis->m_curBlock);
	GameWnd_GetRandomBlock(pthis, &pthis->m_nextBlock);
	pthis->m_nFrameTick = 0;
	pthis->m_bAccelerate = FALSE;
	pthis->m_nScore = 0;
	pthis->m_nLevel = 0;
	pthis->m_eGameState = eGameState_GAME;
	pthis->m_nPauseIndex = 0;
	GameWnd_DrawStatus(pthis);
}

void GameWnd_GetRandomBlock(GameWnd* pthis, SBlock * pBlock)
{
	pBlock->color = GameWnd_GetRandom(pthis, 0, COLOR_NUM - 1);
	pBlock->type = GameWnd_GetRandom(pthis, 0, eBlockType_NUM - 1);
	pBlock->dir = GameWnd_GetRandom(pthis, 0, eDir_NUM - 1);
	pBlock->x = pthis->m_nContainerWidth / 2;
	pBlock->y = pthis->m_nContainerHeight - 1;
}

int16 GameWnd_GetRandom(GameWnd* pthis, int min, int max)
{
	ASSERT(min <= max && "GetSystemRand RandMin >= RandMax");

	if(pthis->m_nRandomIndex >= RANDOM_BUFFER_SIZE)
	{
		GETRAND(pthis->m_pRandomBuf, RANDOM_BUFFER_SIZE);
		pthis->m_nRandomIndex = 0;
	}

	return (min + pthis->m_pRandomBuf[pthis->m_nRandomIndex++] % (max - min + 1));
}

void GameWnd_DrawBlockInGame(GameWnd* pthis)
{
	int i;
	int x, y;

	for (i = 0; i < 4; i++)
	{
		x = pthis->m_curBlock.x + pthis->m_pBlockDefine[GetBlockIndex(pthis->m_curBlock.type, pthis->m_curBlock.dir, i)].x;
		y = pthis->m_curBlock.y + pthis->m_pBlockDefine[GetBlockIndex(pthis->m_curBlock.type, pthis->m_curBlock.dir, i)].y;
		if (x < 0 || x >= pthis->m_nContainerWidth || y >= pthis->m_nContainerHeight || y < 0)
			continue;
		pthis->m_rcBlock.x = x * BLOCK_SIZE + pthis->m_rectBorder.x;
		pthis->m_rcBlock.y = pthis->m_rectBorder.y + (pthis->m_nContainerHeight - y - 1) * BLOCK_SIZE;
#ifdef COLOR_BLOCK
		IDISPLAY_BitBlt(pthis->pMe->a.m_pIDisplay, pthis->m_rcBlock.x, pthis->m_rcBlock.y, 
						BLOCK_SIZE, BLOCK_SIZE, pthis->m_pbmpBlock, 
						BLOCK_SIZE * pthis->m_curBlock.color, 0, AEE_RO_COPY);
#else
		IDISPLAY_FillRect(pthis->pMe->a.m_pIDisplay, &pthis->m_rcBlock, RGB_WHITE);
#endif
	}
}

void GameWnd_DrawContainer(GameWnd* pthis)
{
	int x, y;
	byte data;

	//IDISPLAY_FillRect(pthis->pMe->a.m_pIDisplay, &pthis->m_rectBorder, RGB_BLACK);
	IIMAGE_Draw(pthis->m_pimgGirl, CONTAINER_LEFT, CONTAINER_TOP);
	IIMAGE_Draw(pthis->m_pimgGameBGLeft, 0, 0);

	for (y = 0; y < pthis->m_nContainerHeight; y++)
	{
		for (x = 0; x < pthis->m_nContainerWidth; x++)
		{
			data = pthis->m_pContainerData[y * pthis->m_nContainerWidth + x];
			if (data & 0x01)
			{
				pthis->m_rcBlock.x = x * BLOCK_SIZE + pthis->m_rectBorder.x;
				pthis->m_rcBlock.y = pthis->m_rectBorder.y + (pthis->m_nContainerHeight - y - 1) * BLOCK_SIZE;
#ifdef COLOR_BLOCK
				IDISPLAY_BitBlt(pthis->pMe->a.m_pIDisplay, pthis->m_rcBlock.x, pthis->m_rcBlock.y, 
								BLOCK_SIZE, BLOCK_SIZE, pthis->m_pbmpBlock, 
								BLOCK_SIZE * ((data & 0xf0) >> 4), 0, AEE_RO_COPY);
#else
				IDISPLAY_FillRect(pthis->pMe->a.m_pIDisplay, &pthis->m_rcBlock, RGB_WHITE);
#endif
			}
		}
	}
}

void GameWnd_DrawStatus(GameWnd* pthis)
{
	int i;
	int x[4], y[4];
	int minX = 0, minY = 0;
	int maxX = 0, maxY = 0;
	int width, height;
	AECHAR num[100];

	// 清屏
	//IDISPLAY_FillRect(pthis->pMe->a.m_pIDisplay, &pthis->m_rectStatus, RGB_BLACK);
	IIMAGE_Draw(pthis->m_pimgGameBGRight, pthis->m_rectStatus.x, 0);

	// 画下一个块
	// 先循环一遍确定最左和最上的分别是什么,用来事先居中
	for (i = 0; i < 4; i++)
	{
		x[i] = pthis->m_pBlockDefine[GetBlockIndex(pthis->m_nextBlock.type, pthis->m_nextBlock.dir, i)].x;
		y[i] = pthis->m_pBlockDefine[GetBlockIndex(pthis->m_nextBlock.type, pthis->m_nextBlock.dir, i)].y;
		
		if (x[i] < minX)		minX = x[i];
		else if (x[i] > maxX)	maxX = x[i];

		if (y[i] < minY)		minY = y[i];
		else if (y[i] > maxY)	maxY = y[i];
	}

	width = (maxX - minX + 1) * BLOCK_SIZE;
	height = (maxY - minY + 1) * BLOCK_SIZE;

	for (i = 0; i < 4; i++)
	{
		pthis->m_rcBlock.x = (pthis->m_rectStatus.dx - width) / 2 + 
							 pthis->m_rectStatus.x + (x[i] - minX) * BLOCK_SIZE;
		pthis->m_rcBlock.y = 6 + (43 - height) / 2 - (y[i] - maxY) * BLOCK_SIZE;
#ifdef COLOR_BLOCK
		IDISPLAY_BitBlt(pthis->pMe->a.m_pIDisplay, pthis->m_rcBlock.x, pthis->m_rcBlock.y, 
						BLOCK_SIZE, BLOCK_SIZE, pthis->m_pbmpBlock, 
						BLOCK_SIZE * pthis->m_nextBlock.color, 0, AEE_RO_COPY);
#else
		IDISPLAY_FillRect(pthis->pMe->a.m_pIDisplay, &pthis->m_rcBlock, RGB_WHITE);
#endif
	}

	// 级别
	//IDISPLAY_DrawText(pthis->pMe->a.m_pIDisplay, AEE_FONT_NORMAL, pthis->m_pszText, 2, 
	//					pthis->m_rectStatus.x + 2, 6 * BLOCK_SIZE, NULL, IDF_TEXT_TRANSPARENT);
	WSPRINTF(num, 100, (const AECHAR*)L"%d", pthis->m_nLevel + 1);	// 记录中从0开始记数
	IDISPLAY_DrawText(	pthis->pMe->a.m_pIDisplay, AEE_FONT_NORMAL, num, -1,
						0, 80, NULL, IDF_TEXT_TRANSPARENT | IDF_ALIGN_RIGHT);
	//IDISPLAY_DrawText(	pthis->pMe->a.m_pIDisplay, AEE_FONT_NORMAL, pthis->m_pszText + 2, 2, 
	//					pthis->m_rectStatus.x + 2, 5 * BLOCK_SIZE + FONT_HEIGHT * 2, NULL, IDF_TEXT_TRANSPARENT);
	WSPRINTF(num, 100, (const AECHAR*)L"%d", pthis->m_nScore * 100);
	IDISPLAY_DrawText(	pthis->pMe->a.m_pIDisplay, AEE_FONT_NORMAL, num, -1,
						0, 120, NULL, 
						IDF_TEXT_TRANSPARENT | IDF_ALIGN_RIGHT/* | IDF_ALIGN_BOTTOM*/);
}

boolean GameWnd_BlockMoveable(GameWnd* pthis, EMoveType type)
{
	int i, x, y;

	switch(type)
	{
	case eMoveType_Left:
		// 只要每点的x坐标都大于1即可
		for (i = 0; i < 4; i++)
		{
			x = pthis->m_curBlock.x + pthis->m_pBlockDefine[GetBlockIndex(pthis->m_curBlock.type, pthis->m_curBlock.dir, i)].x - 1;
			if (x < 0)
				return FALSE;
			y = pthis->m_curBlock.y + pthis->m_pBlockDefine[GetBlockIndex(pthis->m_curBlock.type, pthis->m_curBlock.dir, i)].y;
			if (y < pthis->m_nContainerHeight && pthis->m_pContainerData[y * pthis->m_nContainerWidth + x])
				return FALSE;
		}
		break;

	case eMoveType_Right:
		// 只要每点的x坐标都小于容器宽减1即可
		for (i = 0; i < 4; i++)
		{
			x = pthis->m_curBlock.x + pthis->m_pBlockDefine[GetBlockIndex(pthis->m_curBlock.type, pthis->m_curBlock.dir, i)].x + 1;
			if (x >= pthis->m_nContainerWidth)
				return FALSE;
			y = pthis->m_curBlock.y + pthis->m_pBlockDefine[GetBlockIndex(pthis->m_curBlock.type, pthis->m_curBlock.dir, i)].y;
			if (y < pthis->m_nContainerHeight && pthis->m_pContainerData[y * pthis->m_nContainerWidth + x])
				return FALSE;
		}
		break;

	case eMoveType_Down:
		// 要判断每个点下方的容器是否已经有东西了
		// 或者是否到底了
		for (i = 0; i < 4; i++)
		{
			x = pthis->m_curBlock.x + pthis->m_pBlockDefine[GetBlockIndex(pthis->m_curBlock.type, pthis->m_curBlock.dir, i)].x;
			y = pthis->m_curBlock.y + pthis->m_pBlockDefine[GetBlockIndex(pthis->m_curBlock.type, pthis->m_curBlock.dir, i)].y - 1;
			if (y < 0)
				return FALSE;
			if (y < pthis->m_nContainerHeight && pthis->m_pContainerData[y * pthis->m_nContainerWidth + x])
				return FALSE;
		}
		break;

	case eMoveType_Turn:
		// 判断旋转后是否越界
		for (i = 0; i < 4; i++)
		{
			x = pthis->m_curBlock.x + pthis->m_pBlockDefine[GetBlockIndex(pthis->m_curBlock.type, (pthis->m_curBlock.dir + 1) % eDir_NUM, i)].x;
			y = pthis->m_curBlock.y + pthis->m_pBlockDefine[GetBlockIndex(pthis->m_curBlock.type, (pthis->m_curBlock.dir + 1) % eDir_NUM, i)].y;
			if (x < 0 || x >= pthis->m_nContainerWidth || y < 0)
				return FALSE;
			if (y < pthis->m_nContainerHeight && pthis->m_pContainerData[y * pthis->m_nContainerWidth + x])
				return FALSE;
		}
		break;
	}

	return TRUE;
}

int16 GameWnd_AddToContainer(GameWnd* pthis)
{
	// 首先要明确一点,这个函数肯定是在验证了方块不可下降后才被调用的
	// 所以只要把方块放到容器中就行了

	int i, j, x, y;
	int modY[4] = {-1,-1,-1,-1};	// 有变化的行
	int disY[4] = {-1,-1,-1,-1};	// 可消除的行
	int disCounter = 0;

	for (i = 0; i < 4; i++)
	{
		x = pthis->m_curBlock.x + pthis->m_pBlockDefine[GetBlockIndex(pthis->m_curBlock.type, pthis->m_curBlock.dir, i)].x;
		y = pthis->m_curBlock.y + pthis->m_pBlockDefine[GetBlockIndex(pthis->m_curBlock.type, pthis->m_curBlock.dir, i)].y;

		if (y >= pthis->m_nContainerHeight)
		{
			// 已经到顶了,死亡
			return -1;
		}
		pthis->m_pContainerData[y * pthis->m_nContainerWidth + x] = ((pthis->m_curBlock.color & 0x0F) << 4) | 0x01;
		
		// 存放有变化且未存放过的行,准备计算消行
		if (modY[0] == y)	continue;
		if (modY[1] == y)	continue;
		if (modY[2] == y)	continue;

		modY[i] = y;
	}

	// 接下来应该判断是否有可消除的行了
	// 可能产生消行的肯定是刚刚加入的这几行
	for (i = 0; i < 4; i++)
	{
		if (modY[i] == -1)	// 本行无变化
			continue;

		for (x = 0; x < pthis->m_nContainerWidth; x++)
		{
			if (pthis->m_pContainerData[modY[i] * pthis->m_nContainerWidth + x] == 0)
				break;
		}

		if (x >= pthis->m_nContainerWidth)
		{
			// 本行可以消去,记录,等到所有行都处理完毕后一次性移动
			disY[disCounter++] = modY[i];
		}
	}

⌨️ 快捷键说明

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