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

📄 animation.cpp

📁 一个自己写的游戏引擎,用DirectX 写成
💻 CPP
字号:
//--------------------------------------------------
//  Desc: Base Animation
//  Author: artsylee/2006.12.7
//--------------------------------------------------
#include "../stdafx.h"
#include "Animation.h"
#include "Common.h"
#include "Log.h"
#include "Graphics.h"

CAnimation::CAnimation()
{
	m_hAnimation = INVALID_HANDLE;
	m_eLoopType = ANI_LOOP;
	m_eAniState = ANI_STOP;
	m_dwCurrFrame = 0;
	m_ptPosition.x = m_ptPosition.y = 0;
	m_dwColor = 0xffffffff;
	m_bShow = true;
	m_dwStartTime = 0;
	m_dwPauseTime = 0;
	memset(&m_FrameInfo, 0, sizeof(FrameDesc));
}

CAnimation::~CAnimation()
{
	Release();
}

void CAnimation::Release()
{
	if(!g_pFrameManager)
		return;

	g_pFrameManager->ReleaseFrame(m_hAnimation);

	m_hAnimation = INVALID_HANDLE;
	m_FrameInfo.m_FrameCount = 0;
	m_dwCurrFrame = 0;
}

//---------------------------------------------------
// 设置当前帧
//---------------------------------------------------
void CAnimation::SetCurrentFrame(DWORD index)
{
	if(m_FrameInfo.m_FrameCount==0)
	{
		index = 0;
	}
	else
	{
		index = index % m_FrameInfo.m_FrameCount;
	}
	m_dwCurrFrame = index;	
}

//---------------------------------------------------
// 从AMF文件加载
//---------------------------------------------------
bool CAnimation::LoadFromFile(const char *szFile, MemoryMode mode /* = MM_AUTO */)
{
	if(szFile == NULL || szFile[0] == 0)
	{
		WriteLog(INFO_ERROR, "Invalidate parameter!");
		return false;
	}
	if(g_pFrameManager==NULL)	return false;
	if(m_hAnimation != INVALID_HANDLE)
	{
		Release();
	}

	m_hAnimation = g_pFrameManager->LoadFrame(szFile, mode);
	if(m_hAnimation == INVALID_HANDLE)
	{
		WriteLog(INFO_ERROR, "Load Animation Error!");
		return false;
	}
	CFrames *pFrame = g_pFrameManager->GetFrame(m_hAnimation);
	if(pFrame==NULL)
		return false;
	pFrame->GetFrameDesc(&m_FrameInfo);
	return true;
}

//---------------------------------------------------
// 由纹理组指针加载(编辑器使用)
// KEEPINMEMORY mode
//---------------------------------------------------
bool CAnimation::LoadFromFrame(CFrames *pFrame)
{
	if(pFrame == NULL)
	{
		WriteLog(INFO_ERROR, "Invalidate parameter!");
		return false;
	}
	if(g_pFrameManager==NULL)	return false;
	
	if(m_hAnimation != INVALID_HANDLE)
	{
		// 重复加载同一个pFrame
		if(g_pFrameManager->GetFrame(m_hAnimation)==pFrame)
		{
			pFrame->GetFrameDesc(&m_FrameInfo);
			return true;
		}
		Release();
	}
	m_hAnimation = g_pFrameManager->InsertFrame(pFrame, MM_KEEPINMEMORY);
	if(m_hAnimation == INVALID_HANDLE)
	{
		WriteLog(INFO_ERROR, "Load Animation Error!");
		return false;
	}
	pFrame->GetFrameDesc(&m_FrameInfo);
	return true;
}

//---------------------------------------------------
// 动画更新
//---------------------------------------------------
void CAnimation::Update()
{
	if(m_eAniState == ANI_STOP || m_eAniState == ANI_PAUSE)
	{
		return;
	}
	if(!m_FrameInfo.m_Delay) return;
	if(!m_FrameInfo.m_FrameCount)	return;
	if(m_eLoopType==ANI_LOOPBACK && m_FrameInfo.m_FrameCount==1)	return;
	DWORD dwDelt = ::timeGetTime() - m_dwStartTime;
	DWORD dwFrame = dwDelt / m_FrameInfo.m_Delay;
	switch(m_eLoopType)
	{
	case ANI_ONCE:
		{
			DWORD dwFrameIndex = dwFrame % m_FrameInfo.m_FrameCount;
			if(dwFrameIndex == m_dwCurrFrame)
			{
				return;
			}

			if(dwFrameIndex > m_dwCurrFrame)
			{
				m_dwCurrFrame = dwFrameIndex;
			}
			else
			{
				m_eAniState = ANI_STOP;
				m_bShow = false;	
				// 在Update前判断动画是否结束可能会出现两个动画间一闪的问题.
			}
		}
		break;
	case ANI_LOOP:
		{
			DWORD dwFrameIndex = dwFrame % m_FrameInfo.m_FrameCount;
			if(dwFrameIndex == m_dwCurrFrame)
			{
				return;
			}
			m_dwCurrFrame = dwFrameIndex;
		}
		break;
	case ANI_LOOPBACK:
		{
			DWORD dwFrameIndex	= dwFrame % (m_FrameInfo.m_FrameCount*2-2);
			if(dwFrameIndex >= m_FrameInfo.m_FrameCount)
			{
				m_dwCurrFrame = (m_FrameInfo.m_FrameCount-2) - dwFrameIndex % m_FrameInfo.m_FrameCount;
			}
			else
			{
				m_dwCurrFrame = dwFrameIndex;
			}
		}
		break;
	}
}

//---------------------------------------------------
// 动画显示
//---------------------------------------------------
void CAnimation::Render()
{
	if(m_bShow && m_hAnimation != INVALID_HANDLE)
	{
		RECT rcDst = { m_ptPosition.x, m_ptPosition.y, 
			m_ptPosition.x+m_FrameInfo.m_Width, m_ptPosition.y+m_FrameInfo.m_Height };
		g_pGraphics->RenderAnimation(m_hAnimation, m_dwCurrFrame, &rcDst, NULL, m_dwColor);
	}
}

//---------------------------------------------------
// 动画显示
//---------------------------------------------------
void CAnimation::Render(int x, int y, float xScale, float yScale, RECT *rcSrc /* = NULL */) const
{
	if(m_bShow && m_hAnimation != INVALID_HANDLE)
	{
		g_pGraphics->RenderAnimation(m_hAnimation, m_dwCurrFrame, x, y, xScale, yScale, rcSrc, m_dwColor);
	}
}

//---------------------------------------------------
// 动画显示
//---------------------------------------------------
void CAnimation::Render(RECT *rcDst, RECT *rcSrc /* = NULL */) const
{
	if(m_bShow && m_hAnimation != INVALID_HANDLE)
	{
		g_pGraphics->RenderAnimation(m_hAnimation, m_dwCurrFrame, rcDst, rcSrc, m_dwColor);
	}
}

//---------------------------------------------------
// 显示一帧
//---------------------------------------------------
void CAnimation::RenderFrame(const DWORD &index) const
{
	if(m_bShow && m_hAnimation != INVALID_HANDLE)
	{
		RECT rcDst = { m_ptPosition.x, m_ptPosition.y, 
			m_ptPosition.x+m_FrameInfo.m_Width, m_ptPosition.y+m_FrameInfo.m_Height };
		g_pGraphics->RenderAnimation(m_hAnimation, index, &rcDst, NULL, m_dwColor);
	}
}

//---------------------------------------------------
// 播放
//---------------------------------------------------
void CAnimation::Play()
{
	if(m_eAniState == ANI_PAUSE)
	{
		m_dwStartTime = m_dwStartTime + (::timeGetTime() - m_dwPauseTime);
	}
	else if(m_eAniState == ANI_STOP)
	{
		m_dwStartTime = ::timeGetTime();
	}
	m_eAniState	= ANI_PLAY;
	if(!m_bShow)
	{
		m_bShow = true;
	}
}

//---------------------------------------------------
// 停止
//---------------------------------------------------
void CAnimation::Stop()
{
	m_eAniState	= ANI_STOP;
	m_dwCurrFrame = 0;
}

//---------------------------------------------------
// 暂停
//---------------------------------------------------
void CAnimation::Pause()
{
	if(m_eAniState == ANI_PLAY)
	{
		m_eAniState = ANI_PAUSE;
		m_dwPauseTime = ::timeGetTime();
	}
}

//---------------------------------------------------
// 重放
//---------------------------------------------------
void CAnimation::Replay()
{
	m_dwCurrFrame = 0;
	m_dwStartTime = ::timeGetTime();
	m_eAniState	= ANI_PLAY;
}

⌨️ 快捷键说明

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