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

📄 gamewnd.c

📁 俄罗斯方块的整套源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
#include "GameWnd.h"

#include "russdmd.h"
#include "russdmd_res.h"
#include "commondef.h"


#define BLOCK_SIZE				(7)		// 每个方块宽
#define CONTAINER_LEFT			(4)
#define CONTAINER_TOP			(29)
#define	CONTAINER_BOTTOM		(5)
#define CONTAINER_WIDTH			(10)	// 容器横向可容纳的方块数
#define	CONTAINER_HEIGHT		((pthis->pMe->screenHeight - CONTAINER_TOP - CONTAINER_BOTTOM) / BLOCK_SIZE)

#define RANDOM_BUFFER_SIZE		(64)
#define COLOR_NUM				(8)

#define GetBlockIndex(type, dir, index)	((type) * (eDir_NUM * 4) + (dir) * 4 + (index))
#define	DefineBlock(type, dir, index, i, j)		\
		{	\
			pthis->m_pBlockDefine[GetBlockIndex(type, dir, index)].x = (i);	\
			pthis->m_pBlockDefine[GetBlockIndex(type, dir, index)].y = (j);	\
		}
#define GetSpeed(level)	(MAX_LEVEL - (level))	// 速度嫌慢,那就加快吧

typedef enum _EMoveType
{
	eMoveType_Left = 0,		// 向左移动
	eMoveType_Right,		// 向右移动
	eMoveType_Down,			// 向下移动
	eMoveType_Turn,			// 旋转

	eMoveType_NUM
} EMoveType;


static void GameWnd_Update			(GameWnd* pthis);
void		GameWnd_DefineBlock		(GameWnd* pthis);
void		GameWnd_InitData		(GameWnd* pthis);
void		GameWnd_GetRandomBlock	(GameWnd* pthis, SBlock* pBlock);
int16		GameWnd_GetRandom		(GameWnd* pthis, int min, int max);
void		GameWnd_DrawBlockInGame	(GameWnd* pthis);
void		GameWnd_DrawContainer	(GameWnd* pthis);
void		GameWnd_DrawStatus		(GameWnd* pthis);
boolean		GameWnd_BlockMoveable	(GameWnd* pthis, EMoveType type);		// 这个操作肯定是针对当前方块的,所以不需要再传方块指针了
int16		GameWnd_AddToContainer	(GameWnd* pthis);						// 返回值是消除的行数,0表示没有消除,返回-1死亡

// ----------------------------------------------------------------------
// 各个不同状态下的逻辑计算和绘制函数
// ----------------------------------------------------------------------
boolean		GameWnd_Game_Compute	(GameWnd* pthis);
void		GameWnd_Game_Draw		(GameWnd* pthis);

boolean		GameWnd_Pause_Compute	(GameWnd* pthis);
void		GameWnd_Pause_Draw		(GameWnd* pthis);

boolean		GameWnd_End_Compute		(GameWnd* pthis);
void		GameWnd_End_Draw		(GameWnd* pthis);


boolean GameWnd_New(GameWnd *pthis, RussDmdApp* pMe)
{
	pthis->pMe = pMe;
	pthis->m_eGameState = eGameState_GAME;
	pthis->m_nContainerWidth = CONTAINER_WIDTH;
	pthis->m_nContainerHeight = CONTAINER_HEIGHT;
	//pthis->m_nContainerTop = pthis->pMe->screenHeight - CONTAINER_BOTTOM - pthis->m_nContainerHeight * BLOCK_SIZE;
	//pthis->m_nContainerLeft = CONTAINER_LEFT;
#ifdef ENABLE_MUSIC
	pthis->m_bMusicOn = TRUE;
	pthis->m_pBgSound = NULL;
	MEMSET(&pthis->m_BgSndData, 0, sizeof(pthis->m_BgSndData));
#endif
	pthis->m_pszText = NULL;
	pthis->m_pimgGameBGRight = NULL;
	pthis->m_pimgGameBGLeft = NULL;
	pthis->m_pimgGirl = NULL;
	pthis->m_pimgGameIn = NULL;
#ifdef COLOR_BLOCK
	pthis->m_pbmpBlock = NULL;
#endif
	
	SETAEERECT(	&pthis->m_rectBorder, 
				CONTAINER_LEFT, pthis->pMe->screenHeight - CONTAINER_BOTTOM - pthis->m_nContainerHeight * BLOCK_SIZE, 
				pthis->m_nContainerWidth * BLOCK_SIZE, pthis->m_nContainerHeight * BLOCK_SIZE);
	SETAEERECT(&pthis->m_rcBlock, 0, 0, BLOCK_SIZE - 1, BLOCK_SIZE - 1);

	return TRUE;
}

boolean GameWnd_HandleEvent(GameWnd * pthis, AEEEvent eCode, uint16 wParam, uint32 dwParam)
{
	switch (eCode) 
	{
	case EVT_APP_SUSPEND:
#ifdef ENABLE_MUSIC
		GameWnd_ReleaseMusic(pthis);
#endif
		ISHELL_CancelTimer(pthis->pMe->a.m_pIShell, (PFNNOTIFY)GameWnd_Update, pthis);
		return TRUE;
		
	case EVT_APP_RESUME:
		GameWnd_Update(pthis);
		GameWnd_DrawStatus(pthis);
#ifdef ENABLE_MUSIC
		GameWnd_CreateMusic(pthis);
		if (pthis->m_bMute == FALSE)
			GameWnd_PlayMusic(pthis);
#endif
		return TRUE;
		
	case EVT_APP_NO_SLEEP:
		return TRUE;
		
	default:
		return FALSE;
	}
}

boolean GameWnd_Open(GameWnd *pthis)
{
	// 背景透明色有问题,清一次瓶
	IDISPLAY_FillRect(pthis->pMe->a.m_pIDisplay, NULL, RGB_BLACK);

	if (pthis->m_pRandomBuf == NULL)
		pthis->m_pRandomBuf = (byte*)MALLOC(RANDOM_BUFFER_SIZE);
	GETRAND(pthis->m_pRandomBuf, RANDOM_BUFFER_SIZE);
	pthis->m_nRandomIndex = 0;

	// 载入块的图片资源
	if (pthis->m_pimgGameBGLeft == NULL)
		pthis->m_pimgGameBGLeft = ISHELL_LoadResImage(pthis->pMe->a.m_pIShell, RUSSDMD_RES_FILE, IMG_GAME_BG_LEFT);
	IIMAGE_SetParm(pthis->m_pimgGameBGLeft, IPARM_ROP, AEE_RO_TRANSPARENT, NULL);

	if (pthis->m_pimgGameBGRight == NULL)
		pthis->m_pimgGameBGRight = ISHELL_LoadResImage(pthis->pMe->a.m_pIShell, RUSSDMD_RES_FILE, IMG_GAME_BG_RIGHT);
	IIMAGE_GetInfo(pthis->m_pimgGameBGRight, &pthis->m_pi);
	SETAEERECT(&pthis->m_rectStatus, pthis->pMe->screenWidth - pthis->m_pi.cx, 0, pthis->m_pi.cx, pthis->pMe->screenHeight);

#ifdef COLOR_BLOCK
	if (pthis->m_pbmpBlock == NULL)
		pthis->m_pbmpBlock = ISHELL_LoadResBitmap(pthis->pMe->a.m_pIShell, RUSSDMD_RES_FILE, BMP_BLOCK);
#endif

	// 载入所需文字资源
	if (pthis->m_pszText == NULL)
	{
		pthis->m_pszText = (AECHAR*)MALLOC(50 * 2);
		ISHELL_LoadResString(pthis->pMe->a.m_pIShell, RUSSDMD_RES_FILE, IDS_GAME, pthis->m_pszText, 50 * 2);
	}

	if (pthis->m_pContainerData == NULL)
		pthis->m_pContainerData = (uint8*)MALLOC(pthis->m_nContainerHeight * pthis->m_nContainerWidth);

	if (pthis->m_pBlockDefine == NULL)
	{
		pthis->m_pBlockDefine = (SPoint*)MALLOC(eBlockType_NUM * eDir_NUM * 4 * 2);	// 每个块有四个点,每个点占两字节
		GameWnd_DefineBlock(pthis);
	}

	//此处再加载美女图片,如果失败不显示也没有关系
	CleanDeleteImage(pthis->m_pimgGirl);
	pthis->m_pimgGirl = ISHELL_LoadResImage(pthis->pMe->a.m_pIShell, RUSSDMD_RES_FILE, 
						IMG_GIRL_1 + GameWnd_GetRandom(pthis, 0, GIRL_NUMBER - 1));

#ifdef ENABLE_MUSIC

	GameWnd_CreateMusic(pthis);
	GameWnd_PlayMusic(pthis);

#endif

	GameWnd_InitData(pthis);
	
	GameWnd_Update(pthis);
	return TRUE;
}

void GameWnd_Close(GameWnd *pthis)
{
	FREEIF(pthis->m_pszText);
	FREEIF(pthis->m_pContainerData);
	FREEIF(pthis->m_pBlockDefine);
	FREEIF(pthis->m_pRandomBuf);
	CleanDeleteImage(pthis->m_pimgGameBGRight);
	CleanDeleteImage(pthis->m_pimgGameBGLeft);
	CleanDeleteImage(pthis->m_pimgGameIn);
	CleanDeleteImage(pthis->m_pimgGirl);

#ifdef COLOR_BLOCK
	CleanDeleteBitmap(pthis->m_pbmpBlock);
#endif

#ifdef ENABLE_MUSIC
	if (pthis->m_pBgSound)
	{
		IMEDIA_Release(pthis->m_pBgSound);
		pthis->m_pBgSound = NULL;
	}
#endif

	ISHELL_CancelTimer(pthis->pMe->a.m_pIShell, (PFNNOTIFY)GameWnd_Update, pthis);
}

void GameWnd_Free(GameWnd *pthis)
{
	GameWnd_Close(pthis);
}

static void GameWnd_Update(GameWnd *pthis)
{
	ISHELL_SetTimer(pthis->pMe->a.m_pIShell, MAIN_LOOP_TIME, (PFNNOTIFY)GameWnd_Update, pthis);

	switch(pthis->m_eGameState)
	{
	case eGameState_GAME:
		if (GameWnd_Game_Compute(pthis))
			GameWnd_Game_Draw(pthis);
		break;
	case eGameState_PAUSE:
		if (GameWnd_Pause_Compute(pthis))
			GameWnd_Pause_Draw(pthis);
		break;
	case eGameState_END:
		if (GameWnd_End_Compute(pthis))
			GameWnd_End_Draw(pthis);
		break;
	}
	pthis->pMe->keyFlag = kKeypad_NULL;

	IDISPLAY_Update(pthis->pMe->a.m_pIDisplay);
}

boolean GameWnd_Game_Compute(GameWnd* pthis)
{
	int32 line;

	// ----------------------------------------------------------------------
	// 判断玩家按键动作
	// ----------------------------------------------------------------------
	if (pthis->pMe->keyFlag & kKeypad_Up)
	{
		if (GameWnd_BlockMoveable(pthis, eMoveType_Turn))
			pthis->m_curBlock.dir = (pthis->m_curBlock.dir + 1) % eDir_NUM;
	}
	if (pthis->pMe->keyFlag & kKeypad_Right)
	{
		if (GameWnd_BlockMoveable(pthis, eMoveType_Right))
			pthis->m_curBlock.x ++;
	}
	if (pthis->pMe->keyFlag & kKeypad_Left)
	{
		if (GameWnd_BlockMoveable(pthis, eMoveType_Left))
			pthis->m_curBlock.x --;
	}
	if (pthis->pMe->keyFlag & kKeypad_Down)
	{
		if (pthis->m_bAccelerate == FALSE && GameWnd_BlockMoveable(pthis, eMoveType_Down))
			pthis->m_bAccelerate = TRUE;
	}
	if (pthis->pMe->keyFlag & kKeypad_Clr)
	{
#ifdef ENABLE_MUSIC
		GameWnd_CloseMusic(pthis);
#endif
		pthis->m_eGameState = eGameState_PAUSE;
		CleanDeleteImage(pthis->m_pimgGameIn);
		//CleanDeleteImage(pthis->m_pimgGameBGLeft);
		//CleanDeleteImage(pthis->m_pimgGameBGRight);
		pthis->m_pimgGameIn = ISHELL_LoadResImage(pthis->pMe->a.m_pIShell, RUSSDMD_RES_FILE, IMG_PAUSE);
		IIMAGE_GetInfo(pthis->m_pimgGameIn, &pthis->m_pi);
		return FALSE;
	}

	// ----------------------------------------------------------------------
	// 下落判断
	// ----------------------------------------------------------------------
	pthis->m_nFrameTick++;
	if (pthis->m_bAccelerate || pthis->m_nFrameTick >= GetSpeed(pthis->m_nLevel))
	{
		// 一但处于加速状态,则每帧下落一格
		if (GameWnd_BlockMoveable(pthis, eMoveType_Down))
		{
			pthis->m_curBlock.y--;
			pthis->m_nFrameTick = 0;
		}
		else
		{
			// 将到头的方块放到容器中
			if ((line = GameWnd_AddToContainer(pthis)) != 0)
			{
				if (line == 1)
					pthis->m_nScore += 1;	// 注意,这里的分数只记录百位,即此处相当于增加100分
				else if (line == 2)
					pthis->m_nScore += 3;
				else if (line == 3)
					pthis->m_nScore += 5;
				else if (line == 4)
					pthis->m_nScore += 7;
				else if (line == -1)
				{
					pthis->m_eGameState = eGameState_END;
					CleanDeleteImage(pthis->m_pimgGameIn);
					//CleanDeleteImage(pthis->m_pimgGameBGLeft);
					//CleanDeleteImage(pthis->m_pimgGameBGRight);
					pthis->m_pimgGameIn = ISHELL_LoadResImage(pthis->pMe->a.m_pIShell, RUSSDMD_RES_FILE, IMG_END);
					IIMAGE_GetInfo(pthis->m_pimgGameIn, &pthis->m_pi);
					return FALSE;
				}
				// 计算等级
				if (pthis->m_nLevel < MAX_LEVEL && pthis->m_nScore >= (uint32)((pthis->m_nLevel + 1) * (pthis->m_nLevel + 2) * 5))
				{
					pthis->m_nLevel++;
					CleanDeleteImage(pthis->m_pimgGirl);
					pthis->m_pimgGirl = ISHELL_LoadResImage(pthis->pMe->a.m_pIShell, RUSSDMD_RES_FILE, 
												IMG_GIRL_1 + GameWnd_GetRandom(pthis, 0, GIRL_NUMBER - 1));
				}
				if (pthis->m_bIsDemo && pthis->m_nLevel > 2)
				{
					pthis->pMe->mainMenu.m_state = eMenuState_DEMOERROR;
					RussDmdApp_SetActiveWnd(pthis->pMe, IDW_MAINMENU);
					return FALSE;
				}
			}
			// 生成新的方块
			pthis->m_curBlock = pthis->m_nextBlock;
			GameWnd_GetRandomBlock(pthis, &pthis->m_nextBlock);
			pthis->m_nFrameTick = GetSpeed(pthis->m_nLevel);
			pthis->m_bAccelerate = FALSE;
			GameWnd_DrawStatus(pthis);
		}
	}

	return TRUE;
}

void GameWnd_Game_Draw(GameWnd* pthis)
{
	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);
}

boolean GameWnd_Pause_Compute(GameWnd* pthis)
{
	if (pthis->pMe->keyFlag & kKeypad_Clr)
	{
#ifdef ENABLE_MUSIC
		GameWnd_PlayMusic(pthis);
#endif

⌨️ 快捷键说明

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