修复了组合动画在某些情况下时间重置出错的BUG
This commit is contained in:
parent
80d4880f19
commit
2fca388cb2
|
|
@ -97,6 +97,10 @@ void e2d::EAction::_reset()
|
||||||
{
|
{
|
||||||
m_bInit = false;
|
m_bInit = false;
|
||||||
m_bEnding = false;
|
m_bEnding = false;
|
||||||
// 记录当前时间
|
m_tLast = GetNow();
|
||||||
|
}
|
||||||
|
|
||||||
|
void e2d::EAction::_resetTime()
|
||||||
|
{
|
||||||
m_tLast = GetNow();
|
m_tLast = GetNow();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,3 +53,8 @@ void e2d::EActionLoop::_reset()
|
||||||
m_pAction->_reset();
|
m_pAction->_reset();
|
||||||
m_nTimes = 0;
|
m_nTimes = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void e2d::EActionLoop::_resetTime()
|
||||||
|
{
|
||||||
|
m_pAction->_resetTime();
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,14 @@ void e2d::EActionSequence::_reset()
|
||||||
m_nActionIndex = 0;
|
m_nActionIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void e2d::EActionSequence::_resetTime()
|
||||||
|
{
|
||||||
|
for (auto action : m_vActions)
|
||||||
|
{
|
||||||
|
action->_resetTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void e2d::EActionSequence::addAction(EAction * action)
|
void e2d::EActionSequence::addAction(EAction * action)
|
||||||
{
|
{
|
||||||
if (action)
|
if (action)
|
||||||
|
|
|
||||||
|
|
@ -70,3 +70,9 @@ void e2d::EActionTwo::_reset()
|
||||||
m_pFirstAction->_reset();
|
m_pFirstAction->_reset();
|
||||||
m_pSecondAction->_reset();
|
m_pSecondAction->_reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void e2d::EActionTwo::_resetTime()
|
||||||
|
{
|
||||||
|
m_pFirstAction->_resetTime();
|
||||||
|
m_pSecondAction->_resetTime();
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,3 +69,9 @@ void e2d::EActionTwoAtSameTime::_reset()
|
||||||
m_pFirstAction->_reset();
|
m_pFirstAction->_reset();
|
||||||
m_pSecondAction->_reset();
|
m_pSecondAction->_reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void e2d::EActionTwoAtSameTime::_resetTime()
|
||||||
|
{
|
||||||
|
m_pFirstAction->_resetTime();
|
||||||
|
m_pSecondAction->_resetTime();
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -332,6 +332,11 @@ void e2d::EApp::_mainLoop()
|
||||||
|
|
||||||
void e2d::EApp::_onControl()
|
void e2d::EApp::_onControl()
|
||||||
{
|
{
|
||||||
|
if (isPaused())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 正在切换场景时,执行场景切换动画
|
// 正在切换场景时,执行场景切换动画
|
||||||
if (m_bTransitional)
|
if (m_bTransitional)
|
||||||
{
|
{
|
||||||
|
|
@ -708,13 +713,13 @@ LRESULT e2d::EApp::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam
|
||||||
pEApp->m_bPaused = true;
|
pEApp->m_bPaused = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (pEApp->m_bPaused)
|
||||||
{
|
{
|
||||||
if (pEApp->getCurrentScene() &&
|
if (pEApp->getCurrentScene() &&
|
||||||
pEApp->getCurrentScene()->onActivate() &&
|
pEApp->getCurrentScene()->onActivate() &&
|
||||||
pEApp->onActivate())
|
pEApp->onActivate())
|
||||||
{
|
{
|
||||||
EApp::get()->m_bPaused = false;
|
pEApp->m_bPaused = false;
|
||||||
// 刷新当前时间
|
// 刷新当前时间
|
||||||
GetNow() = steady_clock::now();
|
GetNow() = steady_clock::now();
|
||||||
// 重置动画和定时器
|
// 重置动画和定时器
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<DebugInformationFormat>None</DebugInformationFormat>
|
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||||
<MinimalRebuild>false</MinimalRebuild>
|
<MinimalRebuild>false</MinimalRebuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
|
|
|
||||||
|
|
@ -124,13 +124,13 @@ void e2d::EActionManager::_resetAllActions()
|
||||||
{
|
{
|
||||||
for (const auto & action : s_vActions)
|
for (const auto & action : s_vActions)
|
||||||
{
|
{
|
||||||
action->m_tLast = GetNow();
|
action->_resetTime();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::EActionManager::ActionProc()
|
void e2d::EActionManager::ActionProc()
|
||||||
{
|
{
|
||||||
if (EApp::isPaused() || s_vActions.empty())
|
if (s_vActions.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// 循环遍历所有正在运行的动作
|
// 循环遍历所有正在运行的动作
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ static e2d::EVector<e2d::ETimer*> s_vTimers;
|
||||||
|
|
||||||
void e2d::ETimerManager::TimerProc()
|
void e2d::ETimerManager::TimerProc()
|
||||||
{
|
{
|
||||||
if (s_vTimers.empty() || EApp::isPaused())
|
if (s_vTimers.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (size_t i = 0; i < s_vTimers.size(); i++)
|
for (size_t i = 0; i < s_vTimers.size(); i++)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
#include "..\etools.h"
|
#include "..\etools.h"
|
||||||
#include "..\Win\winbase.h"
|
#include "..\Win\winbase.h"
|
||||||
#include <sstream>
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <commdlg.h>
|
#include <commdlg.h>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,525 @@
|
||||||
|
#include "..\etools.h"
|
||||||
|
#include "..\Win\winbase.h"
|
||||||
|
#include <map>
|
||||||
|
#include <mmsystem.h>
|
||||||
|
#include <Digitalv.h>
|
||||||
|
#pragma comment(lib , "winmm.lib")
|
||||||
|
|
||||||
|
static size_t Hash(const e2d::EString & key);
|
||||||
|
static bool ExtractResource(LPCTSTR strDstFile, LPCTSTR strResType, LPCTSTR strResName);
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// MciPlayer
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class MciPlayer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MciPlayer();
|
||||||
|
~MciPlayer();
|
||||||
|
|
||||||
|
void close();
|
||||||
|
bool open(const e2d::EString & pFileName, size_t uId);
|
||||||
|
bool open(const e2d::EString & pResouceName, const e2d::EString & pResouceType, const e2d::EString & musicExtension, size_t uId);
|
||||||
|
void play(bool bLoop = false);
|
||||||
|
void pause();
|
||||||
|
void resume();
|
||||||
|
void stop();
|
||||||
|
void rewind();
|
||||||
|
void setVolume(float volume);
|
||||||
|
bool isPlaying();
|
||||||
|
size_t getSoundID();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void _sendCommand(int nCommand, DWORD_PTR param1 = 0, DWORD_PTR parma2 = 0);
|
||||||
|
|
||||||
|
MCIDEVICEID m_dev;
|
||||||
|
size_t m_nSoundID;
|
||||||
|
bool m_bPlaying;
|
||||||
|
bool m_bLoop;
|
||||||
|
e2d::EString m_sTempFileName;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
MciPlayer::MciPlayer() :
|
||||||
|
m_dev(0L),
|
||||||
|
m_nSoundID(0),
|
||||||
|
m_bPlaying(false),
|
||||||
|
m_bLoop(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MciPlayer::~MciPlayer()
|
||||||
|
{
|
||||||
|
close(); // 关闭播放器
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MciPlayer::open(const e2d::EString & pFileName, size_t uId)
|
||||||
|
{
|
||||||
|
// 忽略不存在的文件
|
||||||
|
if (pFileName.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// 停止当前音乐
|
||||||
|
close();
|
||||||
|
|
||||||
|
// 设置 MCI_OPEN_PARMS 参数
|
||||||
|
MCI_OPEN_PARMS mciOpen = { 0 };
|
||||||
|
mciOpen.lpstrElementName = pFileName.c_str();
|
||||||
|
|
||||||
|
// 打开这个文件
|
||||||
|
MCIERROR mciError;
|
||||||
|
mciError = mciSendCommand(
|
||||||
|
0,
|
||||||
|
MCI_OPEN,
|
||||||
|
MCI_OPEN_ELEMENT | MCI_NOTIFY,
|
||||||
|
reinterpret_cast<DWORD_PTR>(&mciOpen)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (mciError)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 保存设备等信息
|
||||||
|
m_dev = mciOpen.wDeviceID;
|
||||||
|
m_nSoundID = uId;
|
||||||
|
m_bPlaying = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MciPlayer::open(const e2d::EString & pResouceName, const e2d::EString & pResouceType, const e2d::EString & musicExtension, size_t uId)
|
||||||
|
{
|
||||||
|
// 忽略不存在的文件
|
||||||
|
if (pResouceName.empty() || pResouceType.empty() || musicExtension.empty()) return false;
|
||||||
|
|
||||||
|
// 获取临时文件目录
|
||||||
|
e2d::EString tempFileName = e2d::EFileUtils::getTempPath();
|
||||||
|
|
||||||
|
// 产生临时文件的文件名
|
||||||
|
tempFileName.append(L"\\");
|
||||||
|
tempFileName.append(std::to_wstring(uId));
|
||||||
|
tempFileName.append(L"." + musicExtension);
|
||||||
|
|
||||||
|
// 导出资源为临时文件
|
||||||
|
if (ExtractResource(tempFileName.c_str(), pResouceType.c_str(), pResouceName.c_str()))
|
||||||
|
{
|
||||||
|
if (open(tempFileName, uId))
|
||||||
|
{
|
||||||
|
m_sTempFileName = tempFileName;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MciPlayer::play(bool bLoop)
|
||||||
|
{
|
||||||
|
// 设备为空时,忽略这次操作
|
||||||
|
if (!m_dev)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 设置播放参数
|
||||||
|
MCI_PLAY_PARMS mciPlay = { 0 };
|
||||||
|
MCIERROR s_mciError;
|
||||||
|
|
||||||
|
// 播放声音
|
||||||
|
s_mciError = mciSendCommand(
|
||||||
|
m_dev,
|
||||||
|
MCI_PLAY,
|
||||||
|
MCI_FROM | MCI_NOTIFY | (bLoop ? MCI_DGV_PLAY_REPEAT : 0),
|
||||||
|
reinterpret_cast<DWORD_PTR>(&mciPlay)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 未出错时,置 m_bPlaying 为 true
|
||||||
|
if (!s_mciError)
|
||||||
|
{
|
||||||
|
m_bPlaying = true;
|
||||||
|
m_bLoop = bLoop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MciPlayer::close()
|
||||||
|
{
|
||||||
|
// 停止音乐
|
||||||
|
if (m_bPlaying)
|
||||||
|
{
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
// 关闭设备
|
||||||
|
if (m_dev)
|
||||||
|
{
|
||||||
|
_sendCommand(MCI_CLOSE);
|
||||||
|
}
|
||||||
|
// 删除临时文件
|
||||||
|
if (!m_sTempFileName.empty())
|
||||||
|
{
|
||||||
|
DeleteFile(m_sTempFileName.c_str());
|
||||||
|
m_sTempFileName.clear();
|
||||||
|
}
|
||||||
|
// 恢复默认属性
|
||||||
|
m_dev = 0;
|
||||||
|
m_bPlaying = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MciPlayer::pause()
|
||||||
|
{
|
||||||
|
// 暂停音乐
|
||||||
|
_sendCommand(MCI_PAUSE);
|
||||||
|
m_bPlaying = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MciPlayer::resume()
|
||||||
|
{
|
||||||
|
// 继续播放音乐
|
||||||
|
_sendCommand(MCI_RESUME);
|
||||||
|
m_bPlaying = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MciPlayer::stop()
|
||||||
|
{
|
||||||
|
// 停止音乐
|
||||||
|
_sendCommand(MCI_STOP);
|
||||||
|
m_bPlaying = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MciPlayer::rewind()
|
||||||
|
{
|
||||||
|
// 设备为空时,忽略这次操作
|
||||||
|
if (!m_dev)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 重置播放位置
|
||||||
|
mciSendCommand(
|
||||||
|
m_dev,
|
||||||
|
MCI_SEEK,
|
||||||
|
MCI_SEEK_TO_START | MCI_NOTIFY,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
// 播放音乐
|
||||||
|
MCI_PLAY_PARMS mciPlay = { 0 };
|
||||||
|
MCIERROR s_mciError;
|
||||||
|
|
||||||
|
// 播放声音
|
||||||
|
s_mciError = mciSendCommand(
|
||||||
|
m_dev,
|
||||||
|
MCI_PLAY,
|
||||||
|
MCI_NOTIFY | (m_bLoop ? MCI_DGV_PLAY_REPEAT : 0),
|
||||||
|
reinterpret_cast<DWORD_PTR>(&mciPlay)
|
||||||
|
);
|
||||||
|
m_bPlaying = s_mciError ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MciPlayer::setVolume(float volume)
|
||||||
|
{
|
||||||
|
MCI_DGV_SETAUDIO_PARMS mciSetAudioPara = { 0 };
|
||||||
|
mciSetAudioPara.dwItem = MCI_DGV_SETAUDIO_VOLUME;
|
||||||
|
mciSetAudioPara.dwValue = DWORD(1000 * min(max(volume, 0), 1));
|
||||||
|
mciSendCommand(
|
||||||
|
m_dev,
|
||||||
|
MCI_SETAUDIO,
|
||||||
|
MCI_NOTIFY | MCI_DGV_SETAUDIO_VALUE | MCI_DGV_SETAUDIO_ITEM,
|
||||||
|
(DWORD_PTR)&mciSetAudioPara
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MciPlayer::isPlaying()
|
||||||
|
{
|
||||||
|
return m_bPlaying;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t MciPlayer::getSoundID()
|
||||||
|
{
|
||||||
|
return m_nSoundID;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MciPlayer::_sendCommand(int nCommand, DWORD_PTR param1, DWORD_PTR parma2)
|
||||||
|
{
|
||||||
|
// 空设备时忽略这次操作
|
||||||
|
if (!m_dev)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 向当前设备发送操作
|
||||||
|
mciSendCommand(m_dev, nCommand, param1, parma2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// e2d::EMusicUtils
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
typedef std::map<size_t, MciPlayer *> MusicList;
|
||||||
|
typedef std::pair<size_t, MciPlayer *> Music;
|
||||||
|
|
||||||
|
|
||||||
|
static MusicList& getMciPlayerList()
|
||||||
|
{
|
||||||
|
static MusicList s_List;
|
||||||
|
return s_List;
|
||||||
|
}
|
||||||
|
|
||||||
|
static MciPlayer& getBgMciPlayer()
|
||||||
|
{
|
||||||
|
static MciPlayer s_Music;
|
||||||
|
return s_Music;
|
||||||
|
}
|
||||||
|
|
||||||
|
void e2d::EMusicUtils::end()
|
||||||
|
{
|
||||||
|
// 停止背景音乐
|
||||||
|
getBgMciPlayer().close();
|
||||||
|
// 停止其他所有音乐
|
||||||
|
for (auto& iter : getMciPlayerList())
|
||||||
|
{
|
||||||
|
SafeDelete(&iter.second);
|
||||||
|
}
|
||||||
|
// 清空音乐列表
|
||||||
|
getMciPlayerList().clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void e2d::EMusicUtils::setVolume(float volume)
|
||||||
|
{
|
||||||
|
// 设置背景音乐音量
|
||||||
|
getBgMciPlayer().setVolume(volume);
|
||||||
|
// 设置其他音乐音量
|
||||||
|
for (auto& iter : getMciPlayerList())
|
||||||
|
{
|
||||||
|
iter.second->setVolume(volume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void e2d::EMusicUtils::setVolume(const EString & musicFilePath, float volume)
|
||||||
|
{
|
||||||
|
size_t nRet = ::Hash(musicFilePath);
|
||||||
|
|
||||||
|
MusicList::iterator p = getMciPlayerList().find(nRet);
|
||||||
|
if (p != getMciPlayerList().end())
|
||||||
|
{
|
||||||
|
p->second->setVolume(volume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void e2d::EMusicUtils::playBackgroundMusic(const EString & musicFilePath, bool bLoop)
|
||||||
|
{
|
||||||
|
if (musicFilePath.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
getBgMciPlayer().open(musicFilePath, ::Hash(musicFilePath));
|
||||||
|
getBgMciPlayer().play(bLoop);
|
||||||
|
}
|
||||||
|
|
||||||
|
void e2d::EMusicUtils::playBackgroundMusic(const EString & musicResourceName, const EString & musicResourceType, const EString & musicExtension, bool loop)
|
||||||
|
{
|
||||||
|
if (musicResourceName.empty() || musicResourceType.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
getBgMciPlayer().open(musicResourceName, musicResourceType, musicExtension, ::Hash(musicResourceName));
|
||||||
|
getBgMciPlayer().play(loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
void e2d::EMusicUtils::stopBackgroundMusic(bool bReleaseData)
|
||||||
|
{
|
||||||
|
if (bReleaseData)
|
||||||
|
{
|
||||||
|
getBgMciPlayer().close();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
getBgMciPlayer().stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void e2d::EMusicUtils::pauseBackgroundMusic()
|
||||||
|
{
|
||||||
|
getBgMciPlayer().pause();
|
||||||
|
}
|
||||||
|
|
||||||
|
void e2d::EMusicUtils::resumeBackgroundMusic()
|
||||||
|
{
|
||||||
|
getBgMciPlayer().resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
void e2d::EMusicUtils::rewindBackgroundMusic()
|
||||||
|
{
|
||||||
|
getBgMciPlayer().rewind();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool e2d::EMusicUtils::isBackgroundMusicPlaying()
|
||||||
|
{
|
||||||
|
return getBgMciPlayer().isPlaying();
|
||||||
|
}
|
||||||
|
|
||||||
|
void e2d::EMusicUtils::setBackgroundMusicVolume(float volume)
|
||||||
|
{
|
||||||
|
getBgMciPlayer().setVolume(volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
void e2d::EMusicUtils::playMusic(const EString & musicFilePath, bool bLoop)
|
||||||
|
{
|
||||||
|
size_t nRet = ::Hash(musicFilePath);
|
||||||
|
|
||||||
|
preloadMusic(musicFilePath);
|
||||||
|
|
||||||
|
MusicList::iterator p = getMciPlayerList().find(nRet);
|
||||||
|
if (p != getMciPlayerList().end())
|
||||||
|
{
|
||||||
|
p->second->play(bLoop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void e2d::EMusicUtils::playMusic(const EString & musicResourceName, const EString & musicResourceType, const EString & musicExtension, bool loop)
|
||||||
|
{
|
||||||
|
size_t nRet = ::Hash(musicResourceName);
|
||||||
|
|
||||||
|
preloadMusic(musicResourceName, musicResourceType, musicExtension);
|
||||||
|
|
||||||
|
MusicList::iterator p = getMciPlayerList().find(nRet);
|
||||||
|
if (p != getMciPlayerList().end())
|
||||||
|
{
|
||||||
|
p->second->play(loop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void e2d::EMusicUtils::_stopMusic(size_t nSoundId)
|
||||||
|
{
|
||||||
|
MusicList::iterator p = getMciPlayerList().find(nSoundId);
|
||||||
|
if (p != getMciPlayerList().end())
|
||||||
|
{
|
||||||
|
p->second->stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void e2d::EMusicUtils::preloadMusic(const EString & musicFilePath)
|
||||||
|
{
|
||||||
|
if (musicFilePath.empty()) return;
|
||||||
|
|
||||||
|
size_t nRet = ::Hash(musicFilePath);
|
||||||
|
|
||||||
|
if (getMciPlayerList().end() != getMciPlayerList().find(nRet)) return;
|
||||||
|
|
||||||
|
getMciPlayerList().insert(Music(nRet, new MciPlayer()));
|
||||||
|
MciPlayer * pPlayer = getMciPlayerList()[nRet];
|
||||||
|
pPlayer->open(musicFilePath, nRet);
|
||||||
|
|
||||||
|
if (nRet == pPlayer->getSoundID()) return;
|
||||||
|
|
||||||
|
delete pPlayer;
|
||||||
|
getMciPlayerList().erase(nRet);
|
||||||
|
nRet = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void e2d::EMusicUtils::preloadMusic(const EString & musicResourceName, const EString & musicResourceType, const EString & musicExtension)
|
||||||
|
{
|
||||||
|
if (musicResourceName.empty() || musicResourceType.empty()) return;
|
||||||
|
|
||||||
|
size_t nRet = ::Hash(musicResourceName);
|
||||||
|
|
||||||
|
if (getMciPlayerList().end() != getMciPlayerList().find(nRet)) return;
|
||||||
|
|
||||||
|
getMciPlayerList().insert(Music(nRet, new MciPlayer()));
|
||||||
|
MciPlayer * pPlayer = getMciPlayerList()[nRet];
|
||||||
|
pPlayer->open(musicResourceName, musicResourceType, musicExtension, nRet);
|
||||||
|
|
||||||
|
if (nRet == pPlayer->getSoundID()) return;
|
||||||
|
|
||||||
|
delete pPlayer;
|
||||||
|
getMciPlayerList().erase(nRet);
|
||||||
|
nRet = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void e2d::EMusicUtils::_pauseMusic(size_t nSoundId)
|
||||||
|
{
|
||||||
|
MusicList::iterator p = getMciPlayerList().find(nSoundId);
|
||||||
|
if (p != getMciPlayerList().end())
|
||||||
|
{
|
||||||
|
p->second->pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void e2d::EMusicUtils::pauseAllMusics()
|
||||||
|
{
|
||||||
|
for (auto& iter : getMciPlayerList())
|
||||||
|
{
|
||||||
|
iter.second->pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void e2d::EMusicUtils::_resumeMusic(size_t nSoundId)
|
||||||
|
{
|
||||||
|
MusicList::iterator p = getMciPlayerList().find(nSoundId);
|
||||||
|
if (p != getMciPlayerList().end())
|
||||||
|
{
|
||||||
|
p->second->resume();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void e2d::EMusicUtils::resumeAllMusics()
|
||||||
|
{
|
||||||
|
for (auto& iter : getMciPlayerList())
|
||||||
|
{
|
||||||
|
iter.second->resume();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void e2d::EMusicUtils::stopAllMusics()
|
||||||
|
{
|
||||||
|
for (auto& iter : getMciPlayerList())
|
||||||
|
{
|
||||||
|
iter.second->stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void e2d::EMusicUtils::unloadMusic(const EString & musicFilePath)
|
||||||
|
{
|
||||||
|
size_t nID = ::Hash(musicFilePath);
|
||||||
|
|
||||||
|
MusicList::iterator p = getMciPlayerList().find(nID);
|
||||||
|
if (p != getMciPlayerList().end())
|
||||||
|
{
|
||||||
|
SafeDelete(&p->second);
|
||||||
|
getMciPlayerList().erase(nID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
size_t Hash(const e2d::EString & key)
|
||||||
|
{
|
||||||
|
static std::hash<e2d::EString> h;
|
||||||
|
return h(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ExtractResource(LPCTSTR strDstFile, LPCTSTR strResType, LPCTSTR strResName)
|
||||||
|
{
|
||||||
|
// 创建文件
|
||||||
|
HANDLE hFile = ::CreateFile(strDstFile, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL);
|
||||||
|
if (hFile == INVALID_HANDLE_VALUE)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// 查找资源文件中、加载资源到内存、得到资源大小
|
||||||
|
HRSRC hRes = ::FindResource(NULL, strResName, strResType);
|
||||||
|
HGLOBAL hMem = ::LoadResource(NULL, hRes);
|
||||||
|
DWORD dwSize = ::SizeofResource(NULL, hRes);
|
||||||
|
|
||||||
|
// 写入文件
|
||||||
|
DWORD dwWrite = 0; // 返回写入字节
|
||||||
|
::WriteFile(hFile, hMem, dwSize, &dwWrite, NULL);
|
||||||
|
::CloseHandle(hFile);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
@ -370,14 +370,31 @@ void e2d::EMusicUtils::setBackgroundMusicVolume(float volume)
|
||||||
|
|
||||||
void e2d::EMusicUtils::playMusic(const EString & musicFilePath, bool bLoop)
|
void e2d::EMusicUtils::playMusic(const EString & musicFilePath, bool bLoop)
|
||||||
{
|
{
|
||||||
size_t nRet = ::Hash(musicFilePath);
|
MCI_OPEN_PARMS mciOpen = { 0 };
|
||||||
|
mciOpen.lpstrElementName = musicFilePath.c_str();
|
||||||
|
|
||||||
preloadMusic(musicFilePath);
|
// 打开这个文件
|
||||||
|
MCIERROR mciError;
|
||||||
|
mciError = mciSendCommand(
|
||||||
|
0,
|
||||||
|
MCI_OPEN,
|
||||||
|
MCI_OPEN_ELEMENT | MCI_NOTIFY,
|
||||||
|
reinterpret_cast<DWORD_PTR>(&mciOpen)
|
||||||
|
);
|
||||||
|
|
||||||
MusicList::iterator p = getMciPlayerList().find(nRet);
|
if (!mciError)
|
||||||
if (p != getMciPlayerList().end())
|
|
||||||
{
|
{
|
||||||
p->second->play(bLoop);
|
// 设置播放参数
|
||||||
|
MCI_PLAY_PARMS mciPlay = { 0 };
|
||||||
|
MCIERROR s_mciError;
|
||||||
|
|
||||||
|
// 播放声音
|
||||||
|
s_mciError = mciSendCommand(
|
||||||
|
mciOpen.wDeviceID,
|
||||||
|
MCI_PLAY,
|
||||||
|
MCI_FROM | MCI_NOTIFY | (bLoop ? MCI_DGV_PLAY_REPEAT : 0),
|
||||||
|
reinterpret_cast<DWORD_PTR>(&mciPlay)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,9 @@ protected:
|
||||||
// 重置动作
|
// 重置动作
|
||||||
virtual void _reset();
|
virtual void _reset();
|
||||||
|
|
||||||
|
// 重置动画时间
|
||||||
|
virtual void _resetTime();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool m_bRunning;
|
bool m_bRunning;
|
||||||
bool m_bEnding;
|
bool m_bEnding;
|
||||||
|
|
@ -410,6 +413,9 @@ protected:
|
||||||
// 重置动作
|
// 重置动作
|
||||||
virtual void _reset() override;
|
virtual void _reset() override;
|
||||||
|
|
||||||
|
// 重置动画时间
|
||||||
|
virtual void _resetTime() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
EAction * m_pFirstAction;
|
EAction * m_pFirstAction;
|
||||||
EAction * m_pSecondAction;
|
EAction * m_pSecondAction;
|
||||||
|
|
@ -455,6 +461,9 @@ protected:
|
||||||
// 重置动作
|
// 重置动作
|
||||||
virtual void _reset() override;
|
virtual void _reset() override;
|
||||||
|
|
||||||
|
// 重置动画时间
|
||||||
|
virtual void _resetTime() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
UINT m_nActionIndex;
|
UINT m_nActionIndex;
|
||||||
std::vector<EAction*> m_vActions;
|
std::vector<EAction*> m_vActions;
|
||||||
|
|
@ -515,6 +524,9 @@ protected:
|
||||||
// 重置动作
|
// 重置动作
|
||||||
virtual void _reset() override;
|
virtual void _reset() override;
|
||||||
|
|
||||||
|
// 重置动画时间
|
||||||
|
virtual void _resetTime() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
EAction * m_pFirstAction;
|
EAction * m_pFirstAction;
|
||||||
EAction * m_pSecondAction;
|
EAction * m_pSecondAction;
|
||||||
|
|
@ -546,6 +558,9 @@ protected:
|
||||||
// 重置动作
|
// 重置动作
|
||||||
virtual void _reset() override;
|
virtual void _reset() override;
|
||||||
|
|
||||||
|
// 重置动画时间
|
||||||
|
virtual void _resetTime() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
EAction * m_pAction;
|
EAction * m_pAction;
|
||||||
int m_nTimes;
|
int m_nTimes;
|
||||||
|
|
|
||||||
|
|
@ -1,85 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
Action::Action() :
|
|
||||||
m_bRunning(true),
|
|
||||||
m_bWaiting(false),
|
|
||||||
m_bEnding(false),
|
|
||||||
m_bInit(false),
|
|
||||||
m_pTargetSprite(nullptr),
|
|
||||||
m_pParentScene(nullptr)
|
|
||||||
{
|
|
||||||
// 默认动作 15ms 运行一次
|
|
||||||
setInterval(15);
|
|
||||||
}
|
|
||||||
|
|
||||||
Action::~Action()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Action::isRunning()
|
|
||||||
{
|
|
||||||
return m_bRunning && !m_bWaiting;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Action::isEnding()
|
|
||||||
{
|
|
||||||
return m_bEnding;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Action::start()
|
|
||||||
{
|
|
||||||
m_bRunning = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Action::resume()
|
|
||||||
{
|
|
||||||
m_bRunning = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Action::pause()
|
|
||||||
{
|
|
||||||
m_bRunning = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Action::stop()
|
|
||||||
{
|
|
||||||
m_bEnding = true;
|
|
||||||
}
|
|
||||||
void Action::wait()
|
|
||||||
{
|
|
||||||
m_bWaiting = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Action::notify()
|
|
||||||
{
|
|
||||||
m_bWaiting = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Action::setInterval(LONGLONG milliSeconds)
|
|
||||||
{
|
|
||||||
// 设置动作的时间间隔
|
|
||||||
m_nAnimationInterval = milliSeconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
Action * Action::reverse() const
|
|
||||||
{
|
|
||||||
assert(0);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sprite * Action::getTarget()
|
|
||||||
{
|
|
||||||
return m_pTargetSprite;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Action::_init()
|
|
||||||
{
|
|
||||||
m_bInit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Action::_reset()
|
|
||||||
{
|
|
||||||
m_bInit = false;
|
|
||||||
m_bEnding = false;
|
|
||||||
}
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
|
|
||||||
ActionCallback::ActionCallback(const std::function<void()>& callback) :
|
|
||||||
m_Callback(callback)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionCallback::~ActionCallback()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionCallback * ActionCallback::copy() const
|
|
||||||
{
|
|
||||||
return new ActionCallback(m_Callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionCallback::_init()
|
|
||||||
{
|
|
||||||
Action::_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionCallback::_exec(std::chrono::steady_clock::time_point nNow)
|
|
||||||
{
|
|
||||||
m_Callback();
|
|
||||||
this->stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionCallback::_reset()
|
|
||||||
{
|
|
||||||
Action::_reset();
|
|
||||||
}
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
#include "..\Win\winbase.h"
|
|
||||||
|
|
||||||
ActionDelay::ActionDelay(float duration)
|
|
||||||
{
|
|
||||||
setInterval(LONGLONG(duration * 1000));
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionDelay::~ActionDelay()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionDelay * ActionDelay::copy() const
|
|
||||||
{
|
|
||||||
return new ActionDelay(m_nAnimationInterval / 1000.0f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionDelay::_init()
|
|
||||||
{
|
|
||||||
Action::_init();
|
|
||||||
// 记录当前时间
|
|
||||||
m_nLast = steady_clock::now();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionDelay::_exec(steady_clock::time_point nNow)
|
|
||||||
{
|
|
||||||
// 判断时间间隔是否足够
|
|
||||||
if (duration_cast<milliseconds>(nNow - m_nLast).count() > m_nAnimationInterval)
|
|
||||||
{
|
|
||||||
this->stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionDelay::_reset()
|
|
||||||
{
|
|
||||||
Action::_reset();
|
|
||||||
// 记录当前时间
|
|
||||||
m_nLast = steady_clock::now();
|
|
||||||
}
|
|
||||||
|
|
@ -1,83 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
#include "..\Win\winbase.h"
|
|
||||||
|
|
||||||
ActionFrames::ActionFrames() :
|
|
||||||
m_nFrameIndex(0)
|
|
||||||
{
|
|
||||||
// 帧动画默认 .5s 刷新一次
|
|
||||||
setInterval(500);
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionFrames::ActionFrames(LONGLONG frameDelay) :
|
|
||||||
m_nFrameIndex(0)
|
|
||||||
{
|
|
||||||
setInterval(frameDelay);
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionFrames::~ActionFrames()
|
|
||||||
{
|
|
||||||
for (auto frame : m_vFrames)
|
|
||||||
{
|
|
||||||
frame->autoRelease();
|
|
||||||
frame->release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionFrames::_init()
|
|
||||||
{
|
|
||||||
Action::_init();
|
|
||||||
// 记录当前时间
|
|
||||||
m_nLast = steady_clock::now();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionFrames::_exec(steady_clock::time_point nNow)
|
|
||||||
{
|
|
||||||
// 判断时间间隔是否足够
|
|
||||||
while (duration_cast<milliseconds>(nNow - m_nLast).count() > m_nAnimationInterval)
|
|
||||||
{
|
|
||||||
// 重新记录时间
|
|
||||||
m_nLast += milliseconds(m_nAnimationInterval);
|
|
||||||
m_pTargetSprite->setImage(m_vFrames[m_nFrameIndex]);
|
|
||||||
m_nFrameIndex++;
|
|
||||||
// 判断动作是否结束
|
|
||||||
if (m_nFrameIndex == m_vFrames.size())
|
|
||||||
{
|
|
||||||
this->stop();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionFrames::_reset()
|
|
||||||
{
|
|
||||||
Action::_reset();
|
|
||||||
m_nFrameIndex = 0;
|
|
||||||
// 记录当前时间
|
|
||||||
m_nLast = steady_clock::now();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionFrames::addFrame(Image * frame)
|
|
||||||
{
|
|
||||||
if (frame)
|
|
||||||
{
|
|
||||||
m_vFrames.push_back(frame);
|
|
||||||
frame->retain();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionFrames * ActionFrames::copy() const
|
|
||||||
{
|
|
||||||
auto a = new ActionFrames(this->m_nAnimationInterval);
|
|
||||||
for (auto f : m_vFrames)
|
|
||||||
{
|
|
||||||
a->addFrame(f);
|
|
||||||
}
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionFrames * ActionFrames::reverse() const
|
|
||||||
{
|
|
||||||
auto a = this->copy();
|
|
||||||
a->m_vFrames.reserve(m_vFrames.size());
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
#include "..\Win\winbase.h"
|
|
||||||
|
|
||||||
ActionMoveBy::ActionMoveBy(float duration, CVector vec) :
|
|
||||||
Animation(duration)
|
|
||||||
{
|
|
||||||
m_MoveVector = vec;
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionMoveBy::~ActionMoveBy()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionMoveBy::_init()
|
|
||||||
{
|
|
||||||
Animation::_init();
|
|
||||||
m_BeginPos = m_pTargetSprite->getPos();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionMoveBy::_exec(steady_clock::time_point nNow)
|
|
||||||
{
|
|
||||||
while (Animation::_isDelayEnough(nNow))
|
|
||||||
{
|
|
||||||
// 计算移动位置
|
|
||||||
float scale = float(m_nDuration) / m_nTotalDuration;
|
|
||||||
// 移动 Sprite
|
|
||||||
m_pTargetSprite->setPos(int(m_BeginPos.x + m_MoveVector.x * scale),
|
|
||||||
int(m_BeginPos.y + m_MoveVector.y * scale));
|
|
||||||
// 判断动作是否结束
|
|
||||||
if (_isEnd())
|
|
||||||
{
|
|
||||||
this->stop();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionMoveBy::_reset()
|
|
||||||
{
|
|
||||||
Animation::_reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionMoveBy * ActionMoveBy::copy() const
|
|
||||||
{
|
|
||||||
return new ActionMoveBy(m_nAnimationInterval / 1000.0f, m_MoveVector);
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionMoveBy * ActionMoveBy::reverse() const
|
|
||||||
{
|
|
||||||
return new ActionMoveBy(m_nTotalDuration / 1000.0f, CVector(-m_MoveVector.x, -m_MoveVector.y));
|
|
||||||
}
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
|
|
||||||
ActionMoveTo::ActionMoveTo(float duration, CPoint pos) :
|
|
||||||
ActionMoveBy(duration, CVector())
|
|
||||||
{
|
|
||||||
m_EndPos = pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionMoveTo::~ActionMoveTo()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionMoveTo * ActionMoveTo::copy() const
|
|
||||||
{
|
|
||||||
return new ActionMoveTo(m_nAnimationInterval / 1000.0f, m_EndPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionMoveTo::_init()
|
|
||||||
{
|
|
||||||
ActionMoveBy::_init();
|
|
||||||
m_MoveVector = m_EndPos - m_BeginPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionMoveTo::_reset()
|
|
||||||
{
|
|
||||||
ActionMoveBy::_reset();
|
|
||||||
}
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
|
|
||||||
ActionNeverStop::ActionNeverStop(Action * action) :
|
|
||||||
m_Action(action)
|
|
||||||
{
|
|
||||||
m_Action->retain();
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionNeverStop::~ActionNeverStop()
|
|
||||||
{
|
|
||||||
SafeRelease(m_Action);
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionNeverStop * ActionNeverStop::copy() const
|
|
||||||
{
|
|
||||||
return new ActionNeverStop(m_Action->copy());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionNeverStop::_init()
|
|
||||||
{
|
|
||||||
Action::_init();
|
|
||||||
m_Action->m_pTargetSprite = m_pTargetSprite;
|
|
||||||
m_Action->_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionNeverStop::_exec(std::chrono::steady_clock::time_point nNow)
|
|
||||||
{
|
|
||||||
m_Action->_exec(nNow);
|
|
||||||
|
|
||||||
if (m_Action->isEnding())
|
|
||||||
{
|
|
||||||
m_Action->_reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionNeverStop::_reset()
|
|
||||||
{
|
|
||||||
Action::_reset();
|
|
||||||
}
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
#include "..\Win\winbase.h"
|
|
||||||
|
|
||||||
ActionOpacityBy::ActionOpacityBy(float duration, float opacity) :
|
|
||||||
Animation(duration)
|
|
||||||
{
|
|
||||||
m_nVariation = opacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionOpacityBy::~ActionOpacityBy()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionOpacityBy::_init()
|
|
||||||
{
|
|
||||||
Animation::_init();
|
|
||||||
m_nBeginVal = m_pTargetSprite->getOpacity();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionOpacityBy::_exec(steady_clock::time_point nNow)
|
|
||||||
{
|
|
||||||
while (Animation::_isDelayEnough(nNow))
|
|
||||||
{
|
|
||||||
// 计算移动位置
|
|
||||||
float scale = float(m_nDuration) / m_nTotalDuration;
|
|
||||||
// 移动 Sprite
|
|
||||||
m_pTargetSprite->setOpacity(m_nBeginVal + m_nVariation * scale);
|
|
||||||
// 判断动作是否结束
|
|
||||||
if (_isEnd())
|
|
||||||
{
|
|
||||||
this->stop();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionOpacityBy::_reset()
|
|
||||||
{
|
|
||||||
Animation::_reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionOpacityBy * ActionOpacityBy::copy() const
|
|
||||||
{
|
|
||||||
return new ActionOpacityBy(m_nAnimationInterval / 1000.0f, m_nVariation);
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionOpacityBy * ActionOpacityBy::reverse() const
|
|
||||||
{
|
|
||||||
return new ActionOpacityBy(m_nTotalDuration / 1000.0f, -m_nVariation);
|
|
||||||
}
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
|
|
||||||
ActionOpacityTo::ActionOpacityTo(float duration, float opacity) :
|
|
||||||
ActionOpacityBy(duration, 0)
|
|
||||||
{
|
|
||||||
m_nEndVal = opacity;
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionOpacityTo::~ActionOpacityTo()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionOpacityTo * ActionOpacityTo::copy() const
|
|
||||||
{
|
|
||||||
return new ActionOpacityTo(m_nAnimationInterval / 1000.0f, m_nEndVal);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionOpacityTo::_init()
|
|
||||||
{
|
|
||||||
ActionOpacityBy::_init();
|
|
||||||
m_nVariation = m_nEndVal - m_nBeginVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionOpacityTo::_reset()
|
|
||||||
{
|
|
||||||
ActionOpacityBy::_reset();
|
|
||||||
}
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
#include "..\Win\winbase.h"
|
|
||||||
|
|
||||||
ActionScaleBy::ActionScaleBy(float duration, float scaleX, float scaleY) :
|
|
||||||
Animation(duration)
|
|
||||||
{
|
|
||||||
m_nVariationX = scaleX;
|
|
||||||
m_nVariationY = scaleY;
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionScaleBy::~ActionScaleBy()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionScaleBy::_init()
|
|
||||||
{
|
|
||||||
Animation::_init();
|
|
||||||
m_nBeginScaleX = m_pTargetSprite->getScaleX();
|
|
||||||
m_nBeginScaleY = m_pTargetSprite->getScaleY();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionScaleBy::_exec(steady_clock::time_point nNow)
|
|
||||||
{
|
|
||||||
while (Animation::_isDelayEnough(nNow))
|
|
||||||
{
|
|
||||||
// 计算移动位置
|
|
||||||
float scale = float(m_nDuration) / m_nTotalDuration;
|
|
||||||
// 移动 Sprite
|
|
||||||
m_pTargetSprite->setScale(m_nBeginScaleX + m_nVariationX * scale, m_nBeginScaleX + m_nVariationX * scale);
|
|
||||||
// 判断动作是否结束
|
|
||||||
if (_isEnd())
|
|
||||||
{
|
|
||||||
this->stop();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionScaleBy::_reset()
|
|
||||||
{
|
|
||||||
Animation::_reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionScaleBy * ActionScaleBy::copy() const
|
|
||||||
{
|
|
||||||
return new ActionScaleBy(m_nAnimationInterval / 1000.0f, m_nVariationX, m_nVariationY);
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionScaleBy * ActionScaleBy::reverse() const
|
|
||||||
{
|
|
||||||
return new ActionScaleBy(m_nTotalDuration / 1000.0f, -m_nVariationX, -m_nVariationY);
|
|
||||||
}
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
|
|
||||||
ActionScaleTo::ActionScaleTo(float duration, float scaleX, float scaleY) :
|
|
||||||
ActionScaleBy(duration, 0, 0)
|
|
||||||
{
|
|
||||||
m_nEndScaleX = scaleX;
|
|
||||||
m_nEndScaleY = scaleY;
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionScaleTo::~ActionScaleTo()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionScaleTo * ActionScaleTo::copy() const
|
|
||||||
{
|
|
||||||
return new ActionScaleTo(m_nAnimationInterval / 1000.0f, m_nEndScaleX, m_nEndScaleY);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionScaleTo::_init()
|
|
||||||
{
|
|
||||||
ActionScaleBy::_init();
|
|
||||||
m_nVariationX = m_nEndScaleX - m_nBeginScaleX;
|
|
||||||
m_nVariationY = m_nEndScaleY - m_nBeginScaleY;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionScaleTo::_reset()
|
|
||||||
{
|
|
||||||
ActionScaleBy::_reset();
|
|
||||||
}
|
|
||||||
|
|
@ -1,105 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
ActionSequence::ActionSequence() :
|
|
||||||
m_nActionIndex(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionSequence::ActionSequence(int number, Action * action1, ...) :
|
|
||||||
m_nActionIndex(0)
|
|
||||||
{
|
|
||||||
va_list params;
|
|
||||||
va_start(params, number);
|
|
||||||
|
|
||||||
while (number > 0)
|
|
||||||
{
|
|
||||||
this->addAction(va_arg(params, Action*));
|
|
||||||
number--;
|
|
||||||
}
|
|
||||||
|
|
||||||
va_end(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionSequence::~ActionSequence()
|
|
||||||
{
|
|
||||||
for (auto action : m_vActions)
|
|
||||||
{
|
|
||||||
SafeRelease(action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionSequence::_init()
|
|
||||||
{
|
|
||||||
Action::_init();
|
|
||||||
// 将所有动作与目标绑定
|
|
||||||
for (auto action : m_vActions)
|
|
||||||
{
|
|
||||||
action->m_pTargetSprite = m_pTargetSprite;
|
|
||||||
}
|
|
||||||
// 初始化第一个动作
|
|
||||||
m_vActions[0]->_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionSequence::_exec(std::chrono::steady_clock::time_point nNow)
|
|
||||||
{
|
|
||||||
m_vActions[m_nActionIndex]->_exec(nNow);
|
|
||||||
|
|
||||||
if (m_vActions[m_nActionIndex]->isEnding())
|
|
||||||
{
|
|
||||||
m_nActionIndex++;
|
|
||||||
if (m_nActionIndex == m_vActions.size())
|
|
||||||
{
|
|
||||||
this->stop();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_vActions[m_nActionIndex]->_init();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionSequence::_reset()
|
|
||||||
{
|
|
||||||
Action::_reset();
|
|
||||||
for (auto action : m_vActions)
|
|
||||||
{
|
|
||||||
action->_reset();
|
|
||||||
}
|
|
||||||
m_nActionIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionSequence::addAction(Action * action)
|
|
||||||
{
|
|
||||||
m_vActions.push_back(action);
|
|
||||||
action->retain();
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionSequence * ActionSequence::copy() const
|
|
||||||
{
|
|
||||||
auto a = new ActionSequence();
|
|
||||||
for (auto action : m_vActions)
|
|
||||||
{
|
|
||||||
a->addAction(action->copy());
|
|
||||||
}
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionSequence * ActionSequence::reverse(bool actionReverse) const
|
|
||||||
{
|
|
||||||
auto a = new ActionSequence();
|
|
||||||
for (auto action : a->m_vActions)
|
|
||||||
{
|
|
||||||
if (actionReverse)
|
|
||||||
{
|
|
||||||
a->addAction(action->reverse());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
a->addAction(action->copy());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 将动作顺序逆序排列
|
|
||||||
a->m_vActions.reserve(m_vActions.size());
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
|
|
@ -1,70 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
|
|
||||||
ActionTwo::ActionTwo(Action * actionFirst, Action * actionSecond) :
|
|
||||||
m_FirstAction(actionFirst),
|
|
||||||
m_SecondAction(actionSecond)
|
|
||||||
{
|
|
||||||
m_FirstAction->retain();
|
|
||||||
m_SecondAction->retain();
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionTwo::~ActionTwo()
|
|
||||||
{
|
|
||||||
SafeRelease(m_FirstAction);
|
|
||||||
SafeRelease(m_SecondAction);
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionTwo * ActionTwo::copy() const
|
|
||||||
{
|
|
||||||
return new ActionTwo(m_FirstAction->copy(), m_SecondAction->copy());
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionTwo * ActionTwo::reverse(bool actionReverse) const
|
|
||||||
{
|
|
||||||
if (actionReverse)
|
|
||||||
{
|
|
||||||
return new ActionTwo(m_SecondAction->reverse(), m_FirstAction->reverse());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return new ActionTwo(m_SecondAction->copy(), m_FirstAction->copy());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionTwo::_init()
|
|
||||||
{
|
|
||||||
Action::_init();
|
|
||||||
m_FirstAction->m_pTargetSprite = m_pTargetSprite;
|
|
||||||
m_SecondAction->m_pTargetSprite = m_pTargetSprite;
|
|
||||||
|
|
||||||
m_FirstAction->_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionTwo::_exec(std::chrono::steady_clock::time_point nNow)
|
|
||||||
{
|
|
||||||
if (!m_FirstAction->isEnding())
|
|
||||||
{
|
|
||||||
m_FirstAction->_exec(nNow);
|
|
||||||
if (m_FirstAction->isEnding())
|
|
||||||
{
|
|
||||||
// 返回 true 表示第一个动作已经结束
|
|
||||||
m_SecondAction->_init();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!m_SecondAction->isEnding())
|
|
||||||
{
|
|
||||||
m_SecondAction->_exec(nNow);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
this->stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionTwo::_reset()
|
|
||||||
{
|
|
||||||
Action::_reset();
|
|
||||||
|
|
||||||
m_FirstAction->_reset();
|
|
||||||
m_SecondAction->_reset();
|
|
||||||
}
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
#include "..\Win\winbase.h"
|
|
||||||
|
|
||||||
Animation::Animation(float duration)
|
|
||||||
{
|
|
||||||
m_nDuration = 0;
|
|
||||||
m_nTotalDuration = UINT(duration * 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
Animation::~Animation()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Animation::_isEnd() const
|
|
||||||
{
|
|
||||||
return m_nDuration >= m_nTotalDuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Animation::_init()
|
|
||||||
{
|
|
||||||
Action::_init();
|
|
||||||
// 记录当前时间
|
|
||||||
m_nLast = steady_clock::now();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Animation::_isDelayEnough(steady_clock::time_point nNow)
|
|
||||||
{
|
|
||||||
// 判断时间间隔是否足够
|
|
||||||
if (duration_cast<milliseconds>(nNow - m_nLast).count() > m_nAnimationInterval)
|
|
||||||
{
|
|
||||||
// 重新记录时间
|
|
||||||
m_nLast += milliseconds(m_nAnimationInterval);
|
|
||||||
m_nDuration += m_nAnimationInterval;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Animation::_reset()
|
|
||||||
{
|
|
||||||
Action::_reset();
|
|
||||||
m_nDuration = 0;
|
|
||||||
// 记录当前时间
|
|
||||||
m_nLast = steady_clock::now();
|
|
||||||
}
|
|
||||||
|
|
@ -1,314 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
#include "..\EasyX\easyx.h"
|
|
||||||
#include <conio.h>
|
|
||||||
|
|
||||||
// 按键监听回调函数的容器
|
|
||||||
static std::vector<KeyMsg*> s_vListeners;
|
|
||||||
|
|
||||||
// 虚拟键值的定义
|
|
||||||
const VK_KEY KeyMsg::A = 'A';
|
|
||||||
const VK_KEY KeyMsg::B = 'B';
|
|
||||||
const VK_KEY KeyMsg::C = 'C';
|
|
||||||
const VK_KEY KeyMsg::D = 'D';
|
|
||||||
const VK_KEY KeyMsg::E = 'E';
|
|
||||||
const VK_KEY KeyMsg::F = 'F';
|
|
||||||
const VK_KEY KeyMsg::G = 'G';
|
|
||||||
const VK_KEY KeyMsg::H = 'H';
|
|
||||||
const VK_KEY KeyMsg::I = 'I';
|
|
||||||
const VK_KEY KeyMsg::J = 'J';
|
|
||||||
const VK_KEY KeyMsg::K = 'K';
|
|
||||||
const VK_KEY KeyMsg::L = 'L';
|
|
||||||
const VK_KEY KeyMsg::M = 'M';
|
|
||||||
const VK_KEY KeyMsg::N = 'N';
|
|
||||||
const VK_KEY KeyMsg::O = 'O';
|
|
||||||
const VK_KEY KeyMsg::P = 'P';
|
|
||||||
const VK_KEY KeyMsg::Q = 'Q';
|
|
||||||
const VK_KEY KeyMsg::R = 'R';
|
|
||||||
const VK_KEY KeyMsg::S = 'S';
|
|
||||||
const VK_KEY KeyMsg::T = 'T';
|
|
||||||
const VK_KEY KeyMsg::U = 'U';
|
|
||||||
const VK_KEY KeyMsg::V = 'V';
|
|
||||||
const VK_KEY KeyMsg::W = 'W';
|
|
||||||
const VK_KEY KeyMsg::X = 'X';
|
|
||||||
const VK_KEY KeyMsg::Y = 'Y';
|
|
||||||
const VK_KEY KeyMsg::Z = 'Z';
|
|
||||||
const VK_KEY KeyMsg::NUM_0 = '0';
|
|
||||||
const VK_KEY KeyMsg::NUM_1 = '1';
|
|
||||||
const VK_KEY KeyMsg::NUM_2 = '2';
|
|
||||||
const VK_KEY KeyMsg::NUM_3 = '3';
|
|
||||||
const VK_KEY KeyMsg::NUM_4 = '4';
|
|
||||||
const VK_KEY KeyMsg::NUM_5 = '5';
|
|
||||||
const VK_KEY KeyMsg::NUM_6 = '6';
|
|
||||||
const VK_KEY KeyMsg::NUM_7 = '7';
|
|
||||||
const VK_KEY KeyMsg::NUM_8 = '8';
|
|
||||||
const VK_KEY KeyMsg::NUM_9 = '9';
|
|
||||||
const VK_KEY KeyMsg::NUMPAD_0 = VK_NUMPAD0;
|
|
||||||
const VK_KEY KeyMsg::NUMPAD_1 = VK_NUMPAD1;
|
|
||||||
const VK_KEY KeyMsg::NUMPAD_2 = VK_NUMPAD2;
|
|
||||||
const VK_KEY KeyMsg::NUMPAD_3 = VK_NUMPAD3;
|
|
||||||
const VK_KEY KeyMsg::NUMPAD_4 = VK_NUMPAD4;
|
|
||||||
const VK_KEY KeyMsg::NUMPAD_5 = VK_NUMPAD5;
|
|
||||||
const VK_KEY KeyMsg::NUMPAD_6 = VK_NUMPAD6;
|
|
||||||
const VK_KEY KeyMsg::NUMPAD_7 = VK_NUMPAD7;
|
|
||||||
const VK_KEY KeyMsg::NUMPAD_8 = VK_NUMPAD8;
|
|
||||||
const VK_KEY KeyMsg::NUMPAD_9 = VK_NUMPAD9;
|
|
||||||
const VK_KEY KeyMsg::Enter = VK_RETURN;
|
|
||||||
const VK_KEY KeyMsg::Space = VK_SPACE;
|
|
||||||
const VK_KEY KeyMsg::Ctrl = VK_CONTROL;
|
|
||||||
const VK_KEY KeyMsg::LCtrl = VK_LCONTROL;
|
|
||||||
const VK_KEY KeyMsg::RCtrl = VK_RCONTROL;
|
|
||||||
const VK_KEY KeyMsg::Shift = VK_SHIFT;
|
|
||||||
const VK_KEY KeyMsg::LShift = VK_LSHIFT;
|
|
||||||
const VK_KEY KeyMsg::RShift = VK_RSHIFT;
|
|
||||||
const VK_KEY KeyMsg::Up = VK_UP;
|
|
||||||
const VK_KEY KeyMsg::Down = VK_DOWN;
|
|
||||||
const VK_KEY KeyMsg::Left = VK_LEFT;
|
|
||||||
const VK_KEY KeyMsg::Right = VK_RIGHT;
|
|
||||||
const VK_KEY KeyMsg::Esc = VK_ESCAPE;
|
|
||||||
const VK_KEY KeyMsg::F1 = VK_F1;
|
|
||||||
const VK_KEY KeyMsg::F2 = VK_F2;
|
|
||||||
const VK_KEY KeyMsg::F3 = VK_F3;
|
|
||||||
const VK_KEY KeyMsg::F4 = VK_F4;
|
|
||||||
const VK_KEY KeyMsg::F5 = VK_F5;
|
|
||||||
const VK_KEY KeyMsg::F6 = VK_F6;
|
|
||||||
const VK_KEY KeyMsg::F7 = VK_F7;
|
|
||||||
const VK_KEY KeyMsg::F8 = VK_F8;
|
|
||||||
const VK_KEY KeyMsg::F9 = VK_F9;
|
|
||||||
const VK_KEY KeyMsg::F10 = VK_F10;
|
|
||||||
const VK_KEY KeyMsg::F11 = VK_F11;
|
|
||||||
const VK_KEY KeyMsg::F12 = VK_F12;
|
|
||||||
|
|
||||||
static VK_KEY convert(int ascii);
|
|
||||||
|
|
||||||
KeyMsg::KeyMsg(TString name, const KEY_CALLBACK & callback) :
|
|
||||||
m_sName(name),
|
|
||||||
m_callback(callback),
|
|
||||||
m_pParentScene(nullptr),
|
|
||||||
m_bRunning(true),
|
|
||||||
m_bWaiting(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
KeyMsg::~KeyMsg()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeyMsg::onKbHit(VK_KEY key)
|
|
||||||
{
|
|
||||||
m_callback(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeyMsg::start()
|
|
||||||
{
|
|
||||||
m_bRunning = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeyMsg::stop()
|
|
||||||
{
|
|
||||||
m_bRunning = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeyMsg::wait()
|
|
||||||
{
|
|
||||||
m_bWaiting = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeyMsg::notify()
|
|
||||||
{
|
|
||||||
m_bWaiting = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeyMsg::__exec()
|
|
||||||
{
|
|
||||||
if (_kbhit()) // 检测有无按键消息
|
|
||||||
{
|
|
||||||
VK_KEY key = convert(_getch()); // 获取键盘消息
|
|
||||||
|
|
||||||
for (auto l : s_vListeners) // 分发该消息
|
|
||||||
{
|
|
||||||
if (!l->m_bWaiting && l->m_bRunning)
|
|
||||||
{
|
|
||||||
l->onKbHit(key); // 执行按键回调函数
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeyMsg::addListener(TString name, const KEY_CALLBACK & callback)
|
|
||||||
{
|
|
||||||
// 创建新的监听对象
|
|
||||||
auto listener = new KeyMsg(name, callback);
|
|
||||||
// 绑定在场景上
|
|
||||||
listener->m_pParentScene = EApp::getLoadingScene();
|
|
||||||
// 添加新的按键回调函数
|
|
||||||
s_vListeners.push_back(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeyMsg::startListener(TString name)
|
|
||||||
{
|
|
||||||
// 查找名称相同的监听器
|
|
||||||
for (auto l : s_vListeners)
|
|
||||||
{
|
|
||||||
if (l->m_sName == name && l->m_pParentScene == EApp::getCurrentScene())
|
|
||||||
{
|
|
||||||
l->start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeyMsg::stopListener(TString name)
|
|
||||||
{
|
|
||||||
// 查找名称相同的监听器
|
|
||||||
for (auto l : s_vListeners)
|
|
||||||
{
|
|
||||||
if (l->m_sName == name && l->m_pParentScene == EApp::getCurrentScene())
|
|
||||||
{
|
|
||||||
l->stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeyMsg::delListener(TString name)
|
|
||||||
{
|
|
||||||
// 创建迭代器
|
|
||||||
std::vector<KeyMsg*>::iterator iter;
|
|
||||||
// 循环遍历所有监听器
|
|
||||||
for (iter = s_vListeners.begin(); iter != s_vListeners.end();)
|
|
||||||
{
|
|
||||||
// 查找相同名称的监听器
|
|
||||||
if ((*iter)->m_sName == name && (*iter)->m_pParentScene == EApp::getCurrentScene())
|
|
||||||
{
|
|
||||||
// 删除该定时器
|
|
||||||
delete (*iter);
|
|
||||||
iter = s_vListeners.erase(iter);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeyMsg::notifyAllSceneListeners(EScene * scene)
|
|
||||||
{
|
|
||||||
for (auto l : s_vListeners)
|
|
||||||
{
|
|
||||||
if (l->m_pParentScene == scene)
|
|
||||||
{
|
|
||||||
l->notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeyMsg::waitAllSceneListeners(EScene * scene)
|
|
||||||
{
|
|
||||||
for (auto l : s_vListeners)
|
|
||||||
{
|
|
||||||
if (l->m_pParentScene == scene)
|
|
||||||
{
|
|
||||||
l->wait();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeyMsg::clearAllSceneListeners(EScene * scene)
|
|
||||||
{
|
|
||||||
// 创建迭代器
|
|
||||||
std::vector<KeyMsg*>::iterator iter;
|
|
||||||
// 循环遍历所有监听器
|
|
||||||
for (iter = s_vListeners.begin(); iter != s_vListeners.end();)
|
|
||||||
{
|
|
||||||
// 查找相同名称的监听器
|
|
||||||
if ((*iter)->m_pParentScene == scene)
|
|
||||||
{
|
|
||||||
// 删除该定时器
|
|
||||||
delete (*iter);
|
|
||||||
iter = s_vListeners.erase(iter);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void KeyMsg::clearAllListeners()
|
|
||||||
{
|
|
||||||
// 删除所有监听器
|
|
||||||
for (auto l : s_vListeners)
|
|
||||||
{
|
|
||||||
delete l;
|
|
||||||
}
|
|
||||||
// 清空容器
|
|
||||||
s_vListeners.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool KeyMsg::isKeyDown(VK_KEY key)
|
|
||||||
{
|
|
||||||
// 获取 key 的按下情况
|
|
||||||
return (GetAsyncKeyState(key) & 0x8000);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VK_KEY convert(int ascii)
|
|
||||||
{
|
|
||||||
// 字母键
|
|
||||||
if (ascii >= 'a' && ascii <= 'z')
|
|
||||||
{
|
|
||||||
return VK_KEY(ascii - ('a' - 'A'));
|
|
||||||
}
|
|
||||||
else if (ascii >= 'A' && ascii <= 'Z')
|
|
||||||
{
|
|
||||||
return VK_KEY(ascii);
|
|
||||||
}
|
|
||||||
// 数字键
|
|
||||||
else if (ascii >= '0' && ascii <= '9')
|
|
||||||
{
|
|
||||||
return VK_KEY(ascii);
|
|
||||||
}
|
|
||||||
// 回车、空格、Esc键
|
|
||||||
else if (ascii == 0x0D || ascii == 0x20 || ascii == 0x1B)
|
|
||||||
{
|
|
||||||
return VK_KEY(ascii);
|
|
||||||
}
|
|
||||||
// 功能键
|
|
||||||
else if (ascii == 0 || ascii == 0xE0)
|
|
||||||
{
|
|
||||||
switch (_getch())
|
|
||||||
{
|
|
||||||
case 72:
|
|
||||||
return KeyMsg::Up;
|
|
||||||
case 75:
|
|
||||||
return KeyMsg::Left;
|
|
||||||
case 77:
|
|
||||||
return KeyMsg::Right;
|
|
||||||
case 80:
|
|
||||||
return KeyMsg::Down;
|
|
||||||
case 59:
|
|
||||||
return KeyMsg::F1;
|
|
||||||
case 60:
|
|
||||||
return KeyMsg::F2;
|
|
||||||
case 61:
|
|
||||||
return KeyMsg::F3;
|
|
||||||
case 62:
|
|
||||||
return KeyMsg::F4;
|
|
||||||
case 63:
|
|
||||||
return KeyMsg::F5;
|
|
||||||
case 64:
|
|
||||||
return KeyMsg::F6;
|
|
||||||
case 65:
|
|
||||||
return KeyMsg::F7;
|
|
||||||
case 66:
|
|
||||||
return KeyMsg::F8;
|
|
||||||
case 67:
|
|
||||||
return KeyMsg::F9;
|
|
||||||
case 133:
|
|
||||||
return KeyMsg::F10;
|
|
||||||
case 134:
|
|
||||||
return KeyMsg::F11;
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -1,223 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
#include "..\EasyX\easyx.h"
|
|
||||||
|
|
||||||
// 鼠标监听回调函数的容器
|
|
||||||
static std::vector<MouseMsg*> s_vListeners;
|
|
||||||
|
|
||||||
// 鼠标消息
|
|
||||||
static MOUSEMSG s_mouseMsg;
|
|
||||||
|
|
||||||
void MouseMsg::__exec()
|
|
||||||
{
|
|
||||||
// 获取鼠标消息
|
|
||||||
while (MouseHit())
|
|
||||||
{
|
|
||||||
// 获取鼠标消息
|
|
||||||
s_mouseMsg = GetMouseMsg();
|
|
||||||
// 执行场景程序
|
|
||||||
EApp::get()->getCurrentScene()->_exec();
|
|
||||||
// 执行鼠标监听回调函数
|
|
||||||
for (auto l : s_vListeners) // 循环遍历所有的鼠标监听
|
|
||||||
{
|
|
||||||
if (!l->m_bWaiting && l->m_bRunning)
|
|
||||||
{
|
|
||||||
l->onMouseMsg(); // 执行回调函数
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseMsg::MouseMsg() :
|
|
||||||
m_callback([]() {}),
|
|
||||||
m_pParentScene(nullptr),
|
|
||||||
m_bRunning(true),
|
|
||||||
m_bWaiting(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseMsg::MouseMsg(TString name, const MOUSE_CALLBACK & callback) :
|
|
||||||
m_sName(name),
|
|
||||||
m_callback(callback),
|
|
||||||
m_pParentScene(nullptr),
|
|
||||||
m_bRunning(true),
|
|
||||||
m_bWaiting(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseMsg::~MouseMsg()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseMsg::onMouseMsg()
|
|
||||||
{
|
|
||||||
m_callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseMsg::addListener(TString name, const MOUSE_CALLBACK & callback)
|
|
||||||
{
|
|
||||||
// 创建新的监听对象
|
|
||||||
auto listener = new MouseMsg(name, callback);
|
|
||||||
// 绑定在场景上
|
|
||||||
listener->m_pParentScene = EApp::getLoadingScene();
|
|
||||||
// 添加新的按键回调函数
|
|
||||||
s_vListeners.push_back(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseMsg::startListener(TString name)
|
|
||||||
{
|
|
||||||
// 查找名称相同的监听器
|
|
||||||
for (auto l : s_vListeners)
|
|
||||||
{
|
|
||||||
if (l->m_sName == name && l->m_pParentScene == EApp::getCurrentScene())
|
|
||||||
{
|
|
||||||
l->start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseMsg::stopListener(TString name)
|
|
||||||
{
|
|
||||||
// 查找名称相同的监听器
|
|
||||||
for (auto l : s_vListeners)
|
|
||||||
{
|
|
||||||
if (l->m_sName == name && l->m_pParentScene == EApp::getCurrentScene())
|
|
||||||
{
|
|
||||||
l->stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseMsg::delListener(TString name)
|
|
||||||
{
|
|
||||||
// 创建迭代器
|
|
||||||
std::vector<MouseMsg*>::iterator iter;
|
|
||||||
// 循环遍历所有监听器
|
|
||||||
for (iter = s_vListeners.begin(); iter != s_vListeners.end();)
|
|
||||||
{
|
|
||||||
// 查找相同名称的监听器
|
|
||||||
if ((*iter)->m_sName == name && (*iter)->m_pParentScene == EApp::getCurrentScene())
|
|
||||||
{
|
|
||||||
// 删除该定时器
|
|
||||||
delete (*iter);
|
|
||||||
iter = s_vListeners.erase(iter);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseMsg::start()
|
|
||||||
{
|
|
||||||
m_bRunning = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseMsg::stop()
|
|
||||||
{
|
|
||||||
m_bRunning = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseMsg::wait()
|
|
||||||
{
|
|
||||||
m_bWaiting = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseMsg::notify()
|
|
||||||
{
|
|
||||||
m_bWaiting = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseMsg::clearAllListeners()
|
|
||||||
{
|
|
||||||
// 删除所有监听器
|
|
||||||
for (auto l : s_vListeners)
|
|
||||||
{
|
|
||||||
delete l;
|
|
||||||
}
|
|
||||||
// 清空容器
|
|
||||||
s_vListeners.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseMsg::notifyAllSceneListeners(EScene * scene)
|
|
||||||
{
|
|
||||||
for (auto l : s_vListeners)
|
|
||||||
{
|
|
||||||
if (l->m_pParentScene == scene)
|
|
||||||
{
|
|
||||||
l->notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseMsg::waitAllSceneListeners(EScene * scene)
|
|
||||||
{
|
|
||||||
for (auto l : s_vListeners)
|
|
||||||
{
|
|
||||||
if (l->m_pParentScene == scene)
|
|
||||||
{
|
|
||||||
l->wait();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseMsg::clearAllSceneListeners(EScene * scene)
|
|
||||||
{
|
|
||||||
// 创建迭代器
|
|
||||||
std::vector<MouseMsg*>::iterator iter;
|
|
||||||
// 循环遍历所有监听器
|
|
||||||
for (iter = s_vListeners.begin(); iter != s_vListeners.end();)
|
|
||||||
{
|
|
||||||
// 查找相同名称的监听器
|
|
||||||
if ((*iter)->m_pParentScene == scene)
|
|
||||||
{
|
|
||||||
// 删除该定时器
|
|
||||||
delete (*iter);
|
|
||||||
iter = s_vListeners.erase(iter);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MouseMsg::isLButtonDown()
|
|
||||||
{
|
|
||||||
return s_mouseMsg.mkLButton;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MouseMsg::isRButtonDown()
|
|
||||||
{
|
|
||||||
return s_mouseMsg.mkRButton;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MouseMsg::isMButtonDown()
|
|
||||||
{
|
|
||||||
return s_mouseMsg.mkMButton;
|
|
||||||
}
|
|
||||||
|
|
||||||
int MouseMsg::getX()
|
|
||||||
{
|
|
||||||
return s_mouseMsg.x;
|
|
||||||
}
|
|
||||||
|
|
||||||
int MouseMsg::getY()
|
|
||||||
{
|
|
||||||
return s_mouseMsg.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
CPoint MouseMsg::getPos()
|
|
||||||
{
|
|
||||||
return CPoint(s_mouseMsg.x, s_mouseMsg.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
int MouseMsg::getWheel()
|
|
||||||
{
|
|
||||||
return s_mouseMsg.wheel;
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseMsg::MESSAGE MouseMsg::getMsg()
|
|
||||||
{
|
|
||||||
return MESSAGE(s_mouseMsg.uMsg);
|
|
||||||
}
|
|
||||||
|
|
@ -1,190 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
#include "..\EasyX\easyx.h"
|
|
||||||
|
|
||||||
BatchNode::BatchNode()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BatchNode::~BatchNode()
|
|
||||||
{
|
|
||||||
clearAllChildren();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BatchNode::_exec(bool active)
|
|
||||||
{
|
|
||||||
// 批量节点是否显示
|
|
||||||
if (!m_bDisplay)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// 逆序遍历所有子节点
|
|
||||||
for (int i = int(m_vChildren.size() - 1); i >= 0; i--)
|
|
||||||
{
|
|
||||||
if (m_vChildren[i]->_exec(active))
|
|
||||||
{
|
|
||||||
active = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 若子节点取得了画面焦点,则该节点也取得了焦点
|
|
||||||
return !active;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BatchNode::_onDraw()
|
|
||||||
{
|
|
||||||
// 节点是否显示
|
|
||||||
if (!m_bDisplay)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto child : m_vChildren)
|
|
||||||
{
|
|
||||||
// 绘制子节点
|
|
||||||
child->_onDraw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BatchNode::add(Node * child, int z_Order)
|
|
||||||
{
|
|
||||||
if (child == nullptr) return;
|
|
||||||
|
|
||||||
// 设置节点的父场景
|
|
||||||
child->setParentScene(this->getParentScene());
|
|
||||||
// 设置节点在批量节点中的 z 轴顺序
|
|
||||||
child->setZOrder(z_Order);
|
|
||||||
// 对象的引用计数加一
|
|
||||||
child->retain();
|
|
||||||
// 修改子节点位置
|
|
||||||
child->move(getPos());
|
|
||||||
|
|
||||||
// 按 z 轴顺序插入节点
|
|
||||||
size_t size = m_vChildren.size();
|
|
||||||
for (unsigned i = 0; i <= size; i++)
|
|
||||||
{
|
|
||||||
if (i != size)
|
|
||||||
{
|
|
||||||
if (z_Order < m_vChildren.at(i)->getZOrder())
|
|
||||||
{
|
|
||||||
m_vChildren.insert(m_vChildren.begin() + i, child);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_vChildren.push_back(child);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BatchNode::del(Node * child)
|
|
||||||
{
|
|
||||||
if (child == nullptr) return false;
|
|
||||||
|
|
||||||
// 寻找是否有相同节点
|
|
||||||
std::vector<Node*>::iterator iter;
|
|
||||||
for (iter = m_vChildren.begin(); iter != m_vChildren.end(); iter++)
|
|
||||||
{
|
|
||||||
// 找到相同节点
|
|
||||||
if ((*iter) == child)
|
|
||||||
{
|
|
||||||
// 对象的引用计数减一
|
|
||||||
(*iter)->release();
|
|
||||||
// 去掉该节点
|
|
||||||
m_vChildren.erase(iter);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int BatchNode::getCount()
|
|
||||||
{
|
|
||||||
return (int)m_vChildren.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Node*>& BatchNode::getChildren()
|
|
||||||
{
|
|
||||||
return m_vChildren;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BatchNode::clearAllChildren()
|
|
||||||
{
|
|
||||||
// 所有节点的引用计数减一
|
|
||||||
for (auto child : m_vChildren)
|
|
||||||
{
|
|
||||||
child->autoRelease();
|
|
||||||
child->release();
|
|
||||||
}
|
|
||||||
// 清空储存节点的容器
|
|
||||||
m_vChildren.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void BatchNode::setX(int x)
|
|
||||||
{
|
|
||||||
// 计算相对移动位置
|
|
||||||
int var = x - getX();
|
|
||||||
// 移动所有子节点的位置
|
|
||||||
for (auto child : m_vChildren)
|
|
||||||
{
|
|
||||||
child->move(var, 0);
|
|
||||||
}
|
|
||||||
Node::setX(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BatchNode::setY(int y)
|
|
||||||
{
|
|
||||||
// 计算相对移动位置
|
|
||||||
int var = y - getY();
|
|
||||||
// 移动所有子节点的位置
|
|
||||||
for (auto child : m_vChildren)
|
|
||||||
{
|
|
||||||
child->move(0, var);
|
|
||||||
}
|
|
||||||
Node::setY(y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BatchNode::setPos(int x, int y)
|
|
||||||
{
|
|
||||||
// 计算相对移动位置
|
|
||||||
CPoint var(x - getX(), y - getY());
|
|
||||||
// 移动所有子节点的位置
|
|
||||||
for (auto child : m_vChildren)
|
|
||||||
{
|
|
||||||
child->move(var);
|
|
||||||
}
|
|
||||||
Node::setPos(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BatchNode::setPos(CPoint p)
|
|
||||||
{
|
|
||||||
// 计算相对移动位置
|
|
||||||
CPoint var(p - getPos());
|
|
||||||
// 移动所有子节点的位置
|
|
||||||
for (auto child : m_vChildren)
|
|
||||||
{
|
|
||||||
child->move(var);
|
|
||||||
}
|
|
||||||
Node::setPos(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BatchNode::move(int x, int y)
|
|
||||||
{
|
|
||||||
// 移动所有子节点的位置
|
|
||||||
for (auto child : m_vChildren)
|
|
||||||
{
|
|
||||||
child->move(x, y);
|
|
||||||
}
|
|
||||||
Node::move(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BatchNode::move(CVector v)
|
|
||||||
{
|
|
||||||
// 移动所有子节点的位置
|
|
||||||
for (auto child : m_vChildren)
|
|
||||||
{
|
|
||||||
child->move(v);
|
|
||||||
}
|
|
||||||
Node::move(v);
|
|
||||||
}
|
|
||||||
|
|
@ -1,260 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
|
|
||||||
BatchSprite::BatchSprite()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
BatchSprite::~BatchSprite()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void BatchSprite::addSprite(Sprite * sprite, int z_Order)
|
|
||||||
{
|
|
||||||
if (sprite == nullptr) return;
|
|
||||||
|
|
||||||
// 设置节点的父场景
|
|
||||||
sprite->setParentScene(this->getParentScene());
|
|
||||||
// 设置节点在批量节点中的 z 轴顺序
|
|
||||||
sprite->setZOrder(z_Order);
|
|
||||||
// 对象的引用计数加一
|
|
||||||
sprite->retain();
|
|
||||||
|
|
||||||
// 按 z 轴顺序插入节点
|
|
||||||
size_t size = m_vSprites.size();
|
|
||||||
for (unsigned i = 0; i <= size; i++)
|
|
||||||
{
|
|
||||||
if (i != size)
|
|
||||||
{
|
|
||||||
if (z_Order < m_vSprites.at(i)->getZOrder())
|
|
||||||
{
|
|
||||||
m_vSprites.insert(m_vSprites.begin() + i, sprite);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_vSprites.push_back(sprite);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BatchSprite::delSprite(Sprite * sprite)
|
|
||||||
{
|
|
||||||
if (sprite == nullptr) return false;
|
|
||||||
|
|
||||||
// 寻找是否有相同节点
|
|
||||||
std::vector<Sprite*>::iterator iter;
|
|
||||||
for (iter = m_vSprites.begin(); iter != m_vSprites.end(); iter++)
|
|
||||||
{
|
|
||||||
// 找到相同节点
|
|
||||||
if ((*iter) == sprite)
|
|
||||||
{
|
|
||||||
// 对象的引用计数减一
|
|
||||||
(*iter)->release();
|
|
||||||
// 去掉该节点
|
|
||||||
m_vSprites.erase(iter);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int BatchSprite::getCount()
|
|
||||||
{
|
|
||||||
return (int)m_vSprites.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<Sprite*>& BatchSprite::getChildren()
|
|
||||||
{
|
|
||||||
return m_vSprites;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BatchSprite::clearAllSprites()
|
|
||||||
{
|
|
||||||
// 所有节点的引用计数减一
|
|
||||||
for (auto s : m_vSprites)
|
|
||||||
{
|
|
||||||
s->release();
|
|
||||||
}
|
|
||||||
// 清空储存节点的容器
|
|
||||||
m_vSprites.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BatchSprite::_exec(bool active)
|
|
||||||
{
|
|
||||||
// 批量节点是否显示
|
|
||||||
if (!m_bDisplay)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// 逆序遍历所有子节点
|
|
||||||
for (int i = int(m_vSprites.size() - 1); i >= 0; i--)
|
|
||||||
{
|
|
||||||
if (m_vSprites[i]->_exec(active))
|
|
||||||
{
|
|
||||||
active = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 若子节点取得了画面焦点,则该节点也取得了焦点
|
|
||||||
return !active;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BatchSprite::_onDraw()
|
|
||||||
{
|
|
||||||
// 节点是否显示
|
|
||||||
if (!m_bDisplay)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 在相对位置绘制子节点
|
|
||||||
for (auto sprite : m_vSprites)
|
|
||||||
{
|
|
||||||
// 将子节点移动到相对位置
|
|
||||||
sprite->move(getX(), getY());
|
|
||||||
// 绘制子节点
|
|
||||||
sprite->_onDraw();
|
|
||||||
// 将子节点移回原位
|
|
||||||
sprite->move(-getX(), -getY());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Sprite * BatchSprite::isCollisionWith(Sprite * sprite)
|
|
||||||
{
|
|
||||||
for (int i = int(m_vSprites.size() - 1); i >= 0; i--)
|
|
||||||
{
|
|
||||||
if (m_vSprites[i]->isCollisionWith(sprite))
|
|
||||||
{
|
|
||||||
return m_vSprites[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Sprite * BatchSprite::isPointIn(CPoint point)
|
|
||||||
{
|
|
||||||
for (int i = int(m_vSprites.size() - 1); i >= 0; i--)
|
|
||||||
{
|
|
||||||
if (m_vSprites[i]->isPointIn(point))
|
|
||||||
{
|
|
||||||
return m_vSprites[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BatchSprite::addAction(Action * action)
|
|
||||||
{
|
|
||||||
Sprite::addAction(action);
|
|
||||||
}
|
|
||||||
|
|
||||||
float BatchSprite::getScaleX() const
|
|
||||||
{
|
|
||||||
return m_fScaleX;
|
|
||||||
}
|
|
||||||
|
|
||||||
float BatchSprite::getScaleY() const
|
|
||||||
{
|
|
||||||
return m_fScaleY;
|
|
||||||
}
|
|
||||||
|
|
||||||
float BatchSprite::getOpacity() const
|
|
||||||
{
|
|
||||||
return m_nAlpha / 255.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BatchSprite::setScale(float scaleX, float scaleY)
|
|
||||||
{
|
|
||||||
m_fScaleX = scaleX;
|
|
||||||
m_fScaleY = scaleY;
|
|
||||||
for (auto s : m_vSprites)
|
|
||||||
{
|
|
||||||
s->setScale(scaleX, scaleY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BatchSprite::setOpacity(float opacity)
|
|
||||||
{
|
|
||||||
m_nAlpha = BYTE(min(max(opacity, 0), 1) * 255);
|
|
||||||
for (auto s : m_vSprites)
|
|
||||||
{
|
|
||||||
s->setOpacity(opacity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BatchSprite::setImage(Image * image)
|
|
||||||
{
|
|
||||||
for (auto s : m_vSprites)
|
|
||||||
{
|
|
||||||
s->setImage(image);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BatchSprite::setX(int x)
|
|
||||||
{
|
|
||||||
// 计算相对移动位置
|
|
||||||
int var = x - getX();
|
|
||||||
// 移动所有子节点的位置
|
|
||||||
for (auto s : m_vSprites)
|
|
||||||
{
|
|
||||||
s->move(var, 0);
|
|
||||||
}
|
|
||||||
RectNode::setX(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BatchSprite::setY(int y)
|
|
||||||
{
|
|
||||||
// 计算相对移动位置
|
|
||||||
int var = y - getY();
|
|
||||||
// 移动所有子节点的位置
|
|
||||||
for (auto s : m_vSprites)
|
|
||||||
{
|
|
||||||
s->move(0, var);
|
|
||||||
}
|
|
||||||
RectNode::setY(y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BatchSprite::setPos(int x, int y)
|
|
||||||
{
|
|
||||||
// 计算相对移动位置
|
|
||||||
CPoint var(x - getX(), y - getY());
|
|
||||||
// 移动所有子节点的位置
|
|
||||||
for (auto s : m_vSprites)
|
|
||||||
{
|
|
||||||
s->move(var);
|
|
||||||
}
|
|
||||||
RectNode::setPos(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BatchSprite::setPos(CPoint p)
|
|
||||||
{
|
|
||||||
// 计算相对移动位置
|
|
||||||
CPoint var(p - getPos());
|
|
||||||
// 移动所有子节点的位置
|
|
||||||
for (auto s : m_vSprites)
|
|
||||||
{
|
|
||||||
s->move(var);
|
|
||||||
}
|
|
||||||
RectNode::setPos(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BatchSprite::move(int x, int y)
|
|
||||||
{
|
|
||||||
// 移动所有子节点的位置
|
|
||||||
for (auto s : m_vSprites)
|
|
||||||
{
|
|
||||||
s->move(x, y);
|
|
||||||
}
|
|
||||||
RectNode::move(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BatchSprite::move(CVector v)
|
|
||||||
{
|
|
||||||
// 移动所有子节点的位置
|
|
||||||
for (auto s : m_vSprites)
|
|
||||||
{
|
|
||||||
s->move(v);
|
|
||||||
}
|
|
||||||
RectNode::move(v);
|
|
||||||
}
|
|
||||||
|
|
@ -1,80 +0,0 @@
|
||||||
#include "..\..\easy2d.h"
|
|
||||||
#include "..\..\EasyX\easyx.h"
|
|
||||||
|
|
||||||
|
|
||||||
Button::Button() :
|
|
||||||
m_bEnable(true)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Button::~Button()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Button::_exec(bool active)
|
|
||||||
{
|
|
||||||
// 按钮是否启用
|
|
||||||
if (!m_bEnable)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return MouseNode::_exec(active);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Button::_onDraw()
|
|
||||||
{
|
|
||||||
// 按钮是否启用
|
|
||||||
if (!m_bEnable)
|
|
||||||
{
|
|
||||||
// 未启用时,绘制 Disable 状态
|
|
||||||
_onDisable();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
MouseNode::_onDraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Button::isEnable()
|
|
||||||
{
|
|
||||||
return m_bEnable;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Button::setEnable(bool enable)
|
|
||||||
{
|
|
||||||
m_bEnable = enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Button::setX(int x)
|
|
||||||
{
|
|
||||||
MouseNode::setX(x);
|
|
||||||
_resetPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Button::setY(int y)
|
|
||||||
{
|
|
||||||
MouseNode::setY(y);
|
|
||||||
_resetPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Button::setPos(int x, int y)
|
|
||||||
{
|
|
||||||
MouseNode::setPos(x, y);
|
|
||||||
_resetPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Button::setPos(CPoint p)
|
|
||||||
{
|
|
||||||
MouseNode::setPos(p);
|
|
||||||
_resetPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Button::move(int x, int y)
|
|
||||||
{
|
|
||||||
MouseNode::move(x, y);
|
|
||||||
_resetPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Button::move(CVector v)
|
|
||||||
{
|
|
||||||
MouseNode::move(v);
|
|
||||||
_resetPosition();
|
|
||||||
}
|
|
||||||
|
|
@ -1,172 +0,0 @@
|
||||||
#include "..\..\easy2d.h"
|
|
||||||
|
|
||||||
|
|
||||||
ImageButton::ImageButton() :
|
|
||||||
m_pNormalImage(nullptr),
|
|
||||||
m_pMouseInImage(nullptr),
|
|
||||||
m_pSelectedImage(nullptr),
|
|
||||||
m_pUnableImage(nullptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageButton::ImageButton(LPCTSTR image) :
|
|
||||||
ImageButton()
|
|
||||||
{
|
|
||||||
setNormal(new Image(image)); // 设置按钮在正常状态时的图片
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageButton::ImageButton(Image * image) :
|
|
||||||
ImageButton()
|
|
||||||
{
|
|
||||||
setNormal(image); // 设置按钮在正常状态时的图片
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageButton::~ImageButton()
|
|
||||||
{
|
|
||||||
// 所有图片的引用计数减一
|
|
||||||
SafeRelease(m_pNormalImage);
|
|
||||||
SafeRelease(m_pMouseInImage);
|
|
||||||
SafeRelease(m_pSelectedImage);
|
|
||||||
SafeRelease(m_pUnableImage);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageButton::_setStatus(Status status)
|
|
||||||
{
|
|
||||||
if (m_eStatus != status)
|
|
||||||
{
|
|
||||||
if (status == MOUSEIN)
|
|
||||||
{
|
|
||||||
if (m_pMouseInImage) setRect(m_pMouseInImage->getRect());
|
|
||||||
}
|
|
||||||
else if (status == SELECTED)
|
|
||||||
{
|
|
||||||
if (m_pSelectedImage) setRect(m_pSelectedImage->getRect());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
setRect(m_pNormalImage->getRect());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MouseNode::_setStatus(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageButton::_onNormal()
|
|
||||||
{
|
|
||||||
if (m_pNormalImage)
|
|
||||||
{
|
|
||||||
m_pNormalImage->_onDraw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageButton::_onMouseIn()
|
|
||||||
{
|
|
||||||
if (m_pMouseInImage)
|
|
||||||
{
|
|
||||||
m_pMouseInImage->_onDraw();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_onNormal();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageButton::_onSelected()
|
|
||||||
{
|
|
||||||
if (m_pSelectedImage)
|
|
||||||
{
|
|
||||||
m_pSelectedImage->_onDraw();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_onNormal();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageButton::_onDisable()
|
|
||||||
{
|
|
||||||
if (m_pUnableImage)
|
|
||||||
{
|
|
||||||
m_pUnableImage->_onDraw();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_onNormal();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageButton::setNormal(Image * image)
|
|
||||||
{
|
|
||||||
if (image)
|
|
||||||
{
|
|
||||||
// 原图片引用计数减一
|
|
||||||
SafeRelease(m_pNormalImage);
|
|
||||||
// 修改图片
|
|
||||||
m_pNormalImage = image;
|
|
||||||
// 现图片引用计数加一
|
|
||||||
m_pNormalImage->retain();
|
|
||||||
// 根据图片宽高设定按钮大小
|
|
||||||
setSize(m_pNormalImage->getSize());
|
|
||||||
// 重新计算图片位置
|
|
||||||
_resetPosition();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageButton::setMouseIn(Image * image)
|
|
||||||
{
|
|
||||||
if (image)
|
|
||||||
{
|
|
||||||
SafeRelease(m_pMouseInImage);
|
|
||||||
m_pMouseInImage = image;
|
|
||||||
m_pMouseInImage->retain();
|
|
||||||
_resetPosition();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageButton::setSelected(Image * image)
|
|
||||||
{
|
|
||||||
if (image)
|
|
||||||
{
|
|
||||||
SafeRelease(m_pSelectedImage);
|
|
||||||
m_pSelectedImage = image;
|
|
||||||
m_pSelectedImage->retain();
|
|
||||||
_resetPosition();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageButton::setUnable(Image * image)
|
|
||||||
{
|
|
||||||
if (image)
|
|
||||||
{
|
|
||||||
SafeRelease(m_pUnableImage);
|
|
||||||
m_pUnableImage = image;
|
|
||||||
m_pUnableImage->retain();
|
|
||||||
_resetPosition();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageButton::_resetPosition()
|
|
||||||
{
|
|
||||||
if (m_pNormalImage)
|
|
||||||
{
|
|
||||||
// 根据按钮位置和图片宽高设置图片位置居中显示
|
|
||||||
m_pNormalImage->setPos(getX(), getY());
|
|
||||||
}
|
|
||||||
if (m_pMouseInImage)
|
|
||||||
{
|
|
||||||
m_pMouseInImage->setPos(
|
|
||||||
getX() + (getWidth() - m_pMouseInImage->getWidth()) / 2,
|
|
||||||
getY() + (getHeight() - m_pMouseInImage->getHeight()) / 2);
|
|
||||||
}
|
|
||||||
if (m_pSelectedImage)
|
|
||||||
{
|
|
||||||
m_pSelectedImage->setPos(
|
|
||||||
getX() + (getWidth() - m_pSelectedImage->getWidth()) / 2,
|
|
||||||
getY() + (getHeight() - m_pSelectedImage->getHeight()) / 2);
|
|
||||||
}
|
|
||||||
if (m_pUnableImage)
|
|
||||||
{
|
|
||||||
m_pUnableImage->setPos(
|
|
||||||
getX() + (getWidth() - m_pUnableImage->getWidth()) / 2,
|
|
||||||
getY() + (getHeight() - m_pUnableImage->getHeight()) / 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,172 +0,0 @@
|
||||||
#include "..\..\easy2d.h"
|
|
||||||
|
|
||||||
|
|
||||||
TextButton::TextButton() :
|
|
||||||
m_pNormalText(nullptr),
|
|
||||||
m_pMouseInText(nullptr),
|
|
||||||
m_pSelectedText(nullptr),
|
|
||||||
m_pUnableText(nullptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
TextButton::TextButton(TString text) :
|
|
||||||
TextButton()
|
|
||||||
{
|
|
||||||
setNormal(new Text(text)); // 设置按钮在正常状态时的文字
|
|
||||||
}
|
|
||||||
|
|
||||||
TextButton::TextButton(Text * text) :
|
|
||||||
TextButton()
|
|
||||||
{
|
|
||||||
setNormal(text); // 设置按钮在正常状态时的文字
|
|
||||||
}
|
|
||||||
|
|
||||||
TextButton::~TextButton()
|
|
||||||
{
|
|
||||||
// 所有文本的引用计数减一
|
|
||||||
SafeRelease(m_pNormalText);
|
|
||||||
SafeRelease(m_pMouseInText);
|
|
||||||
SafeRelease(m_pSelectedText);
|
|
||||||
SafeRelease(m_pUnableText);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextButton::_setStatus(Status status)
|
|
||||||
{
|
|
||||||
if (m_eStatus != status)
|
|
||||||
{
|
|
||||||
if (status == MOUSEIN)
|
|
||||||
{
|
|
||||||
if (m_pMouseInText) setRect(m_pMouseInText->getRect());
|
|
||||||
}
|
|
||||||
else if (status == SELECTED)
|
|
||||||
{
|
|
||||||
if (m_pSelectedText) setRect(m_pSelectedText->getRect());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
setRect(m_pNormalText->getRect());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MouseNode::_setStatus(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextButton::_onNormal()
|
|
||||||
{
|
|
||||||
if (m_pNormalText)
|
|
||||||
{
|
|
||||||
m_pNormalText->_onDraw();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextButton::_onMouseIn()
|
|
||||||
{
|
|
||||||
if (m_pMouseInText)
|
|
||||||
{
|
|
||||||
m_pMouseInText->_onDraw();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_onNormal();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextButton::_onSelected()
|
|
||||||
{
|
|
||||||
if (m_pSelectedText)
|
|
||||||
{
|
|
||||||
m_pSelectedText->_onDraw();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_onNormal();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextButton::_onDisable()
|
|
||||||
{
|
|
||||||
if (m_pUnableText)
|
|
||||||
{
|
|
||||||
m_pUnableText->_onDraw();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_onNormal();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextButton::setNormal(Text * text)
|
|
||||||
{
|
|
||||||
if (text)
|
|
||||||
{
|
|
||||||
// 原文本引用计数减一
|
|
||||||
SafeRelease(m_pNormalText);
|
|
||||||
// 修改文本
|
|
||||||
m_pNormalText = text;
|
|
||||||
// 现文本引用计数加一
|
|
||||||
m_pNormalText->retain();
|
|
||||||
// 根据文字宽高设定按钮大小
|
|
||||||
setSize(m_pNormalText->getSize());
|
|
||||||
// 重新计算文本位置
|
|
||||||
_resetPosition();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextButton::setMouseIn(Text * text)
|
|
||||||
{
|
|
||||||
if (text)
|
|
||||||
{
|
|
||||||
SafeRelease(m_pMouseInText);
|
|
||||||
m_pMouseInText = text;
|
|
||||||
m_pMouseInText->retain();
|
|
||||||
_resetPosition();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextButton::setSelected(Text * text)
|
|
||||||
{
|
|
||||||
if (text)
|
|
||||||
{
|
|
||||||
SafeRelease(m_pSelectedText);
|
|
||||||
m_pSelectedText = text;
|
|
||||||
m_pSelectedText->retain();
|
|
||||||
_resetPosition();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextButton::setUnable(Text * text)
|
|
||||||
{
|
|
||||||
if (text)
|
|
||||||
{
|
|
||||||
SafeRelease(m_pUnableText);
|
|
||||||
m_pUnableText = text;
|
|
||||||
m_pUnableText->retain();
|
|
||||||
_resetPosition();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextButton::_resetPosition()
|
|
||||||
{
|
|
||||||
if (m_pNormalText)
|
|
||||||
{
|
|
||||||
// 根据按钮位置和文字宽高设置文字位置居中显示
|
|
||||||
m_pNormalText->setPos(getX() , getY());
|
|
||||||
}
|
|
||||||
if (m_pMouseInText)
|
|
||||||
{
|
|
||||||
m_pMouseInText->setPos(
|
|
||||||
getX() + (getWidth() - m_pMouseInText->getWidth()) / 2,
|
|
||||||
getY() + (getHeight() - m_pMouseInText->getHeight()) / 2);
|
|
||||||
}
|
|
||||||
if (m_pSelectedText)
|
|
||||||
{
|
|
||||||
m_pSelectedText->setPos(
|
|
||||||
getX() + (getWidth() - m_pSelectedText->getWidth()) / 2,
|
|
||||||
getY() + (getHeight() - m_pSelectedText->getHeight()) / 2);
|
|
||||||
}
|
|
||||||
if (m_pUnableText)
|
|
||||||
{
|
|
||||||
m_pUnableText->setPos(
|
|
||||||
getX() + (getWidth() - m_pUnableText->getWidth()) / 2,
|
|
||||||
getY() + (getHeight() - m_pUnableText->getHeight()) / 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,199 +0,0 @@
|
||||||
#include "..\enodes.h"
|
|
||||||
#include "..\Win\winbase.h"
|
|
||||||
|
|
||||||
e2d::ENode::ENode()
|
|
||||||
: m_nZOrder(0)
|
|
||||||
, m_bVisiable(true)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
e2d::ENode::ENode(EPoint p)
|
|
||||||
: ENode()
|
|
||||||
{
|
|
||||||
setPos(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
e2d::ENode::ENode(int x, int y)
|
|
||||||
: ENode()
|
|
||||||
{
|
|
||||||
setPos(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
e2d::ENode::~ENode()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool e2d::ENode::_exec(bool active)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void e2d::ENode::_onDraw()
|
|
||||||
{
|
|
||||||
D2D1_RECT_F rectangle = D2D1::RectF(
|
|
||||||
m_Rect.left,
|
|
||||||
m_Rect.top,
|
|
||||||
m_Rect.right,
|
|
||||||
m_Rect.bottom
|
|
||||||
);
|
|
||||||
ID2D1SolidColorBrush* m_pLightSlateGrayBrush;
|
|
||||||
GetRenderTarget()->CreateSolidColorBrush(
|
|
||||||
D2D1::ColorF(D2D1::ColorF::LightSlateGray),
|
|
||||||
&m_pLightSlateGrayBrush
|
|
||||||
);
|
|
||||||
GetRenderTarget()->FillRectangle(&rectangle, m_pLightSlateGrayBrush);
|
|
||||||
}
|
|
||||||
|
|
||||||
int e2d::ENode::getX() const
|
|
||||||
{
|
|
||||||
if (m_pParent)
|
|
||||||
{
|
|
||||||
return m_pParent->getX() + m_Rect.TopLeft().x;
|
|
||||||
}
|
|
||||||
return m_Rect.TopLeft().x;
|
|
||||||
}
|
|
||||||
|
|
||||||
int e2d::ENode::getY() const
|
|
||||||
{
|
|
||||||
if (m_pParent)
|
|
||||||
{
|
|
||||||
return m_pParent->getY() + m_Rect.TopLeft().y;
|
|
||||||
}
|
|
||||||
return m_Rect.TopLeft().y;
|
|
||||||
}
|
|
||||||
|
|
||||||
CPoint e2d::ENode::getPos() const
|
|
||||||
{
|
|
||||||
if (m_pParent)
|
|
||||||
{
|
|
||||||
return m_pParent->getPos() + m_Rect.TopLeft();
|
|
||||||
}
|
|
||||||
return m_Rect.TopLeft();
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT32 e2d::ENode::getWidth() const
|
|
||||||
{
|
|
||||||
return UINT32(m_Rect.Size().cx);
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT32 e2d::ENode::getHeight() const
|
|
||||||
{
|
|
||||||
return UINT32(m_Rect.Size().cy);
|
|
||||||
}
|
|
||||||
|
|
||||||
e2d::ESize e2d::ENode::getSize() const
|
|
||||||
{
|
|
||||||
return e2d::ESize(m_Rect.Size());
|
|
||||||
}
|
|
||||||
|
|
||||||
e2d::ERect e2d::ENode::getRect() const
|
|
||||||
{
|
|
||||||
return e2d::ERect(m_Rect);
|
|
||||||
}
|
|
||||||
|
|
||||||
void e2d::ENode::setX(int x)
|
|
||||||
{
|
|
||||||
m_Rect.TopLeft().x = x;
|
|
||||||
}
|
|
||||||
|
|
||||||
void e2d::ENode::setY(int y)
|
|
||||||
{
|
|
||||||
m_Rect.TopLeft().y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
void e2d::ENode::setPos(int x, int y)
|
|
||||||
{
|
|
||||||
m_Rect.TopLeft().SetPoint(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void e2d::ENode::setPos(EPoint p)
|
|
||||||
{
|
|
||||||
m_Rect.TopLeft() = p;
|
|
||||||
}
|
|
||||||
|
|
||||||
void e2d::ENode::move(int x, int y)
|
|
||||||
{
|
|
||||||
m_Rect.OffsetRect(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void e2d::ENode::move(EVector v)
|
|
||||||
{
|
|
||||||
m_Rect.OffsetRect(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
void e2d::ENode::setWidth(UINT32 width)
|
|
||||||
{
|
|
||||||
m_Rect.BottomRight().x = m_Rect.TopLeft().x + width;
|
|
||||||
}
|
|
||||||
|
|
||||||
void e2d::ENode::setHeight(UINT32 height)
|
|
||||||
{
|
|
||||||
m_Rect.BottomRight().y = m_Rect.TopLeft().y + height;
|
|
||||||
}
|
|
||||||
|
|
||||||
void e2d::ENode::setSize(UINT32 width, UINT32 height)
|
|
||||||
{
|
|
||||||
setWidth(width);
|
|
||||||
setHeight(height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void e2d::ENode::setSize(e2d::ESize size)
|
|
||||||
{
|
|
||||||
setSize(size.cx, size.cy);
|
|
||||||
}
|
|
||||||
|
|
||||||
void e2d::ENode::setRect(int x1, int y1, int x2, int y2)
|
|
||||||
{
|
|
||||||
m_Rect.SetRect(x1, y1, x2, y2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void e2d::ENode::setRect(EPoint leftTop, EPoint rightBottom)
|
|
||||||
{
|
|
||||||
m_Rect.TopLeft() = leftTop;
|
|
||||||
m_Rect.BottomRight() = rightBottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
void e2d::ENode::setRect(e2d::ERect rect)
|
|
||||||
{
|
|
||||||
m_Rect = rect;
|
|
||||||
}
|
|
||||||
|
|
||||||
int e2d::ENode::getZOrder() const
|
|
||||||
{
|
|
||||||
return m_nZOrder;
|
|
||||||
}
|
|
||||||
|
|
||||||
void e2d::ENode::setZOrder(int z)
|
|
||||||
{
|
|
||||||
m_nZOrder = z;
|
|
||||||
}
|
|
||||||
|
|
||||||
void e2d::ENode::setParent(e2d::ENode * parent)
|
|
||||||
{
|
|
||||||
m_pParent = parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
e2d::ENode *& e2d::ENode::getParent()
|
|
||||||
{
|
|
||||||
return m_pParent;
|
|
||||||
}
|
|
||||||
|
|
||||||
e2d::EScene * &e2d::ENode::getParentScene()
|
|
||||||
{
|
|
||||||
return m_pParentScene;
|
|
||||||
}
|
|
||||||
|
|
||||||
void e2d::ENode::setParentScene(e2d::EScene * scene)
|
|
||||||
{
|
|
||||||
m_pParentScene = scene;
|
|
||||||
}
|
|
||||||
|
|
||||||
void e2d::ENode::setVisiable(bool value)
|
|
||||||
{
|
|
||||||
m_bVisiable = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool e2d::ENode::isVisiable() const
|
|
||||||
{
|
|
||||||
return m_bVisiable;
|
|
||||||
}
|
|
||||||
|
|
@ -1,251 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
#include "..\EasyX\easyx.h"
|
|
||||||
#include <map>
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
// 图片缓存
|
|
||||||
static map<TString, CImage*> s_mCImages;
|
|
||||||
// 从图片缓存中读取图片
|
|
||||||
static CImage* GetCImage(TString name, bool fromRes = false);
|
|
||||||
// 对 PNG 图像进行像素转换
|
|
||||||
static void CrossImage(CImage &img);
|
|
||||||
|
|
||||||
|
|
||||||
Image::Image() :
|
|
||||||
m_pCImage(nullptr),
|
|
||||||
m_nAlpha(255),
|
|
||||||
m_fScaleX(1),
|
|
||||||
m_fScaleY(1)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Image::Image(LPCTSTR ImageFile) :
|
|
||||||
Image()
|
|
||||||
{
|
|
||||||
setImage(ImageFile); // 设置图片资源
|
|
||||||
}
|
|
||||||
|
|
||||||
Image::Image(LPCTSTR ImageFile, int x, int y, int width, int height) :
|
|
||||||
Image()
|
|
||||||
{
|
|
||||||
setImage(ImageFile, x, y, width, height); // 设置图片资源和裁剪大小
|
|
||||||
}
|
|
||||||
|
|
||||||
Image::~Image()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Image::_onDraw()
|
|
||||||
{
|
|
||||||
// display 属性为 false,或未设置图片资源时,不绘制该图片
|
|
||||||
if (!m_bDisplay || !m_pCImage)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 绘制图片
|
|
||||||
if (m_pCImage->GetBPP() == 32)
|
|
||||||
{
|
|
||||||
m_pCImage->AlphaBlend(GetImageHDC(), m_Rect, m_SrcRect, m_nAlpha, AC_SRC_OVER);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_pCImage->Draw(GetImageHDC(), m_Rect, m_SrcRect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float Image::getScaleX() const
|
|
||||||
{
|
|
||||||
return m_fScaleX;
|
|
||||||
}
|
|
||||||
|
|
||||||
float Image::getScaleY() const
|
|
||||||
{
|
|
||||||
return m_fScaleY;
|
|
||||||
}
|
|
||||||
|
|
||||||
float Image::getOpacity() const
|
|
||||||
{
|
|
||||||
return m_nAlpha / 255.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Image::setImage(LPCTSTR ImageFile)
|
|
||||||
{
|
|
||||||
m_pCImage = GetCImage(ImageFile);
|
|
||||||
if (m_pCImage)
|
|
||||||
{
|
|
||||||
reset();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Image::setImage(LPCTSTR ImageFile, int x, int y, int width, int height)
|
|
||||||
{
|
|
||||||
if (!setImage(ImageFile))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// 裁剪图片大小
|
|
||||||
crop(x, y, width, height);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Image::setImageFromRes(LPCTSTR pResName)
|
|
||||||
{
|
|
||||||
m_pCImage = GetCImage(pResName, true);
|
|
||||||
if (m_pCImage)
|
|
||||||
{
|
|
||||||
reset();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Image::setImageFromRes(LPCTSTR pResName, int x, int y, int width, int height)
|
|
||||||
{
|
|
||||||
if (!setImageFromRes(pResName))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// 裁剪图片大小
|
|
||||||
crop(x, y, width, height);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Image::crop(int x, int y, int width, int height)
|
|
||||||
{
|
|
||||||
width = min(max(width, 0), m_pCImage->GetWidth() - x);
|
|
||||||
height = min(max(height, 0), m_pCImage->GetHeight() - y);
|
|
||||||
// 设置源矩形的位置和大小(用于裁剪)
|
|
||||||
m_SrcRect.SetRect(x, y, x + width, y + height);
|
|
||||||
// 设置目标矩形(即绘制到窗口的位置和大小)
|
|
||||||
setSize(int(width * m_fScaleX), int(height * m_fScaleY));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Image::stretch(int width, int height)
|
|
||||||
{
|
|
||||||
// 设置目标矩形的位置和大小(即绘制到窗口的位置和大小,用于拉伸图片)
|
|
||||||
setSize(max(width, 0), max(height, 0));
|
|
||||||
// 重置比例缩放属性
|
|
||||||
m_fScaleX = 1;
|
|
||||||
m_fScaleY = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Image::setScale(float scaleX, float scaleY)
|
|
||||||
{
|
|
||||||
m_fScaleX = max(scaleX, 0);
|
|
||||||
m_fScaleY = max(scaleY, 0);
|
|
||||||
setSize(int(m_SrcRect.Width() * scaleX), int(m_SrcRect.Height() * scaleY));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Image::setOpacity(float value)
|
|
||||||
{
|
|
||||||
if (m_pCImage->GetBPP() == 32)
|
|
||||||
{
|
|
||||||
m_nAlpha = BYTE(min(max(value, 0), 1) * 255);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Image::setTransparentColor(COLORREF value)
|
|
||||||
{
|
|
||||||
// 设置透明色
|
|
||||||
m_pCImage->SetTransparentColor(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Image::reset()
|
|
||||||
{
|
|
||||||
// 设置目标矩形(即绘制到窗口的位置和大小)
|
|
||||||
setSize(m_pCImage->GetWidth(), m_pCImage->GetHeight());
|
|
||||||
// 设置源矩形(即截取图片的大小)
|
|
||||||
m_SrcRect.SetRect(0, 0, m_pCImage->GetWidth(), m_pCImage->GetHeight());
|
|
||||||
// 重置缩放属性
|
|
||||||
m_fScaleX = 1;
|
|
||||||
m_fScaleY = 1;
|
|
||||||
// 重置透明度
|
|
||||||
m_nAlpha = 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Image::preload(LPCTSTR fileName, bool fromRes)
|
|
||||||
{
|
|
||||||
// 判断图片是否已经加载
|
|
||||||
if (s_mCImages.find(fileName) != s_mCImages.end())
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// 加载图片
|
|
||||||
CImage* cImage = nullptr;
|
|
||||||
if (fromRes)
|
|
||||||
{
|
|
||||||
cImage = new CImage();
|
|
||||||
// 从资源加载图片(不支持 PNG)
|
|
||||||
cImage->LoadFromResource(GetModuleHandle(NULL), fileName);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//判断图片路径是否存在
|
|
||||||
if (!PathFileExists(fileName))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
cImage = new CImage();
|
|
||||||
cImage->Load(fileName);
|
|
||||||
}
|
|
||||||
// 加载失败
|
|
||||||
if (!cImage || cImage->IsNull())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// 确认该图像包含 Alpha 通道
|
|
||||||
if (cImage->GetBPP() == 32)
|
|
||||||
{
|
|
||||||
// 透明图片处理
|
|
||||||
CrossImage(*cImage);
|
|
||||||
}
|
|
||||||
s_mCImages.insert(map<TString, CImage*>::value_type(fileName, cImage));
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Image::saveScreenshot()
|
|
||||||
{
|
|
||||||
TString savePath;
|
|
||||||
// 获取保存位置
|
|
||||||
if (FileUtils::getSaveFilePath(savePath, _T("截图保存到"), _T("jpg")))
|
|
||||||
{
|
|
||||||
// 保存窗口截图
|
|
||||||
IMAGE image;
|
|
||||||
getimage(&image, 0, 0, EApp::getWidth(), EApp::getHeight());
|
|
||||||
saveimage(savePath.c_str(), &image);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 对 PNG 图像进行像素转换
|
|
||||||
void CrossImage(CImage &img)
|
|
||||||
{
|
|
||||||
// 进行像素转换
|
|
||||||
for (int i = 0; i < img.GetWidth(); i++)
|
|
||||||
{
|
|
||||||
for (int j = 0; j < img.GetHeight(); j++)
|
|
||||||
{
|
|
||||||
UCHAR *cr = (UCHAR*)img.GetPixelAddress(i, j);
|
|
||||||
cr[0] = cr[0] * cr[3] / 255;
|
|
||||||
cr[1] = cr[1] * cr[3] / 255;
|
|
||||||
cr[2] = cr[2] * cr[3] / 255;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CImage* GetCImage(TString name, bool fromRes)
|
|
||||||
{
|
|
||||||
if (Image::preload(name.c_str()))
|
|
||||||
{
|
|
||||||
return s_mCImages.at(name);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
|
|
||||||
|
|
||||||
Layer::Layer() :
|
|
||||||
m_bBlock(true)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Layer::~Layer()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int Layer::getBlock() const
|
|
||||||
{
|
|
||||||
return m_bBlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Layer::setBlock(bool block)
|
|
||||||
{
|
|
||||||
m_bBlock = block;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Layer::_exec(bool active)
|
|
||||||
{
|
|
||||||
// 若图层阻塞消息,则永远取得画面焦点
|
|
||||||
return BatchNode::_exec(active) || m_bBlock;
|
|
||||||
}
|
|
||||||
|
|
@ -1,174 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
|
|
||||||
|
|
||||||
MouseNode::MouseNode() :
|
|
||||||
m_bBlock(true),
|
|
||||||
m_bTarget(false),
|
|
||||||
m_ClickCallback([]() {}),
|
|
||||||
m_OnMouseInCallback([]() {}),
|
|
||||||
m_OnMouseOutCallback([]() {}),
|
|
||||||
m_OnSelectCallback([]() {}),
|
|
||||||
m_OnUnselectCallback([]() {})
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseNode::~MouseNode()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MouseNode::_exec(bool active)
|
|
||||||
{
|
|
||||||
// 若 display 属性为 false,退出函数
|
|
||||||
if (!m_bDisplay)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// 若画面已取得焦点,重置按钮属性并退出
|
|
||||||
if (!active)
|
|
||||||
{
|
|
||||||
reset();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// 判断节点当前的状态
|
|
||||||
// 若节点未取得焦点,则重新判断节点状态
|
|
||||||
if (!m_bTarget)
|
|
||||||
{
|
|
||||||
// 若鼠标位置在节点所在的矩形区域中
|
|
||||||
if (_isMouseIn())
|
|
||||||
{
|
|
||||||
// 状态设为 MOUSEIN
|
|
||||||
_setStatus(MOUSEIN);
|
|
||||||
// 若此时按下鼠标左键
|
|
||||||
if (MouseMsg::getMsg() == MouseMsg::LBUTTON_DOWN)
|
|
||||||
{
|
|
||||||
m_bTarget = true; // 取得焦点标记
|
|
||||||
_setStatus(SELECTED); // 状态设为 SELECTED
|
|
||||||
}
|
|
||||||
// 若节点阻塞鼠标消息,则取得画面焦点
|
|
||||||
if (m_bBlock) return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
reset(); // 恢复默认状态
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 节点取得焦点时鼠标左键抬起
|
|
||||||
if (MouseMsg::getMsg() == MouseMsg::LBUTTON_UP)
|
|
||||||
{
|
|
||||||
// 若左键抬起时鼠标仍在节点内
|
|
||||||
if (_isMouseIn())
|
|
||||||
{
|
|
||||||
m_ClickCallback(); // 执行回调函数
|
|
||||||
}
|
|
||||||
reset(); // 恢复默认状态
|
|
||||||
}
|
|
||||||
// 若节点阻塞鼠标消息,则取得画面焦点
|
|
||||||
if (m_bBlock) return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseNode::_onDraw()
|
|
||||||
{
|
|
||||||
// 节点是否显示
|
|
||||||
if (!m_bDisplay)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 节点是否被选中
|
|
||||||
if (m_eStatus == SELECTED)
|
|
||||||
{
|
|
||||||
_onSelected();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 鼠标是否在节点上
|
|
||||||
if (m_eStatus == MOUSEIN)
|
|
||||||
{
|
|
||||||
_onMouseIn();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_onNormal();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MouseNode::_isMouseIn()
|
|
||||||
{
|
|
||||||
return isPointIn(MouseMsg::getPos());
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseNode::_setStatus(Status status)
|
|
||||||
{
|
|
||||||
if (m_eStatus != status)
|
|
||||||
{
|
|
||||||
// 退出某个状态的回调函数
|
|
||||||
if (m_eStatus == MOUSEIN)
|
|
||||||
{
|
|
||||||
m_OnMouseOutCallback();
|
|
||||||
}
|
|
||||||
else if (m_eStatus == SELECTED)
|
|
||||||
{
|
|
||||||
m_OnUnselectCallback();
|
|
||||||
}
|
|
||||||
// 进入某个状态的回调函数
|
|
||||||
if (status == MOUSEIN)
|
|
||||||
{
|
|
||||||
m_OnMouseInCallback();
|
|
||||||
}
|
|
||||||
else if (status == SELECTED)
|
|
||||||
{
|
|
||||||
m_OnSelectCallback();
|
|
||||||
}
|
|
||||||
m_eStatus = status;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MouseNode::isMouseIn()
|
|
||||||
{
|
|
||||||
return m_eStatus == MOUSEIN || m_eStatus == SELECTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MouseNode::isSelected()
|
|
||||||
{
|
|
||||||
return m_eStatus == SELECTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseNode::setClickedCallback(const CLICK_CALLBACK & callback)
|
|
||||||
{
|
|
||||||
m_ClickCallback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseNode::setMouseInCallback(const CLICK_CALLBACK & callback)
|
|
||||||
{
|
|
||||||
m_OnMouseInCallback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseNode::setMouseOutCallback(const CLICK_CALLBACK & callback)
|
|
||||||
{
|
|
||||||
m_OnMouseOutCallback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseNode::setSelectCallback(const CLICK_CALLBACK & callback)
|
|
||||||
{
|
|
||||||
m_OnSelectCallback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseNode::setUnselectCallback(const CLICK_CALLBACK & callback)
|
|
||||||
{
|
|
||||||
m_OnUnselectCallback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseNode::reset()
|
|
||||||
{
|
|
||||||
m_bTarget = false; // 失去焦点标记
|
|
||||||
_setStatus(NORMAL); // 恢复默认状态
|
|
||||||
}
|
|
||||||
|
|
||||||
void MouseNode::setBlock(bool block)
|
|
||||||
{
|
|
||||||
m_bBlock = block;
|
|
||||||
}
|
|
||||||
|
|
@ -1,139 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
|
|
||||||
RectNode::RectNode() :
|
|
||||||
m_Rect(0, 0, 0, 0)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
RectNode::~RectNode()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RectNode::isCollisionWith(RectNode * rectNode) const
|
|
||||||
{
|
|
||||||
static CRect rt;
|
|
||||||
return IntersectRect(&rt, &m_Rect, &rectNode->m_Rect);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RectNode::isPointIn(CPoint p) const
|
|
||||||
{
|
|
||||||
return m_Rect.PtInRect(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RectNode::setWindowCenterX()
|
|
||||||
{
|
|
||||||
setX((EApp::getWidth() - getWidth()) / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RectNode::setWindowCenterY()
|
|
||||||
{
|
|
||||||
setY((EApp::getHeight() - getHeight()) / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RectNode::setWindowCenter()
|
|
||||||
{
|
|
||||||
setWindowCenterX();
|
|
||||||
setWindowCenterY();
|
|
||||||
}
|
|
||||||
|
|
||||||
int RectNode::getX() const
|
|
||||||
{
|
|
||||||
return m_Rect.left;
|
|
||||||
}
|
|
||||||
|
|
||||||
int RectNode::getY() const
|
|
||||||
{
|
|
||||||
return m_Rect.top;
|
|
||||||
}
|
|
||||||
|
|
||||||
CPoint RectNode::getPos() const
|
|
||||||
{
|
|
||||||
return m_Rect.TopLeft();
|
|
||||||
}
|
|
||||||
|
|
||||||
int RectNode::getWidth() const
|
|
||||||
{
|
|
||||||
return m_Rect.Width(); // 矩形宽度
|
|
||||||
}
|
|
||||||
|
|
||||||
int RectNode::getHeight() const
|
|
||||||
{
|
|
||||||
return m_Rect.Height(); // 矩形高度
|
|
||||||
}
|
|
||||||
|
|
||||||
CSize RectNode::getSize() const
|
|
||||||
{
|
|
||||||
return m_Rect.Size();
|
|
||||||
}
|
|
||||||
|
|
||||||
CRect RectNode::getRect() const
|
|
||||||
{
|
|
||||||
return m_Rect;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RectNode::setX(int x)
|
|
||||||
{
|
|
||||||
m_Rect.MoveToX(x);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RectNode::setY(int y)
|
|
||||||
{
|
|
||||||
m_Rect.MoveToY(y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RectNode::setPos(int x, int y)
|
|
||||||
{
|
|
||||||
m_Rect.MoveToXY(x, y); // 修改矩形位置
|
|
||||||
}
|
|
||||||
|
|
||||||
void RectNode::setPos(CPoint p)
|
|
||||||
{
|
|
||||||
m_Rect.MoveToXY(p); // 修改矩形位置
|
|
||||||
}
|
|
||||||
|
|
||||||
void RectNode::move(int x, int y)
|
|
||||||
{
|
|
||||||
m_Rect.OffsetRect(x, y); // 移动矩形
|
|
||||||
}
|
|
||||||
|
|
||||||
void RectNode::move(CVector v)
|
|
||||||
{
|
|
||||||
m_Rect.OffsetRect(v); // 移动矩形
|
|
||||||
}
|
|
||||||
|
|
||||||
void RectNode::setWidth(int width)
|
|
||||||
{
|
|
||||||
m_Rect.right = max(m_Rect.left + width, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RectNode::setHeight(int height)
|
|
||||||
{
|
|
||||||
m_Rect.bottom = max(m_Rect.top + height, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RectNode::setSize(int width, int height)
|
|
||||||
{
|
|
||||||
setWidth(width);
|
|
||||||
setHeight(height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RectNode::setSize(CSize size)
|
|
||||||
{
|
|
||||||
setSize(size.cx, size.cy);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RectNode::setRect(int x1, int y1, int x2, int y2)
|
|
||||||
{
|
|
||||||
m_Rect.SetRect(x1, y1, x2, y2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RectNode::setRect(CPoint leftTop, CPoint rightBottom)
|
|
||||||
{
|
|
||||||
m_Rect.SetRect(leftTop, rightBottom);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RectNode::setRect(CRect rect)
|
|
||||||
{
|
|
||||||
m_Rect.CopyRect(&rect);
|
|
||||||
}
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
#include "..\..\easy2d.h"
|
|
||||||
#include "..\..\EasyX\easyx.h"
|
|
||||||
|
|
||||||
|
|
||||||
Circle::Circle() :
|
|
||||||
m_nRadius(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Circle::Circle(int x, int y, int radius) :
|
|
||||||
m_nRadius(radius)
|
|
||||||
{
|
|
||||||
setPos(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
Circle::~Circle()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Circle::solidShape()
|
|
||||||
{
|
|
||||||
solidcircle(getX(), getY(), m_nRadius);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Circle::fillShape()
|
|
||||||
{
|
|
||||||
fillcircle(getX(), getY(), m_nRadius);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Circle::roundShape()
|
|
||||||
{
|
|
||||||
circle(getX(), getY(), m_nRadius);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Circle::getRadius() const
|
|
||||||
{
|
|
||||||
return m_nRadius;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Circle::setRadius(int r)
|
|
||||||
{
|
|
||||||
m_nRadius = r;
|
|
||||||
}
|
|
||||||
|
|
@ -1,58 +0,0 @@
|
||||||
#include "..\..\easy2d.h"
|
|
||||||
#include "..\..\EasyX\easyx.h"
|
|
||||||
|
|
||||||
|
|
||||||
Rect::Rect()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Rect::Rect(int x, int y, int width, int height) :
|
|
||||||
m_Size(width, height)
|
|
||||||
{
|
|
||||||
setPos(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
Rect::~Rect()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Rect::solidShape()
|
|
||||||
{
|
|
||||||
solidrectangle(getX(), getY(), getX() + m_Size.cx, getY() + m_Size.cy);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Rect::fillShape()
|
|
||||||
{
|
|
||||||
fillrectangle(getX(), getY(), getX() + m_Size.cx, getY() + m_Size.cy);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Rect::roundShape()
|
|
||||||
{
|
|
||||||
rectangle(getX(), getY(), getX() + m_Size.cx, getY() + m_Size.cy);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Rect::getWidth() const
|
|
||||||
{
|
|
||||||
return m_Size.cx;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Rect::getHeight() const
|
|
||||||
{
|
|
||||||
return m_Size.cy;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Rect::setWidth(int width)
|
|
||||||
{
|
|
||||||
m_Size.cx = width;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Rect::setHeight(int height)
|
|
||||||
{
|
|
||||||
m_Size.cy = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Rect::setSize(int width, int height)
|
|
||||||
{
|
|
||||||
m_Size.cx = width;
|
|
||||||
m_Size.cy = height;
|
|
||||||
}
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
#include "..\..\easy2d.h"
|
|
||||||
#include "..\..\EasyX\easyx.h"
|
|
||||||
|
|
||||||
Shape::Shape() :
|
|
||||||
lineColor(Color::black),
|
|
||||||
fillColor(Color::white),
|
|
||||||
m_eStyle(SOLID)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Shape::~Shape()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shape::_onDraw()
|
|
||||||
{
|
|
||||||
// 形状是否显示
|
|
||||||
if (!m_bDisplay)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 设置线条和填充颜色
|
|
||||||
setlinecolor(lineColor);
|
|
||||||
setfillcolor(fillColor);
|
|
||||||
|
|
||||||
// 根据形状的样式进行不同的绘制
|
|
||||||
if (m_eStyle == Shape::STYLE::ROUND)
|
|
||||||
{
|
|
||||||
roundShape();
|
|
||||||
}
|
|
||||||
else if (m_eStyle == Shape::STYLE::SOLID)
|
|
||||||
{
|
|
||||||
solidShape();
|
|
||||||
}
|
|
||||||
else if (m_eStyle == Shape::STYLE::FILL)
|
|
||||||
{
|
|
||||||
fillShape();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline COLORREF Shape::getFillColor() const
|
|
||||||
{
|
|
||||||
return fillColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline COLORREF Shape::getLineColor() const
|
|
||||||
{
|
|
||||||
return lineColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shape::setFillColor(COLORREF color)
|
|
||||||
{
|
|
||||||
fillColor = color;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shape::setLineColor(COLORREF color)
|
|
||||||
{
|
|
||||||
lineColor = color;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shape::setStyle(STYLE style)
|
|
||||||
{
|
|
||||||
m_eStyle = style;
|
|
||||||
}
|
|
||||||
|
|
@ -1,147 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
#include "..\EasyX\easyx.h"
|
|
||||||
|
|
||||||
Sprite::Sprite() :
|
|
||||||
m_nAlpha(255),
|
|
||||||
m_fScaleX(1),
|
|
||||||
m_fScaleY(1),
|
|
||||||
m_pImage(nullptr)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Sprite::Sprite(Image * image) :
|
|
||||||
Sprite()
|
|
||||||
{
|
|
||||||
setImage(image);
|
|
||||||
}
|
|
||||||
|
|
||||||
Sprite::Sprite(LPCTSTR imageFileName) :
|
|
||||||
Sprite()
|
|
||||||
{
|
|
||||||
setImage(new Image(imageFileName));
|
|
||||||
}
|
|
||||||
|
|
||||||
Sprite::~Sprite()
|
|
||||||
{
|
|
||||||
SafeRelease(m_pImage);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Sprite::_exec(bool active)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sprite::_onDraw()
|
|
||||||
{
|
|
||||||
// display 属性为 false,或未设置图片资源时,不绘制该图片
|
|
||||||
if (!m_bDisplay || !m_pImage || !m_pImage->m_pCImage)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 绘制图片
|
|
||||||
if (m_pImage->m_pCImage->GetBPP() == 32)
|
|
||||||
{
|
|
||||||
m_pImage->m_pCImage->AlphaBlend(GetImageHDC(), getRect(), m_pImage->m_SrcRect, m_nAlpha, AC_SRC_OVER);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_pImage->m_pCImage->Draw(GetImageHDC(), getRect(), m_pImage->m_SrcRect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sprite::setImage(Image * image)
|
|
||||||
{
|
|
||||||
SafeRelease(m_pImage);
|
|
||||||
m_pImage = image;
|
|
||||||
setSize(int(m_pImage->getWidth() * m_fScaleX), int(m_pImage->getHeight() * m_fScaleY));
|
|
||||||
m_pImage->retain();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Sprite::isCollisionWith(Sprite * sprite)
|
|
||||||
{
|
|
||||||
static CRect rt;
|
|
||||||
return IntersectRect(&rt, &getRect(), &sprite->getRect());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sprite::addAction(Action * action)
|
|
||||||
{
|
|
||||||
if (action)
|
|
||||||
{
|
|
||||||
// 将动作与 Sprite 绑定
|
|
||||||
action->m_pTargetSprite = this;
|
|
||||||
// 将动作加入动作管理器,管理器会处理这个动作
|
|
||||||
ActionManager::addAction(action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sprite::runAction(Action * action)
|
|
||||||
{
|
|
||||||
addAction(action);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sprite::resumeAction(Action * action)
|
|
||||||
{
|
|
||||||
if (action->getTarget() == this)
|
|
||||||
{
|
|
||||||
ActionManager::resumeAction(action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sprite::pauseAction(Action * action)
|
|
||||||
{
|
|
||||||
if (action->getTarget() == this)
|
|
||||||
{
|
|
||||||
ActionManager::pauseAction(action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sprite::stopAction(Action * action)
|
|
||||||
{
|
|
||||||
if (action->getTarget() == this)
|
|
||||||
{
|
|
||||||
ActionManager::stopAction(action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sprite::pauseAllActions()
|
|
||||||
{
|
|
||||||
ActionManager::pauseSpriteAllActions(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sprite::resumeAllActions()
|
|
||||||
{
|
|
||||||
ActionManager::resumeSpriteAllActions(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sprite::stopAllActions()
|
|
||||||
{
|
|
||||||
ActionManager::stopSpriteAllActions(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
float Sprite::getScaleX() const
|
|
||||||
{
|
|
||||||
return m_fScaleX;
|
|
||||||
}
|
|
||||||
|
|
||||||
float Sprite::getScaleY() const
|
|
||||||
{
|
|
||||||
return m_fScaleY;
|
|
||||||
}
|
|
||||||
|
|
||||||
float Sprite::getOpacity() const
|
|
||||||
{
|
|
||||||
return m_nAlpha / 255.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sprite::setScale(float scaleX, float scaleY)
|
|
||||||
{
|
|
||||||
m_fScaleX = max(scaleX, 0);
|
|
||||||
m_fScaleY = max(scaleY, 0);
|
|
||||||
setSize(int(m_pImage->getWidth() * scaleX), int(m_pImage->getHeight() * scaleY));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sprite::setOpacity(float opacity)
|
|
||||||
{
|
|
||||||
m_nAlpha = BYTE(min(max(opacity, 0), 1) * 255);
|
|
||||||
}
|
|
||||||
|
|
@ -1,91 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
#include "..\EasyX\easyx.h"
|
|
||||||
|
|
||||||
|
|
||||||
Text::Text() :
|
|
||||||
m_sText(_T("")),
|
|
||||||
m_color(Color::white),
|
|
||||||
m_pFontStyle(FontStyle::getDefault())
|
|
||||||
{
|
|
||||||
m_pFontStyle->retain(); // 字体引用计数加一
|
|
||||||
}
|
|
||||||
|
|
||||||
Text::Text(TString text, COLORREF color, FontStyle * font) :
|
|
||||||
m_color(color),
|
|
||||||
m_pFontStyle(font)
|
|
||||||
{
|
|
||||||
setText(text);
|
|
||||||
m_pFontStyle->retain(); // 字体引用计数加一
|
|
||||||
}
|
|
||||||
|
|
||||||
Text::Text(int x, int y, TString text, COLORREF color, FontStyle * font) :
|
|
||||||
m_color(color),
|
|
||||||
m_pFontStyle(font)
|
|
||||||
{
|
|
||||||
setText(text);
|
|
||||||
setPos(x, y);
|
|
||||||
m_pFontStyle->retain(); // 字体引用计数加一
|
|
||||||
}
|
|
||||||
|
|
||||||
Text::~Text()
|
|
||||||
{
|
|
||||||
SafeRelease(m_pFontStyle); // 字体引用计数减一
|
|
||||||
}
|
|
||||||
|
|
||||||
void Text::_onDraw()
|
|
||||||
{
|
|
||||||
// 若 display 属性为 false,不绘制这个文本
|
|
||||||
if (!m_bDisplay)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 设置字体
|
|
||||||
settextstyle(&m_pFontStyle->m_font);
|
|
||||||
// 设置文本颜色
|
|
||||||
settextcolor(m_color);
|
|
||||||
// 输出文字
|
|
||||||
outtextxy(getX(), getY(), m_sText.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
COLORREF Text::getColor() const
|
|
||||||
{
|
|
||||||
return m_color;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString Text::getText() const
|
|
||||||
{
|
|
||||||
return m_sText;
|
|
||||||
}
|
|
||||||
|
|
||||||
FontStyle * Text::getFontStyle()
|
|
||||||
{
|
|
||||||
return m_pFontStyle;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Text::isEmpty() const
|
|
||||||
{
|
|
||||||
return m_sText.empty(); // 文本是否为空
|
|
||||||
}
|
|
||||||
|
|
||||||
void Text::setText(TString text)
|
|
||||||
{
|
|
||||||
m_sText = text;
|
|
||||||
// 先设置字体,然后获取该文本在该字体下的宽度和高度
|
|
||||||
settextstyle(&m_pFontStyle->m_font);
|
|
||||||
setSize(textwidth(getText().c_str()), textheight(getText().c_str()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Text::setColor(COLORREF color)
|
|
||||||
{
|
|
||||||
m_color = color;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Text::setFontStyle(FontStyle * style)
|
|
||||||
{
|
|
||||||
SafeRelease(m_pFontStyle); // 原字体引用计数减一
|
|
||||||
m_pFontStyle = style; // 修改字体
|
|
||||||
m_pFontStyle->retain(); // 现字体引用计数加一
|
|
||||||
// 先设置字体,然后获取该文本在该字体下的宽度和高度
|
|
||||||
settextstyle(&m_pFontStyle->m_font);
|
|
||||||
setSize(textwidth(getText().c_str()), textheight(getText().c_str()));
|
|
||||||
}
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
#include "..\EasyX\easyx.h"
|
|
||||||
|
|
||||||
// 常用颜色值的定义
|
|
||||||
const COLORREF Color::black = BLACK;
|
|
||||||
const COLORREF Color::blue = BLUE;
|
|
||||||
const COLORREF Color::green = GREEN;
|
|
||||||
const COLORREF Color::cyan = CYAN;
|
|
||||||
const COLORREF Color::red = RED;
|
|
||||||
const COLORREF Color::magenta = MAGENTA;
|
|
||||||
const COLORREF Color::brown = BROWN;
|
|
||||||
const COLORREF Color::lightgray = LIGHTGRAY;
|
|
||||||
const COLORREF Color::darkgray = DARKGRAY;
|
|
||||||
const COLORREF Color::lightblue = LIGHTBLUE;
|
|
||||||
const COLORREF Color::lightgreen = LIGHTGREEN;
|
|
||||||
const COLORREF Color::lightcyan = LIGHTCYAN;
|
|
||||||
const COLORREF Color::lightred = LIGHTRED;
|
|
||||||
const COLORREF Color::lightmagenta = LIGHTMAGENTA;
|
|
||||||
const COLORREF Color::yellow = YELLOW;
|
|
||||||
const COLORREF Color::white = WHITE;
|
|
||||||
|
|
||||||
|
|
||||||
COLORREF Color::getFromRGB(BYTE r, BYTE g, BYTE b)
|
|
||||||
{
|
|
||||||
return RGB(r, g, b); // 从 (r, g, b) 三色值转化为颜色
|
|
||||||
}
|
|
||||||
|
|
||||||
COLORREF Color::getFromHSL(float H, float S, float L)
|
|
||||||
{
|
|
||||||
return HSLtoRGB(H, S, L);
|
|
||||||
}
|
|
||||||
|
|
||||||
COLORREF Color::getFromHSV(float H, float S, float V)
|
|
||||||
{
|
|
||||||
return HSVtoRGB(H, S, V);
|
|
||||||
}
|
|
||||||
|
|
||||||
BYTE Color::getRValue(COLORREF color)
|
|
||||||
{
|
|
||||||
return GetRValue(color); // 返回颜色中的红色值
|
|
||||||
}
|
|
||||||
|
|
||||||
BYTE Color::getGValue(COLORREF color)
|
|
||||||
{
|
|
||||||
return GetGValue(color); // 返回颜色中的绿色值
|
|
||||||
}
|
|
||||||
|
|
||||||
BYTE Color::getBValue(COLORREF color)
|
|
||||||
{
|
|
||||||
return GetBValue(color); // 返回颜色中的蓝色值
|
|
||||||
}
|
|
||||||
|
|
||||||
COLORREF Color::getGray(COLORREF color)
|
|
||||||
{
|
|
||||||
return RGBtoGRAY(color); // 获取颜色中的灰度值
|
|
||||||
}
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
/* FillStyle 是 EasyX 中的类,目前尚未考虑实现 */
|
|
||||||
|
|
@ -1,103 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
|
|
||||||
// ³£ÓÃ×ÖÌå´ÖϸֵµÄ¶¨Òå
|
|
||||||
const LONG FontWeight::dontcare = 0;
|
|
||||||
const LONG FontWeight::thin = 100;
|
|
||||||
const LONG FontWeight::extraLight = 200;
|
|
||||||
const LONG FontWeight::light = 300;
|
|
||||||
const LONG FontWeight::normal = 400;
|
|
||||||
const LONG FontWeight::regular = 400;
|
|
||||||
const LONG FontWeight::medium = 500;
|
|
||||||
const LONG FontWeight::demiBlod = 600;
|
|
||||||
const LONG FontWeight::blod = 700;
|
|
||||||
const LONG FontWeight::extraBold = 800;
|
|
||||||
const LONG FontWeight::black = 900;
|
|
||||||
const LONG FontWeight::heavy = 900;
|
|
||||||
|
|
||||||
|
|
||||||
FontStyle::FontStyle()
|
|
||||||
{
|
|
||||||
setFontFamily(_T(""));
|
|
||||||
m_font.lfWeight = 18;
|
|
||||||
m_font.lfHeight = 0;
|
|
||||||
m_font.lfWidth = 0;
|
|
||||||
m_font.lfItalic = 0;
|
|
||||||
m_font.lfUnderline = 0;
|
|
||||||
m_font.lfStrikeOut = 0;
|
|
||||||
m_font.lfEscapement = 0;
|
|
||||||
m_font.lfOrientation = 0;
|
|
||||||
setQuality(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
FontStyle::FontStyle(LPCTSTR fontfamily, LONG height, LONG weight, LONG width, bool italic, bool underline, bool strikeout, LONG escapement, LONG orientation, bool quality)
|
|
||||||
{
|
|
||||||
setFontFamily(fontfamily);
|
|
||||||
m_font.lfWeight = weight;
|
|
||||||
m_font.lfHeight = height;
|
|
||||||
m_font.lfWidth = width;
|
|
||||||
m_font.lfItalic = italic;
|
|
||||||
m_font.lfUnderline = underline;
|
|
||||||
m_font.lfStrikeOut = strikeout;
|
|
||||||
m_font.lfEscapement = escapement;
|
|
||||||
m_font.lfOrientation = orientation;
|
|
||||||
setQuality(quality);
|
|
||||||
}
|
|
||||||
|
|
||||||
FontStyle::~FontStyle()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
FontStyle * FontStyle::getDefault()
|
|
||||||
{
|
|
||||||
return new FontStyle(_T(""), 18, FontWeight::normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FontStyle::setHeight(LONG value)
|
|
||||||
{
|
|
||||||
m_font.lfHeight = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FontStyle::setWidth(LONG value)
|
|
||||||
{
|
|
||||||
m_font.lfWidth = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FontStyle::setFontFamily(LPCTSTR value)
|
|
||||||
{
|
|
||||||
_tcscpy_s(m_font.lfFaceName, 32, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FontStyle::setEscapement(LONG value)
|
|
||||||
{
|
|
||||||
m_font.lfEscapement = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FontStyle::setOrientation(LONG value)
|
|
||||||
{
|
|
||||||
m_font.lfOrientation = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FontStyle::setQuality(bool value)
|
|
||||||
{
|
|
||||||
m_font.lfQuality = value ? ANTIALIASED_QUALITY : DEFAULT_QUALITY;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FontStyle::setWeight(LONG value)
|
|
||||||
{
|
|
||||||
m_font.lfWeight = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FontStyle::setItalic(bool value)
|
|
||||||
{
|
|
||||||
m_font.lfItalic = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FontStyle::setUnderline(bool value)
|
|
||||||
{
|
|
||||||
m_font.lfUnderline = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FontStyle::setStrikeOut(bool value)
|
|
||||||
{
|
|
||||||
m_font.lfStrikeOut = value;
|
|
||||||
}
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
/* LineStyle 是 EasyX 中的类,目前尚未考虑实现 */
|
|
||||||
|
|
@ -1,200 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
#include "..\Win\winbase.h"
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
static std::vector<Action*> s_vActions;
|
|
||||||
|
|
||||||
void ActionManager::__exec()
|
|
||||||
{
|
|
||||||
// 临时指针
|
|
||||||
static Action * action;
|
|
||||||
// 循环遍历所有正在运行的动作
|
|
||||||
for (size_t i = 0; i < s_vActions.size(); i++)
|
|
||||||
{
|
|
||||||
action = s_vActions[i];
|
|
||||||
// 获取动作运行状态
|
|
||||||
if (action->isRunning())
|
|
||||||
{
|
|
||||||
if (action->isEnding())
|
|
||||||
{
|
|
||||||
// 动作已经结束
|
|
||||||
action->autoRelease();
|
|
||||||
action->release();
|
|
||||||
s_vActions.erase(s_vActions.begin() + i);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 初始化动作
|
|
||||||
if (!action->m_bInit)
|
|
||||||
{
|
|
||||||
action->_init();
|
|
||||||
}
|
|
||||||
// 执行动作
|
|
||||||
action->_exec(GetNow());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionManager::addAction(Action * action)
|
|
||||||
{
|
|
||||||
if (action)
|
|
||||||
{
|
|
||||||
#ifdef _DEBUG
|
|
||||||
for (auto a : s_vActions)
|
|
||||||
{
|
|
||||||
assert(a != action);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
action->m_pParentScene = EApp::getLoadingScene();
|
|
||||||
s_vActions.push_back(action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionManager::notifyAllSceneActions(EScene * scene)
|
|
||||||
{
|
|
||||||
for (auto action : s_vActions)
|
|
||||||
{
|
|
||||||
if (action->m_pParentScene == scene)
|
|
||||||
{
|
|
||||||
action->notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionManager::waitAllSceneActions(EScene * scene)
|
|
||||||
{
|
|
||||||
for (auto action : s_vActions)
|
|
||||||
{
|
|
||||||
if (action->m_pParentScene == scene)
|
|
||||||
{
|
|
||||||
action->wait();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionManager::stopAllSceneActions(EScene * scene)
|
|
||||||
{
|
|
||||||
for (auto action : s_vActions)
|
|
||||||
{
|
|
||||||
if (action->m_pParentScene == scene)
|
|
||||||
{
|
|
||||||
action->stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionManager::startAction(Action * action)
|
|
||||||
{
|
|
||||||
resumeAction(action);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionManager::resumeAction(Action * action)
|
|
||||||
{
|
|
||||||
for (auto act : s_vActions)
|
|
||||||
{
|
|
||||||
if (act == action)
|
|
||||||
{
|
|
||||||
act->resume();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionManager::pauseAction(Action * action)
|
|
||||||
{
|
|
||||||
for (auto act : s_vActions)
|
|
||||||
{
|
|
||||||
if (act == action)
|
|
||||||
{
|
|
||||||
act->pause();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionManager::stopAction(Action * action)
|
|
||||||
{
|
|
||||||
for (auto act : s_vActions)
|
|
||||||
{
|
|
||||||
if (act == action)
|
|
||||||
{
|
|
||||||
act->stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionManager::startSpriteAllActions(Sprite * sprite)
|
|
||||||
{
|
|
||||||
resumeSpriteAllActions(sprite);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionManager::resumeSpriteAllActions(Sprite * sprite)
|
|
||||||
{
|
|
||||||
for (auto action : s_vActions)
|
|
||||||
{
|
|
||||||
if (action->m_pTargetSprite == sprite)
|
|
||||||
{
|
|
||||||
action->resume();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionManager::pauseSpriteAllActions(Sprite * sprite)
|
|
||||||
{
|
|
||||||
for (auto action : s_vActions)
|
|
||||||
{
|
|
||||||
if (action->m_pTargetSprite == sprite)
|
|
||||||
{
|
|
||||||
action->pause();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionManager::stopSpriteAllActions(Sprite * sprite)
|
|
||||||
{
|
|
||||||
for (auto action : s_vActions)
|
|
||||||
{
|
|
||||||
if (action->m_pTargetSprite == sprite)
|
|
||||||
{
|
|
||||||
action->stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionManager::startAllActions()
|
|
||||||
{
|
|
||||||
resumeAllActions();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionManager::resumeAllActions()
|
|
||||||
{
|
|
||||||
for (auto action : s_vActions)
|
|
||||||
{
|
|
||||||
action->resume();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionManager::pauseAllActions()
|
|
||||||
{
|
|
||||||
for (auto action : s_vActions)
|
|
||||||
{
|
|
||||||
action->pause();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionManager::stopAllActions()
|
|
||||||
{
|
|
||||||
for (auto action : s_vActions)
|
|
||||||
{
|
|
||||||
action->stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionManager::clearAllActions()
|
|
||||||
{
|
|
||||||
for (auto action : s_vActions)
|
|
||||||
{
|
|
||||||
action->autoRelease();
|
|
||||||
action->release();
|
|
||||||
}
|
|
||||||
s_vActions.clear();
|
|
||||||
}
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
#include "..\etools.h"
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
// EObjectManager 释放池的实现机制:
|
|
||||||
/// EObject 类中的引用计数(m_nRefCount)保证了指针的使用安全
|
|
||||||
/// 它记录了对象被使用的次数,当计数为 0 时,EObjectManager 会自动释放这个对象
|
|
||||||
/// 所有的 EObject 对象都应在被使用时(例如 Text 添加到了场景中)
|
|
||||||
/// 调用 retain 函数保证该对象不被删除,并在不再使用时调用 release 函数
|
|
||||||
/// 让其自动释放
|
|
||||||
|
|
||||||
// 释放池容器
|
|
||||||
static std::vector<e2d::EObject*> s_vPool;
|
|
||||||
|
|
||||||
void e2d::EObjectManager::__flush()
|
|
||||||
{
|
|
||||||
// 创建迭代器
|
|
||||||
static std::vector<e2d::EObject*>::iterator iter;
|
|
||||||
// 循环遍历容器中的所有对象
|
|
||||||
for (iter = s_vPool.begin(); iter != s_vPool.end();)
|
|
||||||
{
|
|
||||||
if ((*iter)->m_bAutoRelease && (*iter)->m_nRefCount == 0)
|
|
||||||
{
|
|
||||||
// 若对象的引用的计数为 0, 释放该对象
|
|
||||||
delete (*iter);
|
|
||||||
// 从释放池中删除该对象
|
|
||||||
iter = s_vPool.erase(iter);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
iter++; // 移动迭代器
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void e2d::EObjectManager::add(e2d::EObject * nptr)
|
|
||||||
{
|
|
||||||
if (!nptr->m_bManaged)
|
|
||||||
{
|
|
||||||
nptr->m_bManaged = true;
|
|
||||||
s_vPool.push_back(nptr); // 将一个对象放入释放池中
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void e2d::EObjectManager::clearAllObjects()
|
|
||||||
{
|
|
||||||
for (auto o : s_vPool)
|
|
||||||
{
|
|
||||||
delete o;
|
|
||||||
}
|
|
||||||
s_vPool.clear();
|
|
||||||
}
|
|
||||||
|
|
@ -1,168 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
#include "..\EasyX\easyx.h"
|
|
||||||
#include <Shlobj.h>
|
|
||||||
#pragma comment(lib, "shell32.lib")
|
|
||||||
#include <sstream>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#ifndef UNICODE
|
|
||||||
#include <io.h>
|
|
||||||
#include <direct.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
TString FileUtils::getLocalAppDataPath()
|
|
||||||
{
|
|
||||||
TCHAR m_lpszDefaultDir[MAX_PATH] = { 0 };
|
|
||||||
TCHAR szDocument[MAX_PATH] = { 0 };
|
|
||||||
|
|
||||||
// 获取 AppData\Local 文件夹的 ID
|
|
||||||
LPITEMIDLIST pidl = NULL;
|
|
||||||
SHGetSpecialFolderLocation(NULL, CSIDL_LOCAL_APPDATA, &pidl);
|
|
||||||
if (pidl && SHGetPathFromIDList(pidl, szDocument))
|
|
||||||
{
|
|
||||||
// 获取文件夹路径
|
|
||||||
GetShortPathName(szDocument, m_lpszDefaultDir, _MAX_PATH);
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_lpszDefaultDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString FileUtils::getDefaultSavePath()
|
|
||||||
{
|
|
||||||
TCHAR m_lpszDefaultDir[MAX_PATH] = { 0 };
|
|
||||||
TCHAR szDocument[MAX_PATH] = { 0 };
|
|
||||||
|
|
||||||
// 获取 AppData\Local 文件夹的 ID
|
|
||||||
LPITEMIDLIST pidl = NULL;
|
|
||||||
SHGetSpecialFolderLocation(NULL, CSIDL_LOCAL_APPDATA, &pidl);
|
|
||||||
if (pidl && SHGetPathFromIDList(pidl, szDocument))
|
|
||||||
{
|
|
||||||
// 获取文件夹路径
|
|
||||||
GetShortPathName(szDocument, m_lpszDefaultDir, _MAX_PATH);
|
|
||||||
}
|
|
||||||
|
|
||||||
TString path = m_lpszDefaultDir;
|
|
||||||
path.append(_T("\\"));
|
|
||||||
path.append(EApp::getAppName());
|
|
||||||
|
|
||||||
#ifdef UNICODE
|
|
||||||
if (_waccess(path.c_str(), 0) == -1)
|
|
||||||
{
|
|
||||||
_wmkdir(path.c_str());
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (_access(path.c_str(), 0) == -1)
|
|
||||||
{
|
|
||||||
_mkdir(path.c_str());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
path.append(_T("\\DefaultData.ini"));
|
|
||||||
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileUtils::saveInt(LPCTSTR key, int value)
|
|
||||||
{
|
|
||||||
#ifdef UNICODE
|
|
||||||
std::wstringstream ss;
|
|
||||||
#else
|
|
||||||
std::stringstream ss;
|
|
||||||
#endif
|
|
||||||
ss << value;
|
|
||||||
::WritePrivateProfileString(_T("Default"), key, ss.str().c_str(), getDefaultSavePath().c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileUtils::saveDouble(LPCTSTR key, double value)
|
|
||||||
{
|
|
||||||
#ifdef UNICODE
|
|
||||||
std::wstringstream ss;
|
|
||||||
#else
|
|
||||||
std::stringstream ss;
|
|
||||||
#endif
|
|
||||||
ss << value;
|
|
||||||
::WritePrivateProfileString(_T("Default"), key, ss.str().c_str(), getDefaultSavePath().c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileUtils::saveString(LPCTSTR key, TString value)
|
|
||||||
{
|
|
||||||
::WritePrivateProfileString(_T("Default"), key, value.c_str(), getDefaultSavePath().c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
int FileUtils::getInt(LPCTSTR key, int default)
|
|
||||||
{
|
|
||||||
return ::GetPrivateProfileInt(_T("Default"), key, default, getDefaultSavePath().c_str());
|
|
||||||
}
|
|
||||||
#include <iostream>
|
|
||||||
using namespace std;
|
|
||||||
double FileUtils::getDouble(LPCTSTR key, double default)
|
|
||||||
{
|
|
||||||
// 将 default 参数转化为字符串
|
|
||||||
#ifdef UNICODE
|
|
||||||
std::wstringstream ss;
|
|
||||||
#else
|
|
||||||
std::stringstream ss;
|
|
||||||
#endif
|
|
||||||
ss << default;
|
|
||||||
// 读取数据
|
|
||||||
TCHAR temp[128] = { 0 };
|
|
||||||
::GetPrivateProfileString(_T("Default"), key, ss.str().c_str(), temp, 128, getDefaultSavePath().c_str());
|
|
||||||
// 转换为字符串流
|
|
||||||
ss.str(_T(""));
|
|
||||||
ss << temp;
|
|
||||||
// 将字符串转化为 double
|
|
||||||
#ifdef UNICODE
|
|
||||||
double d = _wtof(ss.str().c_str());
|
|
||||||
#else
|
|
||||||
double d = atof(ss.str().c_str());
|
|
||||||
#endif
|
|
||||||
return d;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString FileUtils::geTString(LPCTSTR key, TString default)
|
|
||||||
{
|
|
||||||
TCHAR temp[128] = { 0 };
|
|
||||||
::GetPrivateProfileString(_T("Default"), key, default.c_str(), temp, 128, getDefaultSavePath().c_str());
|
|
||||||
return TString(temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
TString FileUtils::getFileExtension(const TString & filePath)
|
|
||||||
{
|
|
||||||
TString fileExtension;
|
|
||||||
// 找到文件名中的最后一个 '.' 的位置
|
|
||||||
size_t pos = filePath.find_last_of('.');
|
|
||||||
// 判断 pos 是否是个有效位置
|
|
||||||
if (pos != TString::npos)
|
|
||||||
{
|
|
||||||
// 截取扩展名
|
|
||||||
fileExtension = filePath.substr(pos, filePath.length());
|
|
||||||
// 转换为小写字母
|
|
||||||
std::transform(fileExtension.begin(), fileExtension.end(), fileExtension.begin(), ::tolower);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fileExtension;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileUtils::getSaveFilePath(TString& path, LPCTSTR title, LPCTSTR defExt)
|
|
||||||
{
|
|
||||||
// 弹出保存对话框
|
|
||||||
OPENFILENAME ofn = { 0 };
|
|
||||||
TCHAR strFilename[MAX_PATH] = { 0 }; // 用于接收文件名
|
|
||||||
ofn.lStructSize = sizeof(OPENFILENAME); // 结构体大小
|
|
||||||
ofn.hwndOwner = GetHWnd(); // 拥有着窗口句柄,NULL 表示对话框是非模态的
|
|
||||||
ofn.lpstrFilter = _T("所有文件\0*.*\0\0"); // 设置过滤
|
|
||||||
ofn.nFilterIndex = 1; // 过滤器索引
|
|
||||||
ofn.lpstrFile = strFilename; // 接收返回的文件路径和文件名
|
|
||||||
ofn.nMaxFile = sizeof(strFilename); // 缓冲区长度
|
|
||||||
ofn.lpstrInitialDir = NULL; // 初始目录为默认
|
|
||||||
ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;// 目录必须存在,覆盖文件前发出警告
|
|
||||||
ofn.lpstrTitle = title; // 使用系统默认标题留空即可
|
|
||||||
ofn.lpstrDefExt = defExt; // 默认追加的扩展名
|
|
||||||
|
|
||||||
if (GetSaveFileName(&ofn))
|
|
||||||
{
|
|
||||||
path = strFilename;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
|
|
||||||
|
|
||||||
std::default_random_engine &Math::getEngine()
|
|
||||||
{
|
|
||||||
static std::random_device device;
|
|
||||||
static std::default_random_engine engine(device());
|
|
||||||
return engine;
|
|
||||||
}
|
|
||||||
|
|
@ -1,417 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
#include <mmsystem.h>
|
|
||||||
#pragma comment(lib , "winmm.lib")
|
|
||||||
|
|
||||||
#include <Digitalv.h>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// MciPlayer
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
class MciPlayer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MciPlayer();
|
|
||||||
~MciPlayer();
|
|
||||||
|
|
||||||
void close();
|
|
||||||
void open(TString pFileName, UINT uId);
|
|
||||||
void play(bool bLoop = false);
|
|
||||||
void pause();
|
|
||||||
void resume();
|
|
||||||
void stop();
|
|
||||||
void rewind();
|
|
||||||
void setVolume(float volume);
|
|
||||||
bool isPlaying();
|
|
||||||
UINT getSoundID();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void _sendCommand(int nCommand, DWORD_PTR param1 = 0, DWORD_PTR parma2 = 0);
|
|
||||||
|
|
||||||
MCIDEVICEID m_dev;
|
|
||||||
UINT m_nSoundID;
|
|
||||||
bool m_bPlaying;
|
|
||||||
bool m_bLoop;
|
|
||||||
TString m_sExt;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
MciPlayer::MciPlayer() :
|
|
||||||
m_dev(0L),
|
|
||||||
m_nSoundID(0),
|
|
||||||
m_bPlaying(false),
|
|
||||||
m_bLoop(false),
|
|
||||||
m_sExt(_T(""))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
MciPlayer::~MciPlayer()
|
|
||||||
{
|
|
||||||
close(); // 关闭播放器
|
|
||||||
}
|
|
||||||
|
|
||||||
void MciPlayer::open(TString pFileName, UINT uId)
|
|
||||||
{
|
|
||||||
// 忽略不存在的文件
|
|
||||||
if (pFileName.empty() || !PathFileExists(pFileName.c_str())) return;
|
|
||||||
// 获取文件后缀名
|
|
||||||
m_sExt = FileUtils::getFileExtension(pFileName);
|
|
||||||
// 停止当前音乐
|
|
||||||
close();
|
|
||||||
|
|
||||||
// 设置 MCI_OPEN_PARMS 参数
|
|
||||||
MCI_OPEN_PARMS mciOpen = { 0 };
|
|
||||||
mciOpen.lpstrDeviceType = (LPCTSTR)-1; // device ID for "all devices"
|
|
||||||
mciOpen.lpstrElementName = pFileName.c_str();
|
|
||||||
|
|
||||||
// 打开这个文件
|
|
||||||
MCIERROR mciError;
|
|
||||||
mciError = mciSendCommand(0, MCI_OPEN, MCI_OPEN_ELEMENT, reinterpret_cast<DWORD_PTR>(&mciOpen));
|
|
||||||
// 出现错误时,忽略这次操作
|
|
||||||
if (mciError) return;
|
|
||||||
|
|
||||||
// 保存设备等信息
|
|
||||||
m_dev = mciOpen.wDeviceID;
|
|
||||||
m_nSoundID = uId;
|
|
||||||
m_bPlaying = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MciPlayer::play(bool bLoop)
|
|
||||||
{
|
|
||||||
// 设备为空时,忽略这次操作
|
|
||||||
if (!m_dev)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 设置播放参数
|
|
||||||
MCI_PLAY_PARMS mciPlay = { 0 };
|
|
||||||
MCIERROR s_mciError;
|
|
||||||
// 播放声音
|
|
||||||
s_mciError = mciSendCommand(m_dev, MCI_PLAY, MCI_FROM | (bLoop ? MCI_DGV_PLAY_REPEAT : 0), reinterpret_cast<DWORD_PTR>(&mciPlay));
|
|
||||||
// 未出错时,置 m_bPlaying 为 true
|
|
||||||
if (!s_mciError)
|
|
||||||
{
|
|
||||||
m_bPlaying = true;
|
|
||||||
m_bLoop = bLoop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MciPlayer::close()
|
|
||||||
{
|
|
||||||
// 停止音乐
|
|
||||||
if (m_bPlaying)
|
|
||||||
{
|
|
||||||
stop();
|
|
||||||
}
|
|
||||||
// 关闭设备
|
|
||||||
if (m_dev)
|
|
||||||
{
|
|
||||||
_sendCommand(MCI_CLOSE);
|
|
||||||
}
|
|
||||||
// 恢复默认属性
|
|
||||||
m_dev = 0;
|
|
||||||
m_bPlaying = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MciPlayer::pause()
|
|
||||||
{
|
|
||||||
// 暂停音乐
|
|
||||||
_sendCommand(MCI_PAUSE);
|
|
||||||
m_bPlaying = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MciPlayer::resume()
|
|
||||||
{
|
|
||||||
// 继续音乐
|
|
||||||
if (m_sExt == _T(".mid"))
|
|
||||||
{
|
|
||||||
// midi 不支持 MCI_RESUME 参数,应使用 MCI_FROM 设置播放起始位置
|
|
||||||
// 获取 MCI 状态
|
|
||||||
MCI_STATUS_PARMS mciStatusParms;
|
|
||||||
mciStatusParms.dwItem = MCI_STATUS_POSITION;
|
|
||||||
_sendCommand(MCI_STATUS, MCI_STATUS_ITEM, reinterpret_cast<DWORD_PTR>(&mciStatusParms));
|
|
||||||
// 设置播放起始位置,并开始播放
|
|
||||||
MCI_PLAY_PARMS mciPlayParms;
|
|
||||||
mciPlayParms.dwFrom = (DWORD)mciStatusParms.dwReturn;
|
|
||||||
_sendCommand(MCI_PLAY, MCI_FROM, reinterpret_cast<DWORD_PTR>(&mciPlayParms));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 继续播放音乐
|
|
||||||
_sendCommand(MCI_RESUME);
|
|
||||||
m_bPlaying = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MciPlayer::stop()
|
|
||||||
{
|
|
||||||
// 停止音乐
|
|
||||||
_sendCommand(MCI_STOP);
|
|
||||||
m_bPlaying = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MciPlayer::rewind()
|
|
||||||
{
|
|
||||||
// 设备为空时,忽略这次操作
|
|
||||||
if (!m_dev)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 重置播放位置
|
|
||||||
mciSendCommand(m_dev, MCI_SEEK, MCI_SEEK_TO_START, 0);
|
|
||||||
// 播放音乐
|
|
||||||
MCI_PLAY_PARMS mciPlay = { 0 };
|
|
||||||
m_bPlaying = mciSendCommand(m_dev, MCI_PLAY, (m_bLoop ? MCI_DGV_PLAY_REPEAT : 0), reinterpret_cast<DWORD_PTR>(&mciPlay)) ? false : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MciPlayer::setVolume(float volume)
|
|
||||||
{
|
|
||||||
volume = min(max(volume, 0), 1);
|
|
||||||
MCI_DGV_SETAUDIO_PARMS mciSetAudioPara = { 0 };
|
|
||||||
mciSetAudioPara.dwItem = MCI_DGV_SETAUDIO_VOLUME;
|
|
||||||
mciSetAudioPara.dwValue = DWORD(1000 * volume);
|
|
||||||
mciSendCommand(m_dev, MCI_SETAUDIO, MCI_DGV_SETAUDIO_VALUE | MCI_DGV_SETAUDIO_ITEM, (DWORD_PTR)&mciSetAudioPara);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MciPlayer::isPlaying()
|
|
||||||
{
|
|
||||||
return m_bPlaying;
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT MciPlayer::getSoundID()
|
|
||||||
{
|
|
||||||
return m_nSoundID;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MciPlayer::_sendCommand(int nCommand, DWORD_PTR param1, DWORD_PTR parma2)
|
|
||||||
{
|
|
||||||
// 空设备时忽略这次操作
|
|
||||||
if (!m_dev)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 向当前设备发送操作
|
|
||||||
mciSendCommand(m_dev, nCommand, param1, parma2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// MusicUtils
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
typedef std::map<unsigned int, MciPlayer *> MusicList;
|
|
||||||
typedef std::pair<unsigned int, MciPlayer *> Music;
|
|
||||||
|
|
||||||
static unsigned int _Hash(TString key);
|
|
||||||
|
|
||||||
|
|
||||||
static MusicList& getMciPlayerList()
|
|
||||||
{
|
|
||||||
static MusicList s_List;
|
|
||||||
return s_List;
|
|
||||||
}
|
|
||||||
|
|
||||||
static MciPlayer& getBgMciPlayer()
|
|
||||||
{
|
|
||||||
static MciPlayer s_Music;
|
|
||||||
return s_Music;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MusicUtils::end()
|
|
||||||
{
|
|
||||||
// 停止背景音乐
|
|
||||||
getBgMciPlayer().close();
|
|
||||||
// 停止其他所有音乐
|
|
||||||
for (auto& iter : getMciPlayerList())
|
|
||||||
{
|
|
||||||
SafeDelete(iter.second);
|
|
||||||
}
|
|
||||||
// 清空音乐列表
|
|
||||||
getMciPlayerList().clear();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MusicUtils::setVolume(float volume)
|
|
||||||
{
|
|
||||||
// 设置背景音乐音量
|
|
||||||
getBgMciPlayer().setVolume(volume);
|
|
||||||
// 设置其他音乐音量
|
|
||||||
for (auto& iter : getMciPlayerList())
|
|
||||||
{
|
|
||||||
iter.second->setVolume(volume);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MusicUtils::setVolume(TString pszFilePath, float volume)
|
|
||||||
{
|
|
||||||
unsigned int nRet = ::_Hash(pszFilePath);
|
|
||||||
|
|
||||||
MusicList::iterator p = getMciPlayerList().find(nRet);
|
|
||||||
if (p != getMciPlayerList().end())
|
|
||||||
{
|
|
||||||
p->second->setVolume(volume);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MusicUtils::playBackgroundMusic(TString pszFilePath, bool bLoop)
|
|
||||||
{
|
|
||||||
if (pszFilePath.empty())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
getBgMciPlayer().open(pszFilePath, ::_Hash(pszFilePath));
|
|
||||||
getBgMciPlayer().play(bLoop);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MusicUtils::stopBackgroundMusic(bool bReleaseData)
|
|
||||||
{
|
|
||||||
if (bReleaseData)
|
|
||||||
{
|
|
||||||
getBgMciPlayer().close();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
getBgMciPlayer().stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MusicUtils::pauseBackgroundMusic()
|
|
||||||
{
|
|
||||||
getBgMciPlayer().pause();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MusicUtils::resumeBackgroundMusic()
|
|
||||||
{
|
|
||||||
getBgMciPlayer().resume();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MusicUtils::rewindBackgroundMusic()
|
|
||||||
{
|
|
||||||
getBgMciPlayer().rewind();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MusicUtils::isBackgroundMusicPlaying()
|
|
||||||
{
|
|
||||||
return getBgMciPlayer().isPlaying();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MusicUtils::setBackgroundMusicVolume(float volume)
|
|
||||||
{
|
|
||||||
getBgMciPlayer().setVolume(volume);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int MusicUtils::playMusic(TString pszFilePath, bool bLoop)
|
|
||||||
{
|
|
||||||
unsigned int nRet = ::_Hash(pszFilePath);
|
|
||||||
|
|
||||||
preloadMusic(pszFilePath);
|
|
||||||
|
|
||||||
MusicList::iterator p = getMciPlayerList().find(nRet);
|
|
||||||
if (p != getMciPlayerList().end())
|
|
||||||
{
|
|
||||||
p->second->play(bLoop);
|
|
||||||
}
|
|
||||||
return nRet;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MusicUtils::stopMusic(unsigned int nSoundId)
|
|
||||||
{
|
|
||||||
MusicList::iterator p = getMciPlayerList().find(nSoundId);
|
|
||||||
if (p != getMciPlayerList().end())
|
|
||||||
{
|
|
||||||
p->second->stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MusicUtils::preloadMusic(TString pszFilePath)
|
|
||||||
{
|
|
||||||
if (pszFilePath.empty()) return;
|
|
||||||
|
|
||||||
int nRet = ::_Hash(pszFilePath);
|
|
||||||
|
|
||||||
if (getMciPlayerList().end() != getMciPlayerList().find(nRet)) return;
|
|
||||||
|
|
||||||
getMciPlayerList().insert(Music(nRet, new MciPlayer()));
|
|
||||||
MciPlayer * pPlayer = getMciPlayerList()[nRet];
|
|
||||||
pPlayer->open(pszFilePath, nRet);
|
|
||||||
|
|
||||||
if (nRet == pPlayer->getSoundID()) return;
|
|
||||||
|
|
||||||
delete pPlayer;
|
|
||||||
getMciPlayerList().erase(nRet);
|
|
||||||
nRet = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MusicUtils::pauseMusic(unsigned int nSoundId)
|
|
||||||
{
|
|
||||||
MusicList::iterator p = getMciPlayerList().find(nSoundId);
|
|
||||||
if (p != getMciPlayerList().end())
|
|
||||||
{
|
|
||||||
p->second->pause();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MusicUtils::pauseAllMusics()
|
|
||||||
{
|
|
||||||
for (auto& iter : getMciPlayerList())
|
|
||||||
{
|
|
||||||
iter.second->pause();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MusicUtils::resumeMusic(unsigned int nSoundId)
|
|
||||||
{
|
|
||||||
MusicList::iterator p = getMciPlayerList().find(nSoundId);
|
|
||||||
if (p != getMciPlayerList().end())
|
|
||||||
{
|
|
||||||
p->second->resume();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MusicUtils::resumeAllMusics()
|
|
||||||
{
|
|
||||||
for (auto& iter : getMciPlayerList())
|
|
||||||
{
|
|
||||||
iter.second->resume();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MusicUtils::stopAllMusics()
|
|
||||||
{
|
|
||||||
for (auto& iter : getMciPlayerList())
|
|
||||||
{
|
|
||||||
iter.second->stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MusicUtils::unloadMusic(LPCTSTR pszFilePath)
|
|
||||||
{
|
|
||||||
unsigned int nID = ::_Hash(pszFilePath);
|
|
||||||
|
|
||||||
MusicList::iterator p = getMciPlayerList().find(nID);
|
|
||||||
if (p != getMciPlayerList().end())
|
|
||||||
{
|
|
||||||
SafeDelete(p->second);
|
|
||||||
getMciPlayerList().erase(nID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned int _Hash(TString key)
|
|
||||||
{
|
|
||||||
unsigned int len = unsigned(key.size());
|
|
||||||
unsigned int hash = 0;
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < len; i++)
|
|
||||||
{
|
|
||||||
hash *= 16777619;
|
|
||||||
hash ^= (unsigned int)(unsigned char)toupper(key[i]);
|
|
||||||
}
|
|
||||||
return (hash);
|
|
||||||
}
|
|
||||||
|
|
@ -1,223 +0,0 @@
|
||||||
#include "..\easy2d.h"
|
|
||||||
#include "..\Win\winbase.h"
|
|
||||||
|
|
||||||
// 储存所有定时器的容器
|
|
||||||
static std::vector<Timer*> s_vTimers;
|
|
||||||
|
|
||||||
Timer::Timer(TString name, LONGLONG milliSeconds, const TIMER_CALLBACK & callback) :
|
|
||||||
m_sName(name),
|
|
||||||
m_bRunning(false),
|
|
||||||
m_bWaiting(false),
|
|
||||||
m_callback(callback),
|
|
||||||
m_pParentScene(nullptr)
|
|
||||||
{
|
|
||||||
setInterval(milliSeconds); // 设置定时器的时间间隔
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer::~Timer()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Timer::start()
|
|
||||||
{
|
|
||||||
// 标志该定时器正在运行
|
|
||||||
m_bRunning = true;
|
|
||||||
// 记录当前时间
|
|
||||||
m_nLast = steady_clock::now();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Timer::stop()
|
|
||||||
{
|
|
||||||
m_bRunning = false; // 标志该定时器已停止
|
|
||||||
}
|
|
||||||
|
|
||||||
void Timer::wait()
|
|
||||||
{
|
|
||||||
m_bWaiting = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Timer::notify()
|
|
||||||
{
|
|
||||||
m_bWaiting = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Timer::isRunning()
|
|
||||||
{
|
|
||||||
return m_bRunning && !m_bWaiting; // 获取该定时器的运行状态
|
|
||||||
}
|
|
||||||
|
|
||||||
void Timer::setInterval(LONGLONG milliSeconds)
|
|
||||||
{
|
|
||||||
// 设置定时器的时间间隔
|
|
||||||
m_nAnimationInterval = milliSeconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Timer::setCallback(const TIMER_CALLBACK & callback)
|
|
||||||
{
|
|
||||||
m_callback = callback; // 保存回调函数
|
|
||||||
}
|
|
||||||
|
|
||||||
void Timer::setName(TString name)
|
|
||||||
{
|
|
||||||
m_sName = name; // 修改定时器名称
|
|
||||||
}
|
|
||||||
|
|
||||||
LONGLONG Timer::getInterval() const
|
|
||||||
{
|
|
||||||
return m_nAnimationInterval;// 获取定时器的时间间隔
|
|
||||||
}
|
|
||||||
|
|
||||||
TString Timer::getName() const
|
|
||||||
{
|
|
||||||
return m_sName; // 获取定时器的名称
|
|
||||||
}
|
|
||||||
|
|
||||||
void Timer::__exec()
|
|
||||||
{
|
|
||||||
// 定时器容器为空
|
|
||||||
if (!s_vTimers.size())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 循环遍历所有的定时器
|
|
||||||
for (auto timer : s_vTimers)
|
|
||||||
{
|
|
||||||
// 若定时器未运行,跳过这个定时器
|
|
||||||
if (!timer->isRunning())
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// 判断时间间隔是否足够
|
|
||||||
while (duration_cast<milliseconds>(GetNow() - timer->m_nLast).count() > timer->m_nAnimationInterval)
|
|
||||||
{
|
|
||||||
// 重新记录时间
|
|
||||||
timer->m_nLast += milliseconds(timer->m_nAnimationInterval);
|
|
||||||
// 运行回调函数
|
|
||||||
timer->m_callback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Timer::addTimer(Timer * timer)
|
|
||||||
{
|
|
||||||
// 启动定时器
|
|
||||||
timer->start();
|
|
||||||
// 绑定在场景上
|
|
||||||
timer->m_pParentScene = EApp::getLoadingScene();
|
|
||||||
// 将该定时器放入容器
|
|
||||||
s_vTimers.push_back(timer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Timer::addTimer(TString name, const TIMER_CALLBACK & callback)
|
|
||||||
{
|
|
||||||
addTimer(name, 20, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Timer::addTimer(TString name, LONGLONG milliSeconds, const TIMER_CALLBACK & callback)
|
|
||||||
{
|
|
||||||
// 创建定时器
|
|
||||||
auto timer = new Timer(name, milliSeconds, callback);
|
|
||||||
// 添加定时器
|
|
||||||
addTimer(timer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Timer::startTimer(TString name)
|
|
||||||
{
|
|
||||||
// 查找名称相同的定时器
|
|
||||||
for (auto timer : s_vTimers)
|
|
||||||
{
|
|
||||||
if (timer->m_sName == name && timer->m_pParentScene == EApp::getCurrentScene())
|
|
||||||
{
|
|
||||||
// 启动定时器
|
|
||||||
timer->start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Timer::stopTimer(TString name)
|
|
||||||
{
|
|
||||||
// 查找名称相同的定时器
|
|
||||||
for (auto timer : s_vTimers)
|
|
||||||
{
|
|
||||||
if (timer->m_sName == name && timer->m_pParentScene == EApp::getCurrentScene())
|
|
||||||
{
|
|
||||||
// 停止定时器
|
|
||||||
timer->stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Timer::delTimer(TString name)
|
|
||||||
{
|
|
||||||
// 创建迭代器
|
|
||||||
std::vector<Timer*>::iterator iter;
|
|
||||||
// 循环遍历所有定时器
|
|
||||||
for (iter = s_vTimers.begin(); iter != s_vTimers.end();)
|
|
||||||
{
|
|
||||||
// 查找相同名称的定时器
|
|
||||||
if ((*iter)->m_sName == name && (*iter)->m_pParentScene == EApp::getCurrentScene())
|
|
||||||
{
|
|
||||||
// 删除该定时器
|
|
||||||
delete (*iter);
|
|
||||||
iter = s_vTimers.erase(iter);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Timer::clearAllTimers()
|
|
||||||
{
|
|
||||||
// 删除所有定时器
|
|
||||||
for (auto t : s_vTimers)
|
|
||||||
{
|
|
||||||
delete t;
|
|
||||||
}
|
|
||||||
// 清空容器
|
|
||||||
s_vTimers.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Timer::notifyAllSceneTimers(EScene * scene)
|
|
||||||
{
|
|
||||||
for (auto t : s_vTimers)
|
|
||||||
{
|
|
||||||
if (t->m_pParentScene == scene)
|
|
||||||
{
|
|
||||||
t->notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Timer::waitAllSceneTimers(EScene * scene)
|
|
||||||
{
|
|
||||||
for (auto t : s_vTimers)
|
|
||||||
{
|
|
||||||
if (t->m_pParentScene == scene)
|
|
||||||
{
|
|
||||||
t->wait();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Timer::clearAllSceneTimers(EScene * scene)
|
|
||||||
{
|
|
||||||
// 创建迭代器
|
|
||||||
std::vector<Timer*>::iterator iter;
|
|
||||||
// 循环遍历所有定时器
|
|
||||||
for (iter = s_vTimers.begin(); iter != s_vTimers.end();)
|
|
||||||
{
|
|
||||||
// 查找相同名称的定时器
|
|
||||||
if ((*iter)->m_pParentScene == scene)
|
|
||||||
{
|
|
||||||
// 删除该定时器
|
|
||||||
delete (*iter);
|
|
||||||
iter = s_vTimers.erase(iter);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
iter++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
1662
Easy2D/v1/easy2d.h
1662
Easy2D/v1/easy2d.h
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue