refactoring
This commit is contained in:
parent
09a3850135
commit
83986230a1
|
|
@ -41,10 +41,6 @@ e2d::GC::~GC()
|
||||||
Image::clearCache();
|
Image::clearCache();
|
||||||
|
|
||||||
// 删除所有单例
|
// 删除所有单例
|
||||||
Game::destroyInstance();
|
|
||||||
Renderer::destroyInstance();
|
|
||||||
Input::destroyInstance();
|
|
||||||
Window::destroyInstance();
|
|
||||||
Timer::destroyInstance();
|
Timer::destroyInstance();
|
||||||
SceneManager::destroyInstance();
|
SceneManager::destroyInstance();
|
||||||
ActionManager::destroyInstance();
|
ActionManager::destroyInstance();
|
||||||
|
|
|
||||||
|
|
@ -4,35 +4,38 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
|
|
||||||
e2d::Game * e2d::Game::_instance = nullptr;
|
|
||||||
|
|
||||||
e2d::Game::Game()
|
e2d::Game::Game()
|
||||||
: _quit(true)
|
: _quit(true)
|
||||||
, _paused(false)
|
, _paused(false)
|
||||||
, _config()
|
, _config()
|
||||||
|
, _window(nullptr)
|
||||||
|
, _input(nullptr)
|
||||||
|
, _renderer(nullptr)
|
||||||
{
|
{
|
||||||
CoInitialize(nullptr);
|
CoInitialize(nullptr);
|
||||||
|
|
||||||
|
_input = new (std::nothrow) Input;
|
||||||
|
_renderer = new (std::nothrow) Renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
e2d::Game::~Game()
|
e2d::Game::~Game()
|
||||||
{
|
{
|
||||||
|
if (_renderer)
|
||||||
|
delete _renderer;
|
||||||
|
|
||||||
|
if (_input)
|
||||||
|
delete _input;
|
||||||
|
|
||||||
|
if (_window)
|
||||||
|
delete _window;
|
||||||
|
|
||||||
CoUninitialize();
|
CoUninitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
e2d::Game * e2d::Game::getInstance()
|
e2d::Game * e2d::Game::getInstance()
|
||||||
{
|
{
|
||||||
if (!_instance)
|
static Game instance;
|
||||||
_instance = new (std::nothrow) Game;
|
return &instance;
|
||||||
return _instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
void e2d::Game::destroyInstance()
|
|
||||||
{
|
|
||||||
if (_instance)
|
|
||||||
{
|
|
||||||
delete _instance;
|
|
||||||
_instance = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Game::start()
|
void e2d::Game::start()
|
||||||
|
|
@ -41,11 +44,11 @@ void e2d::Game::start()
|
||||||
|
|
||||||
const int minInterval = 5;
|
const int minInterval = 5;
|
||||||
Time last = Time::now();
|
Time last = Time::now();
|
||||||
HWND hWnd = Window::getInstance()->getHWnd();
|
HWND hWnd = _window->getHWnd();
|
||||||
|
|
||||||
::ShowWindow(hWnd, SW_SHOWNORMAL);
|
::ShowWindow(hWnd, SW_SHOWNORMAL);
|
||||||
::UpdateWindow(hWnd);
|
::UpdateWindow(hWnd);
|
||||||
Window::getInstance()->poll();
|
_window->poll();
|
||||||
SceneManager::getInstance()->update();
|
SceneManager::getInstance()->update();
|
||||||
|
|
||||||
while (!_quit)
|
while (!_quit)
|
||||||
|
|
@ -56,12 +59,12 @@ void e2d::Game::start()
|
||||||
if (dur.milliseconds() > minInterval)
|
if (dur.milliseconds() > minInterval)
|
||||||
{
|
{
|
||||||
last = now;
|
last = now;
|
||||||
Input::getInstance()->update();
|
_input->update();
|
||||||
Timer::getInstance()->update();
|
Timer::getInstance()->update();
|
||||||
ActionManager::getInstance()->update();
|
ActionManager::getInstance()->update();
|
||||||
SceneManager::getInstance()->update();
|
SceneManager::getInstance()->update();
|
||||||
Renderer::getInstance()->render();
|
_renderer->render();
|
||||||
Window::getInstance()->poll();
|
_window->poll();
|
||||||
GC::getInstance()->flush();
|
GC::getInstance()->flush();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -103,11 +106,18 @@ void e2d::Game::setConfig(const Config& config)
|
||||||
_config = config;
|
_config = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
const e2d::Config& e2d::Game::getConfig()
|
const e2d::Config& e2d::Game::getConfig() const
|
||||||
{
|
{
|
||||||
return _config;
|
return _config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void e2d::Game::setWindow(Window * window)
|
||||||
|
{
|
||||||
|
_window = window;
|
||||||
|
_renderer->init(_window);
|
||||||
|
_input->init(_window);
|
||||||
|
}
|
||||||
|
|
||||||
void e2d::Game::quit()
|
void e2d::Game::quit()
|
||||||
{
|
{
|
||||||
_quit = true;
|
_quit = true;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
#include "..\e2dmanager.h"
|
#include "..\e2dmanager.h"
|
||||||
#pragma comment(lib, "dinput8.lib")
|
#pragma comment(lib, "dinput8.lib")
|
||||||
|
|
||||||
e2d::Input * e2d::Input::_instance = nullptr;
|
|
||||||
|
|
||||||
e2d::Input::Input()
|
e2d::Input::Input()
|
||||||
: _directInput(false)
|
: _directInput(false)
|
||||||
|
|
@ -23,52 +22,6 @@ e2d::Input::Input()
|
||||||
(void**)&_directInput,
|
(void**)&_directInput,
|
||||||
nullptr
|
nullptr
|
||||||
);
|
);
|
||||||
|
|
||||||
auto window = Window::getInstance();
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
{
|
|
||||||
// 初始化键盘设备
|
|
||||||
hr = _directInput->CreateDevice(
|
|
||||||
GUID_SysKeyboard,
|
|
||||||
&_keyboardDevice,
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
{
|
|
||||||
_keyboardDevice->SetCooperativeLevel(
|
|
||||||
window->getHWnd(),
|
|
||||||
DISCL_FOREGROUND | DISCL_NONEXCLUSIVE
|
|
||||||
);
|
|
||||||
_keyboardDevice->SetDataFormat(
|
|
||||||
&c_dfDIKeyboard);
|
|
||||||
_keyboardDevice->Acquire();
|
|
||||||
_keyboardDevice->Poll();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw SystemException(L"Keyboard not found!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
{
|
|
||||||
// 初始化鼠标设备
|
|
||||||
hr = _directInput->CreateDevice(GUID_SysMouse, &_mouseDevice, nullptr);
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
{
|
|
||||||
_mouseDevice->SetCooperativeLevel(window->getHWnd(), DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
|
|
||||||
_mouseDevice->SetDataFormat(&c_dfDIMouse);
|
|
||||||
_mouseDevice->Acquire();
|
|
||||||
_mouseDevice->Poll();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw SystemException(L"Mouse not found!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
e2d::Input::~Input()
|
e2d::Input::~Input()
|
||||||
|
|
@ -85,20 +38,37 @@ e2d::Input::~Input()
|
||||||
CoUninitialize();
|
CoUninitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
e2d::Input * e2d::Input::getInstance()
|
void e2d::Input::init(Window * window)
|
||||||
{
|
{
|
||||||
if (!_instance)
|
HWND hwnd = window->getHWnd();
|
||||||
_instance = new (std::nothrow) Input;
|
|
||||||
return _instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
void e2d::Input::destroyInstance()
|
// 初始化键盘设备
|
||||||
{
|
ThrowIfFailed(
|
||||||
if (_instance)
|
_directInput->CreateDevice(
|
||||||
{
|
GUID_SysKeyboard,
|
||||||
delete _instance;
|
&_keyboardDevice,
|
||||||
_instance = nullptr;
|
nullptr
|
||||||
}
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
_keyboardDevice->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
|
||||||
|
_keyboardDevice->SetDataFormat(&c_dfDIKeyboard);
|
||||||
|
_keyboardDevice->Acquire();
|
||||||
|
_keyboardDevice->Poll();
|
||||||
|
|
||||||
|
// 初始化鼠标设备
|
||||||
|
ThrowIfFailed(
|
||||||
|
_directInput->CreateDevice(
|
||||||
|
GUID_SysMouse,
|
||||||
|
&_mouseDevice,
|
||||||
|
nullptr
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
_mouseDevice->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
|
||||||
|
_mouseDevice->SetDataFormat(&c_dfDIMouse);
|
||||||
|
_mouseDevice->Acquire();
|
||||||
|
_mouseDevice->Poll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Input::update()
|
void e2d::Input::update()
|
||||||
|
|
@ -160,7 +130,7 @@ float e2d::Input::getMouseY()
|
||||||
|
|
||||||
e2d::Point e2d::Input::getMousePos()
|
e2d::Point e2d::Input::getMousePos()
|
||||||
{
|
{
|
||||||
auto window = Window::getInstance();
|
auto window = Game::getInstance()->getWindow();
|
||||||
|
|
||||||
POINT mousePos;
|
POINT mousePos;
|
||||||
::GetCursorPos(&mousePos);
|
::GetCursorPos(&mousePos);
|
||||||
|
|
|
||||||
|
|
@ -3,39 +3,6 @@
|
||||||
#include "..\e2dnode.h"
|
#include "..\e2dnode.h"
|
||||||
|
|
||||||
|
|
||||||
e2d::Renderer* e2d::Renderer::_instance = nullptr;
|
|
||||||
ID2D1Factory* e2d::Renderer::_d2dFactory = nullptr;
|
|
||||||
IWICImagingFactory* e2d::Renderer::_imagingFactory = nullptr;
|
|
||||||
IDWriteFactory* e2d::Renderer::_writeFactory = nullptr;
|
|
||||||
ID2D1StrokeStyle* e2d::Renderer::_miterStrokeStyle = nullptr;
|
|
||||||
ID2D1StrokeStyle* e2d::Renderer::_bevelStrokeStyle = nullptr;
|
|
||||||
ID2D1StrokeStyle* e2d::Renderer::_roundStrokeStyle = nullptr;
|
|
||||||
|
|
||||||
e2d::Renderer * e2d::Renderer::getInstance()
|
|
||||||
{
|
|
||||||
if (!_instance)
|
|
||||||
{
|
|
||||||
_instance = new (std::nothrow) Renderer;
|
|
||||||
}
|
|
||||||
return _instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
void e2d::Renderer::destroyInstance()
|
|
||||||
{
|
|
||||||
if (_instance)
|
|
||||||
{
|
|
||||||
delete _instance;
|
|
||||||
_instance = nullptr;
|
|
||||||
|
|
||||||
SafeRelease(_miterStrokeStyle);
|
|
||||||
SafeRelease(_bevelStrokeStyle);
|
|
||||||
SafeRelease(_roundStrokeStyle);
|
|
||||||
SafeRelease(_d2dFactory);
|
|
||||||
SafeRelease(_imagingFactory);
|
|
||||||
SafeRelease(_writeFactory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
e2d::Renderer::Renderer()
|
e2d::Renderer::Renderer()
|
||||||
: _lastRenderTime(Time::now())
|
: _lastRenderTime(Time::now())
|
||||||
, _renderTimes(0)
|
, _renderTimes(0)
|
||||||
|
|
@ -44,9 +11,40 @@ e2d::Renderer::Renderer()
|
||||||
, _renderTarget(nullptr)
|
, _renderTarget(nullptr)
|
||||||
, _solidBrush(nullptr)
|
, _solidBrush(nullptr)
|
||||||
, _textRenderer(nullptr)
|
, _textRenderer(nullptr)
|
||||||
|
, _factory(nullptr)
|
||||||
|
, _imagingFactory(nullptr)
|
||||||
|
, _writeFactory(nullptr)
|
||||||
|
, _miterStrokeStyle(nullptr)
|
||||||
|
, _bevelStrokeStyle(nullptr)
|
||||||
|
, _roundStrokeStyle(nullptr)
|
||||||
, _clearColor(D2D1::ColorF(D2D1::ColorF::Black))
|
, _clearColor(D2D1::ColorF(D2D1::ColorF::Black))
|
||||||
{
|
{
|
||||||
CoInitialize(nullptr);
|
CoInitialize(nullptr);
|
||||||
|
|
||||||
|
ThrowIfFailed(
|
||||||
|
D2D1CreateFactory(
|
||||||
|
D2D1_FACTORY_TYPE_SINGLE_THREADED,
|
||||||
|
&_factory
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
ThrowIfFailed(
|
||||||
|
CoCreateInstance(
|
||||||
|
CLSID_WICImagingFactory,
|
||||||
|
nullptr,
|
||||||
|
CLSCTX_INPROC_SERVER,
|
||||||
|
IID_IWICImagingFactory,
|
||||||
|
reinterpret_cast<void**>(&_imagingFactory)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
ThrowIfFailed(
|
||||||
|
DWriteCreateFactory(
|
||||||
|
DWRITE_FACTORY_TYPE_SHARED,
|
||||||
|
__uuidof(IDWriteFactory),
|
||||||
|
reinterpret_cast<IUnknown**>(&_writeFactory)
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
e2d::Renderer::~Renderer()
|
e2d::Renderer::~Renderer()
|
||||||
|
|
@ -57,27 +55,69 @@ e2d::Renderer::~Renderer()
|
||||||
SafeRelease(_solidBrush);
|
SafeRelease(_solidBrush);
|
||||||
SafeRelease(_renderTarget);
|
SafeRelease(_renderTarget);
|
||||||
|
|
||||||
|
SafeRelease(_miterStrokeStyle);
|
||||||
|
SafeRelease(_bevelStrokeStyle);
|
||||||
|
SafeRelease(_roundStrokeStyle);
|
||||||
|
SafeRelease(_factory);
|
||||||
|
SafeRelease(_imagingFactory);
|
||||||
|
SafeRelease(_writeFactory);
|
||||||
|
|
||||||
CoUninitialize();
|
CoUninitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Renderer::discardDeviceResources()
|
void e2d::Renderer::init(Window * window)
|
||||||
{
|
{
|
||||||
SafeRelease(_renderTarget);
|
if (!window)
|
||||||
SafeRelease(_solidBrush);
|
return;
|
||||||
SafeRelease(_textRenderer);
|
|
||||||
|
HWND hWnd = window->getHWnd();
|
||||||
|
|
||||||
|
RECT rc;
|
||||||
|
GetClientRect(hWnd, &rc);
|
||||||
|
|
||||||
|
D2D1_SIZE_U size = D2D1::SizeU(
|
||||||
|
rc.right - rc.left,
|
||||||
|
rc.bottom - rc.top
|
||||||
|
);
|
||||||
|
|
||||||
|
// 创建设备相关资源。这些资源应在 Direct2D 设备消失时重建
|
||||||
|
// 创建一个 Direct2D 渲染目标
|
||||||
|
ThrowIfFailed(
|
||||||
|
_factory->CreateHwndRenderTarget(
|
||||||
|
D2D1::RenderTargetProperties(),
|
||||||
|
D2D1::HwndRenderTargetProperties(
|
||||||
|
hWnd,
|
||||||
|
size,
|
||||||
|
D2D1_PRESENT_OPTIONS_NONE),
|
||||||
|
&_renderTarget
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 创建画刷
|
||||||
|
ThrowIfFailed(
|
||||||
|
_renderTarget->CreateSolidColorBrush(
|
||||||
|
D2D1::ColorF(D2D1::ColorF::White),
|
||||||
|
&_solidBrush
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 创建自定义的文字渲染器
|
||||||
|
ThrowIfFailed(
|
||||||
|
TextRenderer::Create(
|
||||||
|
&_textRenderer,
|
||||||
|
_factory,
|
||||||
|
_renderTarget,
|
||||||
|
_solidBrush
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Renderer::render()
|
void e2d::Renderer::render()
|
||||||
{
|
{
|
||||||
auto renderTarget = this->getRenderTarget();
|
|
||||||
// 仅当窗口没有被遮挡时进行渲染
|
|
||||||
if (renderTarget->CheckWindowState() & D2D1_WINDOW_STATE_OCCLUDED)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// 开始渲染
|
// 开始渲染
|
||||||
renderTarget->BeginDraw();
|
_renderTarget->BeginDraw();
|
||||||
// 使用背景色清空屏幕
|
// 使用背景色清空屏幕
|
||||||
renderTarget->Clear(_clearColor);
|
_renderTarget->Clear(_clearColor);
|
||||||
|
|
||||||
// 渲染场景
|
// 渲染场景
|
||||||
SceneManager::getInstance()->render();
|
SceneManager::getInstance()->render();
|
||||||
|
|
@ -89,19 +129,24 @@ void e2d::Renderer::render()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 终止渲染
|
// 终止渲染
|
||||||
HRESULT hr = renderTarget->EndDraw();
|
HRESULT hr = _renderTarget->EndDraw();
|
||||||
|
|
||||||
if (hr == D2DERR_RECREATE_TARGET)
|
if (hr == D2DERR_RECREATE_TARGET)
|
||||||
{
|
{
|
||||||
// 如果 Direct3D 设备在执行过程中消失,将丢弃当前的设备相关资源
|
// 如果 Direct3D 设备在执行过程中消失,将丢弃当前的设备相关资源
|
||||||
// 并在下一次调用时重建资源
|
// 并在下一次调用时重建资源
|
||||||
hr = S_OK;
|
hr = S_OK;
|
||||||
this->discardDeviceResources();
|
|
||||||
|
SafeRelease(_fpsFormat);
|
||||||
|
SafeRelease(_fpsLayout);
|
||||||
|
SafeRelease(_textRenderer);
|
||||||
|
SafeRelease(_solidBrush);
|
||||||
|
SafeRelease(_renderTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
throw SystemException(L"Device loss recovery failed");
|
throw SystemException("Device loss recovery failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -116,10 +161,10 @@ void e2d::Renderer::_renderFps()
|
||||||
_lastRenderTime = Time::now();
|
_lastRenderTime = Time::now();
|
||||||
_renderTimes = 0;
|
_renderTimes = 0;
|
||||||
|
|
||||||
auto writeFactory = Renderer::getWriteFactory();
|
|
||||||
if (!_fpsFormat)
|
if (!_fpsFormat)
|
||||||
{
|
{
|
||||||
HRESULT hr = writeFactory->CreateTextFormat(
|
ThrowIfFailed(
|
||||||
|
_writeFactory->CreateTextFormat(
|
||||||
L"",
|
L"",
|
||||||
nullptr,
|
nullptr,
|
||||||
DWRITE_FONT_WEIGHT_NORMAL,
|
DWRITE_FONT_WEIGHT_NORMAL,
|
||||||
|
|
@ -128,36 +173,33 @@ void e2d::Renderer::_renderFps()
|
||||||
20,
|
20,
|
||||||
L"",
|
L"",
|
||||||
&_fpsFormat
|
&_fpsFormat
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
ThrowIfFailed(
|
||||||
{
|
_fpsFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP)
|
||||||
_fpsFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SafeRelease(_fpsLayout);
|
SafeRelease(_fpsLayout);
|
||||||
|
|
||||||
if (_fpsFormat)
|
ThrowIfFailed(
|
||||||
{
|
_writeFactory->CreateTextLayout(
|
||||||
writeFactory->CreateTextLayout(
|
|
||||||
(const WCHAR *)fpsText,
|
(const WCHAR *)fpsText,
|
||||||
(UINT32)fpsText.getLength(),
|
(UINT32)fpsText.getLength(),
|
||||||
_fpsFormat,
|
_fpsFormat,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
&_fpsLayout
|
&_fpsLayout
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (_fpsLayout)
|
if (_fpsLayout)
|
||||||
{
|
{
|
||||||
this->getRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity());
|
_renderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
|
||||||
this->getSolidColorBrush()->SetOpacity(1.0f);
|
_solidBrush->SetOpacity(1.0f);
|
||||||
|
_textRenderer->SetTextStyle(
|
||||||
auto textRenderer = this->getTextRenderer();
|
|
||||||
textRenderer->SetTextStyle(
|
|
||||||
D2D1::ColorF(D2D1::ColorF::White),
|
D2D1::ColorF(D2D1::ColorF::White),
|
||||||
TRUE,
|
TRUE,
|
||||||
D2D1::ColorF(D2D1::ColorF::Black, 0.4f),
|
D2D1::ColorF(D2D1::ColorF::Black, 0.4f),
|
||||||
|
|
@ -165,7 +207,9 @@ void e2d::Renderer::_renderFps()
|
||||||
D2D1_LINE_JOIN_ROUND
|
D2D1_LINE_JOIN_ROUND
|
||||||
);
|
);
|
||||||
|
|
||||||
_fpsLayout->Draw(nullptr, textRenderer, 10, 0);
|
ThrowIfFailed(
|
||||||
|
_fpsLayout->Draw(nullptr, _textRenderer, 10, 0)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -179,139 +223,12 @@ void e2d::Renderer::setBackgroundColor(Color color)
|
||||||
_clearColor = (D2D1_COLOR_F)color;
|
_clearColor = (D2D1_COLOR_F)color;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID2D1HwndRenderTarget * e2d::Renderer::getRenderTarget()
|
|
||||||
{
|
|
||||||
if (!_renderTarget)
|
|
||||||
{
|
|
||||||
HWND hWnd = Window::getInstance()->getHWnd();
|
|
||||||
|
|
||||||
// 创建设备相关资源。这些资源应在 Direct3D 设备消失时重建
|
|
||||||
RECT rc;
|
|
||||||
GetClientRect(hWnd, &rc);
|
|
||||||
|
|
||||||
D2D1_SIZE_U size = D2D1::SizeU(
|
|
||||||
rc.right - rc.left,
|
|
||||||
rc.bottom - rc.top
|
|
||||||
);
|
|
||||||
|
|
||||||
// 创建一个 Direct2D 渲染目标
|
|
||||||
HRESULT hr = Renderer::getFactory()->CreateHwndRenderTarget(
|
|
||||||
D2D1::RenderTargetProperties(),
|
|
||||||
D2D1::HwndRenderTargetProperties(
|
|
||||||
hWnd,
|
|
||||||
size,
|
|
||||||
D2D1_PRESENT_OPTIONS_NONE),
|
|
||||||
&_renderTarget
|
|
||||||
);
|
|
||||||
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
throw SystemException(L"Create ID2D1HwndRenderTarget failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _renderTarget;
|
|
||||||
}
|
|
||||||
|
|
||||||
ID2D1SolidColorBrush * e2d::Renderer::getSolidColorBrush()
|
|
||||||
{
|
|
||||||
if (!_solidBrush)
|
|
||||||
{
|
|
||||||
// 创建画刷
|
|
||||||
HRESULT hr = this->getRenderTarget()->CreateSolidColorBrush(
|
|
||||||
D2D1::ColorF(D2D1::ColorF::White),
|
|
||||||
&_solidBrush
|
|
||||||
);
|
|
||||||
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
throw SystemException(L"Create ID2D1SolidColorBrush failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _solidBrush;
|
|
||||||
}
|
|
||||||
|
|
||||||
e2d::TextRenderer * e2d::Renderer::getTextRenderer()
|
|
||||||
{
|
|
||||||
if (!_textRenderer)
|
|
||||||
{
|
|
||||||
// 创建自定义的文字渲染器
|
|
||||||
HRESULT hr = TextRenderer::Create(
|
|
||||||
&_textRenderer,
|
|
||||||
Renderer::getFactory(),
|
|
||||||
this->getRenderTarget(),
|
|
||||||
this->getSolidColorBrush()
|
|
||||||
);
|
|
||||||
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
throw SystemException(L"Create TextRenderer failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _textRenderer;
|
|
||||||
}
|
|
||||||
|
|
||||||
ID2D1Factory * e2d::Renderer::getFactory()
|
|
||||||
{
|
|
||||||
if (!_d2dFactory)
|
|
||||||
{
|
|
||||||
HRESULT hr = D2D1CreateFactory(
|
|
||||||
D2D1_FACTORY_TYPE_SINGLE_THREADED,
|
|
||||||
&_d2dFactory
|
|
||||||
);
|
|
||||||
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
throw SystemException(L"Create ID2D1Factory failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _d2dFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
IWICImagingFactory * e2d::Renderer::getImagingFactory()
|
|
||||||
{
|
|
||||||
if (!_imagingFactory)
|
|
||||||
{
|
|
||||||
// 创建 WIC 绘图工厂,用于统一处理各种格式的图片
|
|
||||||
HRESULT hr = CoCreateInstance(
|
|
||||||
CLSID_WICImagingFactory,
|
|
||||||
nullptr,
|
|
||||||
CLSCTX_INPROC_SERVER,
|
|
||||||
IID_IWICImagingFactory,
|
|
||||||
reinterpret_cast<void**>(&_imagingFactory)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
throw SystemException(L"Create IWICImagingFactory failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _imagingFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
IDWriteFactory * e2d::Renderer::getWriteFactory()
|
|
||||||
{
|
|
||||||
if (!_writeFactory)
|
|
||||||
{
|
|
||||||
// 创建 DirectWrite 工厂
|
|
||||||
HRESULT hr = DWriteCreateFactory(
|
|
||||||
DWRITE_FACTORY_TYPE_SHARED,
|
|
||||||
__uuidof(IDWriteFactory),
|
|
||||||
reinterpret_cast<IUnknown**>(&_writeFactory)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
throw SystemException(L"Create IDWriteFactory failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _writeFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
ID2D1StrokeStyle * e2d::Renderer::getMiterStrokeStyle()
|
ID2D1StrokeStyle * e2d::Renderer::getMiterStrokeStyle()
|
||||||
{
|
{
|
||||||
if (!_miterStrokeStyle)
|
if (!_miterStrokeStyle)
|
||||||
{
|
{
|
||||||
HRESULT hr = Renderer::getFactory()->CreateStrokeStyle(
|
ThrowIfFailed(
|
||||||
|
_factory->CreateStrokeStyle(
|
||||||
D2D1::StrokeStyleProperties(
|
D2D1::StrokeStyleProperties(
|
||||||
D2D1_CAP_STYLE_FLAT,
|
D2D1_CAP_STYLE_FLAT,
|
||||||
D2D1_CAP_STYLE_FLAT,
|
D2D1_CAP_STYLE_FLAT,
|
||||||
|
|
@ -323,12 +240,8 @@ ID2D1StrokeStyle * e2d::Renderer::getMiterStrokeStyle()
|
||||||
nullptr,
|
nullptr,
|
||||||
0,
|
0,
|
||||||
&_miterStrokeStyle
|
&_miterStrokeStyle
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
throw SystemException(L"Create ID2D1StrokeStyle failed");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return _miterStrokeStyle;
|
return _miterStrokeStyle;
|
||||||
}
|
}
|
||||||
|
|
@ -337,7 +250,8 @@ ID2D1StrokeStyle * e2d::Renderer::getBevelStrokeStyle()
|
||||||
{
|
{
|
||||||
if (!_bevelStrokeStyle)
|
if (!_bevelStrokeStyle)
|
||||||
{
|
{
|
||||||
HRESULT hr = Renderer::getFactory()->CreateStrokeStyle(
|
ThrowIfFailed(
|
||||||
|
_factory->CreateStrokeStyle(
|
||||||
D2D1::StrokeStyleProperties(
|
D2D1::StrokeStyleProperties(
|
||||||
D2D1_CAP_STYLE_FLAT,
|
D2D1_CAP_STYLE_FLAT,
|
||||||
D2D1_CAP_STYLE_FLAT,
|
D2D1_CAP_STYLE_FLAT,
|
||||||
|
|
@ -349,12 +263,8 @@ ID2D1StrokeStyle * e2d::Renderer::getBevelStrokeStyle()
|
||||||
nullptr,
|
nullptr,
|
||||||
0,
|
0,
|
||||||
&_bevelStrokeStyle
|
&_bevelStrokeStyle
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
throw SystemException(L"Create ID2D1StrokeStyle failed");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return _bevelStrokeStyle;
|
return _bevelStrokeStyle;
|
||||||
}
|
}
|
||||||
|
|
@ -363,7 +273,8 @@ ID2D1StrokeStyle * e2d::Renderer::getRoundStrokeStyle()
|
||||||
{
|
{
|
||||||
if (!_roundStrokeStyle)
|
if (!_roundStrokeStyle)
|
||||||
{
|
{
|
||||||
HRESULT hr = Renderer::getFactory()->CreateStrokeStyle(
|
ThrowIfFailed(
|
||||||
|
_factory->CreateStrokeStyle(
|
||||||
D2D1::StrokeStyleProperties(
|
D2D1::StrokeStyleProperties(
|
||||||
D2D1_CAP_STYLE_FLAT,
|
D2D1_CAP_STYLE_FLAT,
|
||||||
D2D1_CAP_STYLE_FLAT,
|
D2D1_CAP_STYLE_FLAT,
|
||||||
|
|
@ -375,12 +286,8 @@ ID2D1StrokeStyle * e2d::Renderer::getRoundStrokeStyle()
|
||||||
nullptr,
|
nullptr,
|
||||||
0,
|
0,
|
||||||
&_roundStrokeStyle
|
&_roundStrokeStyle
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
throw SystemException(L"Create ID2D1StrokeStyle failed");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return _roundStrokeStyle;
|
return _roundStrokeStyle;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,46 +8,95 @@
|
||||||
#define REGISTER_CLASS L"Easy2DApp"
|
#define REGISTER_CLASS L"Easy2DApp"
|
||||||
|
|
||||||
|
|
||||||
e2d::Window * e2d::Window::_instance = nullptr;
|
e2d::Window::Window(const String & title, int width, int height, int iconID)
|
||||||
|
|
||||||
e2d::Window::Window()
|
|
||||||
: _hWnd(nullptr)
|
: _hWnd(nullptr)
|
||||||
, _size(640, 480)
|
, _width(width)
|
||||||
, _title(L"Easy2D Game")
|
, _height(height)
|
||||||
, _iconID(0)
|
, _title(title)
|
||||||
|
, _iconID(iconID)
|
||||||
, _dpi(0.f)
|
, _dpi(0.f)
|
||||||
{
|
{
|
||||||
|
CoInitialize(nullptr);
|
||||||
|
|
||||||
|
WNDCLASSEX wcex = { 0 };
|
||||||
|
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||||
|
wcex.lpszClassName = REGISTER_CLASS;
|
||||||
|
wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
|
||||||
|
wcex.lpfnWndProc = Window::WndProc;
|
||||||
|
wcex.hIcon = nullptr;
|
||||||
|
wcex.cbClsExtra = 0;
|
||||||
|
wcex.cbWndExtra = sizeof(LONG_PTR);
|
||||||
|
wcex.hInstance = HINST_THISCOMPONENT;
|
||||||
|
wcex.hbrBackground = nullptr;
|
||||||
|
wcex.lpszMenuName = nullptr;
|
||||||
|
wcex.hCursor = ::LoadCursor(nullptr, IDC_ARROW);
|
||||||
|
|
||||||
|
if (_iconID != 0)
|
||||||
|
{
|
||||||
|
wcex.hIcon = (HICON)::LoadImage(
|
||||||
|
HINST_THISCOMPONENT,
|
||||||
|
MAKEINTRESOURCE(_iconID),
|
||||||
|
IMAGE_ICON,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注册窗口类
|
||||||
|
RegisterClassEx(&wcex);
|
||||||
|
|
||||||
|
// 计算窗口大小
|
||||||
|
Rect clientRect = __adjustWindow(_width, _height);
|
||||||
|
|
||||||
|
// 创建窗口
|
||||||
|
HWND hWnd = ::CreateWindowEx(
|
||||||
|
NULL,
|
||||||
|
REGISTER_CLASS,
|
||||||
|
(LPCTSTR)_title,
|
||||||
|
WINDOW_STYLE,
|
||||||
|
int(clientRect.origin.x),
|
||||||
|
int(clientRect.origin.y),
|
||||||
|
int(clientRect.size.width),
|
||||||
|
int(clientRect.size.height),
|
||||||
|
nullptr,
|
||||||
|
nullptr,
|
||||||
|
HINST_THISCOMPONENT,
|
||||||
|
this
|
||||||
|
);
|
||||||
|
|
||||||
|
if (hWnd)
|
||||||
|
{
|
||||||
|
// 禁用输入法
|
||||||
|
setTypewritingEnabled(false);
|
||||||
|
// 禁用控制台关闭按钮
|
||||||
|
HWND consoleHWnd = ::GetConsoleWindow();
|
||||||
|
if (consoleHWnd)
|
||||||
|
{
|
||||||
|
HMENU hmenu = ::GetSystemMenu(consoleHWnd, FALSE);
|
||||||
|
::RemoveMenu(hmenu, SC_CLOSE, MF_BYCOMMAND);
|
||||||
|
}
|
||||||
|
// 获取 DPI
|
||||||
|
_dpi = static_cast<float>(::GetDpiForWindow(hWnd));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
::UnregisterClass(REGISTER_CLASS, HINST_THISCOMPONENT);
|
||||||
|
throw SystemException("Create window failed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
e2d::Window::~Window()
|
e2d::Window::~Window()
|
||||||
{
|
{
|
||||||
// 关闭控制台
|
// 关闭控制台
|
||||||
if (::GetConsoleWindow())
|
if (::GetConsoleWindow())
|
||||||
{
|
|
||||||
::FreeConsole();
|
::FreeConsole();
|
||||||
}
|
|
||||||
// 关闭窗口
|
// 关闭窗口
|
||||||
if (_hWnd)
|
if (_hWnd)
|
||||||
{
|
|
||||||
::DestroyWindow(_hWnd);
|
::DestroyWindow(_hWnd);
|
||||||
_hWnd = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
e2d::Window * e2d::Window::getInstance()
|
CoUninitialize();
|
||||||
{
|
|
||||||
if (!_instance)
|
|
||||||
_instance = new (std::nothrow) Window;
|
|
||||||
return _instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
void e2d::Window::destroyInstance()
|
|
||||||
{
|
|
||||||
if (_instance)
|
|
||||||
{
|
|
||||||
delete _instance;
|
|
||||||
_instance = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool e2d::Window::createMutex(const String & mutex)
|
bool e2d::Window::createMutex(const String & mutex)
|
||||||
|
|
@ -87,80 +136,11 @@ bool e2d::Window::createMutex(const String & mutex)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
HWND e2d::Window::__registerWindow()
|
|
||||||
{
|
|
||||||
WNDCLASSEX wcex = { 0 };
|
|
||||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
|
||||||
wcex.lpszClassName = REGISTER_CLASS;
|
|
||||||
wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
|
|
||||||
wcex.lpfnWndProc = Window::WndProc;
|
|
||||||
wcex.hIcon = nullptr;
|
|
||||||
wcex.cbClsExtra = 0;
|
|
||||||
wcex.cbWndExtra = sizeof(LONG_PTR);
|
|
||||||
wcex.hInstance = HINST_THISCOMPONENT;
|
|
||||||
wcex.hbrBackground = nullptr;
|
|
||||||
wcex.lpszMenuName = nullptr;
|
|
||||||
wcex.hCursor = ::LoadCursor(nullptr, IDC_ARROW);
|
|
||||||
|
|
||||||
if (_iconID != 0)
|
|
||||||
{
|
|
||||||
wcex.hIcon = (HICON)::LoadImage(
|
|
||||||
HINST_THISCOMPONENT,
|
|
||||||
MAKEINTRESOURCE(_iconID),
|
|
||||||
IMAGE_ICON,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 注册窗口类
|
|
||||||
RegisterClassEx(&wcex);
|
|
||||||
|
|
||||||
// 计算窗口大小
|
|
||||||
Rect wRect = __adjustWindow(int(_size.width), int(_size.height));
|
|
||||||
|
|
||||||
// 创建窗口
|
|
||||||
HWND hWnd = ::CreateWindowEx(
|
|
||||||
NULL,
|
|
||||||
REGISTER_CLASS,
|
|
||||||
(LPCTSTR)_title,
|
|
||||||
WINDOW_STYLE,
|
|
||||||
int(wRect.origin.x),
|
|
||||||
int(wRect.origin.y),
|
|
||||||
int(wRect.size.width),
|
|
||||||
int(wRect.size.height),
|
|
||||||
nullptr,
|
|
||||||
nullptr,
|
|
||||||
HINST_THISCOMPONENT,
|
|
||||||
nullptr
|
|
||||||
);
|
|
||||||
|
|
||||||
if (hWnd)
|
|
||||||
{
|
|
||||||
// 禁用输入法
|
|
||||||
setTypewritingEnabled(false);
|
|
||||||
// 禁用控制台关闭按钮
|
|
||||||
HWND consoleHWnd = ::GetConsoleWindow();
|
|
||||||
if (consoleHWnd)
|
|
||||||
{
|
|
||||||
HMENU hmenu = ::GetSystemMenu(consoleHWnd, FALSE);
|
|
||||||
::RemoveMenu(hmenu, SC_CLOSE, MF_BYCOMMAND);
|
|
||||||
}
|
|
||||||
// 获取 DPI
|
|
||||||
_dpi = static_cast<float>(::GetDpiForWindow(hWnd));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
::UnregisterClass(REGISTER_CLASS, HINST_THISCOMPONENT);
|
|
||||||
}
|
|
||||||
return hWnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
e2d::Rect e2d::Window::__adjustWindow(int width, int height)
|
e2d::Rect e2d::Window::__adjustWindow(int width, int height)
|
||||||
{
|
{
|
||||||
float dpiScaleX = 0.f, dpiScaleY = 0.f;
|
float dpiScaleX = 0.f, dpiScaleY = 0.f;
|
||||||
Renderer::getFactory()->GetDesktopDpi(&dpiScaleX, &dpiScaleY);
|
auto renderer = Game::getInstance()->getRenderer();
|
||||||
|
renderer->getFactory()->GetDesktopDpi(&dpiScaleX, &dpiScaleY);
|
||||||
|
|
||||||
Rect result;
|
Rect result;
|
||||||
RECT wRECT = { 0, 0, LONG(ceil(width * dpiScaleX / 96.f)), LONG(ceil(height * dpiScaleY / 96.f)) };
|
RECT wRECT = { 0, 0, LONG(ceil(width * dpiScaleX / 96.f)), LONG(ceil(height * dpiScaleY / 96.f)) };
|
||||||
|
|
@ -190,47 +170,44 @@ void e2d::Window::poll()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float e2d::Window::getWidth()
|
int e2d::Window::getWidth() const
|
||||||
{
|
{
|
||||||
return _size.width;
|
return _width;
|
||||||
}
|
}
|
||||||
|
|
||||||
float e2d::Window::getHeight()
|
int e2d::Window::getHeight() const
|
||||||
{
|
{
|
||||||
return _size.height;
|
return _height;
|
||||||
}
|
}
|
||||||
|
|
||||||
e2d::Size e2d::Window::getSize()
|
e2d::Size e2d::Window::getSize() const
|
||||||
{
|
{
|
||||||
return _size;
|
return Size(float(_width), float(_height));
|
||||||
}
|
}
|
||||||
|
|
||||||
float e2d::Window::getDpi()
|
float e2d::Window::getDpi() const
|
||||||
{
|
{
|
||||||
return _dpi;
|
return _dpi;
|
||||||
}
|
}
|
||||||
|
|
||||||
e2d::String e2d::Window::getTitle()
|
e2d::String e2d::Window::getTitle() const
|
||||||
{
|
{
|
||||||
return _title;
|
return _title;
|
||||||
}
|
}
|
||||||
|
|
||||||
HWND e2d::Window::getHWnd()
|
HWND e2d::Window::getHWnd() const
|
||||||
{
|
{
|
||||||
if (!_hWnd)
|
|
||||||
{
|
|
||||||
_hWnd = __registerWindow();
|
|
||||||
if (_hWnd == nullptr)
|
|
||||||
{
|
|
||||||
throw SystemException(L"注册窗口失败");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _hWnd;
|
return _hWnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Window::setSize(int width, int height)
|
void e2d::Window::setSize(int width, int height)
|
||||||
{
|
{
|
||||||
_size = Size(static_cast<float>(width), static_cast<float>(height));
|
if (_width == width && _height == height)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_width = width;
|
||||||
|
_height = height;
|
||||||
|
|
||||||
if (_hWnd)
|
if (_hWnd)
|
||||||
{
|
{
|
||||||
Rect wRect = __adjustWindow(width, height);
|
Rect wRect = __adjustWindow(width, height);
|
||||||
|
|
@ -390,12 +367,33 @@ bool e2d::Window::popup(const String & text, const String & title, Popup style,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LRESULT e2d::Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
LRESULT e2d::Window::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
LRESULT result = 0;
|
LRESULT result = 0;
|
||||||
bool hasHandled = false;
|
|
||||||
|
|
||||||
switch (message)
|
if (uMsg == WM_CREATE)
|
||||||
|
{
|
||||||
|
LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam;
|
||||||
|
Window *window = (Window *)pcs->lpCreateParams;
|
||||||
|
|
||||||
|
::SetWindowLongPtrW(
|
||||||
|
hWnd,
|
||||||
|
GWLP_USERDATA,
|
||||||
|
PtrToUlong(window)
|
||||||
|
);
|
||||||
|
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool hasHandled = false;
|
||||||
|
Window *window = reinterpret_cast<Window *>(
|
||||||
|
static_cast<LONG_PTR>(
|
||||||
|
::GetWindowLongPtrW(hWnd, GWLP_USERDATA)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
switch (uMsg)
|
||||||
{
|
{
|
||||||
|
|
||||||
// 处理鼠标消息
|
// 处理鼠标消息
|
||||||
|
|
@ -411,7 +409,7 @@ LRESULT e2d::Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar
|
||||||
case WM_MOUSEMOVE:
|
case WM_MOUSEMOVE:
|
||||||
case WM_MOUSEWHEEL:
|
case WM_MOUSEWHEEL:
|
||||||
{
|
{
|
||||||
SceneManager::getInstance()->dispatch(MouseEvent(hWnd, message, wParam, lParam));
|
SceneManager::getInstance()->dispatch(MouseEvent(hWnd, uMsg, wParam, lParam, window->_dpi));
|
||||||
}
|
}
|
||||||
result = 0;
|
result = 0;
|
||||||
hasHandled = true;
|
hasHandled = true;
|
||||||
|
|
@ -421,7 +419,7 @@ LRESULT e2d::Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar
|
||||||
case WM_KEYDOWN:
|
case WM_KEYDOWN:
|
||||||
case WM_KEYUP:
|
case WM_KEYUP:
|
||||||
{
|
{
|
||||||
SceneManager::getInstance()->dispatch(KeyEvent(hWnd, message, wParam, lParam));
|
SceneManager::getInstance()->dispatch(KeyEvent(hWnd, uMsg, wParam, lParam));
|
||||||
}
|
}
|
||||||
result = 0;
|
result = 0;
|
||||||
hasHandled = true;
|
hasHandled = true;
|
||||||
|
|
@ -435,14 +433,15 @@ LRESULT e2d::Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar
|
||||||
|
|
||||||
if (wParam == SIZE_RESTORED)
|
if (wParam == SIZE_RESTORED)
|
||||||
{
|
{
|
||||||
_instance->_size.width = width * 96.f / _instance->_dpi;
|
window->_width = static_cast<int>(width * 96.f / window->_dpi);
|
||||||
_instance->_size.height = height * 96.f / _instance->_dpi;
|
window->_height = static_cast<int>(height * 96.f / window->_dpi);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果程序接收到一个 WM_SIZE 消息,这个方法将调整渲染
|
// 如果程序接收到一个 WM_SIZE 消息,这个方法将调整渲染
|
||||||
// 目标适当。它可能会调用失败,但是这里可以忽略有可能的
|
// 目标适当。它可能会调用失败,但是这里可以忽略有可能的
|
||||||
// 错误,因为这个错误将在下一次调用 EndDraw 时产生
|
// 错误,因为这个错误将在下一次调用 EndDraw 时产生
|
||||||
auto pRT = Renderer::getInstance()->getRenderTarget();
|
auto renderer = Game::getInstance()->getRenderer();
|
||||||
|
auto pRT = renderer->getRenderTarget();
|
||||||
if (pRT)
|
if (pRT)
|
||||||
{
|
{
|
||||||
pRT->Resize(D2D1::SizeU(width, height));
|
pRT->Resize(D2D1::SizeU(width, height));
|
||||||
|
|
@ -453,7 +452,7 @@ LRESULT e2d::Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar
|
||||||
// 处理窗口标题变化消息
|
// 处理窗口标题变化消息
|
||||||
case WM_SETTEXT:
|
case WM_SETTEXT:
|
||||||
{
|
{
|
||||||
_instance->_title = (const wchar_t*)lParam;
|
window->_title = (const wchar_t*)lParam;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -470,7 +469,8 @@ LRESULT e2d::Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar
|
||||||
// 重绘窗口
|
// 重绘窗口
|
||||||
case WM_PAINT:
|
case WM_PAINT:
|
||||||
{
|
{
|
||||||
e2d::Renderer::getInstance()->render();
|
auto renderer = Game::getInstance()->getRenderer();
|
||||||
|
renderer->render();
|
||||||
ValidateRect(hWnd, nullptr);
|
ValidateRect(hWnd, nullptr);
|
||||||
}
|
}
|
||||||
result = 0;
|
result = 0;
|
||||||
|
|
@ -503,8 +503,8 @@ LRESULT e2d::Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar
|
||||||
|
|
||||||
if (!hasHandled)
|
if (!hasHandled)
|
||||||
{
|
{
|
||||||
result = DefWindowProc(hWnd, message, wParam, lParam);
|
result = DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -80,7 +80,7 @@ void e2d::Collider::render()
|
||||||
{
|
{
|
||||||
if (_geometry && _enabled && _visible)
|
if (_geometry && _enabled && _visible)
|
||||||
{
|
{
|
||||||
auto renderer = Renderer::getInstance();
|
auto renderer = Game::getInstance()->getRenderer();
|
||||||
// 获取纯色画刷
|
// 获取纯色画刷
|
||||||
ID2D1SolidColorBrush * brush = renderer->getSolidColorBrush();
|
ID2D1SolidColorBrush * brush = renderer->getSolidColorBrush();
|
||||||
// 设置画刷颜色和透明度
|
// 设置画刷颜色和透明度
|
||||||
|
|
@ -131,13 +131,14 @@ void e2d::Collider::recreate()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SafeRelease(_geometry);
|
SafeRelease(_geometry);
|
||||||
|
auto factory = Game::getInstance()->getRenderer()->getFactory();
|
||||||
|
|
||||||
switch (_shape)
|
switch (_shape)
|
||||||
{
|
{
|
||||||
case Shape::Rect:
|
case Shape::Rect:
|
||||||
{
|
{
|
||||||
ID2D1RectangleGeometry* rectangle = nullptr;
|
ID2D1RectangleGeometry* rectangle = nullptr;
|
||||||
Renderer::getFactory()->CreateRectangleGeometry(
|
factory->CreateRectangleGeometry(
|
||||||
D2D1::RectF(0, 0, _parentNode->getRealWidth(), _parentNode->getRealHeight()),
|
D2D1::RectF(0, 0, _parentNode->getRealWidth(), _parentNode->getRealHeight()),
|
||||||
&rectangle
|
&rectangle
|
||||||
);
|
);
|
||||||
|
|
@ -150,7 +151,7 @@ void e2d::Collider::recreate()
|
||||||
float minSide = std::min(_parentNode->getRealWidth(), _parentNode->getRealHeight());
|
float minSide = std::min(_parentNode->getRealWidth(), _parentNode->getRealHeight());
|
||||||
|
|
||||||
ID2D1EllipseGeometry* circle = nullptr;
|
ID2D1EllipseGeometry* circle = nullptr;
|
||||||
Renderer::getFactory()->CreateEllipseGeometry(
|
factory->CreateEllipseGeometry(
|
||||||
D2D1::Ellipse(
|
D2D1::Ellipse(
|
||||||
D2D1::Point2F(
|
D2D1::Point2F(
|
||||||
_parentNode->getRealWidth() / 2,
|
_parentNode->getRealWidth() / 2,
|
||||||
|
|
@ -171,7 +172,7 @@ void e2d::Collider::recreate()
|
||||||
halfHeight = _parentNode->getHeight() / 2;
|
halfHeight = _parentNode->getHeight() / 2;
|
||||||
|
|
||||||
ID2D1EllipseGeometry* ellipse = nullptr;
|
ID2D1EllipseGeometry* ellipse = nullptr;
|
||||||
Renderer::getFactory()->CreateEllipseGeometry(
|
factory->CreateEllipseGeometry(
|
||||||
D2D1::Ellipse(
|
D2D1::Ellipse(
|
||||||
D2D1::Point2F(
|
D2D1::Point2F(
|
||||||
halfWidth,
|
halfWidth,
|
||||||
|
|
@ -186,7 +187,7 @@ void e2d::Collider::recreate()
|
||||||
}
|
}
|
||||||
|
|
||||||
ID2D1TransformedGeometry * _transformed;
|
ID2D1TransformedGeometry * _transformed;
|
||||||
Renderer::getFactory()->CreateTransformedGeometry(
|
factory->CreateTransformedGeometry(
|
||||||
_geometry,
|
_geometry,
|
||||||
_parentNode->_finalMatri,
|
_parentNode->_finalMatri,
|
||||||
&_transformed
|
&_transformed
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,7 @@ bool e2d::Image::preload(const Resource& res)
|
||||||
IWICStream *pStream = nullptr;
|
IWICStream *pStream = nullptr;
|
||||||
IWICFormatConverter *pConverter = nullptr;
|
IWICFormatConverter *pConverter = nullptr;
|
||||||
ID2D1Bitmap *pBitmap = nullptr;
|
ID2D1Bitmap *pBitmap = nullptr;
|
||||||
IWICImagingFactory *pImagingFactory = Renderer::getImagingFactory();
|
IWICImagingFactory *pImagingFactory = Game::getInstance()->getRenderer()->getImagingFactory();
|
||||||
|
|
||||||
if (!res.isFile())
|
if (!res.isFile())
|
||||||
{
|
{
|
||||||
|
|
@ -273,7 +273,7 @@ bool e2d::Image::preload(const Resource& res)
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
// 从 WIC 位图创建一个 Direct2D 位图
|
// 从 WIC 位图创建一个 Direct2D 位图
|
||||||
hr = Renderer::getInstance()->getRenderTarget()->CreateBitmapFromWicBitmap(
|
hr = Game::getInstance()->getRenderer()->getRenderTarget()->CreateBitmapFromWicBitmap(
|
||||||
pConverter,
|
pConverter,
|
||||||
nullptr,
|
nullptr,
|
||||||
&pBitmap
|
&pBitmap
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ e2d::Exception::Exception() E2D_NOEXCEPT
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
e2d::Exception::Exception(const String& message) E2D_NOEXCEPT
|
e2d::Exception::Exception(const char * message) E2D_NOEXCEPT
|
||||||
: _message(message)
|
: _message(message)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -31,7 +31,7 @@ e2d::Exception::~Exception() E2D_NOEXCEPT
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
e2d::String e2d::Exception::msg() const
|
const char * e2d::Exception::msg() const
|
||||||
{
|
{
|
||||||
return _message;
|
return _message;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
#include "..\e2dcustom.h"
|
#include "..\e2dcustom.h"
|
||||||
|
|
||||||
e2d::SystemException::SystemException() E2D_NOEXCEPT
|
e2d::SystemException::SystemException() E2D_NOEXCEPT
|
||||||
: Exception(L"未知的系统异常")
|
: Exception("Unknown system exception")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
e2d::SystemException::SystemException(const String& message) E2D_NOEXCEPT
|
e2d::SystemException::SystemException(const char * message) E2D_NOEXCEPT
|
||||||
: Exception(message)
|
: Exception(message)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,16 +59,18 @@ STDMETHODIMP_(void) TextRenderer::SetTextStyle(
|
||||||
sOutlineColor_ = outlineColor;
|
sOutlineColor_ = outlineColor;
|
||||||
fOutlineWidth = 2 * outlineWidth;
|
fOutlineWidth = 2 * outlineWidth;
|
||||||
|
|
||||||
|
auto pRenderer = Game::getInstance()->getRenderer();
|
||||||
|
|
||||||
switch (outlineJoin)
|
switch (outlineJoin)
|
||||||
{
|
{
|
||||||
case D2D1_LINE_JOIN_MITER:
|
case D2D1_LINE_JOIN_MITER:
|
||||||
pCurrStrokeStyle_ = Renderer::getMiterStrokeStyle();
|
pCurrStrokeStyle_ = pRenderer->getMiterStrokeStyle();
|
||||||
break;
|
break;
|
||||||
case D2D1_LINE_JOIN_BEVEL:
|
case D2D1_LINE_JOIN_BEVEL:
|
||||||
pCurrStrokeStyle_ = Renderer::getBevelStrokeStyle();
|
pCurrStrokeStyle_ = pRenderer->getBevelStrokeStyle();
|
||||||
break;
|
break;
|
||||||
case D2D1_LINE_JOIN_ROUND:
|
case D2D1_LINE_JOIN_ROUND:
|
||||||
pCurrStrokeStyle_ = Renderer::getRoundStrokeStyle();
|
pCurrStrokeStyle_ = pRenderer->getRoundStrokeStyle();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pCurrStrokeStyle_ = nullptr;
|
pCurrStrokeStyle_ = nullptr;
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,12 @@
|
||||||
#include "..\e2devent.h"
|
#include "..\e2devent.h"
|
||||||
#include "..\e2dbase.h"
|
#include "..\e2dbase.h"
|
||||||
|
|
||||||
e2d::MouseEvent::MouseEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
e2d::MouseEvent::MouseEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, float dpi)
|
||||||
: _message(message)
|
: _message(message)
|
||||||
, _wParam(wParam)
|
, _wParam(wParam)
|
||||||
, _lParam(lParam)
|
, _lParam(lParam)
|
||||||
, _type(Type(message))
|
, _type(Type(message))
|
||||||
{
|
{
|
||||||
float dpi = Window::getInstance()->getDpi();
|
|
||||||
_pos.x = ((float)(short)LOWORD(lParam)) * 96.f / dpi;
|
_pos.x = ((float)(short)LOWORD(lParam)) * 96.f / dpi;
|
||||||
_pos.y = ((float)(short)HIWORD(lParam)) * 96.f / dpi;
|
_pos.y = ((float)(short)HIWORD(lParam)) * 96.f / dpi;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,7 @@ void e2d::ActionManager::start(Action * action, Node * target, bool paused)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw Exception(L"该 Action 已有执行目标");
|
throw Exception("该 Action 已有执行目标");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -188,7 +188,22 @@ void e2d::SceneManager::render()
|
||||||
}
|
}
|
||||||
else if (_currScene)
|
else if (_currScene)
|
||||||
{
|
{
|
||||||
_currScene->visit();
|
auto renderer = Game::getInstance()->getRenderer();
|
||||||
|
_currScene->visit(renderer);
|
||||||
|
|
||||||
|
auto& config = Game::getInstance()->getConfig();
|
||||||
|
if (config.isOutlineVisible())
|
||||||
|
{
|
||||||
|
auto brush = renderer->getSolidColorBrush();
|
||||||
|
brush->SetColor(D2D1::ColorF(D2D1::ColorF::Red, 0.6f));
|
||||||
|
brush->SetOpacity(1.f);
|
||||||
|
_currScene->drawOutline(renderer);
|
||||||
|
}
|
||||||
|
if (config.isColliderVisible())
|
||||||
|
{
|
||||||
|
renderer->getRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity());
|
||||||
|
_currScene->drawCollider();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -189,20 +189,20 @@ bool e2d::Button::dispatch(const MouseEvent & e, bool handled)
|
||||||
return Node::dispatch(e, handled);
|
return Node::dispatch(e, handled);
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Button::visit()
|
void e2d::Button::visit(Renderer* renderer)
|
||||||
{
|
{
|
||||||
Node::visit();
|
Node::visit(renderer);
|
||||||
|
|
||||||
if (_visible &&
|
if (_visible &&
|
||||||
!_enabled &&
|
!_enabled &&
|
||||||
_normal &&
|
_normal &&
|
||||||
_normal->containsPoint(Input::getInstance()->getMousePos()))
|
_normal->containsPoint(Game::getInstance()->getInput()->getMousePos()))
|
||||||
{
|
{
|
||||||
Window::getInstance()->setCursor(Window::Cursor::No);
|
Game::getInstance()->getWindow()->setCursor(Window::Cursor::No);
|
||||||
}
|
}
|
||||||
else if (_status == Status::Mouseover || _status == Status::Selected)
|
else if (_status == Status::Mouseover || _status == Status::Selected)
|
||||||
{
|
{
|
||||||
Window::getInstance()->setCursor(Window::Cursor::Hand);
|
Game::getInstance()->getWindow()->setCursor(Window::Cursor::Hand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ e2d::Node::~Node()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Node::visit()
|
void e2d::Node::visit(Renderer * renderer)
|
||||||
{
|
{
|
||||||
if (!_visible)
|
if (!_visible)
|
||||||
return;
|
return;
|
||||||
|
|
@ -90,7 +90,7 @@ void e2d::Node::visit()
|
||||||
// 保留差别属性
|
// 保留差别属性
|
||||||
_extrapolate = this->getProperty();
|
_extrapolate = this->getProperty();
|
||||||
|
|
||||||
auto pRT = Renderer::getInstance()->getRenderTarget();
|
auto pRT = renderer->getRenderTarget();
|
||||||
if (_clipEnabled)
|
if (_clipEnabled)
|
||||||
{
|
{
|
||||||
pRT->SetTransform(_finalMatri);
|
pRT->SetTransform(_finalMatri);
|
||||||
|
|
@ -103,7 +103,7 @@ void e2d::Node::visit()
|
||||||
if (_children.empty())
|
if (_children.empty())
|
||||||
{
|
{
|
||||||
pRT->SetTransform(_finalMatri);
|
pRT->SetTransform(_finalMatri);
|
||||||
this->draw();
|
this->draw(renderer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -117,7 +117,7 @@ void e2d::Node::visit()
|
||||||
// 访问 Order 小于零的节点
|
// 访问 Order 小于零的节点
|
||||||
if (child->getOrder() < 0)
|
if (child->getOrder() < 0)
|
||||||
{
|
{
|
||||||
child->visit();
|
child->visit(renderer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -126,11 +126,11 @@ void e2d::Node::visit()
|
||||||
}
|
}
|
||||||
|
|
||||||
pRT->SetTransform(_finalMatri);
|
pRT->SetTransform(_finalMatri);
|
||||||
this->draw();
|
this->draw(renderer);
|
||||||
|
|
||||||
// 访问剩余节点
|
// 访问剩余节点
|
||||||
for (; i < _children.size(); ++i)
|
for (; i < _children.size(); ++i)
|
||||||
_children[i]->visit();
|
_children[i]->visit(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_clipEnabled)
|
if (_clipEnabled)
|
||||||
|
|
@ -139,11 +139,10 @@ void e2d::Node::visit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Node::_renderOutline()
|
void e2d::Node::drawOutline(Renderer * renderer)
|
||||||
{
|
{
|
||||||
if (_visible)
|
if (_visible)
|
||||||
{
|
{
|
||||||
auto renderer = Renderer::getInstance();
|
|
||||||
renderer->getRenderTarget()->SetTransform(_finalMatri);
|
renderer->getRenderTarget()->SetTransform(_finalMatri);
|
||||||
renderer->getRenderTarget()->DrawRectangle(
|
renderer->getRenderTarget()->DrawRectangle(
|
||||||
D2D1::RectF(0, 0, _width, _height),
|
D2D1::RectF(0, 0, _width, _height),
|
||||||
|
|
@ -154,12 +153,12 @@ void e2d::Node::_renderOutline()
|
||||||
// 渲染所有子节点的轮廓
|
// 渲染所有子节点的轮廓
|
||||||
for (const auto& child : _children)
|
for (const auto& child : _children)
|
||||||
{
|
{
|
||||||
child->_renderOutline();
|
child->drawOutline(renderer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Node::_renderCollider()
|
void e2d::Node::drawCollider()
|
||||||
{
|
{
|
||||||
if (_visible)
|
if (_visible)
|
||||||
{
|
{
|
||||||
|
|
@ -168,7 +167,7 @@ void e2d::Node::_renderCollider()
|
||||||
// 绘制所有子节点的几何碰撞体
|
// 绘制所有子节点的几何碰撞体
|
||||||
for (const auto& child : _children)
|
for (const auto& child : _children)
|
||||||
{
|
{
|
||||||
child->_renderCollider();
|
child->drawCollider();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -610,14 +609,14 @@ void e2d::Node::addChild(Node * child, int order /* = 0 */)
|
||||||
{
|
{
|
||||||
if (child->_parent != nullptr)
|
if (child->_parent != nullptr)
|
||||||
{
|
{
|
||||||
throw Exception(L"节点已有父节点, 不能再添加到其他节点");
|
throw Exception("节点已有父节点, 不能再添加到其他节点");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Node * parent = this; parent != nullptr; parent = parent->getParent())
|
for (Node * parent = this; parent != nullptr; parent = parent->getParent())
|
||||||
{
|
{
|
||||||
if (child == parent)
|
if (child == parent)
|
||||||
{
|
{
|
||||||
throw Exception(L"一个节点不能同时是另一个节点的父节点和子节点");
|
throw Exception("一个节点不能同时是另一个节点的父节点和子节点");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -825,21 +824,23 @@ bool e2d::Node::containsPoint(const Point& point)
|
||||||
// 为节点创建一个轮廓
|
// 为节点创建一个轮廓
|
||||||
BOOL ret = 0;
|
BOOL ret = 0;
|
||||||
ID2D1RectangleGeometry * rectGeo = nullptr;
|
ID2D1RectangleGeometry * rectGeo = nullptr;
|
||||||
auto factory = Renderer::getFactory();
|
auto factory = Game::getInstance()->getRenderer()->getFactory();
|
||||||
|
|
||||||
HRESULT hr = factory->CreateRectangleGeometry(
|
ThrowIfFailed(
|
||||||
|
factory->CreateRectangleGeometry(
|
||||||
D2D1::RectF(0, 0, _width, _height),
|
D2D1::RectF(0, 0, _width, _height),
|
||||||
&rectGeo
|
&rectGeo
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
ThrowIfFailed(
|
||||||
{
|
|
||||||
rectGeo->FillContainsPoint(
|
rectGeo->FillContainsPoint(
|
||||||
D2D1::Point2F(point.x, point.y),
|
D2D1::Point2F(point.x, point.y),
|
||||||
_finalMatri,
|
_finalMatri,
|
||||||
&ret
|
&ret
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
|
||||||
SafeRelease(rectGeo);
|
SafeRelease(rectGeo);
|
||||||
|
|
||||||
return ret != 0;
|
return ret != 0;
|
||||||
|
|
@ -855,48 +856,46 @@ bool e2d::Node::intersects(Node * node)
|
||||||
D2D1_GEOMETRY_RELATION relation = D2D1_GEOMETRY_RELATION_UNKNOWN;
|
D2D1_GEOMETRY_RELATION relation = D2D1_GEOMETRY_RELATION_UNKNOWN;
|
||||||
ID2D1RectangleGeometry *rectGeo = nullptr, *rectGeo2 = nullptr;
|
ID2D1RectangleGeometry *rectGeo = nullptr, *rectGeo2 = nullptr;
|
||||||
ID2D1TransformedGeometry *transGeo = nullptr, *transGeo2 = nullptr;
|
ID2D1TransformedGeometry *transGeo = nullptr, *transGeo2 = nullptr;
|
||||||
auto factory = Renderer::getFactory();
|
auto factory = Game::getInstance()->getRenderer()->getFactory();
|
||||||
|
|
||||||
HRESULT hr = factory->CreateRectangleGeometry(
|
ThrowIfFailed(
|
||||||
|
factory->CreateRectangleGeometry(
|
||||||
D2D1::RectF(0, 0, _width, _height),
|
D2D1::RectF(0, 0, _width, _height),
|
||||||
&rectGeo
|
&rectGeo
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
ThrowIfFailed(
|
||||||
{
|
factory->CreateRectangleGeometry(
|
||||||
hr = factory->CreateRectangleGeometry(
|
|
||||||
D2D1::RectF(0, 0, node->_width, node->_height),
|
D2D1::RectF(0, 0, node->_width, node->_height),
|
||||||
&rectGeo2
|
&rectGeo2
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
ThrowIfFailed(
|
||||||
{
|
factory->CreateTransformedGeometry(
|
||||||
hr = factory->CreateTransformedGeometry(
|
|
||||||
rectGeo,
|
rectGeo,
|
||||||
_finalMatri,
|
_finalMatri,
|
||||||
&transGeo
|
&transGeo
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
ThrowIfFailed(
|
||||||
{
|
factory->CreateTransformedGeometry(
|
||||||
hr = factory->CreateTransformedGeometry(
|
|
||||||
rectGeo2,
|
rectGeo2,
|
||||||
node->_finalMatri,
|
node->_finalMatri,
|
||||||
&transGeo2
|
&transGeo2
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
ThrowIfFailed(
|
||||||
{
|
|
||||||
// 获取相交状态
|
// 获取相交状态
|
||||||
transGeo->CompareWithGeometry(
|
transGeo->CompareWithGeometry(
|
||||||
transGeo2,
|
transGeo2,
|
||||||
D2D1::Matrix3x2F::Identity(),
|
D2D1::Matrix3x2F::Identity(),
|
||||||
&relation
|
&relation
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
SafeRelease(rectGeo);
|
SafeRelease(rectGeo);
|
||||||
SafeRelease(rectGeo2);
|
SafeRelease(rectGeo2);
|
||||||
|
|
|
||||||
|
|
@ -9,22 +9,3 @@ e2d::Scene::Scene()
|
||||||
e2d::Scene::~Scene()
|
e2d::Scene::~Scene()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Scene::visit()
|
|
||||||
{
|
|
||||||
Node::visit();
|
|
||||||
|
|
||||||
if (Game::getInstance()->getConfig().isOutlineVisible())
|
|
||||||
{
|
|
||||||
auto brush = Renderer::getInstance()->getSolidColorBrush();
|
|
||||||
brush->SetColor(D2D1::ColorF(D2D1::ColorF::Red, 0.6f));
|
|
||||||
brush->SetOpacity(1.f);
|
|
||||||
Node::_renderOutline();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Game::getInstance()->getConfig().isColliderVisible())
|
|
||||||
{
|
|
||||||
Renderer::getInstance()->getRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity());
|
|
||||||
Node::_renderCollider();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ e2d::Image * e2d::Sprite::getImage() const
|
||||||
return _image;
|
return _image;
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Sprite::draw() const
|
void e2d::Sprite::draw(Renderer * renderer) const
|
||||||
{
|
{
|
||||||
if (_image && _image->getBitmap())
|
if (_image && _image->getBitmap())
|
||||||
{
|
{
|
||||||
|
|
@ -100,7 +100,7 @@ void e2d::Sprite::draw() const
|
||||||
float fCropX = _image->getCropX();
|
float fCropX = _image->getCropX();
|
||||||
float fCropY = _image->getCropY();
|
float fCropY = _image->getCropY();
|
||||||
// äÖȾͼƬ
|
// äÖȾͼƬ
|
||||||
Renderer::getInstance()->getRenderTarget()->DrawBitmap(
|
renderer->getRenderTarget()->DrawBitmap(
|
||||||
_image->getBitmap(),
|
_image->getBitmap(),
|
||||||
D2D1::RectF(0, 0, _width, _height),
|
D2D1::RectF(0, 0, _width, _height),
|
||||||
_displayOpacity,
|
_displayOpacity,
|
||||||
|
|
|
||||||
|
|
@ -287,11 +287,10 @@ void e2d::Text::setOutlineJoin(LineJoin outlineJoin)
|
||||||
_style.outlineJoin = outlineJoin;
|
_style.outlineJoin = outlineJoin;
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Text::draw() const
|
void e2d::Text::draw(Renderer * renderer) const
|
||||||
{
|
{
|
||||||
if (_textLayout)
|
if (_textLayout)
|
||||||
{
|
{
|
||||||
auto renderer = Renderer::getInstance();
|
|
||||||
// 创建文本区域
|
// 创建文本区域
|
||||||
D2D1_RECT_F textLayoutRect = D2D1::RectF(0, 0, _width, _height);
|
D2D1_RECT_F textLayoutRect = D2D1::RectF(0, 0, _width, _height);
|
||||||
// 设置画刷颜色和透明度
|
// 设置画刷颜色和透明度
|
||||||
|
|
@ -321,7 +320,7 @@ void e2d::Text::_createFormat()
|
||||||
{
|
{
|
||||||
SafeRelease(_textFormat);
|
SafeRelease(_textFormat);
|
||||||
|
|
||||||
HRESULT hr = Renderer::getWriteFactory()->CreateTextFormat(
|
HRESULT hr = Game::getInstance()->getRenderer()->getWriteFactory()->CreateTextFormat(
|
||||||
(const WCHAR *)_font.family,
|
(const WCHAR *)_font.family,
|
||||||
nullptr,
|
nullptr,
|
||||||
DWRITE_FONT_WEIGHT(_font.weight),
|
DWRITE_FONT_WEIGHT(_font.weight),
|
||||||
|
|
@ -384,14 +383,14 @@ void e2d::Text::_createLayout()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT32 length = (UINT32)_text.getLength();
|
|
||||||
|
|
||||||
// ´´½¨ TextLayout
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
UINT32 length = (UINT32)_text.getLength();
|
||||||
|
auto writeFactory = Game::getInstance()->getRenderer()->getWriteFactory();
|
||||||
|
|
||||||
// 对文本自动换行情况下进行处理
|
// 对文本自动换行情况下进行处理
|
||||||
if (_style.wrapping)
|
if (_style.wrapping)
|
||||||
{
|
{
|
||||||
hr = Renderer::getWriteFactory()->CreateTextLayout(
|
hr = writeFactory->CreateTextLayout(
|
||||||
(const WCHAR *)_text,
|
(const WCHAR *)_text,
|
||||||
length,
|
length,
|
||||||
_textFormat,
|
_textFormat,
|
||||||
|
|
@ -410,7 +409,7 @@ void e2d::Text::_createLayout()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hr = Renderer::getWriteFactory()->CreateTextLayout((const WCHAR *)_text, length, _textFormat, 0, 0, &_textLayout);
|
hr = writeFactory->CreateTextLayout((const WCHAR *)_text, length, _textFormat, 0, 0, &_textLayout);
|
||||||
// 为防止文本对齐问题,根据刚才创建的 layout 宽度重新创建它
|
// 为防止文本对齐问题,根据刚才创建的 layout 宽度重新创建它
|
||||||
if (_textLayout)
|
if (_textLayout)
|
||||||
{
|
{
|
||||||
|
|
@ -421,7 +420,7 @@ void e2d::Text::_createLayout()
|
||||||
this->setSize(metrics.width, metrics.height);
|
this->setSize(metrics.width, metrics.height);
|
||||||
// 重新创建 layout
|
// 重新创建 layout
|
||||||
SafeRelease(_textLayout);
|
SafeRelease(_textLayout);
|
||||||
hr = Renderer::getWriteFactory()->CreateTextLayout((const WCHAR *)_text, length, _textFormat, _width, 0, &_textLayout);
|
hr = writeFactory->CreateTextLayout((const WCHAR *)_text, length, _textFormat, _width, 0, &_textLayout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -160,11 +160,14 @@ bool e2d::File::createFolder(const String & dirPath)
|
||||||
|
|
||||||
e2d::String e2d::File::getSaveFilePath(const String& title, const String& defExt)
|
e2d::String e2d::File::getSaveFilePath(const String& title, const String& defExt)
|
||||||
{
|
{
|
||||||
|
auto window = Game::getInstance()->getWindow();
|
||||||
|
HWND hwnd = window->getHWnd();
|
||||||
|
|
||||||
// 弹出保存对话框
|
// 弹出保存对话框
|
||||||
OPENFILENAME ofn = { 0 };
|
OPENFILENAME ofn = { 0 };
|
||||||
wchar_t strFilename[MAX_PATH] = { 0 }; // 用于接收文件名
|
wchar_t strFilename[MAX_PATH] = { 0 }; // 用于接收文件名
|
||||||
ofn.lStructSize = sizeof(OPENFILENAME); // 结构体大小
|
ofn.lStructSize = sizeof(OPENFILENAME); // 结构体大小
|
||||||
ofn.hwndOwner = Window::getInstance()->getHWnd(); // ´°¿Ú¾ä±ú
|
ofn.hwndOwner = hwnd; // ´°¿Ú¾ä±ú
|
||||||
ofn.lpstrFilter = L"所有文件\0*.*\0\0"; // 设置过滤
|
ofn.lpstrFilter = L"所有文件\0*.*\0\0"; // 设置过滤
|
||||||
ofn.nFilterIndex = 1; // 过滤器索引
|
ofn.nFilterIndex = 1; // 过滤器索引
|
||||||
ofn.lpstrFile = strFilename; // 接收返回的文件路径和文件名
|
ofn.lpstrFile = strFilename; // 接收返回的文件路径和文件名
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ bool e2d::Transition::_init(Scene * prev)
|
||||||
|
|
||||||
// ´´½¨Í¼²ã
|
// ´´½¨Í¼²ã
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
auto renderer = Renderer::getInstance();
|
auto renderer = Game::getInstance()->getRenderer();
|
||||||
if (_inScene)
|
if (_inScene)
|
||||||
{
|
{
|
||||||
hr = renderer->getRenderTarget()->CreateLayer(&_inLayer);
|
hr = renderer->getRenderTarget()->CreateLayer(&_inLayer);
|
||||||
|
|
@ -57,7 +57,7 @@ bool e2d::Transition::_init(Scene * prev)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_windowSize = Window::getInstance()->getSize();
|
_windowSize = Game::getInstance()->getWindow()->getSize();
|
||||||
_outLayerParam = _inLayerParam = D2D1::LayerParameters(
|
_outLayerParam = _inLayerParam = D2D1::LayerParameters(
|
||||||
D2D1::InfiniteRect(),
|
D2D1::InfiniteRect(),
|
||||||
nullptr,
|
nullptr,
|
||||||
|
|
@ -86,7 +86,8 @@ void e2d::Transition::_update()
|
||||||
|
|
||||||
void e2d::Transition::_render()
|
void e2d::Transition::_render()
|
||||||
{
|
{
|
||||||
auto pRT = Renderer::getInstance()->getRenderTarget();
|
auto renderer = Game::getInstance()->getRenderer();
|
||||||
|
auto pRT = renderer->getRenderTarget();
|
||||||
|
|
||||||
if (_outScene)
|
if (_outScene)
|
||||||
{
|
{
|
||||||
|
|
@ -101,7 +102,7 @@ void e2d::Transition::_render()
|
||||||
pRT->PushAxisAlignedClip(clipRect, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
|
pRT->PushAxisAlignedClip(clipRect, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
|
||||||
pRT->PushLayer(_outLayerParam, _outLayer);
|
pRT->PushLayer(_outLayerParam, _outLayer);
|
||||||
|
|
||||||
_outScene->visit();
|
_outScene->visit(renderer);
|
||||||
|
|
||||||
pRT->PopLayer();
|
pRT->PopLayer();
|
||||||
pRT->PopAxisAlignedClip();
|
pRT->PopAxisAlignedClip();
|
||||||
|
|
@ -120,7 +121,7 @@ void e2d::Transition::_render()
|
||||||
pRT->PushAxisAlignedClip(clipRect, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
|
pRT->PushAxisAlignedClip(clipRect, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
|
||||||
pRT->PushLayer(_inLayerParam, _inLayer);
|
pRT->PushLayer(_inLayerParam, _inLayer);
|
||||||
|
|
||||||
_inScene->visit();
|
_inScene->visit(renderer);
|
||||||
|
|
||||||
pRT->PopLayer();
|
pRT->PopLayer();
|
||||||
pRT->PopAxisAlignedClip();
|
pRT->PopAxisAlignedClip();
|
||||||
|
|
|
||||||
236
core/e2dbase.h
236
core/e2dbase.h
|
|
@ -72,58 +72,6 @@ protected:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// 游戏主体
|
|
||||||
class Game
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// 获取游戏实例
|
|
||||||
static Game * getInstance();
|
|
||||||
|
|
||||||
// 销毁实例
|
|
||||||
static void destroyInstance();
|
|
||||||
|
|
||||||
// 启动游戏
|
|
||||||
void start();
|
|
||||||
|
|
||||||
// 暂停游戏
|
|
||||||
void pause();
|
|
||||||
|
|
||||||
// 继续游戏
|
|
||||||
void resume();
|
|
||||||
|
|
||||||
// 结束游戏
|
|
||||||
void quit();
|
|
||||||
|
|
||||||
// 清理资源
|
|
||||||
void cleanup();
|
|
||||||
|
|
||||||
// 游戏是否暂停
|
|
||||||
bool isPaused();
|
|
||||||
|
|
||||||
// 修改游戏配置
|
|
||||||
void setConfig(
|
|
||||||
const Config& config
|
|
||||||
);
|
|
||||||
|
|
||||||
// 获取游戏配置
|
|
||||||
const Config& getConfig();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Game();
|
|
||||||
|
|
||||||
~Game();
|
|
||||||
|
|
||||||
E2D_DISABLE_COPY(Game);
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool _quit;
|
|
||||||
bool _paused;
|
|
||||||
Config _config;
|
|
||||||
|
|
||||||
static Game * _instance;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// 窗体
|
// 窗体
|
||||||
class Window
|
class Window
|
||||||
{
|
{
|
||||||
|
|
@ -147,11 +95,14 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// 获取窗体实例
|
Window(
|
||||||
static Window * getInstance();
|
const String& title, /* 窗体标题 */
|
||||||
|
int width, /* 窗体宽度 */
|
||||||
|
int height, /* 窗体高度 */
|
||||||
|
int iconID = 0 /* 窗体图标 */
|
||||||
|
);
|
||||||
|
|
||||||
// 销毁窗体实例
|
~Window();
|
||||||
static void destroyInstance();
|
|
||||||
|
|
||||||
// 创建窗体互斥体
|
// 创建窗体互斥体
|
||||||
bool createMutex(
|
bool createMutex(
|
||||||
|
|
@ -180,22 +131,22 @@ public:
|
||||||
);
|
);
|
||||||
|
|
||||||
// 获取窗体标题
|
// 获取窗体标题
|
||||||
String getTitle();
|
String getTitle() const;
|
||||||
|
|
||||||
// 获取窗体宽度
|
// 获取窗体宽度
|
||||||
float getWidth();
|
int getWidth() const;
|
||||||
|
|
||||||
// 获取窗体高度
|
// 获取窗体高度
|
||||||
float getHeight();
|
int getHeight() const;
|
||||||
|
|
||||||
// 获取窗体大小
|
// 获取窗体大小
|
||||||
Size getSize();
|
Size getSize() const;
|
||||||
|
|
||||||
// 获取窗口 DPI
|
// 获取窗口 DPI
|
||||||
float getDpi();
|
float getDpi() const;
|
||||||
|
|
||||||
// 获取窗口句柄
|
// 获取窗口句柄
|
||||||
HWND getHWnd();
|
HWND getHWnd() const;
|
||||||
|
|
||||||
// 打开或隐藏控制台
|
// 打开或隐藏控制台
|
||||||
void setConsoleEnabled(
|
void setConsoleEnabled(
|
||||||
|
|
@ -220,15 +171,6 @@ public:
|
||||||
void poll();
|
void poll();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Window();
|
|
||||||
|
|
||||||
~Window();
|
|
||||||
|
|
||||||
E2D_DISABLE_COPY(Window);
|
|
||||||
|
|
||||||
// 注册窗口
|
|
||||||
HWND __registerWindow();
|
|
||||||
|
|
||||||
// 根据客户区大小计算合适的窗口区域
|
// 根据客户区大小计算合适的窗口区域
|
||||||
Rect __adjustWindow(
|
Rect __adjustWindow(
|
||||||
int width,
|
int width,
|
||||||
|
|
@ -238,7 +180,7 @@ private:
|
||||||
// Win32 窗口消息回调程序
|
// Win32 窗口消息回调程序
|
||||||
static LRESULT CALLBACK WndProc(
|
static LRESULT CALLBACK WndProc(
|
||||||
HWND hWnd,
|
HWND hWnd,
|
||||||
UINT message,
|
UINT uMsg,
|
||||||
WPARAM wParam,
|
WPARAM wParam,
|
||||||
LPARAM lParam
|
LPARAM lParam
|
||||||
);
|
);
|
||||||
|
|
@ -246,12 +188,11 @@ private:
|
||||||
private:
|
private:
|
||||||
HWND _hWnd;
|
HWND _hWnd;
|
||||||
MSG _msg;
|
MSG _msg;
|
||||||
Size _size;
|
int _width;
|
||||||
|
int _height;
|
||||||
String _title;
|
String _title;
|
||||||
int _iconID;
|
int _iconID;
|
||||||
float _dpi;
|
float _dpi;
|
||||||
|
|
||||||
static Window * _instance;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -259,11 +200,9 @@ private:
|
||||||
class Input
|
class Input
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// 获取输入设备实例
|
Input();
|
||||||
static Input * getInstance();
|
|
||||||
|
|
||||||
// 销毁输入设备实例
|
~Input();
|
||||||
static void destroyInstance();
|
|
||||||
|
|
||||||
// 检测键盘某按键是否正被按下
|
// 检测键盘某按键是否正被按下
|
||||||
bool isDown(
|
bool isDown(
|
||||||
|
|
@ -296,12 +235,10 @@ public:
|
||||||
// 刷新输入设备状态
|
// 刷新输入设备状态
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
private:
|
// 初始化渲染器(不应手动调用该函数)
|
||||||
Input();
|
void init(
|
||||||
|
Window * window
|
||||||
~Input();
|
);
|
||||||
|
|
||||||
E2D_DISABLE_COPY(Input);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IDirectInput8W* _directInput;
|
IDirectInput8W* _directInput;
|
||||||
|
|
@ -309,20 +246,16 @@ private:
|
||||||
IDirectInputDevice8W* _mouseDevice;
|
IDirectInputDevice8W* _mouseDevice;
|
||||||
DIMOUSESTATE _mouseState;
|
DIMOUSESTATE _mouseState;
|
||||||
char _keyBuffer[256];
|
char _keyBuffer[256];
|
||||||
|
|
||||||
static Input * _instance;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// 渲染器
|
// 图形设备
|
||||||
class Renderer
|
class Renderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// 获取渲染器实例
|
Renderer();
|
||||||
static Renderer * getInstance();
|
|
||||||
|
|
||||||
// 销毁实例
|
~Renderer();
|
||||||
static void destroyInstance();
|
|
||||||
|
|
||||||
// 获取背景色
|
// 获取背景色
|
||||||
Color getBackgroundColor();
|
Color getBackgroundColor();
|
||||||
|
|
@ -332,46 +265,42 @@ public:
|
||||||
Color color
|
Color color
|
||||||
);
|
);
|
||||||
|
|
||||||
// 获取文字渲染器
|
|
||||||
TextRenderer * getTextRenderer();
|
|
||||||
|
|
||||||
// 获取 ID2D1HwndRenderTarget 对象
|
|
||||||
ID2D1HwndRenderTarget * getRenderTarget();
|
|
||||||
|
|
||||||
// 获取 ID2D1SolidColorBrush 对象
|
|
||||||
ID2D1SolidColorBrush * getSolidColorBrush();
|
|
||||||
|
|
||||||
// 渲染游戏画面
|
// 渲染游戏画面
|
||||||
void render();
|
void render();
|
||||||
|
|
||||||
// 删除设备相关资源
|
// 获取文字渲染器
|
||||||
void discardDeviceResources();
|
TextRenderer * getTextRenderer() const { return _textRenderer; }
|
||||||
|
|
||||||
|
// 获取 ID2D1HwndRenderTarget 对象
|
||||||
|
ID2D1HwndRenderTarget * getRenderTarget() const { return _renderTarget; }
|
||||||
|
|
||||||
|
// 获取 ID2D1SolidColorBrush 对象
|
||||||
|
ID2D1SolidColorBrush * getSolidColorBrush() const { return _solidBrush; }
|
||||||
|
|
||||||
// 获取 ID2D1Factory 对象
|
// 获取 ID2D1Factory 对象
|
||||||
static ID2D1Factory * getFactory();
|
ID2D1Factory * getFactory() const { return _factory; }
|
||||||
|
|
||||||
// 获取 IWICImagingFactory 对象
|
// 获取 IWICImagingFactory 对象
|
||||||
static IWICImagingFactory * getImagingFactory();
|
IWICImagingFactory * getImagingFactory() const { return _imagingFactory; }
|
||||||
|
|
||||||
// 获取 IDWriteFactory 对象
|
// 获取 IDWriteFactory 对象
|
||||||
static IDWriteFactory * getWriteFactory();
|
IDWriteFactory * getWriteFactory() const { return _writeFactory; }
|
||||||
|
|
||||||
// 获取 Miter 样式的 ID2D1StrokeStyle
|
// 获取 Miter 样式的 ID2D1StrokeStyle
|
||||||
static ID2D1StrokeStyle * getMiterStrokeStyle();
|
ID2D1StrokeStyle * getMiterStrokeStyle();
|
||||||
|
|
||||||
// 获取 Bevel 样式的 ID2D1StrokeStyle
|
// 获取 Bevel 样式的 ID2D1StrokeStyle
|
||||||
static ID2D1StrokeStyle * getBevelStrokeStyle();
|
ID2D1StrokeStyle * getBevelStrokeStyle();
|
||||||
|
|
||||||
// 获取 Round 样式的 ID2D1StrokeStyle
|
// 获取 Round 样式的 ID2D1StrokeStyle
|
||||||
static ID2D1StrokeStyle * getRoundStrokeStyle();
|
ID2D1StrokeStyle * getRoundStrokeStyle();
|
||||||
|
|
||||||
|
// 初始化渲染器(不应手动调用该函数)
|
||||||
|
void init(
|
||||||
|
Window * window
|
||||||
|
);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Renderer();
|
|
||||||
|
|
||||||
~Renderer();
|
|
||||||
|
|
||||||
E2D_DISABLE_COPY(Renderer);
|
|
||||||
|
|
||||||
// 渲染 FPS
|
// 渲染 FPS
|
||||||
void _renderFps();
|
void _renderFps();
|
||||||
|
|
||||||
|
|
@ -384,14 +313,77 @@ private:
|
||||||
IDWriteTextLayout* _fpsLayout;
|
IDWriteTextLayout* _fpsLayout;
|
||||||
ID2D1SolidColorBrush* _solidBrush;
|
ID2D1SolidColorBrush* _solidBrush;
|
||||||
ID2D1HwndRenderTarget* _renderTarget;
|
ID2D1HwndRenderTarget* _renderTarget;
|
||||||
|
ID2D1Factory* _factory;
|
||||||
|
IWICImagingFactory* _imagingFactory;
|
||||||
|
IDWriteFactory* _writeFactory;
|
||||||
|
ID2D1StrokeStyle* _miterStrokeStyle;
|
||||||
|
ID2D1StrokeStyle* _bevelStrokeStyle;
|
||||||
|
ID2D1StrokeStyle* _roundStrokeStyle;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 游戏
|
||||||
|
class Game
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// 获取 Game 实例
|
||||||
|
static Game * getInstance();
|
||||||
|
|
||||||
|
// 启动游戏
|
||||||
|
void start();
|
||||||
|
|
||||||
|
// 暂停游戏
|
||||||
|
void pause();
|
||||||
|
|
||||||
|
// 继续游戏
|
||||||
|
void resume();
|
||||||
|
|
||||||
|
// 结束游戏
|
||||||
|
void quit();
|
||||||
|
|
||||||
|
// 清理资源
|
||||||
|
void cleanup();
|
||||||
|
|
||||||
|
// 游戏是否暂停
|
||||||
|
bool isPaused();
|
||||||
|
|
||||||
|
// 修改游戏配置
|
||||||
|
void setConfig(
|
||||||
|
const Config& config
|
||||||
|
);
|
||||||
|
|
||||||
|
// 获取游戏配置
|
||||||
|
const Config& getConfig() const;
|
||||||
|
|
||||||
|
// 设置窗体
|
||||||
|
void setWindow(
|
||||||
|
Window * window
|
||||||
|
);
|
||||||
|
|
||||||
|
// 获取窗体
|
||||||
|
Window * getWindow() const { return _window; }
|
||||||
|
|
||||||
|
// 获取输入设备
|
||||||
|
Input * getInput() const { return _input; }
|
||||||
|
|
||||||
|
// 获取图形设备
|
||||||
|
Renderer * getRenderer() const { return _renderer; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Game();
|
||||||
|
|
||||||
|
~Game();
|
||||||
|
|
||||||
|
E2D_DISABLE_COPY(Game);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _quit;
|
||||||
|
bool _paused;
|
||||||
|
Config _config;
|
||||||
|
Window * _window;
|
||||||
|
Input * _input;
|
||||||
|
Renderer * _renderer;
|
||||||
|
|
||||||
static ID2D1Factory* _d2dFactory;
|
|
||||||
static IWICImagingFactory* _imagingFactory;
|
|
||||||
static IDWriteFactory* _writeFactory;
|
|
||||||
static ID2D1StrokeStyle* _miterStrokeStyle;
|
|
||||||
static ID2D1StrokeStyle* _bevelStrokeStyle;
|
|
||||||
static ID2D1StrokeStyle* _roundStrokeStyle;
|
|
||||||
static Renderer * _instance;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,17 +6,6 @@ namespace e2d
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
template<class Interface>
|
|
||||||
inline void SafeRelease(Interface*& p)
|
|
||||||
{
|
|
||||||
if (p != nullptr)
|
|
||||||
{
|
|
||||||
p->Release();
|
|
||||||
p = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class Music;
|
class Music;
|
||||||
|
|
||||||
// 音源回调
|
// 音源回调
|
||||||
|
|
@ -173,7 +162,7 @@ class Exception
|
||||||
public:
|
public:
|
||||||
Exception() E2D_NOEXCEPT;
|
Exception() E2D_NOEXCEPT;
|
||||||
|
|
||||||
explicit Exception(const String& message) E2D_NOEXCEPT;
|
explicit Exception(const char * message) E2D_NOEXCEPT;
|
||||||
|
|
||||||
Exception(Exception const& other) E2D_NOEXCEPT;
|
Exception(Exception const& other) E2D_NOEXCEPT;
|
||||||
|
|
||||||
|
|
@ -182,10 +171,10 @@ public:
|
||||||
Exception& operator=(Exception const& other) E2D_NOEXCEPT;
|
Exception& operator=(Exception const& other) E2D_NOEXCEPT;
|
||||||
|
|
||||||
// 获取异常信息
|
// 获取异常信息
|
||||||
virtual String msg() const;
|
virtual const char * msg() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
String _message;
|
const char * _message;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -196,7 +185,30 @@ class SystemException
|
||||||
public:
|
public:
|
||||||
SystemException() E2D_NOEXCEPT;
|
SystemException() E2D_NOEXCEPT;
|
||||||
|
|
||||||
explicit SystemException(const String& message) E2D_NOEXCEPT;
|
explicit SystemException(const char * message) E2D_NOEXCEPT;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<class Interface>
|
||||||
|
inline void SafeRelease(Interface*& p)
|
||||||
|
{
|
||||||
|
if (p != nullptr)
|
||||||
|
{
|
||||||
|
p->Release();
|
||||||
|
p = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void ThrowIfFailed(HRESULT hr)
|
||||||
|
{
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
// 在此处设置断点以捕获 D2D API 异常.
|
||||||
|
static char s_str[64] = {};
|
||||||
|
sprintf_s(s_str, "Failure with HRESULT of %08X", static_cast<unsigned int>(hr));
|
||||||
|
throw SystemException(s_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -70,7 +70,8 @@ public:
|
||||||
HWND hWnd,
|
HWND hWnd,
|
||||||
UINT message,
|
UINT message,
|
||||||
WPARAM wParam,
|
WPARAM wParam,
|
||||||
LPARAM lParam
|
LPARAM lParam,
|
||||||
|
float dpi
|
||||||
);
|
);
|
||||||
|
|
||||||
// 資函報炎罪恫炎
|
// 資函報炎罪恫炎
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,9 @@ public:
|
||||||
virtual ~Node();
|
virtual ~Node();
|
||||||
|
|
||||||
// 渲染节点
|
// 渲染节点
|
||||||
virtual void draw() const {}
|
virtual void draw(
|
||||||
|
Renderer * renderer
|
||||||
|
) const {}
|
||||||
|
|
||||||
// 获取节点显示状态
|
// 获取节点显示状态
|
||||||
virtual bool isVisible() const;
|
virtual bool isVisible() const;
|
||||||
|
|
@ -395,17 +397,21 @@ public:
|
||||||
);
|
);
|
||||||
|
|
||||||
// 遍历节点
|
// 遍历节点
|
||||||
virtual void visit();
|
virtual void visit(
|
||||||
|
Renderer * renderer
|
||||||
|
);
|
||||||
|
|
||||||
|
// äÖȾ½ÚµãÂÖÀª
|
||||||
|
virtual void drawOutline(
|
||||||
|
Renderer * renderer
|
||||||
|
);
|
||||||
|
|
||||||
|
// äÖȾÅöײÌåÂÖÀª
|
||||||
|
virtual void drawCollider();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
E2D_DISABLE_COPY(Node);
|
E2D_DISABLE_COPY(Node);
|
||||||
|
|
||||||
// 渲染节点轮廓
|
|
||||||
virtual void _renderOutline();
|
|
||||||
|
|
||||||
// 渲染碰撞体轮廓
|
|
||||||
virtual void _renderCollider();
|
|
||||||
|
|
||||||
// 设置节点所在场景
|
// 设置节点所在场景
|
||||||
virtual void _setParentScene(
|
virtual void _setParentScene(
|
||||||
Scene * scene
|
Scene * scene
|
||||||
|
|
@ -468,9 +474,6 @@ public:
|
||||||
// 说明:返回 false 将阻止窗口关闭
|
// 说明:返回 false 将阻止窗口关闭
|
||||||
virtual bool onCloseWindow() { return true; }
|
virtual bool onCloseWindow() { return true; }
|
||||||
|
|
||||||
// 渲染场景
|
|
||||||
virtual void visit() override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
E2D_DISABLE_COPY(Scene);
|
E2D_DISABLE_COPY(Scene);
|
||||||
};
|
};
|
||||||
|
|
@ -531,7 +534,9 @@ public:
|
||||||
virtual Image * getImage() const;
|
virtual Image * getImage() const;
|
||||||
|
|
||||||
// 渲染精灵
|
// 渲染精灵
|
||||||
virtual void draw() const override;
|
virtual void draw(
|
||||||
|
Renderer * renderer
|
||||||
|
) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
E2D_DISABLE_COPY(Sprite);
|
E2D_DISABLE_COPY(Sprite);
|
||||||
|
|
@ -735,7 +740,9 @@ public:
|
||||||
);
|
);
|
||||||
|
|
||||||
// 渲染文字
|
// 渲染文字
|
||||||
virtual void draw() const override;
|
virtual void draw(
|
||||||
|
Renderer * renderer
|
||||||
|
) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
E2D_DISABLE_COPY(Text);
|
E2D_DISABLE_COPY(Text);
|
||||||
|
|
@ -837,7 +844,9 @@ public:
|
||||||
) override;
|
) override;
|
||||||
|
|
||||||
// 渲染节点
|
// 渲染节点
|
||||||
virtual void visit() override;
|
virtual void visit(
|
||||||
|
Renderer * renderer
|
||||||
|
) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
E2D_DISABLE_COPY(Button);
|
E2D_DISABLE_COPY(Button);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue