📄 gamewnd.c
字号:
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 + -