diff --git a/Easy2D/Base/App.cpp b/Easy2D/Base/App.cpp index 3d01b642..0864f5a6 100644 --- a/Easy2D/Base/App.cpp +++ b/Easy2D/Base/App.cpp @@ -1,140 +1,193 @@ #include "..\easy2d.h" #include "..\Win\winbase.h" -#include "..\EasyX\easyx.h" -#include -#include -#include -#pragma comment(lib, "imm32.lib") #include #include #include - using namespace std::chrono; +using namespace std::this_thread; -// App 的唯一实例 -static App * s_pInstance = nullptr; -// 场景栈 -static std::stack s_SceneStack; -App::App() : - m_pCurrentScene(nullptr), - m_pNextScene(nullptr), - m_pLoadingScene(nullptr), - m_bRunning(false), - m_nWindowMode(0), - m_bSaveScene(true) +#ifndef HINST_THISCOMPONENT +EXTERN_C IMAGE_DOS_HEADER __ImageBase; +#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase) +#endif + + +EApp * s_pInstance = nullptr; +std::stack s_SceneStack; + +e2d::EApp::EApp() + : m_bRunning(false) + , m_ClearColor(EColor::White) + , m_bSaveScene(true) + , m_pCurrentScene(nullptr) + , m_pNextScene(nullptr) + , m_pLoadingScene(nullptr) { - assert(!s_pInstance); // 不能同时存在两个 App 实例 s_pInstance = this; // 保存实例对象 } -App::~App() +e2d::EApp::~EApp() { + SafeReleaseInterface(&GetFactory()); + SafeReleaseInterface(&GetRenderTarget()); } -App * App::get() +EApp * e2d::EApp::get() { - assert(s_pInstance); // 断言实例存在 - return s_pInstance; // 获取 App 的唯一实例 + Assert(s_pInstance); // 断言实例存在 + return s_pInstance; // 获取 EApp 的唯一实例 } -int App::run() +bool e2d::EApp::init(EString title, ESize size, bool bShowConsole /* = false */) { - // 开启批量绘图 - BeginBatchDraw(); - // 记录当前时间 - steady_clock::time_point nLast = steady_clock::now(); - // 帧间隔 - LONGLONG nAnimationInterval = 17LL; - // 时间间隔 - LONGLONG nInterval = 0LL; - // 挂起时长 - LONGLONG nWaitMS = 0L; + return init(title, size.width, size.height, bShowConsole); +} - // 将隐藏的窗口显示 - ShowWindow(GetHWnd(), SW_NORMAL); - // 运行游戏 - m_bRunning = true; +bool e2d::EApp::init(EString title, UINT32 width, UINT32 height, bool bShowConsole /* = false */) +{ + m_sTitle = title; - // 启动多线程 - //std::thread t(std::bind(&App::_mainLoop, this)); - //t.join(); + HRESULT hr; + hr = CoInitialize(NULL); - // 进入主循环 - while (m_bRunning) + if (SUCCEEDED(hr)) { - // 刷新计时 - ::FlushSteadyClock(); - // 计算时间间隔 - nInterval = duration_cast(GetNow() - nLast).count(); - // 判断间隔时间是否足够 - if (nInterval >= nAnimationInterval) + // 关闭控制台. + if (bShowConsole) { - // 记录当前时间 - nLast = GetNow(); - // 刷新游戏画面 - _draw(); - } - else - { - // 计算挂起时长 - nWaitMS = nAnimationInterval - nInterval - 1; - // 挂起线程,释放 CPU 占用 - if (nWaitMS > 1LL) + HWND hwnd = FindWindow(L"ConsoleWindowClass", NULL); + + if (hwnd) { - std::this_thread::sleep_for(milliseconds(nWaitMS)); + hr = ShowWindow(hwnd, SW_HIDE); } } } - // 停止批量绘图 - EndBatchDraw(); + + if (SUCCEEDED(hr)) + { + // 初始化 device-indpendent 资源 + // 比如 Direct2D factory. + hr = CreateDeviceIndependentResources(); + + if (SUCCEEDED(hr)) + { + // 注册窗口类 + WNDCLASSEX wcex = { sizeof(WNDCLASSEX) }; + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = EApp::WndProc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = sizeof(LONG_PTR); + wcex.hInstance = HINST_THISCOMPONENT; + wcex.hbrBackground = NULL; + wcex.lpszMenuName = NULL; + wcex.hCursor = LoadCursor(NULL, IDI_APPLICATION); + wcex.lpszClassName = L"E2DApp"; + + RegisterClassEx(&wcex); + + + // Because the CreateWindow function takes its size in pixels, + // obtain the system DPI and use it to scale the window size. + FLOAT dpiX, dpiY; + + // The factory returns the current system DPI. This is also the value it will use + // to create its own windows. + GetFactory()->GetDesktopDpi(&dpiX, &dpiY); + + + // Create the window. + GetHWnd() = CreateWindow( + L"E2DApp", + m_sTitle.c_str(), + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + static_cast(ceil(width * dpiX / 96.f)), + static_cast(ceil(height * dpiY / 96.f)), + NULL, + NULL, + HINST_THISCOMPONENT, + this + ); + hr = GetHWnd() ? S_OK : E_FAIL; + } + } + + return SUCCEEDED(hr); +} + +// 运行游戏 +void e2d::EApp::run() +{ + // 显示窗口 + ShowWindow(GetHWnd(), SW_SHOWNORMAL); + UpdateWindow(GetHWnd()); + // 运行游戏 + m_bRunning = true; + + MSG msg; + + while (m_bRunning) + { + // 处理窗口消息 + if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) + { + if (msg.message == WM_QUIT) + { + m_bRunning = false; + } + TranslateMessage(&msg); + DispatchMessage(&msg); + } + // 执行主循环 + _mainLoop(); + } // 关闭窗口 close(); // 释放所有内存占用 free(); - - return 0; } -void App::_initGraph() +void e2d::EApp::_mainLoop() { - // 创建绘图环境 - initgraph(m_Size.cx, m_Size.cy, m_nWindowMode); - // 隐藏当前窗口(防止在加载阶段显示黑窗口) - ShowWindow(GetHWnd(), SW_HIDE); - // 获取屏幕分辨率 - int screenWidth = GetSystemMetrics(SM_CXSCREEN); - int screenHeight = GetSystemMetrics(SM_CYSCREEN); - // 获取窗口大小 - CRect rcWindow; - GetWindowRect(GetHWnd(), &rcWindow); - // 设置窗口在屏幕居中 - SetWindowPos(GetHWnd(), HWND_TOP, - (screenWidth - rcWindow.Size().cx) / 2, - (screenHeight - rcWindow.Size().cy) / 2, - rcWindow.Size().cx, - rcWindow.Size().cy, - SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOSIZE); - // 禁用输入法 - ImmAssociateContext(GetHWnd(), NULL); - // 重置绘图环境 - reset(); - // 设置窗口标题 - if (m_sTitle.empty()) + static steady_clock::time_point nNow; + static steady_clock::time_point nLast = steady_clock::now(); + // 帧间隔 + static LONGLONG nAnimationInterval = 17LL; + // 时间间隔 + static LONGLONG nInterval = 0LL; + // 挂起时长 + static LONGLONG nWaitMS = 0L; + + // 刷新计时 + nNow = steady_clock::now(); + // 计算时间间隔 + nInterval = duration_cast(nNow - nLast).count(); + // 判断间隔时间是否足够 + if (nInterval >= nAnimationInterval) { - // 保存当前标题 - TCHAR title[31]; - GetWindowText(GetHWnd(), title, 30); - m_sTitle = title; - if (m_sAppName.empty()) m_sAppName = title; + // 记录当前时间 + nLast = nNow; + // + _onControl(); + // 刷新游戏画面 + _onRender(); } else { - setWindowTitle(m_sTitle); + // 计算挂起时长 + nWaitMS = nAnimationInterval - nInterval - 1; + // 挂起线程,释放 CPU 占用 + if (nWaitMS > 1LL) + { + std::this_thread::sleep_for(milliseconds(nWaitMS)); + } } } -void App::_draw() +void e2d::EApp::_onControl() { // 下一场景指针不为空时,切换场景 if (m_pNextScene) @@ -143,164 +196,196 @@ void App::_draw() _enterNextScene(); } // 断言当前场景非空 - assert(m_pCurrentScene); + Assert(m_pCurrentScene); - cleardevice(); // 清空画面 - m_pCurrentScene->_onDraw(); // 绘制当前场景 - FlushBatchDraw(); // 刷新画面 - - MouseMsg::__exec(); // 鼠标检测 - KeyMsg::__exec(); // 键盘按键检测 - Timer::__exec(); // 定时器执行程序 - ActionManager::__exec(); // 动作管理器执行程序 - FreePool::__flush(); // 刷新内存池 + //MouseMsg::__exec(); // 鼠标检测 + //KeyMsg::__exec(); // 键盘按键检测 + //Timer::__exec(); // 定时器执行程序 + //ActionManager::__exec(); // 动作管理器执行程序 + //FreePool::__flush(); // 刷新内存池 } -void App::_mainLoop() +// This method discards device-specific +// resources if the Direct3D device dissapears during execution and +// recreates the resources the next time it's invoked. +bool e2d::EApp::_onRender() { - while (true) + HRESULT hr = S_OK; + + hr = CreateDeviceResources(); + + if (SUCCEEDED(hr)) { - if (m_bRunning) - { - MouseMsg::__exec(); // 鼠标检测 - KeyMsg::__exec(); // 键盘按键检测 - Timer::__exec(); // 定时器执行程序 - ActionManager::__exec(); // 动作管理器执行程序 - FreePool::__flush(); // 刷新内存池 - } - std::this_thread::sleep_for(milliseconds(10)); + GetRenderTarget()->BeginDraw(); + + GetRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity()); + + GetRenderTarget()->Clear(D2D1::ColorF(m_ClearColor)); + + m_pCurrentScene->_onDraw(); // 绘制当前场景 + + hr = GetRenderTarget()->EndDraw(); } - + + if (hr == D2DERR_RECREATE_TARGET) + { + hr = S_OK; + DiscardDeviceResources(); + } + + return SUCCEEDED(hr); } -void App::createWindow(int width, int height, int mode) +void e2d::EApp::setWindowSize(int width, int height) { - // 保存窗口信息 - m_Size.cx = width; - m_Size.cy = height; - m_nWindowMode = mode; - // 创建窗口 - _initGraph(); -} - -void App::createWindow(CSize size, int mode) -{ - createWindow(size.cx, size.cy, mode); -} - -void App::createWindow(TString title, int width, int height, int mode) -{ - // 保存窗口信息 - m_Size.cx = width; - m_Size.cy = height; - m_nWindowMode = mode; - m_sTitle = title; - if (m_sAppName.empty()) m_sAppName = title; - // 创建窗口 - _initGraph(); -} - -void App::createWindow(TString title, CSize size, int mode) -{ - createWindow(title, size.cx, size.cy, mode); -} - -void App::setWindowSize(int width, int height) -{ - // 游戏正在运行时才允许修改窗口大小 - assert(s_pInstance->m_bRunning); - // 获取屏幕分辨率 int screenWidth = GetSystemMetrics(SM_CXSCREEN); int screenHeight = GetSystemMetrics(SM_CYSCREEN); // 获取窗口大小(包含菜单栏) - CRect rcWindow; + tagRECT rcWindow; GetWindowRect(GetHWnd(), &rcWindow); // 获取客户区大小 - CRect rcClient; + tagRECT rcClient; GetClientRect(GetHWnd(), &rcClient); // 计算边框大小 width += (rcWindow.right - rcWindow.left) - (rcClient.right - rcClient.left); height += (rcWindow.bottom - rcWindow.top) - (rcClient.bottom - rcClient.top); // 销毁当前窗口 - // DestroyWindow(GetHWnd());/* 无法操作多线程导致失效 */ + // DestroyWindow(m_); // 修改窗口大小,并设置窗口在屏幕居中 - SetWindowPos(GetHWnd(), HWND_TOP, + SetWindowPos( + GetHWnd(), + HWND_TOP, (screenWidth - width) / 2, (screenHeight - height) / 2, width, height, - SWP_SHOWWINDOW); - // 重置窗口属性 - reset(); + SWP_SHOWWINDOW + ); } -void App::setWindowSize(CSize size) +void e2d::EApp::setWindowSize(ESize size) { - setWindowSize(size.cx, size.cy); + setWindowSize(size.width, size.height); } -void App::setWindowTitle(TString title) +void e2d::EApp::setWindowTitle(EString title) { // 设置窗口标题 SetWindowText(GetHWnd(), title.c_str()); // 保存当前标题,用于修改窗口大小时恢复标题 - s_pInstance->m_sTitle = title; + m_sTitle = title; } -TString App::getWindowTitle() +EString e2d::EApp::getTitle() { - return s_pInstance->m_sTitle; + return m_sTitle; } -void App::close() +int e2d::EApp::getWidth() { - closegraph(); // 关闭绘图环境 + return GetRenderTarget()->GetPixelSize().width; } -void App::enterScene(Scene * scene, bool save) +int e2d::EApp::getHeight() +{ + return GetRenderTarget()->GetPixelSize().height; +} + +void e2d::EApp::enterScene(Scene * scene, bool save /* = true */) { // 保存下一场景的指针 - s_pInstance->m_pNextScene = scene; + m_pNextScene = scene; // 切换场景时,是否保存当前场景 - s_pInstance->m_bSaveScene = save; + m_bSaveScene = save; } -void App::backScene() +void e2d::EApp::backScene() { // 从栈顶取出场景指针,作为下一场景 - s_pInstance->m_pNextScene = s_SceneStack.top(); + m_pNextScene = s_SceneStack.top(); // 不保存当前场景 - s_pInstance->m_bSaveScene = false; + m_bSaveScene = false; } -void App::clearScene() +void e2d::EApp::clearScene() { // 清空场景栈 while (s_SceneStack.size()) { auto temp = s_SceneStack.top(); - SafeDelete(temp); + SafeDelete(&temp); s_SceneStack.pop(); } } -void App::setAppName(TString appname) +Scene * e2d::EApp::getCurrentScene() +{ + return m_pCurrentScene; +} + +Scene * e2d::EApp::getLoadingScene() +{ + return m_pLoadingScene; +} + +void e2d::EApp::setAppName(EString appname) { s_pInstance->m_sAppName = appname; } -TString App::getAppName() +EString e2d::EApp::getAppName() { return s_pInstance->m_sAppName; } -void App::setBkColor(COLORREF color) +void EApp::setBkColor(EColor::Enum color) { - setbkcolor(color); + m_ClearColor = color; } -void App::_enterNextScene() +void e2d::EApp::close() +{ + ShowWindow(GetHWnd(), SW_HIDE); +} + +void e2d::EApp::show() +{ + ShowWindow(GetHWnd(), SW_NORMAL); +} + +void EApp::free() +{ + // 释放场景内存 + SafeDelete(&m_pCurrentScene); + SafeDelete(&m_pNextScene); + // 清空场景栈 + while (s_SceneStack.size()) + { + auto temp = s_SceneStack.top(); + SafeDelete(&temp); + s_SceneStack.pop(); + } + // 删除所有定时器 + //Timer::clearAllTimers(); + //MouseMsg::clearAllListeners(); + //KeyMsg::clearAllListeners(); + //ActionManager::clearAllActions(); + // 删除所有对象 + //FreePool::__clearAllObjects(); +} + +void EApp::quit() +{ + m_bRunning = false; +} + +void EApp::end() +{ + m_bRunning = false; +} + +void EApp::_enterNextScene() { bool bBackScene = false; @@ -321,19 +406,19 @@ void App::_enterNextScene() // 若要保存当前场景,把它放入栈中 s_SceneStack.push(m_pCurrentScene); // 暂停当前场景上运行的所有定时器 - Timer::waitAllSceneTimers(m_pCurrentScene); - MouseMsg::waitAllSceneListeners(m_pCurrentScene); - KeyMsg::waitAllSceneListeners(m_pCurrentScene); - ActionManager::waitAllSceneActions(m_pCurrentScene); + //Timer::waitAllSceneTimers(m_pCurrentScene); + //MouseMsg::waitAllSceneListeners(m_pCurrentScene); + //KeyMsg::waitAllSceneListeners(m_pCurrentScene); + //ActionManager::waitAllSceneActions(m_pCurrentScene); } else { // 不保存场景时,停止当前场景上运行的所有定时器,并删除当前场景 - Timer::clearAllSceneTimers(m_pCurrentScene); - MouseMsg::clearAllSceneListeners(m_pCurrentScene); - KeyMsg::clearAllSceneListeners(m_pCurrentScene); - ActionManager::stopAllSceneActions(m_pCurrentScene); - SafeDelete(m_pCurrentScene); + //Timer::clearAllSceneTimers(m_pCurrentScene); + //MouseMsg::clearAllSceneListeners(m_pCurrentScene); + //KeyMsg::clearAllSceneListeners(m_pCurrentScene); + //ActionManager::stopAllSceneActions(m_pCurrentScene); + SafeDelete(&m_pCurrentScene); } } @@ -343,10 +428,10 @@ void App::_enterNextScene() if (bBackScene) { // 返回上一场景时,恢复场景上的定时器 - Timer::notifyAllSceneTimers(m_pCurrentScene); - MouseMsg::notifyAllSceneListeners(m_pCurrentScene); - KeyMsg::notifyAllSceneListeners(m_pCurrentScene); - ActionManager::notifyAllSceneActions(m_pCurrentScene); + //Timer::notifyAllSceneTimers(m_pCurrentScene); + //MouseMsg::notifyAllSceneListeners(m_pCurrentScene); + //KeyMsg::notifyAllSceneListeners(m_pCurrentScene); + //ActionManager::notifyAllSceneActions(m_pCurrentScene); } else { @@ -356,62 +441,144 @@ void App::_enterNextScene() m_pCurrentScene->onEnter(); // 执行下一场景的 onEnter 函数 } -void App::quit() +// Creates resources that are not bound to a particular device. +// Their lifetime effectively extends for the duration of the +// application. +HRESULT e2d::EApp::CreateDeviceIndependentResources() { - s_pInstance->m_bRunning = false; + HRESULT hr = S_OK; + + // Create a Direct2D factory. + hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &GetFactory()); + + return hr; } -void App::end() +// Creates resources that are bound to a particular +// Direct3D device. These resources need to be recreated +// if the Direct3D device dissapears, such as when the display +// changes, the window is remoted, etc. +HRESULT e2d::EApp::CreateDeviceResources() { - s_pInstance->m_bRunning = false; -} + HRESULT hr = S_OK; -void App::reset() -{ - // 重置绘图环境 - graphdefaults(); - setbkmode(TRANSPARENT); - setbkcolor(Color::black); -} - -Scene * App::getCurrentScene() -{ - // 获取当前场景的指针 - return s_pInstance->m_pCurrentScene; -} - -Scene * App::getLoadingScene() -{ - return s_pInstance->m_pLoadingScene; -} - -int App::getWidth() -{ - return s_pInstance->m_Size.cx; -} - -int App::getHeight() -{ - return s_pInstance->m_Size.cy; -} - -void App::free() -{ - // 释放场景内存 - SafeDelete(m_pCurrentScene); - SafeDelete(m_pNextScene); - // 清空场景栈 - while (s_SceneStack.size()) + if (!GetRenderTarget()) { - auto temp = s_SceneStack.top(); - SafeDelete(temp); - s_SceneStack.pop(); + RECT rc; + GetClientRect(GetHWnd(), &rc); + + D2D1_SIZE_U size = D2D1::SizeU( + rc.right - rc.left, + rc.bottom - rc.top + ); + + // Create a Direct2D render target. + hr = GetFactory()->CreateHwndRenderTarget( + D2D1::RenderTargetProperties(), + D2D1::HwndRenderTargetProperties(GetHWnd(), size), + &GetRenderTarget() + ); } - // 删除所有定时器 - Timer::clearAllTimers(); - MouseMsg::clearAllListeners(); - KeyMsg::clearAllListeners(); - ActionManager::clearAllActions(); - // 删除所有对象 - FreePool::__clearAllObjects(); + + return hr; } + +// Discards device-dependent resources. These resources must be +// recreated when the Direct3D device is lost. +void e2d::EApp::DiscardDeviceResources() +{ + SafeReleaseInterface(&GetRenderTarget()); +} + +// If the application receives a WM_SIZE message, this method +// resizes the render target appropriately. +void e2d::EApp::_onResize(UINT width, UINT height) +{ + if (GetRenderTarget()) + { + // Note: This method can fail, but it's okay to ignore the + // error here, because the error will be returned again + // the next time EndDraw is called. + GetRenderTarget()->Resize(D2D1::SizeU(width, height)); + } +} + +// Handles window messages. +LRESULT e2d::EApp::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + LRESULT result = 0; + + if (message == WM_CREATE) + { + LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam; + EApp *pEApp = (EApp *)pcs->lpCreateParams; + + ::SetWindowLongPtrW( + GetHWnd(), + GWLP_USERDATA, + PtrToUlong(pEApp) + ); + + result = 1; + } + else + { + EApp *pEApp = reinterpret_cast(static_cast( + ::GetWindowLongPtrW( + GetHWnd(), + GWLP_USERDATA + ))); + + bool wasHandled = false; + + if (pEApp) + { + switch (message) + { + case WM_SIZE: + { + UINT width = LOWORD(lParam); + UINT height = HIWORD(lParam); + pEApp->_onResize(width, height); + } + result = 0; + wasHandled = true; + break; + + case WM_DISPLAYCHANGE: + { + InvalidateRect(GetHWnd(), NULL, FALSE); + } + result = 0; + wasHandled = true; + break; + + case WM_PAINT: + { + pEApp->_onRender(); + ValidateRect(GetHWnd(), NULL); + } + result = 0; + wasHandled = true; + break; + + case WM_DESTROY: + { + PostQuitMessage(0); + } + result = 1; + wasHandled = true; + break; + } + } + + if (!wasHandled) + { + result = DefWindowProc(GetHWnd(), message, wParam, lParam); + } + } + + return result; +} + + diff --git a/Easy2D/Base/Scene.cpp b/Easy2D/Base/Scene.cpp index 42949087..57309427 100644 --- a/Easy2D/Base/Scene.cpp +++ b/Easy2D/Base/Scene.cpp @@ -3,7 +3,7 @@ Scene::Scene() { - App::get()->m_pLoadingScene = this; + EApp::get()->m_pLoadingScene = this; } Scene::~Scene() diff --git a/Easy2D/Easy2D.vcxproj b/Easy2D/Easy2D.vcxproj index b9c06cd1..e7210351 100644 --- a/Easy2D/Easy2D.vcxproj +++ b/Easy2D/Easy2D.vcxproj @@ -190,8 +190,10 @@ false - EasyXa.lib;GdiPlus.lib - EasyX\x86 + + + + @@ -209,10 +211,12 @@ true - EasyXw.lib;GdiPlus.lib + + - EasyX\x86 + + false @@ -233,8 +237,10 @@ true - EasyX\x64 - EasyXa.lib;GdiPlus.lib + + + + @@ -252,8 +258,10 @@ true - EasyXw.lib;GdiPlus.lib - EasyX\x64 + + + + @@ -274,8 +282,10 @@ true - EasyX\x86 - EasyXa.lib;GdiPlus.lib + + + + @@ -296,8 +306,10 @@ true - EasyXw.lib;GdiPlus.lib - EasyX\x86 + + + + @@ -320,8 +332,10 @@ true - EasyX\x64 - EasyXa.lib;GdiPlus.lib + + + + @@ -342,59 +356,22 @@ true - EasyXw.lib;GdiPlus.lib - EasyX\x64 + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + diff --git a/Easy2D/Easy2D.vcxproj.filters b/Easy2D/Easy2D.vcxproj.filters index 68d00f98..158f09de 100644 --- a/Easy2D/Easy2D.vcxproj.filters +++ b/Easy2D/Easy2D.vcxproj.filters @@ -13,104 +13,14 @@ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - {18e7fd5c-0935-47bb-9a2e-38da40377f7d} - - - {682a1a3c-39d8-4ac9-ba03-fa90c089c9ab} - - - {d6778635-8947-4f9b-9388-dd088642b5b2} - - - {065a3244-7169-4a45-bc9f-f2a80d8a9759} - - - {72dbabab-8278-4ee4-917f-bfffb474a51b} - - - {bdcd902b-b53d-4537-9632-76ea14c141a0} - - - {e1501580-8f69-4ad6-a9f1-76d825572c3d} - {261633d3-3814-40c7-bd6d-201ede6c6ade} - {37b7730c-acb0-4b57-b1f8-01680951611c} + {2f0f3d30-bfc2-4aea-a170-258bbaacaa79} - - 婧愭枃浠禱Style - - - 婧愭枃浠禱Tool - - - 婧愭枃浠禱Tool - - - 婧愭枃浠禱Tool - - - 婧愭枃浠禱Style - - - 婧愭枃浠禱Object - - - 婧愭枃浠禱Object - - - 婧愭枃浠禱Object - - - 婧愭枃浠禱Object - - - 婧愭枃浠禱Object\Shape - - - 婧愭枃浠禱Object\Shape - - - 婧愭枃浠禱Object\Shape - - - 婧愭枃浠禱Object - - - 婧愭枃浠禱Style - - - 婧愭枃浠禱Object - - - 婧愭枃浠禱Style - - - 婧愭枃浠禱Msg - - - 婧愭枃浠禱Msg - - - 婧愭枃浠禱Object\Button - - - 婧愭枃浠禱Object\Button - - - 婧愭枃浠禱Object\Button - - - 婧愭枃浠禱Object - - - 婧愭枃浠禱Action - 婧愭枃浠禱Base @@ -120,60 +30,6 @@ 婧愭枃浠禱Base - - 婧愭枃浠禱Action - - - 婧愭枃浠禱Action - - - 婧愭枃浠禱Action - - - 婧愭枃浠禱Action - - - 婧愭枃浠禱Object - - - 婧愭枃浠禱Action - - - 婧愭枃浠禱Action - - - 婧愭枃浠禱Tool - - - 婧愭枃浠禱Action - - - 婧愭枃浠禱Action - - - 婧愭枃浠禱Action - - - 婧愭枃浠禱Action - - - 婧愭枃浠禱Action - - - 婧愭枃浠禱Action - - - 婧愭枃浠禱Action - - - 婧愭枃浠禱Object - - - 婧愭枃浠禱Object - - - 婧愭枃浠禱Tool - 婧愭枃浠禱Win @@ -182,6 +38,12 @@ 澶存枃浠 + + 澶存枃浠 + + + 澶存枃浠 + 婧愭枃浠禱Win diff --git a/Easy2D/Msg/KeyMsg.cpp b/Easy2D/Msg/KeyMsg.cpp index 347a519a..a7e8569b 100644 --- a/Easy2D/Msg/KeyMsg.cpp +++ b/Easy2D/Msg/KeyMsg.cpp @@ -139,7 +139,7 @@ void KeyMsg::addListener(TString name, const KEY_CALLBACK & callback) // 创建新的监听对象 auto listener = new KeyMsg(name, callback); // 绑定在场景上 - listener->m_pParentScene = App::getLoadingScene(); + listener->m_pParentScene = EApp::getLoadingScene(); // 添加新的按键回调函数 s_vListeners.push_back(listener); } @@ -149,7 +149,7 @@ void KeyMsg::startListener(TString name) // 查找名称相同的监听器 for (auto l : s_vListeners) { - if (l->m_sName == name && l->m_pParentScene == App::getCurrentScene()) + if (l->m_sName == name && l->m_pParentScene == EApp::getCurrentScene()) { l->start(); } @@ -161,7 +161,7 @@ void KeyMsg::stopListener(TString name) // 查找名称相同的监听器 for (auto l : s_vListeners) { - if (l->m_sName == name && l->m_pParentScene == App::getCurrentScene()) + if (l->m_sName == name && l->m_pParentScene == EApp::getCurrentScene()) { l->stop(); } @@ -176,7 +176,7 @@ void KeyMsg::delListener(TString name) for (iter = s_vListeners.begin(); iter != s_vListeners.end();) { // 查找相同名称的监听器 - if ((*iter)->m_sName == name && (*iter)->m_pParentScene == App::getCurrentScene()) + if ((*iter)->m_sName == name && (*iter)->m_pParentScene == EApp::getCurrentScene()) { // 删除该定时器 delete (*iter); diff --git a/Easy2D/Msg/MouseMsg.cpp b/Easy2D/Msg/MouseMsg.cpp index e225439e..9d4eeecd 100644 --- a/Easy2D/Msg/MouseMsg.cpp +++ b/Easy2D/Msg/MouseMsg.cpp @@ -15,7 +15,7 @@ void MouseMsg::__exec() // 获取鼠标消息 s_mouseMsg = GetMouseMsg(); // 执行场景程序 - App::get()->getCurrentScene()->_exec(); + EApp::get()->getCurrentScene()->_exec(); // 执行鼠标监听回调函数 for (auto l : s_vListeners) // 循环遍历所有的鼠标监听 { @@ -58,7 +58,7 @@ void MouseMsg::addListener(TString name, const MOUSE_CALLBACK & callback) // 创建新的监听对象 auto listener = new MouseMsg(name, callback); // 绑定在场景上 - listener->m_pParentScene = App::getLoadingScene(); + listener->m_pParentScene = EApp::getLoadingScene(); // 添加新的按键回调函数 s_vListeners.push_back(listener); } @@ -68,7 +68,7 @@ void MouseMsg::startListener(TString name) // 查找名称相同的监听器 for (auto l : s_vListeners) { - if (l->m_sName == name && l->m_pParentScene == App::getCurrentScene()) + if (l->m_sName == name && l->m_pParentScene == EApp::getCurrentScene()) { l->start(); } @@ -80,7 +80,7 @@ void MouseMsg::stopListener(TString name) // 查找名称相同的监听器 for (auto l : s_vListeners) { - if (l->m_sName == name && l->m_pParentScene == App::getCurrentScene()) + if (l->m_sName == name && l->m_pParentScene == EApp::getCurrentScene()) { l->stop(); } @@ -95,7 +95,7 @@ void MouseMsg::delListener(TString name) for (iter = s_vListeners.begin(); iter != s_vListeners.end();) { // 查找相同名称的监听器 - if ((*iter)->m_sName == name && (*iter)->m_pParentScene == App::getCurrentScene()) + if ((*iter)->m_sName == name && (*iter)->m_pParentScene == EApp::getCurrentScene()) { // 删除该定时器 delete (*iter); diff --git a/Easy2D/Object/Image.cpp b/Easy2D/Object/Image.cpp index 005d70ce..83b8a0b7 100644 --- a/Easy2D/Object/Image.cpp +++ b/Easy2D/Object/Image.cpp @@ -216,7 +216,7 @@ void Image::saveScreenshot() { // 保存窗口截图 IMAGE image; - getimage(&image, 0, 0, App::getWidth(), App::getHeight()); + getimage(&image, 0, 0, EApp::getWidth(), EApp::getHeight()); saveimage(savePath.c_str(), &image); } } diff --git a/Easy2D/Object/RectNode.cpp b/Easy2D/Object/RectNode.cpp index 795c7a8c..ba5854da 100644 --- a/Easy2D/Object/RectNode.cpp +++ b/Easy2D/Object/RectNode.cpp @@ -23,12 +23,12 @@ bool RectNode::isPointIn(CPoint p) const void RectNode::setWindowCenterX() { - setX((App::getWidth() - getWidth()) / 2); + setX((EApp::getWidth() - getWidth()) / 2); } void RectNode::setWindowCenterY() { - setY((App::getHeight() - getHeight()) / 2); + setY((EApp::getHeight() - getHeight()) / 2); } void RectNode::setWindowCenter() diff --git a/Easy2D/Tool/ActionManager.cpp b/Easy2D/Tool/ActionManager.cpp index 7e1ef398..8fd455c7 100644 --- a/Easy2D/Tool/ActionManager.cpp +++ b/Easy2D/Tool/ActionManager.cpp @@ -46,7 +46,7 @@ void ActionManager::addAction(Action * action) assert(a != action); } #endif - action->m_pParentScene = App::getLoadingScene(); + action->m_pParentScene = EApp::getLoadingScene(); s_vActions.push_back(action); } } diff --git a/Easy2D/Tool/FileUtils.cpp b/Easy2D/Tool/FileUtils.cpp index 89ea7164..0c14dec6 100644 --- a/Easy2D/Tool/FileUtils.cpp +++ b/Easy2D/Tool/FileUtils.cpp @@ -43,7 +43,7 @@ TString FileUtils::getDefaultSavePath() TString path = m_lpszDefaultDir; path.append(_T("\\")); - path.append(App::getAppName()); + path.append(EApp::getAppName()); #ifdef UNICODE if (_waccess(path.c_str(), 0) == -1) diff --git a/Easy2D/Tool/Timer.cpp b/Easy2D/Tool/Timer.cpp index 1c4a9692..bbea8a29 100644 --- a/Easy2D/Tool/Timer.cpp +++ b/Easy2D/Tool/Timer.cpp @@ -103,7 +103,7 @@ void Timer::addTimer(Timer * timer) // 启动定时器 timer->start(); // 绑定在场景上 - timer->m_pParentScene = App::getLoadingScene(); + timer->m_pParentScene = EApp::getLoadingScene(); // 将该定时器放入容器 s_vTimers.push_back(timer); } @@ -126,7 +126,7 @@ void Timer::startTimer(TString name) // 查找名称相同的定时器 for (auto timer : s_vTimers) { - if (timer->m_sName == name && timer->m_pParentScene == App::getCurrentScene()) + if (timer->m_sName == name && timer->m_pParentScene == EApp::getCurrentScene()) { // 启动定时器 timer->start(); @@ -139,7 +139,7 @@ void Timer::stopTimer(TString name) // 查找名称相同的定时器 for (auto timer : s_vTimers) { - if (timer->m_sName == name && timer->m_pParentScene == App::getCurrentScene()) + if (timer->m_sName == name && timer->m_pParentScene == EApp::getCurrentScene()) { // 停止定时器 timer->stop(); @@ -155,7 +155,7 @@ void Timer::delTimer(TString name) for (iter = s_vTimers.begin(); iter != s_vTimers.end();) { // 查找相同名称的定时器 - if ((*iter)->m_sName == name && (*iter)->m_pParentScene == App::getCurrentScene()) + if ((*iter)->m_sName == name && (*iter)->m_pParentScene == EApp::getCurrentScene()) { // 删除该定时器 delete (*iter); diff --git a/Easy2D/Win/winbase.cpp b/Easy2D/Win/winbase.cpp index 64d436cb..17a13d67 100644 --- a/Easy2D/Win/winbase.cpp +++ b/Easy2D/Win/winbase.cpp @@ -1,23 +1,24 @@ #include "winbase.h" -#include -#include -#include +#include "..\emacros.h" -static steady_clock::time_point nNow; +HWND m_hwnd = nullptr; +ID2D1Factory * m_pDirect2dFactory = nullptr; +ID2D1HwndRenderTarget * m_pRenderTarget = nullptr; -steady_clock::time_point GetNow() + +HWND &GetHWnd() { - return nNow; + return m_hwnd; } -void FlushSteadyClock() +ID2D1Factory * &GetFactory() { - nNow = steady_clock::now(); // 获取当前时间 + return m_pDirect2dFactory; } -LONGLONG GetInterval(steady_clock::time_point nLast) +ID2D1HwndRenderTarget * &GetRenderTarget() { - return duration_cast(nNow - nLast).count(); + return m_pRenderTarget; } void WindowCenter(HWND hWnd) @@ -26,60 +27,16 @@ void WindowCenter(HWND hWnd) int screenWidth = GetSystemMetrics(SM_CXSCREEN); int screenHeight = GetSystemMetrics(SM_CYSCREEN); // 获取窗口大小 - CRect rcWindow; + tagRECT rcWindow; GetWindowRect(hWnd, &rcWindow); // 设置窗口在屏幕居中 - SetWindowPos(hWnd, HWND_TOP, - (screenWidth - rcWindow.Size().cx) / 2, - (screenHeight - rcWindow.Size().cy) / 2, - rcWindow.Size().cx, - rcWindow.Size().cy, - SWP_SHOWWINDOW | SWP_NOSIZE); + SetWindowPos( + hWnd, + HWND_TOP, + (screenWidth - (rcWindow.left - rcWindow.right)) / 2, + (screenHeight - (rcWindow.top - rcWindow.bottom)) / 2, + (rcWindow.left - rcWindow.right), + (rcWindow.top - rcWindow.bottom), + SWP_SHOWWINDOW | SWP_NOSIZE + ); } - -void CreateGameWindow() -{ - HWND _wnd; - HINSTANCE s_hInstance; - 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("Easy2dCallbackWnd"); // 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("Easy2dCallbackWnd"), // 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); - } -} \ No newline at end of file diff --git a/Easy2D/Win/winbase.h b/Easy2D/Win/winbase.h index e1d83cfa..cfaf4ba8 100644 --- a/Easy2D/Win/winbase.h +++ b/Easy2D/Win/winbase.h @@ -1,7 +1,27 @@ #pragma once -#include -using namespace std::chrono; +#include +#include +#include +#include -steady_clock::time_point GetNow(); +HWND &GetHWnd(); -void FlushSteadyClock(); \ No newline at end of file +ID2D1Factory * &GetFactory(); + +ID2D1HwndRenderTarget * &GetRenderTarget(); + +void WindowCenter(HWND hWnd); + + +template +inline void SafeReleaseInterface( + Interface **ppInterfaceToRelease +) +{ + if (*ppInterfaceToRelease != nullptr) + { + (*ppInterfaceToRelease)->Release(); + + (*ppInterfaceToRelease) = nullptr; + } +} \ No newline at end of file diff --git a/Easy2D/easy2d.h b/Easy2D/easy2d.h index ab6d62bd..c05135da 100644 --- a/Easy2D/easy2d.h +++ b/Easy2D/easy2d.h @@ -2,8 +2,7 @@ * Easy2D Game Engine * * Website: http://www.easy2d.cn -* Github: https://github.com/Nomango/Easy2D -* Gitee: https://gitee.com/werelone/Easy2D +* Source Code: https://gitee.com/werelone/Easy2D ******************************************************/ #pragma once @@ -17,197 +16,205 @@ #endif -#include -#include -#include -#include -#include -#include -#include -#include +// Modify the following defines if you have to target a platform prior to the ones specified below. +// Refer to MSDN for the latest info on corresponding values for different platforms. +#ifndef WINVER // Allow use of features specific to Windows 7 or later. +#define WINVER 0x0700 // Change this to the appropriate value to target other versions of Windows. +#endif + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows 7 or later. +#define _WIN32_WINNT 0x0700 // Change this to the appropriate value to target other versions of Windows. +#endif + +#ifndef UNICODE +#define UNICODE +#endif + +// Exclude rarely-used items from Windows headers. +#define WIN32_LEAN_AND_MEAN + +// Windows Header Files: +#include + +// C RunTime Header Files: +#include + +#include "emacros.h" +#include "ecommon.h" #if defined(UNICODE) && (_DEBUG) - #pragma comment(lib,"Easy2Ddw.lib") + #pragma comment(lib, "Easy2Ddw.lib") #elif !defined(UNICODE) && (_DEBUG) - #pragma comment(lib,"Easy2Dd.lib") + #pragma comment(lib, "Easy2Dd.lib") #elif defined(UNICODE) - #pragma comment(lib,"Easy2Dw.lib") + #pragma comment(lib, "Easy2Dw.lib") #elif !defined(UNICODE) - #pragma comment(lib,"Easy2D.lib") + #pragma comment(lib, "Easy2D.lib") #endif -// Type Declare - -typedef CPoint CVector; -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; - -#ifdef UNICODE - typedef std::wstring TString; -#else - typedef std::string TString; -#endif - // Classes Declare -namespace easy2d +namespace e2d { - class App; + class EApp; class Scene; - class Object; - class Node; - class FontStyle; - class Color; - class RectNode; - class Text; - class Image; - class BatchNode; - class MouseNode; - class Button; - class TextButton; - class ImageButton; - class Layer; - class Sprite; - class BatchSprite; - class Shape; - class Circle; - class Rectangle; - - class Action; - class Animation; - class ActionMoveTo; - class ActionMoveBy; - class ActionScaleTo; - class ActionScaleBy; - class ActionOpacityTo; - class ActionOpacityBy; - class ActionFadeIn; - class ActionFadeOut; - class ActionFrames; - class ActionDelay; - class ActionCallback; - class ActionTwo; - class ActionSequence; - class ActionNeverStop; - - class MouseMsg; - class KeyMsg; - - class FreePool; - class FileUtils; - class MusicUtils; - class ActionManager; } // Classes -namespace easy2d +namespace e2d { -class App +class EApp { - friend Scene; public: - App(); - ~App(); + EApp(); + ~EApp(); - // 窗口可选模式 - enum MODE { SHOW_CONSOLE = 1, NO_CLOSE = 2, NO_MINI_MIZE = 4 }; + // 获取程序实例 + static EApp * get(); + + // Register the window class and call methods for instantiating drawing resources + bool init( + EString title, + ESize size, + bool bShowConsole = false + ); + + // Register the window class and call methods for instantiating drawing resources + bool init( + EString title, + UINT32 width, + UINT32 height, + bool bShowConsole = false + ); - // 定义绘图窗口 - void createWindow(int width, int height, int mode = 0); - // 定义绘图窗口 - void createWindow(CSize size, int mode = 0); - // 定义绘图窗口 - void createWindow(TString title, int width, int height, int mode = 0); - // 定义绘图窗口 - void createWindow(TString title, CSize size, int mode = 0); // 启动程序 - int run(); + void run(); + + // 修改窗口大小 + void setWindowSize( + int width, + int height + ); + + // 修改窗口大小 + void setWindowSize( + ESize size + ); + + // 设置窗口标题 + void setWindowTitle( + EString title + ); + + // 获取窗口标题 + EString getTitle(); + + // 获取窗口宽度 + int getWidth(); + + // 获取窗口高度 + int getHeight(); + + // 切换场景 + void enterScene( + Scene * scene, + bool save = true + ); + + // 返回上一场景 + void backScene(); + + // 清空保存的所有场景 + void clearScene(); + + // 获取当前场景 + Scene * getCurrentScene(); + + // 获取正处于加载中的场景 + Scene * getLoadingScene(); + + // 设置 AppName + void setAppName( + EString appname + ); + + // 获取 AppName + EString getAppName(); + + // 修改窗口背景色 + void setBkColor( + EColor::Enum color + ); + // 释放所有内存资源 void free(); - // 获取程序实例 - static App * get(); - // 终止程序 - static void quit(); - // 终止程序 - static void end(); - // 修改窗口大小 - static void setWindowSize(int width, int height); - // 修改窗口大小 - static void setWindowSize(CSize size); // 关闭窗口 - static void close(); - // 设置窗口标题 - static void setWindowTitle(TString title); - // 获取窗口标题 - static TString getWindowTitle(); - // 获取窗口宽度 - static int getWidth(); - // 获取窗口高度 - static int getHeight(); - // 切换场景 - static void enterScene(Scene *scene, bool save = true); - // 返回上一场景 - static void backScene(); - // 清空之前保存的所有场景 - static void clearScene(); - // 设置 AppName - static void setAppName(TString appname); - // 获取 AppName - static TString getAppName(); - // 修改窗口背景色 - static void setBkColor(COLORREF color); - // 重置绘图样式为默认值 - static void reset(); - // 获取当前场景 - static Scene * getCurrentScene(); - // 获取正处于加载中的场景 - static Scene * getLoadingScene(); + void close(); + + // 显示窗口 + void show(); + + // 终止程序 + void quit(); + + // 终止程序 + void end(); + +protected: + // Initialize device-independent resources. + HRESULT CreateDeviceIndependentResources(); + + // Initialize device-dependent resources. + HRESULT CreateDeviceResources(); + + // Release device-dependent resource. + void DiscardDeviceResources(); + + void _mainLoop(); + + void _onControl(); + + // Draw content. + bool _onRender(); + + void _enterNextScene(); + + // Resize the render target. + void _onResize( + UINT width, + UINT height + ); + + // The windows procedure. + static LRESULT CALLBACK WndProc( + HWND hWnd, + UINT message, + WPARAM wParam, + LPARAM lParam + ); protected: - TString m_sTitle; - TString m_sAppName; - Scene* m_pCurrentScene; - Scene* m_pNextScene; - Scene* m_pLoadingScene; - CSize m_Size; - int m_nWindowMode; bool m_bRunning; bool m_bSaveScene; - -protected: - void _initGraph(); - void _draw(); - void _mainLoop(); - void _enterNextScene(); -}; - -class FreePool -{ - friend App; - friend Object; -private: - // 刷新内存池 - static void __flush(); - // 将一个节点放入释放池 - static void __add(Object * nptr); - // 删除所有节点 - static void __clearAllObjects(); + EString m_sTitle; + EString m_sAppName; + EColor::Enum m_ClearColor; + + Scene * m_pCurrentScene; + Scene * m_pNextScene; + Scene * m_pLoadingScene; }; class Scene { - friend App; - friend MouseMsg; + friend EApp; public: Scene(); ~Scene(); @@ -226,7 +233,7 @@ public: void clearAllChildren(); protected: - std::vector m_vChildren; + //std::vector m_vChildren; protected: void _exec(); @@ -252,1404 +259,9 @@ protected: bool m_bAutoRelease; }; -class MouseMsg -{ - friend App; -public: - MouseMsg(); - MouseMsg(TString name, const MOUSE_CALLBACK& callback); - ~MouseMsg(); - - enum MESSAGE - { - MOVE = 0x0200, // 鼠标移动 - LBUTTON_DOWN, // 鼠标左键按下 - LBUTTON_UP, // 鼠标左键抬起 - LBUTTON_DBLCLK, // 鼠标左键双击 - RBUTTON_DOWN, // 鼠标右键按下 - RBUTTON_UP, // 鼠标右键抬起 - RBUTTON_DBLCLK, // 鼠标右键双击 - MBUTTON_DOWN, // 鼠标中键按下 - MBUTTON_UP, // 鼠标中键抬起 - MBUTTON_DBLCLK, // 鼠标中键双击 - WHEEL // 滑动滚轮 - }; - - // 启动监听 - void start(); - // 停止监听 - void stop(); - // 进入等待状态 - void wait(); - // 唤醒 - void notify(); - - // 左键是否按下 - static bool isLButtonDown(); - // 右键是否按下 - static bool isRButtonDown(); - // 中键是否按下 - static bool isMButtonDown(); - // 获取鼠标X坐标 - static int getX(); - // 获取鼠标Y坐标 - static int getY(); - // 获取鼠标坐标 - static CPoint getPos(); - // 获取鼠标滚轮值 - static int getWheel(); - // 获取当前鼠标消息 - static MESSAGE getMsg(); - - // 添加鼠标消息监听 - static void addListener(TString name, const MOUSE_CALLBACK& callback); - // 启动鼠标消息监听 - static void startListener(TString name); - // 停止鼠标消息监听 - static void stopListener(TString name); - // 删除鼠标消息监听 - static void delListener(TString name); - // 删除所有鼠标消息监听 - static void clearAllListeners(); - // 启动绑定在场景上的所有监听器 - static void notifyAllSceneListeners(Scene* scene); - // 停止绑定在场景上的所有监听器 - static void waitAllSceneListeners(Scene* scene); - // 清除绑定在场景上的所有监听器 - static void clearAllSceneListeners(Scene* scene); - -private: - static void __exec(); - -protected: - bool m_bRunning; - bool m_bWaiting; - TString m_sName; - MOUSE_CALLBACK m_callback; - Scene * m_pParentScene; - -protected: - // 执行回调函数 - void onMouseMsg(); -}; - -class KeyMsg -{ - friend App; -public: - KeyMsg(TString name, const KEY_CALLBACK& callback); - ~KeyMsg(); - - // 执行回调函数 - void onKbHit(VK_KEY key); - // 启动监听 - void start(); - // 停止监听 - void stop(); - // 进入等待状态 - void wait(); - // 唤醒 - void notify(); - - // 判断键是否被按下,按下返回true - static bool isKeyDown(VK_KEY key); - // 添加按键监听 - static void addListener(TString name, const KEY_CALLBACK& callback); - // 启动按键监听 - static void startListener(TString name); - // 停止按键监听 - static void stopListener(TString name); - // 删除按键监听 - static void KeyMsg::delListener(TString name); - // 启动绑定在场景上的所有监听器 - static void notifyAllSceneListeners(Scene* scene); - // 停止绑定在场景上的所有监听器 - static void waitAllSceneListeners(Scene* scene); - // 停止绑定在场景上的所有定时器 - static void clearAllSceneListeners(Scene* scene); - // 删除所有按键监听 - static void clearAllListeners(); - -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; - // 数字键值 - static const VK_KEY NUM_1, NUM_2, NUM_3, NUM_4, NUM_5, NUM_6, NUM_7, NUM_8, NUM_9, NUM_0; - // 小数字键盘值 - static const VK_KEY NUMPAD_1, NUMPAD_2, NUMPAD_3, NUMPAD_4, NUMPAD_5, NUMPAD_6, NUMPAD_7, NUMPAD_8, NUMPAD_9, NUMPAD_0; - // 控制键值 - static const VK_KEY Enter, Space, Up, Down, Left, Right, Esc, Shift, LShift, RShift, Ctrl, LCtrl, RCtrl; - // F 键值 - static const VK_KEY F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12; - -private: - static void __exec(); - -protected: - bool m_bRunning; - bool m_bWaiting; - TString m_sName; - KEY_CALLBACK m_callback; - Scene * m_pParentScene; -}; - -class FontStyle : - public Object -{ - friend Text; -public: - FontStyle(); - /** - * 使用 [字体名称、字号、粗细、字宽、斜体、下划线、删除线、字符串书写角度、 - * 每个字符书写角度、抗锯齿] 属性创建字体样式 - */ - FontStyle(LPCTSTR fontfamily, LONG height = 18, LONG weight = 0, LONG width = 0, - bool italic = 0, bool underline = 0, bool strikeout = 0, LONG escapement = 0, - LONG orientation = 0, bool quality = true); - virtual ~FontStyle(); - - // 获取默认字体 - static FontStyle * getDefault(); - // 设置字符平均高度 - void setHeight(LONG value); - // 设置字符平均宽度(0表示自适应) - void setWidth(LONG value); - // 设置字体 - void setFontFamily(LPCTSTR value); - // 设置字符笔画粗细,范围0~1000,默认为0 - void setWeight(LONG value); - // 设置斜体 - void setItalic(bool value); - // 设置下划线 - void setUnderline(bool value); - // 设置删除线 - void setStrikeOut(bool value); - // 设置字符串的书写角度,单位0.1度,默认为0 - void setEscapement(LONG value); - // 设置每个字符的书写角度,单位0.1度,默认为0 - void setOrientation(LONG value); - // 设置字体抗锯齿,默认为true - void setQuality(bool value); - -protected: - LOGFONT m_font; -}; - -class FontWeight -{ -public: - static const LONG dontcare; // 粗细值 0 - static const LONG thin; // 粗细值 100 - static const LONG extraLight; // 粗细值 200 - static const LONG light; // 粗细值 300 - static const LONG normal; // 粗细值 400 - static const LONG regular; // 粗细值 400 - static const LONG medium; // 粗细值 500 - static const LONG demiBlod; // 粗细值 600 - static const LONG blod; // 粗细值 700 - static const LONG extraBold; // 粗细值 800 - static const LONG black; // 粗细值 900 - static const LONG heavy; // 粗细值 900 -}; - -class Color -{ -public: - static const COLORREF black; // 黑色 - static const COLORREF blue; // 蓝色 - static const COLORREF green; // 绿色 - static const COLORREF cyan; // 青色 - static const COLORREF red; // 红色 - static const COLORREF magenta; // 紫色 - static const COLORREF brown; // 棕色 - static const COLORREF lightgray; // 亮灰色 - static const COLORREF darkgray; // 深灰色 - static const COLORREF lightblue; // 亮蓝色 - static const COLORREF lightgreen; // 亮绿色 - static const COLORREF lightcyan; // 亮青色 - static const COLORREF lightred; // 亮红色 - static const COLORREF lightmagenta; // 亮紫色 - static const COLORREF yellow; // 亮黄色 - static const COLORREF white; // 白色 - - // 通过红、绿、蓝颜色分量合成颜色 - static COLORREF getFromRGB(BYTE r, BYTE g, BYTE b); - // 通过色相、饱和度、亮度合成颜色 - static COLORREF getFromHSL(float H, float S, float L); - // 通过色相、饱和度、明度合成颜色 - static COLORREF getFromHSV(float H, float S, float V); - - // 返回指定颜色中的红色值 - static BYTE getRValue(COLORREF color); - // 返回指定颜色中的绿色值 - static BYTE getGValue(COLORREF color); - // 返回指定颜色中的蓝色值 - static BYTE getBValue(COLORREF color); - // 返回与指定颜色对应的灰度值颜色 - static COLORREF getGray(COLORREF color); -}; - -class Node : - public Object -{ - friend Scene; - friend BatchNode; -public: - Node(); - Node(CPoint p); - Node(int x, int y); - virtual ~Node(); - - // 获取节点横坐标 - virtual int getX() const; - // 获取节点纵坐标 - virtual int getY() const; - // 获取节点坐标 - virtual CPoint getPos() const; - // 设置节点横坐标 - virtual void setX(int x); - // 设置节点纵坐标 - virtual void setY(int y); - // 设置节点横纵坐标 - virtual void setPos(int x, int y); - // 设置节点横纵坐标 - virtual void setPos(CPoint p); - // 移动节点 - virtual void move(int x, int y); - // 设置节点横纵坐标 - virtual void move(CVector v); - // 节点是否显示 - virtual bool display() const; - // 设置节点是否显示 - virtual void setDisplay(bool value); - // 获取节点绘图顺序 - virtual int getZOrder() const; - // 设置节点绘图顺序(0为最先绘制,显示在最底层) - virtual void setZOrder(int z); - // 获取节点所在场景 - Scene * getParentScene(); - -protected: - int m_nZOrder; - bool m_bDisplay; - Scene* m_pScene; - CPoint m_Pos; - -protected: - virtual bool _exec(bool active); - virtual void _onDraw() = 0; - void setParentScene(Scene * scene); -}; - -class BatchNode : - public Node -{ -public: - BatchNode(); - virtual ~BatchNode(); - - // 添加子节点 - void add(Node *child, int z_Order = 0); - // 删除子节点 - bool del(Node * child); - // 获取子节点数量 - int getCount(); - // 获取所有子节点 - std::vector &getChildren(); - // 清空所有子节点 - void clearAllChildren(); - - // 设置节点横坐标 - virtual void setX(int x) override; - // 设置节点纵坐标 - virtual void setY(int y) override; - // 设置节点坐标 - virtual void setPos(int x, int y) override; - // 设置节点坐标 - virtual void setPos(CPoint p) override; - // 移动节点 - virtual void move(int x, int y) override; - // 移动节点 - virtual void move(CVector v) override; - -protected: - std::vector m_vChildren; - -protected: - virtual bool _exec(bool active) override; - virtual void _onDraw() override; -}; - -class Layer : - public BatchNode -{ -public: - Layer(); - virtual ~Layer(); - - // 图层是否阻塞消息 - int getBlock() const; - // 设置图层是否阻塞消息 - void setBlock(bool block); - -protected: - bool m_bBlock; - -protected: - virtual bool _exec(bool active) override; -}; - -class RectNode : - public Node -{ -public: - RectNode(); - ~RectNode(); - - // 判断两节点是否碰撞 - virtual bool isCollisionWith(RectNode * rectNode) const; - // 判断点是否在节点内 - virtual bool isPointIn(CPoint p) const; - - // 设置节点在窗口居中 - virtual void setWindowCenter(); - // 设置节点在窗口横向居中 - virtual void setWindowCenterX(); - // 设置节点在窗口纵向居中 - virtual void setWindowCenterY(); - - // 获取节点横坐标 - virtual int getX() const override; - // 获取节点纵坐标 - virtual int getY() const override; - // 获取节点坐标 - virtual CPoint getPos() const override; - // 获取节点宽度 - virtual int getWidth() const; - // 获取节点高度 - virtual int getHeight() const; - // 获取节点大小 - virtual CSize getSize() const; - // 获取节点所在的矩形 - virtual CRect getRect() const; - - // 设置节点横坐标 - virtual void setX(int x) override; - // 设置节点纵坐标 - virtual void setY(int y) override; - // 设置节点坐标 - virtual void setPos(int x, int y) override; - // 设置节点坐标 - virtual void setPos(CPoint p) override; - // 移动节点 - virtual void move(int x, int y) override; - // 移动节点 - virtual void move(CVector v) override; - // 设置节点宽度 - virtual void setWidth(int width); - // 设置节点高度 - virtual void setHeight(int height); - // 设置节点大小 - virtual void setSize(int width, int height); - // 设置节点大小 - virtual void setSize(CSize size); - // 设置节点所在的矩形 - virtual void setRect(int x1, int y1, int x2, int y2); - // 设置节点所在的矩形 - virtual void setRect(CPoint leftTop, CPoint rightBottom); - // 设置节点所在的矩形 - virtual void setRect(CRect rect); - -protected: - CRect m_Rect; -}; - -class Text : - public RectNode -{ - friend TextButton; -public: - Text(); - // 根据字符串、颜色和字体创建文字 - Text(TString text, COLORREF color = Color::white, FontStyle * font = FontStyle::getDefault()); - // 根据横纵坐标、字符串、颜色和字体创建文字 - Text(int x, int y, TString text, COLORREF color = Color::white, FontStyle * font = FontStyle::getDefault()); - virtual ~Text(); - - // 获取当前颜色 - COLORREF getColor() const; - // 获取当前文字 - TString getText() const; - // 获取当前字体 - FontStyle * getFontStyle(); - // 文本是否为空 - bool isEmpty() const; - - // 设置文字 - void setText(TString text); - // 设置文字颜色 - void setColor(COLORREF color); - // 设置字体 - void setFontStyle(FontStyle * style); - -protected: - TString m_sText; - COLORREF m_color; - FontStyle * m_pFontStyle; - -protected: - virtual void _onDraw() override; -}; - -class Image : - public RectNode -{ - friend Sprite; - friend ImageButton; -public: - Image(); - // 从图片文件获取图像 - Image(LPCTSTR ImageFile); - /** - * 从图片文件获取图像 - * 参数:图片文件名,图片裁剪坐标,图片裁剪宽度和高度 - */ - Image(LPCTSTR ImageFile, int x, int y, int width, int height); - virtual ~Image(); - - // 获取横向拉伸比例 - float getScaleX() const; - // 获取纵向拉伸比例 - float getScaleY() const; - // 获取透明度 - float getOpacity() const; - - /** - * 从图片文件获取图像 - * 返回值:图片加载是否成功 - */ - bool setImage(LPCTSTR ImageFile); - /** - * 从图片文件获取图像 - * 参数:图片文件名,图片裁剪起始坐标,图片裁剪宽度和高度 - * 返回值:图片加载是否成功 - */ - bool setImage(LPCTSTR ImageFile, int x, int y, int width, int height); - /** - * 从资源文件获取图像,不支持 png - * 返回值:图片加载是否成功 - */ - bool setImageFromRes(LPCTSTR pResName); - /** - * 从资源文件获取图像,不支持 png - * 参数:资源名称,图片裁剪坐标,图片裁剪宽度和高度 - * 返回值:图片加载是否成功 - */ - bool setImageFromRes(LPCTSTR pResName, int x, int y, int width, int height); - // 裁剪图片(裁剪后会恢复 stretch 拉伸) - void crop(int x, int y, int width, int height); - // 将图片拉伸到固定宽高 - void stretch(int width, int height); - // 按比例拉伸图片 - void setScale(float scaleX, float scaleY); - // 设置透明度,范围 0~1.0f(只对 png 图片生效) - void setOpacity(float value); - // 设置透明色 - void setTransparentColor(COLORREF value); - // 重置图片属性 - void reset(); - - // 预加载图片 - static bool preload(LPCTSTR fileName, bool fromRes = false); - // 保存游戏截图 - static void saveScreenshot(); - -protected: - CImage* m_pCImage; - CRect m_SrcRect; - BYTE m_nAlpha; - float m_fScaleX; - float m_fScaleY; - -protected: - virtual void _onDraw() override; -}; - -class Sprite : - public RectNode -{ - friend BatchSprite; -public: - Sprite(); - Sprite(Image * image); - Sprite(LPCTSTR imageFileName); - virtual ~Sprite(); - - // 判断是否和另一个精灵碰撞 - bool isCollisionWith(Sprite * sprite); - // 修改精灵图片 - virtual void setImage(Image * image); - // 执行动作 - virtual void addAction(Action * action); - // 执行动作 - virtual void runAction(Action * action); - // 继续动作 - virtual void resumeAction(Action * action); - // 暂停动作 - virtual void pauseAction(Action * action); - // 停止动作 - virtual void stopAction(Action * action); - // 暂停所有动作 - virtual void pauseAllActions(); - // 继续所有动作 - virtual void resumeAllActions(); - // 停止所有动作 - virtual void stopAllActions(); - - virtual float getScaleX() const; - virtual float getScaleY() const; - virtual float getOpacity() const; - - virtual void setScale(float scaleX, float scaleY); - virtual void setOpacity(float opacity); - -protected: - float m_fScaleX; - float m_fScaleY; - BYTE m_nAlpha; - Image * m_pImage; - -protected: - bool _exec(bool active) override; - void _onDraw() override; -}; - -class BatchSprite : - public Sprite -{ -public: - BatchSprite(); - virtual ~BatchSprite(); - - // 添加精灵 - void addSprite(Sprite * sprite, int z_Order = 0); - // 删除精灵 - bool delSprite(Sprite * child); - // 获取精灵数量 - int getCount(); - // 获取所有精灵 - std::vector &getChildren(); - // 删除所有精灵 - void clearAllSprites(); - // 判断是否有精灵产生碰撞 - // 返回值:若有碰撞,返回第一个产生碰撞的精灵,否则返回空指针 - Sprite * isCollisionWith(Sprite * sprite); - // 判断点是否在精灵内部 - // 返回值:若这个点在任意一个精灵内部,返回这个精灵,否则返回空指针 - Sprite * isPointIn(CPoint point); - // 所有精灵同时执行一段动画 - virtual void addAction(Action * action) override; - // 同时修改所有精灵的图片 - virtual void setImage(Image * image) override; - - // 设置节点横坐标 - virtual void setX(int x) override; - // 设置节点纵坐标 - virtual void setY(int y) override; - // 设置节点坐标 - virtual void setPos(int x, int y) override; - // 设置节点坐标 - virtual void setPos(CPoint p) override; - // 移动节点 - virtual void move(int x, int y) override; - // 移动节点 - virtual void move(CVector v) override; - - virtual float getScaleX() const override; - virtual float getScaleY() const override; - virtual float getOpacity() const override; - - virtual void setScale(float scaleX, float scaleY) override; - virtual void setOpacity(float opacity) override; - -protected: - std::vector m_vSprites; - -protected: - bool _exec(bool active) override; - void _onDraw() override; -}; - -class MouseNode : - public RectNode -{ -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); - -protected: - bool m_bTarget; - bool m_bBlock; - enum Status { NORMAL, MOUSEIN, SELECTED } m_eStatus; - CLICK_CALLBACK m_OnMouseInCallback; - CLICK_CALLBACK m_OnMouseOutCallback; - CLICK_CALLBACK m_OnSelectCallback; - CLICK_CALLBACK m_OnUnselectCallback; - CLICK_CALLBACK m_ClickCallback; - -protected: - virtual bool _exec(bool active) override; - virtual void _onDraw() override; - - // 重写这个方法可以自定义按钮的判断方法 - virtual bool _isMouseIn(); - // 切换状态 - virtual void _setStatus(Status status); - // 正常状态 - virtual void _onNormal() = 0; - // 鼠标移入时 - virtual void _onMouseIn() = 0; - // 鼠标选中时 - virtual void _onSelected() = 0; -}; - -class Button : - public MouseNode -{ -public: - Button(); - virtual ~Button(); - - // 按钮是否启用 - virtual bool isEnable(); - // 设置是否启用 - virtual void setEnable(bool enable); - - // 设置按钮横坐标 - virtual void setX(int x) override; - // 设置按钮纵坐标 - virtual void setY(int y) override; - // 设置按钮坐标 - virtual void setPos(int x, int y) override; - // 设置按钮坐标 - virtual void setPos(CPoint p) override; - // 移动按钮 - virtual void move(int x, int y) override; - // 移动按钮 - virtual void move(CVector v) override; - -protected: - bool m_bEnable; - -protected: - virtual bool _exec(bool active) override; - virtual void _onDraw() override; - virtual void _resetPosition() = 0; - - virtual void _onNormal() = 0; - virtual void _onMouseIn() = 0; - virtual void _onSelected() = 0; - virtual void _onDisable() = 0; -}; - -class TextButton : - public Button -{ -public: - TextButton(); - TextButton(TString text); - TextButton(Text * text); - virtual ~TextButton(); - - // 设置按钮文字 - void setNormal(Text * text); - // 设置鼠标移入时的按钮文字 - void setMouseIn(Text * text); - // 设置鼠标选中时的按钮文字 - void setSelected(Text * text); - // 设置按钮禁用时的按钮文字 - void setUnable(Text * text); - -protected: - Text * m_pNormalText; - Text * m_pMouseInText; - Text * m_pSelectedText; - Text * m_pUnableText; - -protected: - virtual void _resetPosition() override; - - virtual void _setStatus(Status status) override; - virtual void _onNormal() override; - virtual void _onMouseIn() override; - virtual void _onSelected() override; - virtual void _onDisable() override; -}; - -class ImageButton : - public Button -{ -public: - ImageButton(); - ImageButton(LPCTSTR image); - ImageButton(Image * image); - virtual ~ImageButton(); - - // 设置按钮图片 - void setNormal(Image * image); - // 设置鼠标移入时的按钮图片 - void setMouseIn(Image * image); - // 设置鼠标选中时的按钮图片 - void setSelected(Image * image); - // 设置按钮禁用时的按钮图片 - void setUnable(Image * image); - -protected: - Image * m_pNormalImage; - Image * m_pMouseInImage; - Image * m_pSelectedImage; - Image * m_pUnableImage; - -protected: - virtual void _resetPosition() override; - virtual void _setStatus(Status status) override; - virtual void _onNormal() override; - virtual void _onMouseIn() override; - virtual void _onSelected() override; - virtual void _onDisable() override; -}; - -class Shape : - public Node -{ -public: - Shape(); - virtual ~Shape(); - - // 形状填充样式 - enum STYLE { ROUND, SOLID, FILL } m_eStyle; - - // 获取形状的填充颜色 - COLORREF getFillColor() const; - // 获取形状的线条颜色 - COLORREF getLineColor() const; - // 设置填充颜色 - void setFillColor(COLORREF color); - // 设置线条颜色 - 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 Shape -{ -public: - Rect(); - Rect(int x, int y, int width, int height); - virtual ~Rect(); - - // 获取矩形宽度 - int getWidth() const; - // 获取矩形高度 - int getHeight() const; - // 设置矩形宽度 - void setWidth(int width); - // 设置矩形高度 - void setHeight(int height); - // 设置矩形大小 - void setSize(int width, int height); - -protected: - CSize m_Size; - -protected: - virtual void solidShape() override; - virtual void fillShape() override; - virtual void roundShape() override; -}; - -class Circle : - public Shape -{ -public: - Circle(); - Circle(int x, int y, int radius); - virtual ~Circle(); - - // 获取圆形半径 - 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; -}; - -class Action : - public Object -{ - friend Sprite; - friend ActionManager; - friend ActionTwo; - friend ActionNeverStop; - friend ActionSequence; -public: - Action(); - virtual ~Action(); - - // 获取动作运行状态 - virtual bool isRunning(); - // 获取动作结束状态 - virtual bool isEnding(); - // 继续动作 - virtual void start(); - // 继续动作 - virtual void resume(); - // 暂停动作 - virtual void pause(); - // 停止动作 - virtual void stop(); - // 进入等待状态 - virtual void wait(); - // 唤醒 - virtual void notify(); - // 设置动作每一帧时间间隔 - virtual void setInterval(LONGLONG milliSeconds); - // 获取一个新的拷贝动作 - virtual Action * copy() const = 0; - // 获取一个新的逆向动作 - virtual Action * reverse() const; - // 获取执行该动作的目标 - virtual Sprite * getTarget(); - -protected: - bool m_bRunning; - bool m_bWaiting; - bool m_bEnding; - bool m_bInit; - Sprite * m_pTargetSprite; - Scene * m_pParentScene; - LONGLONG m_nAnimationInterval; - std::chrono::steady_clock::time_point m_nLast; - -protected: - virtual void _init(); - virtual void _exec(std::chrono::steady_clock::time_point nNow) = 0; - virtual void _reset(); -}; - -class Animation : - public Action -{ -public: - Animation(float duration); - virtual ~Animation(); - -protected: - LONGLONG m_nDuration; - LONGLONG m_nTotalDuration; - -protected: - bool _isEnd() const; - bool _isDelayEnough(std::chrono::steady_clock::time_point nNow); - virtual void _init() override; - virtual void _reset() override; -}; - -class ActionMoveBy : - public Animation -{ -public: - ActionMoveBy(float duration, CVector vec); - virtual ~ActionMoveBy(); - - virtual ActionMoveBy * copy() const override; - virtual ActionMoveBy * reverse() const override; - -protected: - CPoint m_BeginPos; - CVector m_MoveVector; - -protected: - virtual void _init() override; - virtual void _exec(std::chrono::steady_clock::time_point nNow) override; - virtual void _reset() override; -}; - -class ActionMoveTo : - public ActionMoveBy -{ -public: - ActionMoveTo(float duration, CPoint pos); - virtual ~ActionMoveTo(); - - virtual ActionMoveTo * copy() const override; - -protected: - CPoint m_EndPos; - -protected: - virtual void _init() override; - virtual void _reset() override; -}; - -class ActionScaleBy : - public Animation -{ -public: - ActionScaleBy(float duration, float scaleX, float scaleY); - virtual ~ActionScaleBy(); - - virtual ActionScaleBy * copy() const override; - virtual ActionScaleBy * reverse() const override; - -protected: - float m_nBeginScaleX; - float m_nBeginScaleY; - float m_nVariationX; - float m_nVariationY; - -protected: - virtual void _init() override; - virtual void _exec(std::chrono::steady_clock::time_point nNow) override; - virtual void _reset() override; -}; - -class ActionScaleTo : - public ActionScaleBy -{ -public: - ActionScaleTo(float duration, float scaleX, float scaleY); - virtual ~ActionScaleTo(); - - virtual ActionScaleTo * copy() const override; - -protected: - float m_nEndScaleX; - float m_nEndScaleY; - -protected: - virtual void _init() override; - virtual void _reset() override; -}; - -class ActionOpacityBy : - public Animation -{ -public: - ActionOpacityBy(float duration, float opacity); - virtual ~ActionOpacityBy(); - - virtual ActionOpacityBy * copy() const override; - virtual ActionOpacityBy * reverse() const override; - -protected: - float m_nBeginVal; - float m_nVariation; - -protected: - virtual void _init() override; - virtual void _exec(std::chrono::steady_clock::time_point nNow) override; - virtual void _reset() override; -}; - -class ActionOpacityTo : - public ActionOpacityBy -{ -public: - ActionOpacityTo(float duration, float opacity); - virtual ~ActionOpacityTo(); - - virtual ActionOpacityTo * copy() const override; - -protected: - float m_nEndVal; - -protected: - virtual void _init() override; - virtual void _reset() override; -}; - -class ActionFadeIn : - public ActionOpacityTo -{ -public: - ActionFadeIn(float duration) : ActionOpacityTo(duration, 1) {} -}; - -class ActionFadeOut : - public ActionOpacityTo -{ -public: - ActionFadeOut(float duration) : ActionOpacityTo(duration, 0) {} -}; - -class ActionTwo : - public Action -{ -public: - ActionTwo(Action * actionFirst, Action * actionSecond); - virtual ~ActionTwo(); - - virtual ActionTwo * copy() const override; - virtual ActionTwo * reverse(bool actionReverse = true) const; - -protected: - Action * m_FirstAction; - Action * m_SecondAction; - -protected: - virtual void _init() override; - virtual void _exec(std::chrono::steady_clock::time_point nNow) override; - virtual void _reset() override; -}; - -class ActionSequence : - public Action -{ -public: - ActionSequence(); - ActionSequence(int number, Action * action1, ...); - virtual ~ActionSequence(); - - void addAction(Action * action); - virtual ActionSequence * copy() const override; - virtual ActionSequence * reverse(bool actionReverse = true) const; - -protected: - UINT m_nActionIndex; - std::vector m_vActions; - -protected: - virtual void _init() override; - virtual void _exec(std::chrono::steady_clock::time_point nNow) override; - virtual void _reset() override; -}; - -class ActionDelay : - public Action -{ -public: - ActionDelay(float duration); - virtual ~ActionDelay(); - - virtual ActionDelay * copy() const override; - -protected: - virtual void _init() override; - virtual void _exec(std::chrono::steady_clock::time_point nNow) override; - virtual void _reset() override; -}; - -class ActionNeverStop : - public Action -{ -public: - ActionNeverStop(Action * action); - virtual ~ActionNeverStop(); - - virtual ActionNeverStop * copy() const override; - -protected: - Action * m_Action; - -protected: - virtual void _init() override; - virtual void _exec(std::chrono::steady_clock::time_point nNow) override; - virtual void _reset() override; -}; - -class ActionFrames : - public Action -{ -public: - ActionFrames(); - ActionFrames(LONGLONG frameDelay); - ~ActionFrames(); - - void addFrame(Image * frame); - virtual ActionFrames * copy() const override; - virtual ActionFrames * reverse() const override; - -protected: - UINT m_nFrameIndex; - std::vector m_vFrames; - -protected: - virtual void _init() override; - virtual void _exec(std::chrono::steady_clock::time_point nNow) override; - virtual void _reset() override; -}; - -class ActionCallback : - public Action -{ -public: - ActionCallback(const std::function& callback); - ~ActionCallback(); - - virtual ActionCallback * copy() const override; - -protected: - std::function m_Callback; - -protected: - virtual void _init() override; - virtual void _exec(std::chrono::steady_clock::time_point nNow) override; - virtual void _reset() override; -}; - -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); - /** - * 打开保存文件对话框,得到有效保存路径返回 true - * 参数:返回文件路径的字符串,窗口标题,设置扩展名过滤,设置默认扩展名 - */ - static bool getSaveFilePath(TString& path, LPCTSTR title = _T("保存到"), LPCTSTR defExt = NULL); -}; - -class MusicUtils -{ -public: - // 播放背景音乐 - static void playBackgroundMusic(TString pszFilePath, bool bLoop = true); - // 停止背景音乐 - static void stopBackgroundMusic(bool bReleaseData = false); - // 暂停背景音乐 - static void pauseBackgroundMusic(); - // 继续播放背景音乐 - static void resumeBackgroundMusic(); - // 从头播放背景音乐 - static void rewindBackgroundMusic(); - // 背景音乐是否正在播放 - static bool isBackgroundMusicPlaying(); - // 设置背景音乐音量,0 ~ 1.0f - static void setBackgroundMusicVolume(float volume); - - // 播放音效 - static unsigned int playMusic(TString pszFilePath, bool loop = false); - // 停止音效 - static void stopMusic(unsigned int nSoundId); - // 预加载音效 - static void preloadMusic(TString pszFilePath); - // 暂停音效 - static void pauseMusic(unsigned int nSoundId); - // 继续播放音效 - static void resumeMusic(unsigned int nSoundId); - // 卸载音效 - static void unloadMusic(LPCTSTR pszFilePath); - // 设置特定音乐的音量,0 ~ 1.0f - static void setVolume(TString pszFilePath, float volume); - - // 暂停所有音乐 - static void pauseAllMusics(); - // 继续播放所有音乐 - static void resumeAllMusics(); - // 停止所有音乐 - static void stopAllMusics(); - // 停止所有音乐,并释放内存 - static void end(); - // 设置总音量,0 ~ 1.0f - static void setVolume(float volume); -}; - -class Timer -{ - friend App; -public: - Timer(TString name, LONGLONG milliSeconds, const TIMER_CALLBACK & callback); - ~Timer(); - - // 启动定时器 - void start(); - // 停止定时器 - void stop(); - // 进入等待状态 - void wait(); - // 唤醒 - void notify(); - // 定时器是否正在运行 - bool isRunning(); - // 设置间隔时间 - void setInterval(LONGLONG milliSeconds); - // 设置回调函数 - void setCallback(const TIMER_CALLBACK& callback); - // 设置定时器名称 - void setName(TString name); - // 获取定时器间隔时间 - LONGLONG getInterval() const; - // 获取定时器名称 - TString getName() const; - - // 添加定时器 - static void addTimer(Timer * timer); - // 添加定时器 - static void addTimer(TString name, const TIMER_CALLBACK & callback); - // 添加定时器 - static void addTimer(TString name, LONGLONG milliSeconds, const TIMER_CALLBACK & callback); - // 启动特定定时器 - static void startTimer(TString name); - // 停止特定定时器 - static void stopTimer(TString name); - // 删除特定定时器 - static void delTimer(TString name); - // 删除所有定时器 - static void clearAllTimers(); - - // 继续绑定在场景上的所有定时器 - static void notifyAllSceneTimers(Scene* scene); - // 停止绑定在场景上的所有定时器 - static void waitAllSceneTimers(Scene* scene); - // 清除绑定在场景上的所有定时器 - static void clearAllSceneTimers(Scene* scene); - -protected: - bool m_bRunning; - bool m_bWaiting; - TString m_sName; - TIMER_CALLBACK m_callback; - LONGLONG m_nAnimationInterval; - Scene * m_pParentScene; - std::chrono::steady_clock::time_point m_nLast; - -private: - static void __exec(); -}; - -class ActionManager -{ - friend App; - friend Sprite; -public: - // 继续一个特定的动作 - static void startAction(Action * action); - // 继续一个特定的动作 - static void resumeAction(Action * action); - // 暂停一个特定的动作 - static void pauseAction(Action * action); - // 停止一个特定的动作 - static void stopAction(Action * action); - - // 继续一个 Sprite 的所有动作 - static void startSpriteAllActions(Sprite * sprite); - // 继续一个 Sprite 的所有动作 - static void resumeSpriteAllActions(Sprite * sprite); - // 暂停一个 Sprite 的所有动作 - static void pauseSpriteAllActions(Sprite * sprite); - // 停止一个 Sprite 的所有动作 - static void stopSpriteAllActions(Sprite * sprite); - - // 继续当前存在的所有动作 - static void startAllActions(); - // 继续当前存在的所有动作 - static void resumeAllActions(); - // 暂停当前存在的所有动作 - static void pauseAllActions(); - // 停止当前存在的所有动作 - static void stopAllActions(); - // 删除当前存在的所有动作 - static void clearAllActions(); - - // 继续绑定在场景上的动作 - static void notifyAllSceneActions(Scene* scene); - // 暂停绑定在场景上的动作 - static void waitAllSceneActions(Scene* scene); - // 停止绑定在场景上的动作 - static void stopAllSceneActions(Scene* scene); - -private: - static void __exec(); - // 将一个动作添加进动作管理器 - static void addAction(Action * action); -}; - -class Math -{ -public: - // 取得整型范围内的一个随机数 - template - static T randomInt(T min, T max) - { - std::uniform_int_distribution dist(min, max); - return dist(getEngine()); - } - // 取得浮点数类型范围内的一个随机数 - template - static T randomReal(T min, T max) - { - std::uniform_real_distribution dist(min, max); - return dist(getEngine()); - } - // 获取随机数产生器 - static std::default_random_engine &getEngine(); -}; - } // End of easy2d namespace // Functions Declare -inline void SafeRelease(easy2d::Object * p) { if (p) p->release(); } -inline void SafeDelete(void * p) { if (p) delete p; } - -template -inline T random(T min, T max) { return easy2d::Math::randomInt(min, max); } -inline float random(float min, float max) { return easy2d::Math::randomReal(min, max); } -inline double random(double min, double max) { return easy2d::Math::randomReal(min, max); } -inline long double random(long double min, long double max) { return easy2d::Math::randomReal(min, max); } - -using namespace easy2d; \ No newline at end of file +using namespace e2d; \ No newline at end of file diff --git a/Easy2D/ecommon.h b/Easy2D/ecommon.h new file mode 100644 index 00000000..9ddabd66 --- /dev/null +++ b/Easy2D/ecommon.h @@ -0,0 +1,170 @@ +#pragma once +#include +#include + +typedef std::wstring EString; + + +typedef struct +{ + UINT32 width; + UINT32 height; +} ESize; + + +typedef struct +{ + FLOAT width; + FLOAT height; +} ESize_F; + + +class EColor +{ +public: + + enum Enum + { + AliceBlue = 0xF0F8FF, + AntiqueWhite = 0xFAEBD7, + Aqua = 0x00FFFF, + Aquamarine = 0x7FFFD4, + Azure = 0xF0FFFF, + Beige = 0xF5F5DC, + Bisque = 0xFFE4C4, + Black = 0x000000, + BlanchedAlmond = 0xFFEBCD, + Blue = 0x0000FF, + BlueViolet = 0x8A2BE2, + Brown = 0xA52A2A, + BurlyWood = 0xDEB887, + CadetBlue = 0x5F9EA0, + Chartreuse = 0x7FFF00, + Chocolate = 0xD2691E, + Coral = 0xFF7F50, + CornflowerBlue = 0x6495ED, + Cornsilk = 0xFFF8DC, + Crimson = 0xDC143C, + Cyan = 0x00FFFF, + DarkBlue = 0x00008B, + DarkCyan = 0x008B8B, + DarkGoldenrod = 0xB8860B, + DarkGray = 0xA9A9A9, + DarkGreen = 0x006400, + DarkKhaki = 0xBDB76B, + DarkMagenta = 0x8B008B, + DarkOliveGreen = 0x556B2F, + DarkOrange = 0xFF8C00, + DarkOrchid = 0x9932CC, + DarkRed = 0x8B0000, + DarkSalmon = 0xE9967A, + DarkSeaGreen = 0x8FBC8F, + DarkSlateBlue = 0x483D8B, + DarkSlateGray = 0x2F4F4F, + DarkTurquoise = 0x00CED1, + DarkViolet = 0x9400D3, + DeepPink = 0xFF1493, + DeepSkyBlue = 0x00BFFF, + DimGray = 0x696969, + DodgerBlue = 0x1E90FF, + Firebrick = 0xB22222, + FloralWhite = 0xFFFAF0, + ForestGreen = 0x228B22, + Fuchsia = 0xFF00FF, + Gainsboro = 0xDCDCDC, + GhostWhite = 0xF8F8FF, + Gold = 0xFFD700, + Goldenrod = 0xDAA520, + Gray = 0x808080, + Green = 0x008000, + GreenYellow = 0xADFF2F, + Honeydew = 0xF0FFF0, + HotPink = 0xFF69B4, + IndianRed = 0xCD5C5C, + Indigo = 0x4B0082, + Ivory = 0xFFFFF0, + Khaki = 0xF0E68C, + Lavender = 0xE6E6FA, + LavenderBlush = 0xFFF0F5, + LawnGreen = 0x7CFC00, + LemonChiffon = 0xFFFACD, + LightBlue = 0xADD8E6, + LightCoral = 0xF08080, + LightCyan = 0xE0FFFF, + LightGoldenrodYellow = 0xFAFAD2, + LightGreen = 0x90EE90, + LightGray = 0xD3D3D3, + LightPink = 0xFFB6C1, + LightSalmon = 0xFFA07A, + LightSeaGreen = 0x20B2AA, + LightSkyBlue = 0x87CEFA, + LightSlateGray = 0x778899, + LightSteelBlue = 0xB0C4DE, + LightYellow = 0xFFFFE0, + Lime = 0x00FF00, + LimeGreen = 0x32CD32, + Linen = 0xFAF0E6, + Magenta = 0xFF00FF, + Maroon = 0x800000, + MediumAquamarine = 0x66CDAA, + MediumBlue = 0x0000CD, + MediumOrchid = 0xBA55D3, + MediumPurple = 0x9370DB, + MediumSeaGreen = 0x3CB371, + MediumSlateBlue = 0x7B68EE, + MediumSpringGreen = 0x00FA9A, + MediumTurquoise = 0x48D1CC, + MediumVioletRed = 0xC71585, + MidnightBlue = 0x191970, + MintCream = 0xF5FFFA, + MistyRose = 0xFFE4E1, + Moccasin = 0xFFE4B5, + NavajoWhite = 0xFFDEAD, + Navy = 0x000080, + OldLace = 0xFDF5E6, + Olive = 0x808000, + OliveDrab = 0x6B8E23, + Orange = 0xFFA500, + OrangeRed = 0xFF4500, + Orchid = 0xDA70D6, + PaleGoldenrod = 0xEEE8AA, + PaleGreen = 0x98FB98, + PaleTurquoise = 0xAFEEEE, + PaleVioletRed = 0xDB7093, + PapayaWhip = 0xFFEFD5, + PeachPuff = 0xFFDAB9, + Peru = 0xCD853F, + Pink = 0xFFC0CB, + Plum = 0xDDA0DD, + PowderBlue = 0xB0E0E6, + Purple = 0x800080, + Red = 0xFF0000, + RosyBrown = 0xBC8F8F, + RoyalBlue = 0x4169E1, + SaddleBrown = 0x8B4513, + Salmon = 0xFA8072, + SandyBrown = 0xF4A460, + SeaGreen = 0x2E8B57, + SeaShell = 0xFFF5EE, + Sienna = 0xA0522D, + Silver = 0xC0C0C0, + SkyBlue = 0x87CEEB, + SlateBlue = 0x6A5ACD, + SlateGray = 0x708090, + Snow = 0xFFFAFA, + SpringGreen = 0x00FF7F, + SteelBlue = 0x4682B4, + Tan = 0xD2B48C, + Teal = 0x008080, + Thistle = 0xD8BFD8, + Tomato = 0xFF6347, + Turquoise = 0x40E0D0, + Violet = 0xEE82EE, + Wheat = 0xF5DEB3, + White = 0xFFFFFF, + WhiteSmoke = 0xF5F5F5, + Yellow = 0xFFFF00, + YellowGreen = 0x9ACD32, + }; + +}; \ No newline at end of file diff --git a/Easy2D/emacros.h b/Easy2D/emacros.h new file mode 100644 index 00000000..e0ae5d89 --- /dev/null +++ b/Easy2D/emacros.h @@ -0,0 +1,15 @@ +#pragma once + + +#ifndef Assert + +#if defined( DEBUG ) || defined( _DEBUG ) + #define Assert(b) do {if (!(b)) {OutputDebugStringA("Assert: " #b "\n");}} while(0) +#else + #define Assert(b) +#endif //DEBUG || _DEBUG + +#endif + +template +inline void SafeDelete(T** p) { if (*p) { delete *p; *p = nullptr; } } \ No newline at end of file