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

📄 pokegame.cpp

📁 Brew下的塔罗牌游戏。游戏功能完整
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// PokeGame.cpp: implementation of the CPokeGame class.
// 代码作者:侯宇
// 创建日期:2004/07/04
//////////////////////////////////////////////////////////////////////


#include "pokegame.h"
#include "StdAfx.h"

static const int16 arwPokePath1[32] = {-4,-2,-1,3,-8,-1,3,3,-6,1,6,1,-3,3,8,-1,1,2,4,-3,2,1,-1,-3,2,-1,-2,-3,1,-3,-2,-2};
static const int16 arwPokePath2[14] = {3,3,5,3,6,1,1,-3,-4,-3,-7,-4,-7,-1};


CPokeGame::CPokeGame()
{
	m_pPokeResult = new CStatic();

	m_nStatus = STATUS_START;
	m_nAnimeStep = ANIME_START;

	//初始化数据。数字1-52分别表示牌,0表示此位置无牌
	int i;
	for (i = 0; i < TOTALPOKES; i++)
		m_arwPKQueue[i] = i + 1;
}

CPokeGame::~CPokeGame(void)
{
	if(m_pPokeResult)
		delete m_pPokeResult;

	//Cancel定时器
	if(m_pShell)
		m_pShell->CancelTimer(NULL, (void*)this);

	if(m_pBmpBuffer)
		delete m_pBmpBuffer;
	if(m_pBmpBG)
		delete m_pBmpBG;
	if(m_pBmpBGBk)
		delete m_pBmpBGBk;

	int i;
	for (i = 0;i < 3;i++)
	{
		if(m_pBmpTmp[i])
			delete m_pBmpTmp[i];
	}

	if(m_pBmpPoke)
		delete m_pBmpPoke;
	if(m_pBmpPokeBkH)
		delete m_pBmpPokeBkH;
	if(m_pBmpPokeRotate)
		delete m_pBmpPokeRotate;
	if(m_pBmpPokeFold)
		delete m_pBmpPokeFold;
}

//重载Create函数
boolean CPokeGame::Create(CShell *pShell, CDisplay *pDisplay)
{
	int i;//循环变量

	if(!m_pPokeResult || !CWnd::Create(pShell, pDisplay, POKE_RES_FILE))
		return FALSE;

	//加载游戏元素图片
	if(!LoadObjectImages())
		return FALSE;

	//加载并备份背景图
	m_pBmpBG = pShell->LoadResBitmap(POKE_RES_FILE, IDB_GAMEBG, 0, 0); 
	if(m_pBmpBG == NULL)
		return FALSE;
	m_pBmpBGBk = new CBitmap();
	if(!m_pBmpBGBk)
		return FALSE;
	if(SUCCESS != m_pBmpBG->CreateCompatibleBitmap(m_pBmpBGBk, m_cxScreen, m_cyScreen))
	{
		delete m_pBmpBuffer;
		m_pBmpBuffer = NULL;
		return FALSE;
	}
	m_pBmpBGBk->BltIn(0, 0, m_cxScreen, m_cyScreen, m_pBmpBG, 0, 0, AEE_RO_COPY);

	//创建缓冲图
	m_pBmpBuffer = new CBitmap();
	if(!m_pBmpBuffer)
		return FALSE;
	if(SUCCESS != m_pBmpBG->CreateCompatibleBitmap(m_pBmpBuffer, m_cxScreen, m_cyScreen))
	{
		delete m_pBmpBuffer;
		m_pBmpBuffer = NULL;
		return FALSE;
	}

	//处理图片位置
	SETAEERECT(&m_rcAnime, 0, m_rtPoke.y + DISTANCE_EDGE * 2, m_cxScreen, m_cyScreen - m_rcAnime.y);

	//得到字符高
	m_nCharHeight = m_pDisplay->GetFontMetrics(AEE_FONT_NORMAL, NULL, NULL);
	if (m_nCharHeight == EFAILED)
		return FALSE;

	//结果显示间隔
	m_nPokeDistance = (m_cxScreen - DISTANCE_EDGE * 2 - m_rtPoke.x) / 12;
	//整叠牌厚度
	m_nTotalHeight = TOTALPOKES / POKESPERPIXEL;

	//创建中间缓冲
	m_rtTmp.y = m_rtTmp.x = m_rtPoke.y + m_nTotalHeight;//正方形
	m_rcTmp.x = m_rcTmp.y = 0;m_rcTmp.dx = m_rtTmp.x;m_rcTmp.dy = m_rtTmp.y;
	for (i = 0;i < 3;i++)
	{
		m_pBmpTmp[i] = new CBitmap();
		if(!m_pBmpTmp[i])
			return FALSE;
		if(SUCCESS != m_pBmpBG->CreateCompatibleBitmap(m_pBmpTmp[i], m_rtTmp.x, m_rtTmp.y))
		{
			delete m_pBmpTmp[i];
			m_pBmpTmp[i] = NULL;
			return FALSE;
		}
	}
	if (SUCCESS != m_pBmpTmp[0]->GetTransparencyColor(&m_nTranscolor))
		return FALSE;
	//Load String
	if(m_pShell->LoadResString(POKE_RES_FILE, IDS_XP, m_szFlashText, 50) == 0)
		return FALSE;

	//Create Static to display poke result
	if(!m_pPokeResult->GetHandle())
	{
		//create instance
		if(m_pShell->CreateInstance(AEECLSID_STATIC, m_pPokeResult) != SUCCESS)
			return FALSE;
		//set property
		m_pPokeResult->SetProperties(ST_NOSCROLL);
		//set rectangle
		m_pPokeResult->SetRect(0, m_rcAnime.y, m_cxScreen, m_cyScreen - m_rcAnime.y);
	}

	//初始化坐标,m_ptAnime1、m_ptAnime2分别是上、下半堆牌最上面一张的坐标
	m_ptAnime1.x = (m_rcAnime.dx - m_rtPokeBkH.x - m_nTotalHeight) / 2;
	m_ptAnime1.y = (m_rcAnime.dy - m_rtPokeBkH.y - m_nTotalHeight) / 2 + m_rtPoke.y;
	m_ptAnime2.x = m_ptAnime1.x + 5;
	m_ptAnime2.y = m_ptAnime1.y + 5;
	//m_ptAnime4.x作为路径数组的指针位置
	m_ptAnime4.y = 0;

	return TRUE;
}	

// 加载游戏元素图片
boolean CPokeGame::LoadObjectImages(void)
{
	AEEBitmapInfo imgInfo;

	//52张扑克牌
	m_pBmpPoke = m_pShell->LoadResBitmap(POKE_RES_FILE, IDB_POKE, 0, 0);
	if(!m_pBmpPoke)
		return FALSE;
	m_pBmpPoke->GetInfo(&imgInfo, sizeof(AEEBitmapInfo));
	m_rtPoke.x = (int16) (imgInfo.cx / FRAME_POKE);
	m_rtPoke.y = (int16) imgInfo.cy;

	//横向的扑克背面
	m_pBmpPokeBkH = m_pShell->LoadResBitmap(POKE_RES_FILE, IDB_POKEBKH, 0, 0);
	if(!m_pBmpPokeBkH)
		return FALSE;
	m_pBmpPokeBkH->GetInfo(&imgInfo, sizeof(AEEBitmapInfo));
	m_rtPokeBkH.x = (int16) imgInfo.cx;
	m_rtPokeBkH.y = (int16) imgInfo.cy;

	//牌背面旋转
	m_pBmpPokeRotate = m_pShell->LoadResBitmap(POKE_RES_FILE, IDB_POKEROTATE, 0, 0);
	if(!m_pBmpPokeRotate)
		return FALSE;
	m_pBmpPokeRotate->GetInfo(&imgInfo, sizeof(AEEBitmapInfo));
	m_rtPokeRotate.x = (int16) (imgInfo.cx / FRAME_POKEROTATE);
	m_rtPokeRotate.y = (int16) imgInfo.cy;

	//牌背面弯折
	m_pBmpPokeFold = m_pShell->LoadResBitmap(POKE_RES_FILE, IDB_POKEFOLD, 0, 0);
	if(!m_pBmpPokeFold)
		return FALSE;
	m_pBmpPokeFold->GetInfo(&imgInfo, sizeof(AEEBitmapInfo));
	m_rtPokeFold.x = (int16) (imgInfo.cx / FRAME_POKEFOLD);
	m_rtPokeFold.y = (int16) imgInfo.cy;

	return TRUE;
}

//消息处理
boolean CPokeGame::HandleEvent(AEEEvent evt, uint16 wParam, uint32 dwParam)
{
	//循环变量
	int i = 0,j = 0;

	switch (evt)
	{
	//此程序运行时由于用户长时间无操作,系统会发送此消息,需要处理
	case EVT_APP_NO_SLEEP:
		break;
	case EVT_KEY:
		//如果一次占卜刚刚开始,那么在用户按任意键后开始洗牌
		if (m_nStatus == STATUS_START)
		{
			m_nStatus = STATUS_XP;
			m_nAnimeStep = 0;
			break;
		}
		//如果洗牌完毕,用户按任意键开始发牌
		if (m_nStatus == STATUS_XP)
		{
			if (m_nAnimeStep == 26)
			{
				m_nStatus = STATUS_FP;
				m_nAnimeStep = 1;
			};
			break;
		}
		//发牌过程中不响应按键
		if (m_nStatus == STATUS_FP)
		{
			break;
		}
		//如果正在显示占卜结果
		if (m_nStatus == STATUS_RESULT)
			return m_pPokeResult->HandleEvent(evt, wParam, dwParam);
	default:
		return FALSE;
	}
	return TRUE;
}

//画场景到屏幕
void CPokeGame::Update()
{
	//循环用变量
	int i;

	if(!m_pBmpBuffer)
	{
		m_pDisplay->ClearScreen();
		m_pDisplay->Update();
		return;
	}
	//Clear buffer
	AEERect rcScreen;
	SETAEERECT(&rcScreen, 0, 0, m_cxScreen, m_cyScreen);
	m_pBmpBuffer->FillRect(&rcScreen, m_pBmpBuffer->RGBToNative(MAKE_RGB(0xFF, 0xFF, 0xFF)), AEE_RO_COPY);
	//帖背景到缓冲
	m_pBmpBuffer->BltIn(0, 0, m_cxScreen, m_cyScreen, m_pBmpBG, 0, 0, AEE_RO_COPY);
	switch (m_nStatus)
	{
	case STATUS_START:
		//显示准备好的牌堆
		for (i = 9;i >=0;i--)
			m_pBmpBuffer->BltIn(m_ptAnime1.x + i, m_ptAnime1.y + i, m_rtPokeBkH.x, m_rtPokeBkH.y, m_pBmpPokeBkH, 0, 0, AEE_RO_TRANSPARENT);
		UpdateEx();
		StrFlash(IDS_XP);
		break;
	case STATUS_XP:
		AnimeXP();
		break;
	case STATUS_FP:
		AnimeFP();
		break;
	case STATUS_RESULT:
		ShowResult();
		break;
	}

	m_pDisplay->Update();
}
	
void CPokeGame::UpdateEx()
{
	//画到屏幕——由于在一些地方需要用IDisplay->Drawtext写屏,统一在最后BitBlt的话会把文字罩住,因此单独处理
	m_pDisplay->BitBlt(0, 0, m_cxScreen, m_cyScreen, m_pBmpBuffer->GetHandle(), 0, 0, AEE_RO_COPY);
}

//暂停
void CPokeGame::Pause()
{
	if(m_pShell)
		m_pShell->CancelTimer(NULL, (void*)this);
	CWnd::Pause();
}

//返回
void CPokeGame::Resume()
{
	CWnd::Resume();	
	m_pShell->SetTimer(0, (PFNNOTIFY)OnTimer, (void*) this);
}

//游戏定时器
void CPokeGame::OnTimer(CPokeGame *pGame)
{
	pGame->Update();

⌨️ 快捷键说明

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