Game初始化失败时自动回收资源;Music类初始化过程修改;节点二维矩阵转换方法修改

This commit is contained in:
Nomango 2018-04-24 10:35:58 +08:00
parent 0614701a30
commit f5185f5630
8 changed files with 178 additions and 211 deletions

View File

@ -21,52 +21,65 @@ bool e2d::Game::init(String sGameName)
return false;
}
do
// 初始化 COM 组件
CoInitialize(NULL);
// 创建设备无关资源
if (!Renderer::__createDeviceIndependentResources())
{
// 初始化 COM 组件
CoInitializeEx(NULL, COINIT_MULTITHREADED);
WARN_IF(true, "Renderer::__createDeviceIndependentResources Failed!");
goto dev_ind_res_fail;
}
// 创建设备无关资源
if (!Renderer::__createDeviceIndependentResources())
{
WARN_IF(true, "Renderer::__createDeviceIndependentResources Failed!");
break;
}
// 初始化窗口
if (!Window::__init())
{
WARN_IF(true, "Window::__init Failed!");
goto window_fail;
}
// 初始化窗口
if (!Window::__init())
{
WARN_IF(true, "Window::__init Failed!");
break;
}
// 创建设备相关资源
if (!Renderer::__createDeviceResources())
{
WARN_IF(true, "Renderer::__createDeviceResources Failed!");
goto dev_res_fail;
}
// 创建设备相关资源
if (!Renderer::__createDeviceResources())
{
WARN_IF(true, "Renderer::__createDeviceResources Failed!");
break;
}
// 初始化 DirectInput
if (!Input::__init())
{
WARN_IF(true, "Input::__init Failed!");
goto input_fail;
}
// 初始化 DirectInput
if (!Input::__init())
{
WARN_IF(true, "Input::__init Failed!");
break;
}
// 初始化播放器
if (!Music::__init())
{
WARN_IF(true, "Music::__init Failed!");
goto music_fail;
}
// 初始化播放器
if (!MusicManager::__init())
{
WARN_IF(true, "MusicManager::__init Failed!");
break;
}
// 保存游戏名称
s_sGameName = sGameName;
// 标志初始化成功
s_bInitialized = true;
// 初始化成功
s_sGameName = sGameName;
s_bInitialized = true;
goto succeeded;
} while (0);
music_fail:
Music::__uninit();
input_fail:
Input::__uninit();
dev_res_fail:
Renderer::__discardDeviceResources();
window_fail:
Window::__init();
dev_ind_res_fail:
Renderer::__discardResources();
succeeded:
return s_bInitialized;
}
@ -156,17 +169,19 @@ void e2d::Game::destroy()
{
// 删除所有场景
SceneManager::__uninit();
// 关闭播放器
MusicManager::__uninit();
// 删除监听器
InputManager::__uninit();
ColliderManager::__uninit();
// 删除动画
ActionManager::__uninit();
// 关闭音乐播放器
MusicManager::__uninit();
// 删除所有对象
ObjectManager::__clear();
// 清空图片缓存
Image::clearCache();
// 回收音乐相关资源
Music::__uninit();
// 清空定时器
Timer::__uninit();
// 关闭输入

View File

@ -2,24 +2,13 @@
#include "..\e2dtool.h"
#include <map>
#if HIGHER_THAN_VS2010
static IXAudio2 * s_pXAudio2 = nullptr;
static IXAudio2MasteringVoice * s_pMasteringVoice = nullptr;
#else
static HINSTANCE s_hInstance = nullptr;
#endif
typedef std::pair<UINT, e2d::Music *> MusicPair;
typedef std::map<UINT, e2d::Music *> MusicList;
typedef std::map<UINT, e2d::Music *> MusicMap;
static MusicList& getMusicList()
static MusicMap& GetMusicList()
{
static MusicList s_List;
static MusicMap s_List;
return s_List;
}
@ -28,7 +17,7 @@ bool e2d::MusicManager::preload(String strFilePath)
{
UINT nRet = strFilePath.getHashCode();
if (getMusicList().end() != getMusicList().find(nRet))
if (GetMusicList().end() != GetMusicList().find(nRet))
{
return true;
}
@ -38,7 +27,7 @@ bool e2d::MusicManager::preload(String strFilePath)
if (pPlayer->open(strFilePath))
{
getMusicList().insert(MusicPair(nRet, pPlayer));
GetMusicList().insert(MusicPair(nRet, pPlayer));
pPlayer->retain();
return true;
}
@ -56,7 +45,7 @@ bool e2d::MusicManager::play(String strFilePath, int nLoopCount)
if (MusicManager::preload(strFilePath))
{
UINT nRet = strFilePath.getHashCode();
Music * pMusic = getMusicList()[nRet];
Music * pMusic = GetMusicList()[nRet];
if (pMusic->play(nLoopCount))
{
return true;
@ -99,15 +88,15 @@ e2d::Music * e2d::MusicManager::get(String strFilePath)
UINT nRet = strFilePath.getHashCode();
if (getMusicList().end() != getMusicList().find(nRet))
return getMusicList()[nRet];
if (GetMusicList().end() != GetMusicList().find(nRet))
return GetMusicList()[nRet];
return nullptr;
}
void e2d::MusicManager::pauseAll()
{
for (auto iter = getMusicList().begin(); iter != getMusicList().end(); iter++)
for (auto iter = GetMusicList().begin(); iter != GetMusicList().end(); iter++)
{
(*iter).second->pause();
}
@ -115,7 +104,7 @@ void e2d::MusicManager::pauseAll()
void e2d::MusicManager::resumeAll()
{
for (auto iter = getMusicList().begin(); iter != getMusicList().end(); iter++)
for (auto iter = GetMusicList().begin(); iter != GetMusicList().end(); iter++)
{
(*iter).second->resume();
}
@ -123,100 +112,18 @@ void e2d::MusicManager::resumeAll()
void e2d::MusicManager::stopAll()
{
for (auto iter = getMusicList().begin(); iter != getMusicList().end(); iter++)
for (auto iter = GetMusicList().begin(); iter != GetMusicList().end(); iter++)
{
(*iter).second->stop();
}
}
#if HIGHER_THAN_VS2010
IXAudio2 * e2d::MusicManager::getIXAudio2()
{
return s_pXAudio2;
}
IXAudio2MasteringVoice * e2d::MusicManager::getIXAudio2MasteringVoice()
{
return s_pMasteringVoice;
}
bool e2d::MusicManager::__init()
{
HRESULT hr;
if (FAILED(hr = XAudio2Create(&s_pXAudio2, 0)))
{
WARN_IF(true, "Failed to init XAudio2 engine");
return false;
}
if (FAILED(hr = s_pXAudio2->CreateMasteringVoice(&s_pMasteringVoice)))
{
WARN_IF(true, "Failed creating mastering voice");
SafeReleaseInterface(&s_pXAudio2);
return false;
}
return true;
}
void e2d::MusicManager::__uninit()
{
for (auto iter : getMusicList())
for (auto iter : GetMusicList())
{
iter.second->close();
iter.second->release();
}
getMusicList().clear();
if (s_pMasteringVoice)
{
s_pMasteringVoice->DestroyVoice();
}
SafeReleaseInterface(&s_pXAudio2);
GetMusicList().clear();
}
#else
HINSTANCE e2d::MusicManager::getHInstance()
{
return s_hInstance;
}
bool e2d::MusicManager::__init()
{
s_hInstance = HINST_THISCOMPONENT;
WNDCLASS wc;
wc.style = 0;
wc.lpfnWndProc = Music::MusicProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = s_hInstance;
wc.hIcon = 0;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = MUSIC_CLASS_NAME;
if (!RegisterClass(&wc) && 1410 != GetLastError())
{
return false;
}
return true;
}
void e2d::MusicManager::__uninit()
{
for (auto iter = getMusicList().begin(); iter != getMusicList().end(); iter++)
{
(*iter).second->close();
(*iter).second->release();
}
getMusicList().clear();
}
#endif

View File

@ -51,7 +51,7 @@ void e2d::Node::_update()
{
if (m_bTransformNeeded)
{
_updateTransform(this);
_updateTransform();
}
if (!m_vChildren.empty())
@ -201,7 +201,7 @@ void e2d::Node::_onExit()
}
}
void e2d::Node::_updateTransform()
void e2d::Node::_updateSelfTransform()
{
// 计算中心点坐标
D2D1_POINT_2F pivot = { m_fWidth * m_fPivotX, m_fHeight * m_fPivotY };
@ -231,46 +231,36 @@ void e2d::Node::_updateTransform()
}
}
void e2d::Node::_updateChildrenTransform()
{
FOR_LOOP(child, m_vChildren)
{
_updateTransform(child);
}
}
void e2d::Node::_updateTransform(Node * node)
void e2d::Node::_updateTransform()
{
// 计算自身的转换矩阵
node->_updateTransform();
_updateSelfTransform();
// 绑定于自身的碰撞体也进行相应转换
if (node->m_pCollider)
if (m_pCollider)
{
node->m_pCollider->_transform();
m_pCollider->_transform();
}
// 遍历子节点下的所有节点
node->_updateChildrenTransform();
// 标志已执行过变换
node->m_bTransformNeeded = false;
m_bTransformNeeded = false;
// 遍历子节点下的所有节点
FOR_LOOP(child, this->m_vChildren)
{
child->_updateTransform();
}
}
void e2d::Node::_updateChildrenOpacity()
void e2d::Node::_updateOpacity()
{
if (m_pParent)
{
m_fDisplayOpacity = m_fRealOpacity * m_pParent->m_fDisplayOpacity;
}
FOR_LOOP(child, m_vChildren)
{
_updateOpacity(child);
child->_updateOpacity();
}
}
void e2d::Node::_updateOpacity(Node * node)
{
if (node->m_pParent)
{
node->m_fDisplayOpacity = node->m_fRealOpacity * node->m_pParent->m_fDisplayOpacity;
}
node->_updateChildrenOpacity();
}
bool e2d::Node::isVisiable() const
{
return m_bVisiable;
@ -511,7 +501,7 @@ void e2d::Node::setOpacity(double opacity)
m_fDisplayOpacity = m_fRealOpacity = min(max(static_cast<float>(opacity), 0), 1);
// 更新节点透明度
_updateOpacity(this);
_updateOpacity();
}
void e2d::Node::setPivotX(double pivotX)
@ -674,7 +664,7 @@ void e2d::Node::addChild(Node * child, int order /* = 0 */)
}
// 更新子节点透明度
_updateOpacity(child);
child->_updateOpacity();
// 更新节点转换
child->m_bTransformNeeded = true;
// 更新子节点排序

View File

@ -24,6 +24,39 @@ inline bool TraceError(wchar_t* sPrompt, HRESULT hr)
return false;
}
static IXAudio2 * s_pXAudio2 = nullptr;
static IXAudio2MasteringVoice * s_pMasteringVoice = nullptr;
bool e2d::Music::__init()
{
HRESULT hr;
if (FAILED(hr = XAudio2Create(&s_pXAudio2, 0)))
{
WARN_IF(true, "Failed to init XAudio2 engine");
return false;
}
if (FAILED(hr = s_pXAudio2->CreateMasteringVoice(&s_pMasteringVoice)))
{
WARN_IF(true, "Failed creating mastering voice");
SafeReleaseInterface(&s_pXAudio2);
return false;
}
return true;
}
void e2d::Music::__uninit()
{
if (s_pMasteringVoice)
{
s_pMasteringVoice->DestroyVoice();
}
SafeReleaseInterface(&s_pXAudio2);
}
Music::Music()
: m_bOpened(false)
@ -69,8 +102,7 @@ bool Music::open(String strFileName)
return false;
}
IXAudio2 * pXAudio2 = MusicManager::getIXAudio2();
if (!pXAudio2)
if (!s_pXAudio2)
{
WARN_IF(true, "IXAudio2 nullptr pointer error!");
return false;
@ -116,7 +148,7 @@ bool Music::open(String strFileName)
// ´´½¨ÒôÔ´
HRESULT hr;
if (FAILED(hr = pXAudio2->CreateSourceVoice(&m_pSourceVoice, m_pwfx)))
if (FAILED(hr = s_pXAudio2->CreateSourceVoice(&m_pSourceVoice, m_pwfx)))
{
TraceError(L"Create source voice error", hr);
SAFE_DELETE_ARRAY(m_pbWaveData);
@ -291,6 +323,16 @@ bool Music::setFrequencyRatio(double fFrequencyRatio)
return false;
}
IXAudio2 * e2d::Music::getIXAudio2()
{
return s_pXAudio2;
}
IXAudio2MasteringVoice * e2d::Music::getIXAudio2MasteringVoice()
{
return s_pMasteringVoice;
}
IXAudio2SourceVoice * Music::getIXAudio2SourceVoice() const
{
return m_pSourceVoice;
@ -496,6 +538,33 @@ bool Music::_findMediaFileCch(wchar_t* strDestPath, int cchDest, const wchar_t *
#else
#define MUSIC_CLASS_NAME L"Easy2DMusicCallbackWnd"
static HINSTANCE s_hInstance = nullptr;
bool e2d::Music::__init()
{
s_hInstance = HINST_THISCOMPONENT;
WNDCLASS wc;
wc.style = 0;
wc.lpfnWndProc = Music::MusicProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = s_hInstance;
wc.hIcon = 0;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = MUSIC_CLASS_NAME;
if (!RegisterClass(&wc) && 1410 != GetLastError())
{
return false;
}
return true;
}
e2d::Music::Music()
: m_wnd(NULL)
@ -512,7 +581,7 @@ e2d::Music::Music()
0, 0, 0, 0,
NULL,
NULL,
MusicManager::getHInstance(),
s_hInstance,
NULL);
if (m_wnd)

View File

@ -62,8 +62,6 @@
#if HIGHER_THAN_VS2010
#include <xaudio2.h>
#pragma comment(lib, "xaudio2.lib")
#else
#define MUSIC_CLASS_NAME L"Easy2DMusicCallbackWnd"
#endif

View File

@ -221,26 +221,8 @@ public:
// 停止所有音乐
static void stopAll();
#if HIGHER_THAN_VS2010
// 获取 IXAudio2 对象
static IXAudio2 * getIXAudio2();
// 获取 IXAudio2MasteringVoice 对象
static IXAudio2MasteringVoice * getIXAudio2MasteringVoice();
#else
// 获取 HINSTANCE
static HINSTANCE getHInstance();
#endif
private:
// 初始化音乐播放器
static bool __init();
// 回收相关资源
// 쀼澗稜있栗都
static void __uninit();
};

View File

@ -435,19 +435,13 @@ protected:
);
// 对自身进行二维矩阵变换
void _updateTransform();
// 更新所有子节点矩阵
void _updateChildrenTransform();
// 更新所有子节点透明度
void _updateChildrenOpacity();
void _updateSelfTransform();
// 更新节点二维矩阵
static void _updateTransform(Node * node);
void _updateTransform();
// 更新节点透明度
static void _updateOpacity(Node * node);
void _updateOpacity();
protected:
String m_sName;

View File

@ -56,7 +56,7 @@ private:
class Music :
public Object
{
friend MusicManager;
friend Game;
public:
Music();
@ -108,8 +108,20 @@ public:
double fFrequencyRatio /* 频率比范围为 1/1024.0f ~ 1024.0f,其中 1.0 为正常声调 */
);
private:
static bool __init();
static void __uninit();
#if HIGHER_THAN_VS2010
public:
// 获取 IXAudio2 对象
static IXAudio2 * getIXAudio2();
// 获取 IXAudio2MasteringVoice 对象
static IXAudio2MasteringVoice * getIXAudio2MasteringVoice();
// 获取 IXAudio2SourceVoice 对象
IXAudio2SourceVoice* getIXAudio2SourceVoice() const;