From 35227bb85b18840e6a243d3bfec90775c49c70c2 Mon Sep 17 00:00:00 2001 From: werelone <569629550@qq.com> Date: Wed, 20 Sep 2017 14:52:50 +0800 Subject: [PATCH] Easy2D v1.0.4 --- Easy2D/App.cpp | 27 +- Easy2D/Msg/KeyMsg.cpp | 14 +- Easy2D/Msg/MouseMsg.cpp | 46 +--- Easy2D/Node/Image.cpp | 41 ++-- Easy2D/Node/MouseNode.cpp | 4 +- Easy2D/Tool/FileUtils.cpp | 123 ++++++++++ Easy2D/Tool/MusicUtils.cpp | 390 +++++++++++++---------------- Easy2D/Tool/Timer.cpp | 2 +- Easy2D/easy2d.h | 488 +++++++++++++++++++------------------ 9 files changed, 621 insertions(+), 514 deletions(-) diff --git a/Easy2D/App.cpp b/Easy2D/App.cpp index dee43bb6..811fea1f 100644 --- a/Easy2D/App.cpp +++ b/Easy2D/App.cpp @@ -7,6 +7,8 @@ #include #pragma comment(lib, "winmm.lib") +// Easy2D 版本号 +#define E2D_VERSION _T("1.0.4") // App 的唯一实例 static App * s_pInstance = nullptr; @@ -144,10 +146,11 @@ void App::_initGraph() TCHAR title[31]; GetWindowText(GetHWnd(), title, 30); m_sTitle = title; + m_sAppName = title; } else { - setWindowText(m_sTitle); + setWindowTitle(m_sTitle); } } @@ -197,6 +200,7 @@ void App::createWindow(tstring title, int width, int height, int mode) m_nHeight = height; m_nWindowMode = mode; m_sTitle = title; + m_sAppName = title; // 创建窗口 _initGraph(); } @@ -231,7 +235,7 @@ void App::setWindowSize(int width, int height) reset(); } -void App::setWindowText(tstring title) +void App::setWindowTitle(tstring title) { // 设置窗口标题 SetWindowText(GetHWnd(), title.c_str()); @@ -239,6 +243,11 @@ void App::setWindowText(tstring title) m_sTitle = title; } +tstring App::getWindowTitle() +{ + return m_sTitle; +} + void App::close() { closegraph(); // 关闭绘图环境 @@ -271,6 +280,16 @@ void App::clearScene() } } +void App::setAppName(tstring appname) +{ + m_sAppName = appname; +} + +tstring App::getAppName() const +{ + return m_sAppName; +} + void App::setBkColor(COLORREF color) { setbkcolor(color); @@ -321,9 +340,9 @@ Scene * App::getCurrentScene() return m_currentScene; } -LPCTSTR easy2d::App::getVersion() +LPCTSTR App::getVersion() { - return _T("1.0.2"); + return E2D_VERSION; } void App::setFPS(DWORD fps) diff --git a/Easy2D/Msg/KeyMsg.cpp b/Easy2D/Msg/KeyMsg.cpp index eb483847..faa2c67f 100644 --- a/Easy2D/Msg/KeyMsg.cpp +++ b/Easy2D/Msg/KeyMsg.cpp @@ -116,7 +116,7 @@ void KeyMsg::addListener(tstring name, const KEY_CALLBACK & callback) s_vKeyMsg.push_back(key); } -bool KeyMsg::deleteListener(tstring name) +bool KeyMsg::delListener(tstring name) { // 创建迭代器 std::vector::iterator iter; @@ -136,7 +136,7 @@ bool KeyMsg::deleteListener(tstring name) return false; } -void KeyMsg::clearAllListener() +void KeyMsg::clearAllListeners() { // 删除所有监听器 for (auto k : s_vKeyMsg) @@ -156,18 +156,26 @@ bool KeyMsg::isKeyDown(VK_KEY key) VK_KEY convert(int ascii) { - if (ascii >= 'a' && ascii <= 'z' || ascii >= 'A' && ascii <= 'Z') + // 字母键 + 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()) diff --git a/Easy2D/Msg/MouseMsg.cpp b/Easy2D/Msg/MouseMsg.cpp index f4d459a0..0e8a33c8 100644 --- a/Easy2D/Msg/MouseMsg.cpp +++ b/Easy2D/Msg/MouseMsg.cpp @@ -5,24 +5,21 @@ static std::vector s_vMouseMsg; // 鼠标消息 -static MouseMsg s_mouseMsg = MouseMsg(); - -// 将 EasyX 的 MOUSEMSG 转换为 MouseMsg -static void ConvertMsg(MOUSEMSG msg); +static MOUSEMSG s_mouseMsg; void MouseMsg::__exec() { // 获取鼠标消息 while (MouseHit()) { - // 转换鼠标消息 - ConvertMsg(GetMouseMsg()); + // 获取鼠标消息 + s_mouseMsg = GetMouseMsg(); // 执行场景程序 App::get()->getCurrentScene()->_exec(); // 执行鼠标监听回调函数 - for (auto m : s_vMouseMsg) // 循环遍历所有的鼠标监听 + for (auto m : s_vMouseMsg) // 循环遍历所有的鼠标监听 { - m->onMouseMsg(s_mouseMsg); // 执行回调函数 + m->onMouseMsg(); // 执行回调函数 } } } @@ -41,9 +38,9 @@ MouseMsg::~MouseMsg() { } -void MouseMsg::onMouseMsg(MouseMsg mouse) +void MouseMsg::onMouseMsg() { - m_callback(mouse); + m_callback(); } void MouseMsg::addListener(tstring name, const MOUSE_CALLBACK & callback) @@ -54,7 +51,7 @@ void MouseMsg::addListener(tstring name, const MOUSE_CALLBACK & callback) s_vMouseMsg.push_back(mouse); } -bool MouseMsg::deleteListener(tstring name) +bool MouseMsg::delListener(tstring name) { // 创建迭代器 std::vector::iterator iter; @@ -74,7 +71,7 @@ bool MouseMsg::deleteListener(tstring name) return false; } -void MouseMsg::clearAllListener() +void MouseMsg::clearAllListeners() { // 删除所有监听器 for (auto m : s_vMouseMsg) @@ -85,11 +82,6 @@ void MouseMsg::clearAllListener() s_vMouseMsg.clear(); } -MouseMsg MouseMsg::getMsg() -{ - return s_mouseMsg; // 获取当前鼠标消息 -} - bool MouseMsg::isLButtonDown() { return s_mouseMsg.mkLButton; @@ -105,17 +97,17 @@ bool MouseMsg::isMButtonDown() return s_mouseMsg.mkMButton; } -int MouseMsg::getMouseX() +int MouseMsg::getX() { return s_mouseMsg.x; } -int MouseMsg::getMouseY() +int MouseMsg::getY() { return s_mouseMsg.y; } -int MouseMsg::getMouseWheel() +int MouseMsg::getWheel() { return s_mouseMsg.wheel; } @@ -179,17 +171,3 @@ void MouseMsg::resetMouseMsg() { s_mouseMsg.uMsg = 0; } - -void ConvertMsg(MOUSEMSG msg) -{ - // 将 MOUSEMSG 转换为 MouseMsg - /// 虽然 MOUSEMSG 和 MouseMsg 本质上是一样的 - /// 但是为了实现 Easy2D 与 EasyX 的分离,所以定义了新的 MouseMsg - s_mouseMsg.uMsg = msg.uMsg; - s_mouseMsg.mkLButton = msg.mkLButton; - s_mouseMsg.mkMButton = msg.mkMButton; - s_mouseMsg.mkRButton = msg.mkRButton; - s_mouseMsg.wheel = msg.wheel; - s_mouseMsg.x = msg.x; - s_mouseMsg.y = msg.y; -} diff --git a/Easy2D/Node/Image.cpp b/Easy2D/Node/Image.cpp index 8b39fdda..3b96aad9 100644 --- a/Easy2D/Node/Image.cpp +++ b/Easy2D/Node/Image.cpp @@ -10,6 +10,13 @@ Image::Image() : { } +Image::Image(LPCTSTR ImageFile) : + m_fScaleX(1), + m_fScaleY(1) +{ + setImage(ImageFile); // 设置图片资源 +} + Image::Image(LPCTSTR ImageFile, int x, int y, int width, int height) : m_fScaleX(1), m_fScaleY(1) @@ -82,6 +89,9 @@ bool Image::setImage(LPCTSTR ImageFile) // 设置目标矩形(即绘制到窗口的位置和大小) m_rDest.SetRect(m_nX, m_nY, m_nX + m_Image.GetWidth(), m_nY + m_Image.GetHeight()); m_rSrc.SetRect(0, 0, m_Image.GetWidth(), m_Image.GetHeight()); + // 重置缩放属性 + m_fScaleX = 1; + m_fScaleY = 1; return true; } @@ -110,6 +120,9 @@ bool Image::setImageFromRes(LPCTSTR pResName) // 设置目标矩形(即绘制到窗口的位置和大小) m_rDest.SetRect(m_nX, m_nY, m_nX + m_Image.GetWidth(), m_nY + m_Image.GetHeight()); m_rSrc.SetRect(0, 0, m_Image.GetWidth(), m_Image.GetHeight()); + // 重置缩放属性 + m_fScaleX = 1; + m_fScaleY = 1; return true; } @@ -128,25 +141,23 @@ bool Image::setImageFromRes(LPCTSTR pResName, int x, int y, int width, int heigh void Image::crop(int x, int y, int width, int height) { + width = min(max(width, 0), m_Image.GetWidth()); + height = min(max(height, 0), m_Image.GetHeight()); // 设置源矩形的位置和大小(用于裁剪) - m_rSrc.SetRect( - x, y, - x + (width ? width : m_Image.GetWidth() - x), - y + (height ? height : m_Image.GetHeight() - y)); + m_rSrc.SetRect(x, y, x + width, y + height); // 设置目标矩形(即绘制到窗口的位置和大小) - m_rDest.SetRect( - m_nX, m_nY, - m_nX + (width ? width : int(m_rSrc.Width() * m_fScaleX)), - m_nY + (height ? height : int(m_rSrc.Height() * m_fScaleY))); + m_rDest.SetRect(m_nX, m_nY, m_nX + int(width * m_fScaleX), m_nY + int(height * m_fScaleY)); } void Image::stretch(int width, int height) { + width = max(width, 0); + height = max(height, 0); // 设置目标矩形的位置和大小(即绘制到窗口的位置和大小,用于拉伸图片) - m_rDest.SetRect( - m_nX, m_nY, - m_nX + (width ? width : m_Image.GetWidth()), - m_nY + (height ? height : m_Image.GetHeight())); + m_rDest.SetRect(m_nX, m_nY, m_nX + width, m_nY + height); + // 重置比例缩放属性 + m_fScaleX = 1; + m_fScaleY = 1; } void Image::scale(float scaleX, float scaleY) @@ -155,8 +166,8 @@ void Image::scale(float scaleX, float scaleY) m_fScaleY = max(scaleY, 0); m_rDest.SetRect( m_nX, m_nY, - m_nX + int(m_Image.GetWidth() * scaleX), - m_nY + int(m_Image.GetHeight() * scaleY)); + m_nX + int(m_rSrc.Width() * scaleX), + m_nY + int(m_rSrc.Height() * scaleY)); } void Image::setPos(int x, int y) @@ -195,7 +206,7 @@ void Image::setTransparentColor(COLORREF value) m_Image.SetTransparentColor(value); } -void Image::screenshot() +void Image::saveScreenshot() { tstring savePath; // 获取保存位置 diff --git a/Easy2D/Node/MouseNode.cpp b/Easy2D/Node/MouseNode.cpp index 6c67c3d9..0187ecdf 100644 --- a/Easy2D/Node/MouseNode.cpp +++ b/Easy2D/Node/MouseNode.cpp @@ -98,8 +98,8 @@ void MouseNode::_onDraw() bool MouseNode::_judge() { - return (MouseMsg::getMsg().x >= m_nX && MouseMsg::getMsg().x <= m_nX + m_nWidth) && - (MouseMsg::getMsg().y >= m_nY && MouseMsg::getMsg().y <= m_nY + m_nHeight); + return (MouseMsg::getX() >= m_nX && MouseMsg::getX() <= m_nX + m_nWidth) && + (MouseMsg::getY() >= m_nY && MouseMsg::getY() <= m_nY + m_nHeight); } void MouseNode::_setStatus(Status status) diff --git a/Easy2D/Tool/FileUtils.cpp b/Easy2D/Tool/FileUtils.cpp index 067cca17..811fb46d 100644 --- a/Easy2D/Tool/FileUtils.cpp +++ b/Easy2D/Tool/FileUtils.cpp @@ -1,7 +1,130 @@ #include "..\Easy2d.h" #include "..\EasyX\easyx.h" #include +#include +#include +#pragma comment(lib, "shell32.lib") +#ifndef UNICODE + #include + #include +#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(App::get()->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 +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) { diff --git a/Easy2D/Tool/MusicUtils.cpp b/Easy2D/Tool/MusicUtils.cpp index 33fed5da..8b215cf1 100644 --- a/Easy2D/Tool/MusicUtils.cpp +++ b/Easy2D/Tool/MusicUtils.cpp @@ -1,8 +1,5 @@ #include "..\Easy2d.h" - - -/* 注:MusicUtils 类完全仿照 Cocos2dx 中的 SimpleAudioEngine 实现 */ - +#include #include #pragma comment(lib , "winmm.lib") #include @@ -17,210 +14,184 @@ public: MciPlayer(); ~MciPlayer(); - void Close(); - void Open(tstring pFileName, UINT uId); - void Play(UINT uTimes = 1); - void Pause(); - void Resume(); - void Stop(); - void Rewind(); - bool IsPlaying(); - UINT GetSoundID(); + 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: - friend LRESULT WINAPI _SoundPlayProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); + void _sendCommand(int nCommand, DWORD_PTR param1 = 0, DWORD_PTR parma2 = 0); - void _SendGenericCommand(int nCommand, DWORD_PTR param1 = 0, DWORD_PTR parma2 = 0); - - HWND _wnd; - MCIDEVICEID _dev; - UINT _soundID; - UINT _times; - bool _playing; - tstring strExt; + MCIDEVICEID m_dev; + UINT m_nSoundID; + bool m_bPlaying; + bool m_bLoop; + tstring m_sExt; }; - -#define WIN_CLASS_NAME "Easy2dCallbackWnd" - -static HINSTANCE s_hInstance; -static MCIERROR s_mciError; - -LRESULT WINAPI _SoundPlayProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); - -MciPlayer::MciPlayer() - : _wnd(NULL) - , _dev(0L) - , _soundID(0) - , _times(0) - , _playing(false) - , strExt(_T("")) +MciPlayer::MciPlayer() : + m_dev(0L), + m_nSoundID(0), + m_bPlaying(false), + m_bLoop(false), + m_sExt(_T("")) { - if (!s_hInstance) - { - s_hInstance = GetModuleHandle(NULL); // Grab An Instance For Our Window - - WNDCLASS wc; // Windows Class Structure - - // Redraw On Size, And Own DC For Window. - wc.style = 0; - wc.lpfnWndProc = _SoundPlayProc; // WndProc Handles Messages - wc.cbClsExtra = 0; // No Extra Window Data - wc.cbWndExtra = 0; // No Extra Window Data - wc.hInstance = s_hInstance; // Set The Instance - wc.hIcon = 0; // Load The Default Icon - wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load The Arrow Pointer - wc.hbrBackground = NULL; // No Background Required For GL - wc.lpszMenuName = NULL; // We Don't Want A Menu - wc.lpszClassName = _T(WIN_CLASS_NAME); // Set The Class Name - - if (!RegisterClass(&wc) // Register Our Class - && GetLastError() != 1410) // Class is Already Existent - { - return; - } - } - - _wnd = CreateWindowEx( - WS_EX_APPWINDOW, // Extended Style For The Window - _T(WIN_CLASS_NAME), // Class Name - NULL, // Window Title - WS_POPUPWINDOW, // Defined Window Style - 0, 0, // Window Position - 0, 0, // Window Width And Height - NULL, // No Parent Window - NULL, // No Menu - s_hInstance, // Instance - NULL); // No Param - - if (_wnd) - { - SetWindowLongPtr(_wnd, GWLP_USERDATA, (LONG_PTR)this); - } } MciPlayer::~MciPlayer() { - Close(); - DestroyWindow(_wnd); + close(); // 关闭播放器 } -void MciPlayer::Open(tstring pFileName, UINT uId) +void MciPlayer::open(tstring pFileName, UINT uId) { - if (pFileName.empty() || !_wnd) return; - int nLen = (int)pFileName.size(); - if (!nLen) return; - - strExt = FileUtils::getFileExtension(pFileName); - - Close(); + // 忽略不存在的文件 + if (pFileName.empty() || !PathFileExists(pFileName.c_str())) return; + // 获取文件后缀名 + m_sExt = FileUtils::getFileExtension(pFileName); + // 停止当前音乐 + close(); + // 设置 MCI_OPEN_PARMS 参数 MCI_OPEN_PARMS mciOpen = { 0 }; - MCIERROR mciError; mciOpen.lpstrDeviceType = (LPCTSTR)MCI_ALL_DEVICE_ID; mciOpen.lpstrElementName = pFileName.c_str(); + // 打开这个文件 + MCIERROR mciError; mciError = mciSendCommand(0, MCI_OPEN, MCI_OPEN_ELEMENT, reinterpret_cast(&mciOpen)); + // 出现错误时,忽略这次操作 if (mciError) return; - _dev = mciOpen.wDeviceID; - _soundID = uId; - _playing = false; + // 保存设备等信息 + m_dev = mciOpen.wDeviceID; + m_nSoundID = uId; + m_bPlaying = false; } -void MciPlayer::Play(UINT uTimes /* = 1 */) +void MciPlayer::play(bool bLoop) { - if (!_dev) + // 设备为空时,忽略这次操作 + if (!m_dev) { return; } + // 设置播放参数 MCI_PLAY_PARMS mciPlay = { 0 }; - mciPlay.dwCallback = reinterpret_cast(_wnd); - s_mciError = mciSendCommand(_dev, MCI_PLAY, MCI_FROM | MCI_NOTIFY, reinterpret_cast(&mciPlay)); + MCIERROR s_mciError; + // 播放声音 + s_mciError = mciSendCommand(m_dev, MCI_PLAY, MCI_FROM | (bLoop ? MCI_DGV_PLAY_REPEAT : 0), reinterpret_cast(&mciPlay)); + // 未出错时,置 m_bPlaying 为 true if (!s_mciError) { - _playing = true; - _times = uTimes; + m_bPlaying = true; + m_bLoop = bLoop; } } -void MciPlayer::Close() +void MciPlayer::close() { - if (_playing) + // 停止音乐 + if (m_bPlaying) { - Stop(); + stop(); } - if (_dev) + // 关闭设备 + if (m_dev) { - _SendGenericCommand(MCI_CLOSE); + _sendCommand(MCI_CLOSE); } - _dev = 0; - _playing = false; + // 恢复默认属性 + m_dev = 0; + m_bPlaying = false; } -void MciPlayer::Pause() +void MciPlayer::pause() { - _SendGenericCommand(MCI_PAUSE); - _playing = false; + // 暂停音乐 + _sendCommand(MCI_PAUSE); + m_bPlaying = false; } -void MciPlayer::Resume() +void MciPlayer::resume() { - if (strExt == _T(".mid")) + // 继续音乐 + if (m_sExt == _T(".mid")) { - // midi not support MCI_RESUME, should get the position and use MCI_FROM + // midi 不支持 MCI_RESUME 参数,应使用 MCI_FROM 设置播放起始位置 + // 获取 MCI 状态 MCI_STATUS_PARMS mciStatusParms; - MCI_PLAY_PARMS mciPlayParms; mciStatusParms.dwItem = MCI_STATUS_POSITION; - _SendGenericCommand(MCI_STATUS, MCI_STATUS_ITEM, reinterpret_cast(&mciStatusParms)); // MCI_STATUS - mciPlayParms.dwFrom = mciStatusParms.dwReturn; // get position - _SendGenericCommand(MCI_PLAY, MCI_FROM, reinterpret_cast(&mciPlayParms)); // MCI_FROM + _sendCommand(MCI_STATUS, MCI_STATUS_ITEM, reinterpret_cast(&mciStatusParms)); + // 设置播放起始位置,并开始播放 + MCI_PLAY_PARMS mciPlayParms; + mciPlayParms.dwFrom = mciStatusParms.dwReturn; + _sendCommand(MCI_PLAY, MCI_FROM, reinterpret_cast(&mciPlayParms)); } else { - _SendGenericCommand(MCI_RESUME); - _playing = true; + // 继续播放音乐 + _sendCommand(MCI_RESUME); + m_bPlaying = true; } } -void MciPlayer::Stop() +void MciPlayer::stop() { - _SendGenericCommand(MCI_STOP); - _playing = false; - _times = 0; + // 停止音乐 + _sendCommand(MCI_STOP); + m_bPlaying = false; } -void MciPlayer::Rewind() +void MciPlayer::rewind() { - if (!_dev) + // 设备为空时,忽略这次操作 + if (!m_dev) { return; } - mciSendCommand(_dev, MCI_SEEK, MCI_SEEK_TO_START, 0); - + // 重置播放位置 + mciSendCommand(m_dev, MCI_SEEK, MCI_SEEK_TO_START, 0); + // 播放音乐 MCI_PLAY_PARMS mciPlay = { 0 }; - mciPlay.dwCallback = reinterpret_cast(_wnd); - _playing = mciSendCommand(_dev, MCI_PLAY, MCI_NOTIFY, reinterpret_cast(&mciPlay)) ? false : true; + m_bPlaying = mciSendCommand(m_dev, MCI_PLAY, (m_bLoop ? MCI_DGV_PLAY_REPEAT : 0), reinterpret_cast(&mciPlay)) ? false : true; } -bool MciPlayer::IsPlaying() +void MciPlayer::setVolume(float volume) { - return _playing; + 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)(LPVOID)&mciSetAudioPara); } -UINT MciPlayer::GetSoundID() +bool MciPlayer::isPlaying() { - return _soundID; + return m_bPlaying; } -void MciPlayer::_SendGenericCommand(int nCommand, DWORD_PTR param1 /*= 0*/, DWORD_PTR parma2 /*= 0*/) +UINT MciPlayer::getSoundID() { - if (!_dev) + return m_nSoundID; +} + +void MciPlayer::_sendCommand(int nCommand, DWORD_PTR param1, DWORD_PTR parma2) +{ + // 空设备时忽略这次操作 + if (!m_dev) { return; } - mciSendCommand(_dev, nCommand, param1, parma2); + // 向当前设备发送操作 + mciSendCommand(m_dev, nCommand, param1, parma2); } @@ -234,17 +205,16 @@ void MciPlayer::_SendGenericCommand(int nCommand, DWORD_PTR param1 /*= 0*/, DWOR typedef std::map MusicList; typedef std::pair Music; - static unsigned int _Hash(tstring key); -static MusicList& sharedList() +static MusicList& getMciPlayerList() { static MusicList s_List; return s_List; } -static MciPlayer& sharedMusic() +static MciPlayer& getBgMciPlayer() { static MciPlayer s_Music; return s_Music; @@ -252,27 +222,39 @@ static MciPlayer& sharedMusic() void MusicUtils::end() { - sharedMusic().Close(); - - for (auto& iter : sharedList()) + // 停止背景音乐 + getBgMciPlayer().close(); + // 停止其他所有音乐 + for (auto& iter : getMciPlayerList()) { SAFE_DELETE(iter.second); } - sharedList().clear(); + // 清空音乐列表 + getMciPlayerList().clear(); return; } -////////////////////////////////////////////////////////////////////////// -// BackgroundMusic -////////////////////////////////////////////////////////////////////////// - -/* void MusicUtils::setVolume(float volume) { - if (volume < 0 || volume > 1) return; - waveOutSetVolume(NULL, DWORD(volume * 65535)); + // 设置背景音乐音量 + 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) { @@ -281,45 +263,46 @@ void MusicUtils::playBackgroundMusic(tstring pszFilePath, bool bLoop) return; } - sharedMusic().Open(pszFilePath, ::_Hash(pszFilePath)); - sharedMusic().Play((bLoop) ? -1 : 1); + getBgMciPlayer().open(pszFilePath, ::_Hash(pszFilePath)); + getBgMciPlayer().play(bLoop); } void MusicUtils::stopBackgroundMusic(bool bReleaseData) { if (bReleaseData) { - sharedMusic().Close(); + getBgMciPlayer().close(); } else { - sharedMusic().Stop(); + getBgMciPlayer().stop(); } } void MusicUtils::pauseBackgroundMusic() { - sharedMusic().Pause(); + getBgMciPlayer().pause(); } void MusicUtils::resumeBackgroundMusic() { - sharedMusic().Resume(); + getBgMciPlayer().resume(); } void MusicUtils::rewindBackgroundMusic() { - sharedMusic().Rewind(); + getBgMciPlayer().rewind(); } bool MusicUtils::isBackgroundMusicPlaying() { - return sharedMusic().IsPlaying(); + return getBgMciPlayer().isPlaying(); } -////////////////////////////////////////////////////////////////////////// -// effect function -////////////////////////////////////////////////////////////////////////// +void MusicUtils::setBackgroundMusicVolume(float volume) +{ + getBgMciPlayer().setVolume(volume); +} unsigned int MusicUtils::playMusic(tstring pszFilePath, bool bLoop) { @@ -327,20 +310,20 @@ unsigned int MusicUtils::playMusic(tstring pszFilePath, bool bLoop) preloadMusic(pszFilePath); - MusicList::iterator p = sharedList().find(nRet); - if (p != sharedList().end()) + MusicList::iterator p = getMciPlayerList().find(nRet); + if (p != getMciPlayerList().end()) { - p->second->Play((bLoop) ? -1 : 1); + p->second->play(bLoop); } return nRet; } void MusicUtils::stopMusic(unsigned int nSoundId) { - MusicList::iterator p = sharedList().find(nSoundId); - if (p != sharedList().end()) + MusicList::iterator p = getMciPlayerList().find(nSoundId); + if (p != getMciPlayerList().end()) { - p->second->Stop(); + p->second->stop(); } } @@ -350,58 +333,58 @@ void MusicUtils::preloadMusic(tstring pszFilePath) int nRet = ::_Hash(pszFilePath); - if (sharedList().end() != sharedList().find(nRet)) return; + if (getMciPlayerList().end() != getMciPlayerList().find(nRet)) return; - sharedList().insert(Music(nRet, new MciPlayer())); - MciPlayer * pPlayer = sharedList()[nRet]; - pPlayer->Open(pszFilePath, nRet); + getMciPlayerList().insert(Music(nRet, new MciPlayer())); + MciPlayer * pPlayer = getMciPlayerList()[nRet]; + pPlayer->open(pszFilePath, nRet); - if (nRet == pPlayer->GetSoundID()) return; + if (nRet == pPlayer->getSoundID()) return; delete pPlayer; - sharedList().erase(nRet); + getMciPlayerList().erase(nRet); nRet = 0; } void MusicUtils::pauseMusic(unsigned int nSoundId) { - MusicList::iterator p = sharedList().find(nSoundId); - if (p != sharedList().end()) + MusicList::iterator p = getMciPlayerList().find(nSoundId); + if (p != getMciPlayerList().end()) { - p->second->Pause(); + p->second->pause(); } } void MusicUtils::pauseAllMusics() { - for (auto& iter : sharedList()) + for (auto& iter : getMciPlayerList()) { - iter.second->Pause(); + iter.second->pause(); } } void MusicUtils::resumeMusic(unsigned int nSoundId) { - MusicList::iterator p = sharedList().find(nSoundId); - if (p != sharedList().end()) + MusicList::iterator p = getMciPlayerList().find(nSoundId); + if (p != getMciPlayerList().end()) { - p->second->Resume(); + p->second->resume(); } } void MusicUtils::resumeAllMusics() { - for (auto& iter : sharedList()) + for (auto& iter : getMciPlayerList()) { - iter.second->Resume(); + iter.second->resume(); } } void MusicUtils::stopAllMusics() { - for (auto& iter : sharedList()) + for (auto& iter : getMciPlayerList()) { - iter.second->Stop(); + iter.second->stop(); } } @@ -409,49 +392,16 @@ void MusicUtils::unloadMusic(LPCTSTR pszFilePath) { unsigned int nID = ::_Hash(pszFilePath); - MusicList::iterator p = sharedList().find(nID); - if (p != sharedList().end()) + MusicList::iterator p = getMciPlayerList().find(nID); + if (p != getMciPlayerList().end()) { SAFE_DELETE(p->second); - sharedList().erase(nID); + getMciPlayerList().erase(nID); } } -////////////////////////////////////////////////////////////////////////// -// static function -////////////////////////////////////////////////////////////////////////// - -LRESULT WINAPI _SoundPlayProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) -{ - MciPlayer * pPlayer = NULL; - if (MM_MCINOTIFY == Msg - && MCI_NOTIFY_SUCCESSFUL == wParam - && (pPlayer = (MciPlayer *)GetWindowLongPtr(hWnd, GWLP_USERDATA))) - { - if (pPlayer->_times) - { - --pPlayer->_times; - } - - if (pPlayer->_times) - { - mciSendCommand(lParam, MCI_SEEK, MCI_SEEK_TO_START, 0); - - MCI_PLAY_PARMS mciPlay = { 0 }; - mciPlay.dwCallback = reinterpret_cast(hWnd); - mciSendCommand(lParam, MCI_PLAY, MCI_NOTIFY, reinterpret_cast(&mciPlay)); - } - else - { - pPlayer->_playing = false; - } - return 0; - } - return DefWindowProc(hWnd, Msg, wParam, lParam); -} - unsigned int _Hash(tstring key) { unsigned int len = unsigned(key.size()); diff --git a/Easy2D/Tool/Timer.cpp b/Easy2D/Tool/Timer.cpp index aa62ff90..172a3652 100644 --- a/Easy2D/Tool/Timer.cpp +++ b/Easy2D/Tool/Timer.cpp @@ -151,7 +151,7 @@ bool Timer::stopTimer(tstring name) return false; } -bool Timer::deleteTimer(tstring name) +bool Timer::delTimer(tstring name) { // 创建迭代器 std::vector::iterator iter; diff --git a/Easy2D/easy2d.h b/Easy2D/easy2d.h index 33160c48..52dac1b6 100644 --- a/Easy2D/easy2d.h +++ b/Easy2D/easy2d.h @@ -1,5 +1,5 @@ /****************************************************** -* Easy2D Game Engine (v1.0.3) +* Easy2D Game Engine (v1.0.4) * http://www.easy2d.cn * * Depends on EasyX (Ver:20170827(beta)) @@ -89,34 +89,18 @@ typedef unsigned int VK_KEY; typedef std::function CLICK_CALLBACK; typedef std::function TIMER_CALLBACK; typedef std::function KEY_CALLBACK; -typedef std::function MOUSE_CALLBACK; +typedef std::function MOUSE_CALLBACK; class App { -protected: - tstring m_sTitle; - Scene* m_currentScene; - Scene* m_nextScene; - std::stack m_sceneStack; - LARGE_INTEGER m_nAnimationInterval; - int m_nWidth; - int m_nHeight; - int m_nWindowMode; - bool m_bRunning; - bool m_bSaveScene; - -protected: - void _initGraph(); - void _mainLoop(); - void _enterNextScene(); - public: App(); ~App(); // 窗口可选模式 enum { SHOW_CONSOLE = 1, NO_CLOSE = 2, NO_MINI_MIZE = 4 }; + // 获取程序实例 static App * get(); // 设置坐标原点 @@ -140,7 +124,9 @@ public: // 修改窗口大小 void setWindowSize(int width, int height); // 设置窗口标题 - void setWindowText(tstring title); + void setWindowTitle(tstring title); + // 获取窗口标题 + tstring getWindowTitle(); // 获取窗口宽度 int getWidth() const; // 获取窗口高度 @@ -151,6 +137,10 @@ public: void backScene(); // 清空之前保存的所有场景 void clearScene(); + // 设置 AppName + void setAppName(tstring appname); + // 获取 AppName + tstring getAppName() const; // 修改窗口背景色 void setBkColor(COLORREF color); // 设置帧率 @@ -165,6 +155,24 @@ public: Scene * getCurrentScene(); // 获取 Easy2D 版本号 LPCTSTR getVersion(); + +protected: + tstring m_sTitle; + tstring m_sAppName; + Scene* m_currentScene; + Scene* m_nextScene; + std::stack m_sceneStack; + LARGE_INTEGER m_nAnimationInterval; + int m_nWidth; + int m_nHeight; + int m_nWindowMode; + bool m_bRunning; + bool m_bSaveScene; + +protected: + void _initGraph(); + void _mainLoop(); + void _enterNextScene(); }; class FreePool @@ -184,13 +192,6 @@ class Scene friend class App; friend class MouseMsg; -protected: - std::vector m_vChildren; - -protected: - void _exec(); - void _onDraw(); - public: Scene(); ~Scene(); @@ -205,6 +206,13 @@ public: bool del(Node * child); // 清空所有子成员 void clearAllChildren(); + +protected: + std::vector m_vChildren; + +protected: + void _exec(); + void _onDraw(); }; @@ -212,40 +220,17 @@ class MouseMsg { friend class App; -private: - static void __exec(); - -protected: - tstring m_sName; - MOUSE_CALLBACK m_callback; - -public: - UINT uMsg; // 当前鼠标消息 - bool mkLButton; // 鼠标左键是否按下 - bool mkMButton; // 鼠标中键是否按下 - bool mkRButton; // 鼠标右键是否按下 - short x; // 当前鼠标 x 坐标 - short y; // 当前鼠标 y 坐标 - short wheel; // 鼠标滚轮滚动值 (120 的倍数) - public: MouseMsg(); MouseMsg(tstring name, const MOUSE_CALLBACK& callback); ~MouseMsg(); - // 执行回调函数 - void onMouseMsg(MouseMsg mouse); - // 添加键盘监听 static void addListener(tstring name, const MOUSE_CALLBACK& callback); // 删除键盘监听 - static bool deleteListener(tstring name); + static bool delListener(tstring name); // 删除所有键盘监听 - static void clearAllListener(); - -public: - // 获取当前鼠标消息 - static MouseMsg getMsg(); + static void clearAllListeners(); // 左键是否按下 static bool isLButtonDown(); // 右键是否按下 @@ -253,11 +238,11 @@ public: // 中键是否按下 static bool isMButtonDown(); // 获取鼠标X坐标 - static int getMouseX(); + static int getX(); // 获取鼠标Y坐标 - static int getMouseY(); + static int getY(); // 获取鼠标滚轮值 - static int getMouseWheel(); + static int getWheel(); // 鼠标移动消息 static bool isOnMouseMoved(); // 左键双击消息 @@ -282,6 +267,17 @@ public: static bool isOnWheel(); // 清空鼠标消息 static void resetMouseMsg(); + +private: + static void __exec(); + +protected: + tstring m_sName; + MOUSE_CALLBACK m_callback; + +protected: + // 执行回调函数 + void onMouseMsg(); }; @@ -289,6 +285,22 @@ class KeyMsg { friend class App; +public: + KeyMsg(tstring name, const KEY_CALLBACK& callback); + ~KeyMsg(); + + // 执行回调函数 + void onKbHit(VK_KEY key); + + // 添加键盘监听 + static void addListener(tstring name, const KEY_CALLBACK& callback); + // 删除键盘监听 + static bool delListener(tstring name); + // 删除所有键盘监听 + static void clearAllListeners(); + // 判断键是否被按下,按下返回true + static bool isKeyDown(VK_KEY key); + public: // 字母键值 static const VK_KEY A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z; @@ -307,28 +319,28 @@ private: protected: tstring m_sName; KEY_CALLBACK m_callback; - -public: - KeyMsg(tstring name, const KEY_CALLBACK& callback); - ~KeyMsg(); - - // 执行回调函数 - void onKbHit(VK_KEY key); - - // 添加键盘监听 - static void addListener(tstring name, const KEY_CALLBACK& callback); - // 删除键盘监听 - static bool deleteListener(tstring name); - // 删除所有键盘监听 - static void clearAllListener(); - // 判断键是否被按下,按下返回true - static bool isKeyDown(VK_KEY key); }; class FileUtils { public: + // 获取系统的 AppData\Local 路径 + static tstring getLocalAppDataPath(); + // 获取默认的保存路径 + static tstring getDefaultSavePath(); + // 保存 int 型的值 + static void saveInt(LPCTSTR key, int value); + // 保存 double 型的值 + static void saveDouble(LPCTSTR key, double value); + // 保存 字符串 型的值(不要在 Unicode 字符集下保存中文字符) + static void saveString(LPCTSTR key, tstring value); + // 获取 int 型的值(若不存在则返回 default 参数的值) + static int getInt(LPCTSTR key, int default); + // 获取 double 型的值(若不存在则返回 default 参数的值) + static double getDouble(LPCTSTR key, double default); + // 获取 字符串 型的值(若不存在则返回 default 参数的值) + static tstring getString(LPCTSTR key, tstring default); // 得到文件扩展名(小写) static tstring getFileExtension(const tstring& filePath); /** @@ -343,7 +355,7 @@ class MusicUtils { public: // 播放背景音乐 - static void playBackgroundMusic(tstring pszFilePath, bool bLoop = false); + static void playBackgroundMusic(tstring pszFilePath, bool bLoop = true); // 停止背景音乐 static void stopBackgroundMusic(bool bReleaseData = false); // 暂停背景音乐 @@ -354,6 +366,8 @@ public: static void rewindBackgroundMusic(); // 背景音乐是否正在播放 static bool isBackgroundMusicPlaying(); + // 设置背景音乐音量,0 ~ 1.0f + static void setBackgroundMusicVolume(float volume); // 播放音效 static unsigned int playMusic(tstring pszFilePath, bool loop = false); @@ -367,6 +381,8 @@ public: static void resumeMusic(unsigned int nSoundId); // 卸载音效 static void unloadMusic(LPCTSTR pszFilePath); + // 设置特定音乐的音量,0 ~ 1.0f + static void setVolume(tstring pszFilePath, float volume); // 暂停所有音乐 static void pauseAllMusics(); @@ -376,6 +392,8 @@ public: static void stopAllMusics(); // 停止所有音乐,并释放内存 static void end(); + // 设置总音量,0 ~ 1.0f + static void setVolume(float volume); }; @@ -383,17 +401,6 @@ class Timer { friend class App; -protected: - bool m_bRunning; - tstring m_sName; - TIMER_CALLBACK m_callback; - LARGE_INTEGER m_nLast; - LARGE_INTEGER m_nAnimationInterval; - UINT m_nMilliSeconds; - -private: - static void __exec(); - public: Timer(tstring name, UINT ms, const TIMER_CALLBACK & callback); ~Timer(); @@ -410,7 +417,6 @@ public: void setCallback(const TIMER_CALLBACK& callback); // 设置定时器名称 void setName(tstring name); - // 获取定时器间隔时间 UINT getInterval() const; // 获取定时器名称 @@ -427,9 +433,20 @@ public: // 停止特定定时器 static bool stopTimer(tstring name); // 删除特定定时器 - static bool deleteTimer(tstring name); + static bool delTimer(tstring name); // 删除所有定时器 static void clearAllTimers(); + +protected: + bool m_bRunning; + tstring m_sName; + TIMER_CALLBACK m_callback; + LARGE_INTEGER m_nLast; + LARGE_INTEGER m_nAnimationInterval; + UINT m_nMilliSeconds; + +private: + static void __exec(); }; @@ -475,15 +492,15 @@ class Object { friend class FreePool; -protected: - int m_nRef; - public: Object(); virtual ~Object(); void retain(); void release(); + +protected: + int m_nRef; }; @@ -492,9 +509,6 @@ class FontStyle : { friend class Text; -protected: - LOGFONT m_font; - public: FontStyle(); /** @@ -528,6 +542,9 @@ public: void setOrientation(LONG value); // 设置字体抗锯齿,默认为true void setQuality(bool value); + +protected: + LOGFONT m_font; }; @@ -555,18 +572,6 @@ class Node : friend class Scene; friend class BatchNode; -protected: - int m_nZOrder; - bool m_bDisplay; - Scene* m_pScene; - int m_nX; - int m_nY; - -protected: - virtual bool _exec(bool active); - virtual void _onDraw() = 0; - void setParentScene(Scene * scene); - public: Node(); Node(int x, int y); @@ -594,19 +599,24 @@ public: virtual void setZOrder(int z); // 获取节点所在场景 Scene * getParentScene(); + +protected: + int m_nZOrder; + bool m_bDisplay; + Scene* m_pScene; + int m_nX; + int m_nY; + +protected: + virtual bool _exec(bool active); + virtual void _onDraw() = 0; + void setParentScene(Scene * scene); }; class BatchNode : public virtual Node { -protected: - std::vector m_vChildren; - -protected: - virtual bool _exec(bool active) override; - virtual void _onDraw() override; - public: BatchNode(); virtual ~BatchNode(); @@ -617,18 +627,19 @@ public: bool del(Node * child); // 清空所有子节点 void clearAllChildren(); + +protected: + std::vector m_vChildren; + +protected: + virtual bool _exec(bool active) override; + virtual void _onDraw() override; }; class Layer : public virtual BatchNode { -protected: - bool m_bBlock; - -protected: - virtual bool _exec(bool active) override; - public: Layer(); virtual ~Layer(); @@ -637,6 +648,12 @@ public: int getBlock() const; // 设置图层是否阻塞消息 void setBlock(bool block); + +protected: + bool m_bBlock; + +protected: + virtual bool _exec(bool active) override; }; @@ -645,23 +662,15 @@ class Image : { friend class ImageButton; -protected: - CImage m_Image; - CRect m_rDest; - CRect m_rSrc; - float m_fScaleX; - float m_fScaleY; - -protected: - virtual void _onDraw() override; - public: Image(); + // 从图片文件获取图像 + Image(LPCTSTR ImageFile); /** - * 从图片文件获取图像(png/bmp/jpg/gif/emf/wmf/ico) + * 从图片文件获取图像 * 参数:图片文件名,图片裁剪坐标,图片裁剪宽度和高度 */ - Image(LPCTSTR ImageFile, int x = 0, int y = 0, int width = 0, int height = 0); + Image(LPCTSTR ImageFile, int x, int y, int width, int height); virtual ~Image(); // 获取图像宽度 @@ -674,23 +683,23 @@ public: float getScaleY() const; /** - * 从图片文件获取图像 (png/bmp/jpg/gif/emf/wmf/ico) + * 从图片文件获取图像 * 返回值:图片加载是否成功 */ bool setImage(LPCTSTR ImageFile); /** - * 从图片文件获取图像 (png/bmp/jpg/gif/emf/wmf/ico) + * 从图片文件获取图像 * 参数:图片文件名,图片裁剪起始坐标,图片裁剪宽度和高度 * 返回值:图片加载是否成功 */ bool setImage(LPCTSTR ImageFile, int x, int y, int width, int height); /** - * 从资源文件获取图像,不支持 png (bmp/jpg/gif/emf/wmf/ico) + * 从资源文件获取图像,不支持 png * 返回值:图片加载是否成功 */ bool setImageFromRes(LPCTSTR pResName); /** - * 从资源文件获取图像,不支持 png (bmp/jpg/gif/emf/wmf/ico) + * 从资源文件获取图像,不支持 png * 参数:资源名称,图片裁剪坐标,图片裁剪宽度和高度 * 返回值:图片加载是否成功 */ @@ -698,7 +707,7 @@ public: // 裁剪图片(裁剪后会恢复 stretch 拉伸) void crop(int x, int y, int width, int height); // 将图片拉伸到固定宽高 - void stretch(int width = 0, int height = 0); + void stretch(int width, int height); // 按比例拉伸图片 void scale(float scaleX = 1.0f, float scaleY = 1.0f); // 设置图片位置 @@ -711,8 +720,18 @@ public: void setY(int y) override; // 设置透明色 void setTransparentColor(COLORREF value); - // 保存到截图 - static void screenshot(); + // 保存游戏截图 + static void saveScreenshot(); + +protected: + CImage m_Image; + CRect m_rDest; + CRect m_rSrc; + float m_fScaleX; + float m_fScaleY; + +protected: + virtual void _onDraw() override; }; @@ -721,14 +740,6 @@ class Text : { friend class TextButton; -protected: - tstring m_sText; - COLORREF m_color; - FontStyle * m_pFontStyle; - -protected: - virtual void _onDraw() override; - public: Text(); // 根据字符串、颜色和字体创建文字 @@ -756,12 +767,43 @@ public: void setColor(COLORREF color); // 设置字体 void setFontStyle(FontStyle * style); + +protected: + tstring m_sText; + COLORREF m_color; + FontStyle * m_pFontStyle; + +protected: + virtual void _onDraw() override; }; class MouseNode : public virtual Node { +public: + MouseNode(); + virtual ~MouseNode(); + + // 鼠标是否移入 + virtual bool isMouseIn(); + // 鼠标是否选中 + virtual bool isSelected(); + // 设置回调函数 + virtual void setClickedCallback(const CLICK_CALLBACK & callback); + // 设置回调函数 + virtual void setMouseInCallback(const CLICK_CALLBACK & callback); + // 设置回调函数 + virtual void setMouseOutCallback(const CLICK_CALLBACK & callback); + // 设置回调函数 + virtual void setSelectCallback(const CLICK_CALLBACK & callback); + // 设置回调函数 + virtual void setUnselectCallback(const CLICK_CALLBACK & callback); + // 重置状态 + virtual void reset(); + // 设置节点是否阻塞鼠标消息 + void setBlock(bool block); + private: bool m_bTarget; bool m_bBlock; @@ -790,35 +832,21 @@ protected: virtual void _onMouseIn() = 0; // 鼠标选中时 virtual void _onSelected() = 0; - -public: - MouseNode(); - virtual ~MouseNode(); - - // 鼠标是否移入 - virtual bool isMouseIn(); - // 鼠标是否选中 - virtual bool isSelected(); - // 设置回调函数 - virtual void setClickedCallback(const CLICK_CALLBACK & callback); - // 设置回调函数 - virtual void setMouseInCallback(const CLICK_CALLBACK & callback); - // 设置回调函数 - virtual void setMouseOutCallback(const CLICK_CALLBACK & callback); - // 设置回调函数 - virtual void setSelectCallback(const CLICK_CALLBACK & callback); - // 设置回调函数 - virtual void setUnselectCallback(const CLICK_CALLBACK & callback); - // 重置状态 - virtual void reset(); - // 设置节点是否阻塞鼠标消息 - void setBlock(bool block); }; class Button : public virtual MouseNode { +public: + Button(); + virtual ~Button(); + + // 按钮是否启用 + virtual bool isEnable(); + // 设置是否启用 + virtual void setEnable(bool enable); + protected: bool m_bEnable; @@ -830,15 +858,6 @@ protected: virtual void _onMouseIn() = 0; virtual void _onSelected() = 0; virtual void _onDisable() = 0; - -public: - Button(); - virtual ~Button(); - - // 按钮是否启用 - virtual bool isEnable(); - // 设置是否启用 - virtual void setEnable(bool enable); }; @@ -846,21 +865,6 @@ public: class TextButton : public virtual Button { -protected: - Text * m_pNormalText; - Text * m_pMouseInText; - Text * m_pSelectedText; - Text * m_pUnableText; - -protected: - // 重置文字位置(居中显示) - void resetTextPosition(); - - virtual void _onNormal() override; - virtual void _onMouseIn() override; - virtual void _onSelected() override; - virtual void _onDisable() override; - public: TextButton(); TextButton(tstring text); @@ -882,6 +886,21 @@ public: virtual void setY(int y) override; // 设置按钮横纵坐标 virtual void setPos(int x, int y) override; + +protected: + Text * m_pNormalText; + Text * m_pMouseInText; + Text * m_pSelectedText; + Text * m_pUnableText; + +protected: + // 重置文字位置(居中显示) + void resetTextPosition(); + + virtual void _onNormal() override; + virtual void _onMouseIn() override; + virtual void _onSelected() override; + virtual void _onDisable() override; }; @@ -889,21 +908,6 @@ public: class ImageButton : public virtual Button { -protected: - Image * m_pNormalImage; - Image * m_pMouseInImage; - Image * m_pSelectedImage; - Image * m_pUnableImage; - -protected: - // 重置图片位置(居中显示) - void resetImagePosition(); - - virtual void _onNormal() override; - virtual void _onMouseIn() override; - virtual void _onSelected() override; - virtual void _onDisable() override; - public: ImageButton(); ImageButton(LPCTSTR image); @@ -925,29 +929,33 @@ public: virtual void setY(int y) override; // 设置按钮横纵坐标 virtual void setPos(int x, int y) override; + +protected: + Image * m_pNormalImage; + Image * m_pMouseInImage; + Image * m_pSelectedImage; + Image * m_pUnableImage; + +protected: + // 重置图片位置(居中显示) + void resetImagePosition(); + + virtual void _onNormal() override; + virtual void _onMouseIn() override; + virtual void _onSelected() override; + virtual void _onDisable() override; }; class Shape : public virtual Node { -protected: - COLORREF fillColor; - COLORREF lineColor; - -protected: - virtual void _onDraw() override; - virtual void solidShape() = 0; - virtual void fillShape() = 0; - virtual void roundShape() = 0; - -public: - enum STYLE { ROUND, SOLID, FILL } m_eStyle; // 形状填充样式 - public: Shape(); virtual ~Shape(); + enum STYLE { ROUND, SOLID, FILL } m_eStyle; // 形状填充样式 + // 获取形状的填充颜色 COLORREF getFillColor() const; // 获取形状的线条颜色 @@ -958,21 +966,22 @@ public: void setLineColor(COLORREF color); // 设置填充样式 void setStyle(STYLE style); + +protected: + COLORREF fillColor; + COLORREF lineColor; + +protected: + virtual void _onDraw() override; + virtual void solidShape() = 0; + virtual void fillShape() = 0; + virtual void roundShape() = 0; }; class Rect : public virtual Shape { -protected: - int m_nWidth; - int m_nHeight; - -protected: - virtual void solidShape() override; - virtual void fillShape() override; - virtual void roundShape() override; - public: Rect(); Rect(int x, int y, int width, int height); @@ -988,20 +997,21 @@ public: void setHeight(int height); // 设置矩形大小 void setSize(int width, int height); + +protected: + int m_nWidth; + int m_nHeight; + +protected: + virtual void solidShape() override; + virtual void fillShape() override; + virtual void roundShape() override; }; class Circle : public virtual Shape { -protected: - int m_nRadius; - -protected: - virtual void solidShape() override; - virtual void fillShape() override; - virtual void roundShape() override; - public: Circle(); Circle(int x, int y, int radius); @@ -1011,6 +1021,14 @@ public: int getRadius() const; // 设置圆形半径 void setRadius(int m_nRadius); + +protected: + int m_nRadius; + +protected: + virtual void solidShape() override; + virtual void fillShape() override; + virtual void roundShape() override; }; } // End of easy2d namespace