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

📄 item.cpp

📁 泡泡堂单机版(含ASL游戏引擎源码 泡泡堂单机版(含ASL游戏引擎源码
💻 CPP
字号:
#include "item.h"
#include "map.h"
#include "sound.h"

void MoveAhead(const int nOldX, const int nOldY, int *pnNewX, int *pnNewY, Direction dir)
{
	switch (dir)
	{
	case drUp:
		*pnNewY = nOldY - 1;
		*pnNewX = nOldX;
		break;
	case drDown:
		*pnNewY = nOldY + 1;
		*pnNewX = nOldX;
		break;
	case drLeft:
		*pnNewX = nOldX - 1;
		*pnNewY = nOldY;
		break;
	case drRight:
		*pnNewX = nOldX + 1;
		*pnNewY = nOldY;
	}
}

Cell* CItem::GetCell(Direction dr)
{
	int x = m_nCellX, y = m_nCellY;

	switch (dr)
	{
	case drUp: y--; break;
	case drDown: y++; break;
	case drLeft: x--; break;
	case drRight: x++; break;
	default: break;
	}

	return &MAP[y][x];
}

void CAniItem::Update(float fDelta)
{
	// 非动画状态, 等待动画间隔
	if (!m_bOnAni)
	{
		m_fTime += fDelta;
		if (m_fTime > m_fInterval)
		{
			m_fTime = 0;
			m_bOnAni = true;
		}
	}

	// 动画状态, 处理动画
	if (m_bOnAni)
	{
		m_fTime += fDelta;
		if (m_fTime > m_fDelta)
		{
			m_fTime -= m_fDelta;

			ASSERT(m_qAniSeq.size() != 0);
			m_nCurrentFrame = m_qAniSeq.front();
			m_qAniSeq.pop();
			m_qAniSeq.push(m_nCurrentFrame);

			if (m_nCurrentFrame == ANI_END)
			{
				m_nCurrentFrame = 0;
				m_bOnAni = false;
				m_fTime = 0;
			}
		}
	}
}

void CMedium::Draw(void) const
{
	int x = (m_nCellX-1) * CELL_SIZE + SCENE_LEFT;
	int y = m_nCellY * CELL_SIZE + SCENE_TOP;

	if (m_pbmShadow != NULL)
	{
		m_pbmShadow->DrawAlphaFast(SCREEN, x, y);
	}
	if (m_pbmMain != NULL)
	{
		m_pbmMain->Draw(SCREEN, x, y);
	}
}

void CMediumAni::Draw(void) const
{
	int x = (m_nCellX-1) * CELL_SIZE + SCENE_LEFT;
	int y = m_nCellY * CELL_SIZE + SCENE_TOP;

	if (m_pbmShadow != NULL)
	{
		m_pbmShadow->DrawAlphaFast(SCREEN, x, y);
	}
	if (m_pbmMain != NULL)
	{
		m_pbmMain->Draw(SCREEN, x, y, m_nCurrentFrame);
	}
}

void CLarge::Draw(void) const
{
	int x = (m_nCellX-1) * CELL_SIZE + SCENE_LEFT;
	int y = m_nCellY * CELL_SIZE + SCENE_TOP;

	if (m_pbmShadow != NULL)
	{
		m_pbmShadow->DrawAlphaFast(SCREEN, x, y);
	}
	if (m_pbmMain != NULL)
	{
		m_pbmMain->Draw(SCREEN, x, y);
	}
	if (m_pbmAni != NULL)
	{
		m_pbmAni->Draw(SCREEN, x, y, m_nCurrentFrame);
	}
}

void CBox::Draw(void) const
{
	int x = (m_nCellX-1) * CELL_SIZE + SCENE_LEFT + m_nOffsetX;
	int y = m_nCellY * CELL_SIZE + SCENE_TOP + m_nOffsetY;

	if (m_pbmShadow != NULL)
	{
		m_pbmShadow->DrawAlphaFast(SCREEN, x, y);
	}
	if (m_pbmMain != NULL)
	{
		m_pbmMain->Draw(SCREEN, x, y);
	}
}

void CBox::Update(float fDelta)
{
	static const int STEP = 4;
	Cell *pCell = NULL;

	if (!m_bMoving)
	{
		return;
	}

	switch (m_Direction)
	{
	case drUp:
		m_nOffsetY -= STEP;
		if (m_nOffsetY < -CELL_SIZE/2)
		{
			pCell = GetCell(drMiddle);
			pCell->Type = itNone;
			pCell->pItem = NULL;
			pCell = GetCell(drUp);
			pCell->Type = itBox;
			SAFE_DELETE(pCell->pItem);
			pCell->pItem = this;

			m_nOffsetY += CELL_SIZE;
			m_nCellY--;
		}
		if (m_nOffsetY == 0)
		{
			m_bMoving = false;
		}
		break;

	case drDown:
		m_nOffsetY += STEP;
		if (m_nOffsetY > CELL_SIZE/2)
		{
			pCell = GetCell(drMiddle);
			pCell->Type = itNone;
			pCell->pItem = NULL;
			pCell = GetCell(drDown);
			pCell->Type = itBox;
			SAFE_DELETE(pCell->pItem);
			pCell->pItem = this;

			m_nOffsetY -= CELL_SIZE;
			m_nCellY++;
		}
		if (m_nOffsetY == 0)
		{
			m_bMoving = false;
		}
		break;

	case drLeft:
		m_nOffsetX -= STEP;
		if (m_nOffsetX < -CELL_SIZE/2)
		{
			pCell = GetCell(drMiddle);
			pCell->Type = itNone;
			pCell->pItem = NULL;
			pCell = GetCell(drLeft);
			pCell->Type = itBox;
			SAFE_DELETE(pCell->pItem);
			pCell->pItem = this;

			m_nOffsetX += CELL_SIZE;
			m_nCellX--;
		}
		if (m_nOffsetX == 0)
		{
			m_bMoving = false;
		}				
		break;

	case drRight:
		m_nOffsetX += STEP;
		if (m_nOffsetX > CELL_SIZE/2)
		{
			pCell = GetCell(drMiddle);
			pCell->Type = itNone;
			pCell->pItem = NULL;
			pCell = GetCell(drRight);
			pCell->Type = itBox;
			SAFE_DELETE(pCell->pItem);
			pCell->pItem = this;

			m_nOffsetX -= CELL_SIZE;
			m_nCellX++;
		}
		if (m_nOffsetX == 0)
		{
			m_bMoving = false;
		}
		break;
	} // switch (m_Direction)
}

void CBox::Move(Direction dr)
{
	Cell *pCell;
	int nNewX, nNewY;

	MoveAhead(m_nCellX, m_nCellY, &nNewX, &nNewY, dr);

	pCell = &MAP[nNewY][nNewX];
	
	for (int i = 0; i < ROLE_NUM; ++i)
	{
		if (ROLE[i].GetX() == nNewX && ROLE[i].GetY() == nNewY &&
			!ROLE[i].IsFlying())
		{
			return;
		}
	}

	if (!m_bMoving &&
		(pCell->Type == itGift || pCell->Type == itNone) &&
		(pCell->Blind != btTent || dr != drLeft && dr != drRight))
	{
		m_bMoving = true;
		m_Direction = dr;
	}
}

void CBlindage::Update(float fDelta)
{
	static const float DELTA = 0.08f;

	if (m_bWaggle)
	{
		m_fTime += fDelta;
		if (m_fTime > DELTA)
		{
			m_fTime -= DELTA;
			m_nStatus++;
			if (m_nStatus == 3)
			{
				m_fTime = 0;
				m_nStatus = 0;
				m_bWaggle = false;
			}
		}
	}
}

void CBush::Draw(void) const
{
	int x = (m_nCellX-1) * CELL_SIZE + SCENE_LEFT;
	int y = m_nCellY * CELL_SIZE + SCENE_TOP;

	if (m_pbmShadow != NULL)
	{
		m_pbmShadow->DrawAlphaFast(SCREEN, x, y);
	}
	
	if (m_nStatus == 1)
	{
		y -= 3;
	}
	else if (m_nStatus == 2)
	{
		y += 3;
	}

	if (m_pbmMain != NULL)
	{
		m_pbmMain->Draw(SCREEN, x, y);
	}
}

void CTent::Draw(void) const
{
	int x = (m_nCellX-1) * CELL_SIZE + SCENE_LEFT;
	int y = m_nCellY * CELL_SIZE + SCENE_TOP;

	if (m_pbmShadow != NULL)
	{
		m_pbmShadow->DrawAlphaFast(SCREEN, x, y);
	}
	if (m_pbmMain != NULL)
	{
		m_pbmMain->Draw(SCREEN, x, y, m_nStatus);
	}
}

void CGift::Update(float fDelta)
{
	static const float DELTA = 0.15f;

	if (m_bStart)
	{
		m_nScale++;
		if (m_nScale > 20)
		{
			m_bStart = false;
		}
	}
	else
	{
		m_fTime += fDelta;
		if (m_fTime > DELTA)
		{
			m_fTime -= DELTA;	
			m_nOffsetY += m_nDir;
			if (m_nOffsetY >= 5 || m_nOffsetY <= 0)
			{
				m_nDir = -m_nDir;
			}
		}
	}
}

void CGift::Draw(void) const
{
	int x = (m_nCellX-1) * CELL_SIZE + SCENE_LEFT;
	int y = m_nCellY * CELL_SIZE + SCENE_TOP;

	if (m_bStart)
	{
		m_pbmMain->DrawStretch(SCREEN, x, y + (20 - m_nScale)*2, 
			0.05 * m_nScale, 0.05 * m_nScale, 0);
	}
	else
	{
		// 画阴影
		if (m_pbmShadow != NULL)
		{
			if (m_nOffsetY <= 2)
			{
				m_pbmShadow->DrawAlphaFast(SCREEN, x, y, 1);
			}
			else
			{
				m_pbmShadow->DrawAlphaFast(SCREEN, x, y, 0);
			}
		}

		// 画宝物
		if (m_pbmMain != NULL)
		{
			m_pbmMain->Draw(SCREEN, x, y - m_nOffsetY, m_nOffsetY%3);
		}
	}
}

void CPopo::Draw(void) const
{
	static int seq[4] = { 0, 1, 0, 2 };

	int x = (m_nCellX-1) * CELL_SIZE + SCENE_LEFT + m_nOffsetX;
	int y = m_nCellY * CELL_SIZE + SCENE_TOP + m_nOffsetY;

	// 画阴影
	if (m_pbmShadow != NULL)
	{
		m_pbmShadow->DrawAlphaFast(SCREEN, x, y, seq[m_nSeq]);
	}

	// 画泡泡
	if (m_pbmMain != NULL)
	{
		m_pbmMain->Draw(SCREEN, x, y, seq[m_nSeq]);
	}
}

void CPopo::Update(float fDelta)
{
	static const float DELTA = 0.18f;
	static const int STEP = 8;
	Cell *pCell = NULL;

	m_fRemainTime -= fDelta;
	if (m_fRemainTime <= 0.0f)
	{
		Explode();
		return;
	}

	m_fTime += fDelta;
	if (m_fTime > DELTA)
	{
		m_fTime -= DELTA;
		m_nSeq = (m_nSeq + 1) % 4;
	}

	if (m_bMoving)
	{
		switch (m_Direction)
		{
		case drUp:
			if (m_nOffsetY != 0)
			{
				m_nOffsetY -= STEP;
			}
			else
			{
				pCell = GetCell(drUp);
				if (pCell->Type == itGift || pCell->Type == itNone)
				{
					m_nOffsetY -= STEP;
				}
				else
				{
					m_bMoving = false;
				}
			}

			if (m_nOffsetY < -CELL_SIZE/2)
			{
				pCell = GetCell(drMiddle);
				pCell->Type = itNone;
				pCell->pItem = NULL;
				pCell = GetCell(drUp);
				pCell->Type = itPopo;
				SAFE_DELETE(pCell->pItem);
				pCell->pItem = this;

				m_nOffsetY += CELL_SIZE;
				m_nCellY--;
			}
			break;

		case drDown:
			if (m_nOffsetY != 0)
			{
				m_nOffsetY += STEP;
			}
			else
			{
				pCell = GetCell(drDown);
				if (pCell->Type == itGift || pCell->Type == itNone)
				{
					m_nOffsetY += STEP;
				}
				else
				{
					m_bMoving = false;
				}
			}

			if (m_nOffsetY > CELL_SIZE/2)
			{
				pCell = GetCell(drMiddle);
				pCell->Type = itNone;
				pCell->pItem = NULL;
				pCell = GetCell(drDown);
				pCell->Type = itPopo;
				SAFE_DELETE(pCell->pItem);
				pCell->pItem = this;

				m_nOffsetY -= CELL_SIZE;
				m_nCellY++;
			}
			break;

		case drLeft:
			if (m_nOffsetX != 0)
			{
				m_nOffsetX -= STEP;
			}
			else
			{
				pCell = GetCell(drLeft);
				if (pCell->Type == itGift || pCell->Type == itNone && pCell->Blind != btTent)
				{
					m_nOffsetX -= STEP;
				}
				else
				{
					m_bMoving = false;
				}
			}

			if (m_nOffsetX < -CELL_SIZE/2)
			{
				pCell = GetCell(drMiddle);
				pCell->Type = itNone;
				pCell->pItem = NULL;
				pCell = GetCell(drLeft);
				pCell->Type = itPopo;
				SAFE_DELETE(pCell->pItem);
				pCell->pItem = this;

				m_nOffsetX += CELL_SIZE;
				m_nCellX--;
			}
			break;

		case drRight:
			if (m_nOffsetX != 0)
			{
				m_nOffsetX += STEP;
			}
			else
			{
				pCell = GetCell(drRight);
				if (pCell->Type == itGift || pCell->Type == itNone && pCell->Blind != btTent)
				{
					m_nOffsetX += STEP;
				}
				else
				{
					m_bMoving = false;
				}
			}

			if (m_nOffsetX > CELL_SIZE/2)
			{
				pCell = GetCell(drMiddle);
				pCell->Type = itNone;
				pCell->pItem = NULL;
				pCell = GetCell(drRight);
				pCell->Type = itPopo;
				SAFE_DELETE(pCell->pItem);
				pCell->pItem = this;

				m_nOffsetX -= CELL_SIZE;
				m_nCellX++;
			}
			break;
		}
	}
}

void CPopo::Explode(void)
{
	m_pOwner->GetAbility().nUsedPopo--;
	SOUND.Play(snExplode);

	// 处理爆炸中心
	MAP[m_nCellY][m_nCellX].Explosion.Status = 1;
	MAP[m_nCellY][m_nCellX].Explosion.Dr = drMiddle;
	MAP[m_nCellY][m_nCellX].Explosion.Timer = 1;
	
	MAP[m_nCellY][m_nCellX].Type = itNone;
	MAP[m_nCellY][m_nCellX].pItem = NULL;
	if (MAP[m_nCellY][m_nCellX].Blind == btBush)
	{
		MAP[m_nCellY][m_nCellX].Blind = btNone;
		SAFE_DELETE(MAP[m_nCellY][m_nCellX].pBlindage);
	}

	// 处理爆炸冲击波
	for (int dr = drUp; dr <= drRight; dr++)
	{
		int  i = 0;
		int nCurrentX = m_nCellX, nCurrentY = m_nCellY;

		while (i++ < m_nPower)
		{
			if (MAP[nCurrentY][nCurrentX].Blind == btTent && (dr == drLeft || dr == drRight))
			{
				break;
			}

			MoveAhead(nCurrentX, nCurrentY, &nCurrentX, &nCurrentY, (Direction)dr);
			ExpProperty ep = GetExpProperty(nCurrentY, nCurrentX, (Direction)dr);

			if (ep != epFirm)
			{
				MAP[nCurrentY][nCurrentX].Explosion.Status = 1;
				MAP[nCurrentY][nCurrentX].Explosion.Dr = dr;
				MAP[nCurrentY][nCurrentX].Explosion.IsHead = (i == m_nPower ? 1 : 0);
				MAP[nCurrentY][nCurrentX].Explosion.Timer = i;
				MAP[nCurrentY][nCurrentX].Explosion.Dead = 12 + m_nPower - i;

				if (ep == epSolid)
				{
					SAFE_DELETE(MAP[nCurrentY][nCurrentX].pItem);
					MAP[nCurrentY][nCurrentX].Type = itNone;
					
					if (rand() % 4 == 0)
					{
						int nID = rand() % (FACTORY.GetGiftNum()+8) + 1;
						if (nID >= FACTORY.GetGiftNum() + 4)
						{
							nID = 1;
						}
						else if (nID > FACTORY.GetGiftNum())
						{
							nID = 3;
						}
						MAP[nCurrentY][nCurrentX].pItem = FACTORY.MakeFixedItem(nID);
						MAP[nCurrentY][nCurrentX].pItem->SetPosition(nCurrentY, nCurrentX);
						MAP[nCurrentY][nCurrentX].Type = itGift;

						SOUND.Play(snAppear);
					}

					break;
				}
				else if (ep == epPopo)
				{
					((CPopo*)MAP[nCurrentY][nCurrentX].pItem)->Explode();
				}
				else
				{
					SAFE_DELETE(MAP[nCurrentY][nCurrentX].pItem);
					MAP[nCurrentY][nCurrentX].Type = itNone;
					if (MAP[nCurrentY][nCurrentX].Blind == btBush)
					{
						SAFE_DELETE(MAP[nCurrentY][nCurrentX].pBlindage);
						MAP[nCurrentY][nCurrentX].Blind = btNone;
					}
				}
			}
			else
			{
				break;
			}
		}
	}
	
	delete this;
}

CPopo::ExpProperty CPopo::GetExpProperty(int nCellY, int nCellX, Direction dr)
{
	
	if (MAP[nCellY][nCellX].Type == itFirm ||
		MAP[nCellY][nCellX].Blind == btTent && (dr == drLeft || dr == drRight))
	{
		return epFirm;
	}
	else if (MAP[nCellY][nCellX].Type == itSolid ||
			 MAP[nCellY][nCellX].Type == itBox)
	{
		return epSolid;
	}
	else if (MAP[nCellY][nCellX].Type == itPopo)
	{
		return epPopo;
	}
	else
	{
		return epNone;
	}
}

⌨️ 快捷键说明

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