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