修复多个bug

This commit is contained in:
Nomango 2017-10-31 17:19:13 +08:00
parent db64bf8e8d
commit 56464a36e2
31 changed files with 430 additions and 430 deletions

View File

@ -8,7 +8,7 @@ e2d::EActionLoop::EActionLoop(EAction * action) :
e2d::EActionLoop::~EActionLoop()
{
SafeReleaseAndClear(&m_Action);
SafeRelease(&m_Action);
}
e2d::EActionLoop * e2d::EActionLoop::clone() const

View File

@ -25,7 +25,7 @@ e2d::EActionSequence::~EActionSequence()
{
for (auto action : m_vActions)
{
SafeReleaseAndClear(&action);
SafeRelease(&action);
}
}

View File

@ -10,8 +10,8 @@ e2d::EActionTwo::EActionTwo(EAction * actionFirst, EAction * actionSecond) :
e2d::EActionTwo::~EActionTwo()
{
SafeReleaseAndClear(&m_pFirstAction);
SafeReleaseAndClear(&m_pSecondAction);
SafeRelease(&m_pFirstAction);
SafeRelease(&m_pSecondAction);
}
e2d::EActionTwo * e2d::EActionTwo::clone() const

View File

@ -10,8 +10,8 @@ e2d::EActionTwoAtSameTime::EActionTwoAtSameTime(EAction * actionFirst, EAction *
e2d::EActionTwoAtSameTime::~EActionTwoAtSameTime()
{
SafeReleaseAndClear(&m_pFirstAction);
SafeReleaseAndClear(&m_pSecondAction);
SafeRelease(&m_pFirstAction);
SafeRelease(&m_pSecondAction);
}
e2d::EActionTwoAtSameTime * e2d::EActionTwoAtSameTime::clone() const

View File

@ -19,7 +19,7 @@ e2d::EAnimation::~EAnimation()
{
for (auto frame : m_vFrames)
{
SafeReleaseAndClear(&frame);
SafeRelease(&frame);
}
}

View File

@ -25,6 +25,7 @@ e2d::EApp::EApp()
, m_bManualPaused(false)
, m_bTransitional(false)
, m_bTopMost(false)
, m_bShowConsole(false)
, nAnimationInterval(17LL)
, m_ClearColor(EColor::BLACK)
, m_pCurrentScene(nullptr)
@ -33,7 +34,7 @@ e2d::EApp::EApp()
ASSERT(s_pInstance == nullptr, "EApp instance already exists!");
s_pInstance = this; // 保存实例对象
CoInitializeEx(NULL, COINIT_MULTITHREADED);
CoInitialize(NULL);
}
e2d::EApp::~EApp()
@ -54,104 +55,101 @@ e2d::EApp * e2d::EApp::get()
return s_pInstance; // 获取 EApp 的唯一实例
}
bool e2d::EApp::init(const EString &title, UINT32 width, UINT32 height, bool showConsole /* = false */)
bool e2d::EApp::init(const EString &title, UINT32 width, UINT32 height)
{
return init(title, width, height, EWindowStyle(), showConsole);
return init(title, width, height, EWindowStyle());
}
bool e2d::EApp::init(const EString &title, UINT32 width, UINT32 height, EWindowStyle wStyle, bool showConsole /* = false */)
bool e2d::EApp::init(const EString &title, UINT32 width, UINT32 height, EWindowStyle wStyle)
{
HRESULT hr;
// 显示或关闭控制台
EApp::showConsole(showConsole);
// 注册窗口类
WNDCLASSEX wcex = { sizeof(WNDCLASSEX) };
wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
wcex.lpfnWndProc = EApp::WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = sizeof(LONG_PTR);
wcex.hInstance = HINST_THISCOMPONENT;
wcex.hbrBackground = (HBRUSH)(GetStockObject(BLACK_BRUSH));
wcex.lpszMenuName = NULL;
wcex.hCursor = LoadCursor(NULL, IDI_APPLICATION);
wcex.lpszClassName = L"Easy2DApp";
// 设置窗口是否有关闭按钮
if (wStyle.m_bNoClose)
{
wcex.style |= CS_NOCLOSE;
}
// 设置程序图标
if (wStyle.m_pIconID)
{
wcex.hIcon = (HICON)::LoadImage(
GetModuleHandle(NULL),
wStyle.m_pIconID,
IMAGE_ICON,
0,
0,
LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
}
// 创建设备无关资源
hr = _createDeviceIndependentResources();
RegisterClassEx(&wcex);
// 因为 CreateWindow 函数使用的是像素大小,获取系统的 DPI 以使它
// 适应窗口缩放
FLOAT dpiX, dpiY;
// 工厂将返回当前的系统 DPI这个值也将用来创建窗口
GetFactory()->GetDesktopDpi(&dpiX, &dpiY);
width = static_cast<UINT>(ceil(width * dpiX / 96.f));
height = static_cast<UINT>(ceil(height * dpiY / 96.f));
// 获取屏幕分辨率
UINT screenWidth = static_cast<UINT>(GetSystemMetrics(SM_CXSCREEN));
UINT screenHeight = static_cast<UINT>(GetSystemMetrics(SM_CYSCREEN));
// 当输入的窗口大小比分辨率大时,给出警告
WARN_IF(screenWidth < width || screenHeight < height, "The window is larger than screen!");
// 取最小值
width = min(width, screenWidth);
height = min(height, screenHeight);
// 创建窗口样式
DWORD dwStyle = WS_OVERLAPPED | WS_SYSMENU;
if (!wStyle.m_bNoMiniSize)
{
dwStyle |= WS_MINIMIZEBOX;
}
// 保存窗口是否置顶显示
m_bTopMost = wStyle.m_bTopMost;
// 保存窗口名称
m_sTitle = title;
// 创建窗口
GetHWnd() = CreateWindow(
L"Easy2DApp",
m_sTitle.c_str(),
dwStyle,
0,
0,
width,
height,
NULL,
NULL,
HINST_THISCOMPONENT,
this
);
hr = GetHWnd() ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
// 注册窗口类
WNDCLASSEX wcex = { sizeof(WNDCLASSEX) };
UINT style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
if (wStyle.m_bNoClose)
{
style |= CS_NOCLOSE;
}
wcex.style = style;
wcex.lpfnWndProc = EApp::WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = sizeof(LONG_PTR);
wcex.hInstance = HINST_THISCOMPONENT;
wcex.hbrBackground = (HBRUSH)(GetStockObject(BLACK_BRUSH));
wcex.lpszMenuName = NULL;
wcex.hCursor = LoadCursor(NULL, IDI_APPLICATION);
wcex.lpszClassName = L"Easy2DApp";
if (wStyle.m_pIconID)
{
wcex.hIcon = (HICON)::LoadImage(GetModuleHandle(NULL), wStyle.m_pIconID, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
}
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);
width = static_cast<UINT>(ceil(width * dpiX / 96.f));
height = static_cast<UINT>(ceil(height * dpiY / 96.f));
// 获取屏幕分辨率
UINT screenWidth = static_cast<UINT>(GetSystemMetrics(SM_CXSCREEN));
UINT screenHeight = static_cast<UINT>(GetSystemMetrics(SM_CYSCREEN));
// 当输入的窗口大小比分辨率大时,给出警告
WARN_IF(screenWidth < width || screenHeight < height, "The window is larger than screen!");
width = min(width, screenWidth);
height = min(height, screenHeight);
// 创建窗口样式
DWORD dwStyle = WS_OVERLAPPED | WS_SYSMENU;
if (!wStyle.m_bNoMiniSize)
{
dwStyle |= WS_MINIMIZEBOX;
}
// 保存窗口是否置顶显示
m_bTopMost = wStyle.m_bTopMost;
// 保存窗口名称
m_sTitle = title;
// 创建窗口
GetHWnd() = CreateWindow(
L"Easy2DApp",
m_sTitle.c_str(),
dwStyle,
0,
0,
width,
height,
NULL,
NULL,
HINST_THISCOMPONENT,
this
);
hr = GetHWnd() ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
// 禁用输入法
this->setKeyboardLayoutEnable(false);
// 重设客户区大小
this->setWindowSize(width, height);
}
else
{
UnregisterClass(L"E2DApp", HINST_THISCOMPONENT);
}
// 禁用输入法
this->setKeyboardLayoutEnable(false);
// 重设客户区大小
this->setWindowSize(width, height);
}
else
{
UnregisterClass(L"E2DApp", HINST_THISCOMPONENT);
}
if (FAILED(hr))
@ -186,13 +184,15 @@ bool e2d::EApp::isPaused()
return s_pInstance->m_bPaused || s_pInstance->m_bManualPaused;
}
void e2d::EApp::showConsole(bool show)
void e2d::EApp::showConsole(bool show /* = true */)
{
// 查找已存在的控制台句柄
HWND hwnd = GetConsoleWindow();
static FILE * stdoutstream = nullptr;
static FILE * stdinstream = nullptr;
static FILE * stderrstream = nullptr;
EApp::get()->m_bShowConsole = show;
// 查找已存在的控制台句柄
HWND hwnd = GetConsoleWindow();
// 关闭控制台
if (show)
{
@ -238,6 +238,11 @@ void e2d::EApp::run()
ASSERT(GetHWnd() != nullptr, "Cannot find Game Window.");
// 进入第一个场景
_enterNextScene();
// 关闭控制台
if (!m_bShowConsole)
{
showConsole(false);
}
// 显示窗口
ShowWindow(GetHWnd(), SW_SHOWNORMAL);
UpdateWindow(GetHWnd());
@ -349,48 +354,42 @@ void e2d::EApp::_onControl()
EObjectManager::__flush(); // 刷新内存池
ETimerManager::TimerProc(); // 定时器管理器执行程序
EActionManager::ActionProc(); // 动作管理器执行程序
EPhysicsManager::PhysicsProc(); // 物理引擎执行程序
}
// This method discards device-specific
// resources if the Direct3D device dissapears during execution and
// recreates the resources the next time it's invoked.
void e2d::EApp::_onRender()
{
HRESULT hr = S_OK;
hr = _createDeviceResources();
if (SUCCEEDED(hr))
// 开始绘图
GetRenderTarget()->BeginDraw();
// 使用背景色清空屏幕
GetRenderTarget()->Clear(D2D1::ColorF(m_ClearColor));
// 绘制当前场景
if (m_pCurrentScene)
{
// 开始绘图
GetRenderTarget()->BeginDraw();
// 使用背景色清空屏幕
GetRenderTarget()->Clear(D2D1::ColorF(m_ClearColor));
// 绘制当前场景
if (m_pCurrentScene)
{
m_pCurrentScene->_onRender();
}
// 切换场景时,同时绘制两场景
if (m_bTransitional && m_pNextScene)
{
m_pNextScene->_onRender();
}
// 终止绘图
hr = GetRenderTarget()->EndDraw();
// 刷新界面
UpdateWindow(GetHWnd());
m_pCurrentScene->_onRender();
}
// 切换场景时,同时绘制两场景
if (m_bTransitional && m_pNextScene)
{
m_pNextScene->_onRender();
}
// 终止绘图
hr = GetRenderTarget()->EndDraw();
// 刷新界面
UpdateWindow(GetHWnd());
if (hr == D2DERR_RECREATE_TARGET)
{
// 如果 Direct3D 设备在执行过程中消失,将丢弃当前的设备相关资源
// 并在下一次调用时重建资源
hr = S_OK;
_discardDeviceResources();
SafeReleaseInterface(&GetRenderTarget());
}
if (FAILED(hr))
{
// 渲染时产生了未知的错误,退出游戏
MessageBox(GetHWnd(), L"Game rendering failed!", L"Error", MB_OK);
this->quit();
}
@ -468,22 +467,22 @@ void e2d::EApp::enterScene(EScene * scene, ETransition * transition, bool saveCu
}
}
void e2d::EApp::backScene()
void e2d::EApp::backScene(ETransition * transition /* = nullptr */)
{
backScene(nullptr);
}
// 栈为空时,调用返回场景函数失败
WARN_IF(s_SceneStack.size() == 0, "Scene stack now is empty!");
if (s_SceneStack.size() == 0) return;
void e2d::EApp::backScene(ETransition * transition)
{
ASSERT(s_SceneStack.size(), "Scene stack now is empty!");
// 从栈顶取出场景指针,作为下一场景
get()->m_pNextScene = s_SceneStack.top();
s_SceneStack.pop();
// 不保存当前场景
// 返回上一场景时,不保存当前场景
if (get()->m_pCurrentScene)
{
get()->m_pCurrentScene->m_bWillSave = false;
}
// 设置切换场景动画
if (transition)
{
@ -496,6 +495,8 @@ void e2d::EApp::backScene(ETransition * transition)
}
else
{
// 把这个变量赋为 false场景将在下一帧画面
// 进行切换
get()->m_bTransitional = false;
}
}
@ -506,7 +507,7 @@ void e2d::EApp::clearScene()
while (s_SceneStack.size())
{
auto temp = s_SceneStack.top();
SafeReleaseAndClear(&temp);
SafeRelease(&temp);
s_SceneStack.pop();
}
}
@ -518,14 +519,14 @@ e2d::EScene * e2d::EApp::getCurrentScene()
void e2d::EApp::setAppName(const EString &appname)
{
s_pInstance->m_sAppName = appname;
get()->m_sAppName = appname;
}
e2d::EString e2d::EApp::getAppName()
{
if (s_pInstance->m_sAppName.empty())
s_pInstance->m_sAppName = s_pInstance->m_sTitle;
return s_pInstance->m_sAppName;
if (get()->m_sAppName.empty())
get()->m_sAppName = get()->m_sTitle;
return get()->m_sAppName;
}
void e2d::EApp::setBkColor(UINT32 color)
@ -576,12 +577,13 @@ void e2d::EApp::showWindow()
void e2d::EApp::quit()
{
// 这个变量将控制游戏是否结束
get()->m_bEnd = true;
}
void e2d::EApp::end()
{
get()->m_bEnd = true;
EApp::quit();
}
void e2d::EApp::_enterNextScene()
@ -601,7 +603,7 @@ void e2d::EApp::_enterNextScene()
}
else
{
SafeReleaseAndClear(&m_pCurrentScene);
SafeRelease(&m_pCurrentScene);
}
}
@ -612,59 +614,9 @@ void e2d::EApp::_enterNextScene()
m_pNextScene = nullptr; // 下一场景置空
}
// Creates resources that are not bound to a particular device.
// Their lifetime effectively extends for the duration of the
// application.
HRESULT e2d::EApp::_createDeviceIndependentResources()
{
HRESULT hr = S_OK;
// Create a Direct2D factory.
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &GetFactory());
if (FAILED(hr))
{
MessageBox(nullptr, L"Create Device Independent Resources Failed!", L"Error", MB_OK);
}
return hr;
}
// 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 isVisiable
// changes, the window is remoted, etc.
HRESULT e2d::EApp::_createDeviceResources()
{
// 这个函数将自动创建设备相关资源
GetRenderTarget();
return S_OK;
}
// 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
// re2d::ESizes the render target appropriately.
void e2d::EApp::_onResize(UINT32 width, UINT32 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)
@ -738,7 +690,10 @@ LRESULT e2d::EApp::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam
{
UINT width = LOWORD(lParam);
UINT height = HIWORD(lParam);
pEApp->_onResize(width, height);
// 如果程序接收到一个 WM_SIZE 消息,这个方法将调整渲染
// 目标适当。它可能会调用失败,但是这里可以忽略有可能的
// 错误,因为这个错误将在下一次调用 EndDraw 时产生
GetRenderTarget()->Resize(D2D1::SizeU(width, height));
}
result = 0;
wasHandled = true;
@ -827,6 +782,7 @@ LRESULT e2d::EApp::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam
}
}
// 对当前消息没有特定的处理程序时,执行默认的窗口函数
if (!wasHandled)
{
result = DefWindowProc(hWnd, message, wParam, lParam);

View File

@ -4,7 +4,6 @@
e2d::EObject::EObject()
: m_nRefCount(0)
, m_bManaged(false)
, m_bAutoRelease(false)
{
EObjectManager::add(this); // 将该对象放入释放池中
}
@ -26,8 +25,3 @@ void e2d::EObject::release()
// 通知对象管理池刷新
EObjectManager::notifyFlush();
}
void e2d::EObject::autoRelease()
{
m_bAutoRelease = true;
}

View File

@ -12,6 +12,7 @@ e2d::EScene::EScene()
, m_bGeometryVisiable(false)
, m_pRoot(new ENode())
{
m_pRoot->retain();
m_pRoot->_onEnter();
m_pRoot->_setParentScene(this);
m_pRoot->_setSize(EApp::getWidth(), EApp::getHeight());
@ -20,7 +21,7 @@ e2d::EScene::EScene()
e2d::EScene::~EScene()
{
SafeReleaseAndClear(&m_pRoot);
SafeRelease(&m_pRoot);
}
void e2d::EScene::onEnter()
@ -66,14 +67,14 @@ void e2d::EScene::add(ENode * child, int order /* = 0 */)
m_pRoot->addChild(child, order);
}
bool e2d::EScene::remove(ENode * child, bool release /* = false */)
bool e2d::EScene::remove(ENode * child)
{
return m_pRoot->removeChild(child, release);
return m_pRoot->removeChild(child);
}
void e2d::EScene::remove(const EString &childName, bool release /* = false */)
void e2d::EScene::remove(const EString &childName)
{
return m_pRoot->removeChild(childName, release);
return m_pRoot->removeChild(childName);
}
e2d::EVector<e2d::ENode*>& e2d::EScene::getChildren()

View File

@ -217,7 +217,7 @@
<ClCompile Include="Geometry\EGeometry.cpp" />
<ClCompile Include="Geometry\EPhysicsMsg.cpp" />
<ClCompile Include="Geometry\ERectangle.cpp" />
<ClCompile Include="Listener\ECollisionListener.cpp" />
<ClCompile Include="Listener\EContactListener.cpp" />
<ClCompile Include="Listener\EKeyboardListener.cpp" />
<ClCompile Include="Listener\EKeyboardPressListener.cpp" />
<ClCompile Include="Listener\EListener.cpp" />

View File

@ -192,9 +192,6 @@
<ClCompile Include="Geometry\EEllipse.cpp">
<Filter>Geometry</Filter>
</ClCompile>
<ClCompile Include="Listener\ECollisionListener.cpp">
<Filter>Listener</Filter>
</ClCompile>
<ClCompile Include="Common\EMouseMsg.cpp">
<Filter>Common</Filter>
</ClCompile>
@ -210,6 +207,9 @@
<ClCompile Include="Geometry\EPhysicsMsg.cpp">
<Filter>Geometry</Filter>
</ClCompile>
<ClCompile Include="Listener\EContactListener.cpp">
<Filter>Listener</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Win\winbase.h">

View File

@ -1,15 +1,18 @@
#include "..\egeometry.h"
#include "..\Win\winbase.h"
#include "..\emanagers.h"
#include "..\enodes.h"
#include "..\Win\winbase.h"
e2d::EGeometry::EGeometry()
: m_bTransformed(false)
, m_nCategoryBitmask(0)
,m_nContactBitmask(0)
, m_bIsVisiable(true)
, m_nColor(EColor::RED)
, m_fOpacity(1)
, m_pParentNode(nullptr)
, m_pTransformedGeometry(nullptr)
{
this->autoRelease();
}
e2d::EGeometry::~EGeometry()
@ -17,11 +20,41 @@ e2d::EGeometry::~EGeometry()
SafeReleaseInterface(&m_pTransformedGeometry);
}
bool e2d::EGeometry::isContactWith(EGeometry * geometry)
{
return ((this->m_nContactBitmask & geometry->m_nCategoryBitmask) != 0);
}
e2d::ENode * e2d::EGeometry::getParentNode() const
{
return m_pParentNode;
}
UINT32 e2d::EGeometry::getCategoryBitmask() const
{
return m_nCategoryBitmask;
}
UINT32 e2d::EGeometry::getContactBitmask() const
{
return m_nContactBitmask;
}
void e2d::EGeometry::setCategoryBitmask(UINT32 mask)
{
m_nCategoryBitmask = mask;
}
void e2d::EGeometry::setContactBitmask(UINT32 mask)
{
m_nContactBitmask = mask;
}
void e2d::EGeometry::setVisiable(bool bVisiable)
{
m_bIsVisiable = bVisiable;
}
void e2d::EGeometry::setColor(UINT32 color)
{
m_nColor = color;
@ -29,7 +62,7 @@ void e2d::EGeometry::setColor(UINT32 color)
void e2d::EGeometry::setOpacity(float opacity)
{
m_fOpacity = opacity;
m_fOpacity = min(max(opacity, 0), 1);
}
void e2d::EGeometry::_onRender()
@ -71,14 +104,17 @@ void e2d::EGeometry::_transform()
{
if (m_pParentNode)
{
// 释放原形状
SafeReleaseInterface(&m_pTransformedGeometry);
// 根据父节点转换几何图形
GetFactory()->CreateTransformedGeometry(
_getD2dGeometry(),
m_pParentNode->m_Matri,
&m_pTransformedGeometry
);
this->m_bTransformed = true;
// 判断形状变换后的情况
EPhysicsManager::PhysicsGeometryProc(this);
}
}

View File

@ -1,29 +1,29 @@
#include "..\elisteners.h"
#include "..\egeometry.h"
e2d::ECollisionListener::ECollisionListener()
e2d::EContactListener::EContactListener()
: EPhysicsListener()
{
}
e2d::ECollisionListener::ECollisionListener(const EString & name)
e2d::EContactListener::EContactListener(const EString & name)
: EPhysicsListener(name)
{
}
e2d::ECollisionListener::ECollisionListener(const COLLISION_LISTENER_CALLBACK & callback)
e2d::EContactListener::EContactListener(const COLLISION_LISTENER_CALLBACK & callback)
: EPhysicsListener()
{
this->m_Callback = callback;
}
e2d::ECollisionListener::ECollisionListener(const EString & name, const COLLISION_LISTENER_CALLBACK & callback)
e2d::EContactListener::EContactListener(const EString & name, const COLLISION_LISTENER_CALLBACK & callback)
: EPhysicsListener(name)
{
this->m_Callback = callback;
}
void e2d::ECollisionListener::_callOn()
void e2d::EContactListener::_callOn()
{
if (EPhysicsMsg::getMsg() == EPhysicsMsg::OVERLAP ||
EPhysicsMsg::getMsg() == EPhysicsMsg::CONTAINS ||

View File

@ -80,7 +80,7 @@ void e2d::EActionManager::_clearAllActionsBindedWith(ENode * pTargetNode)
auto a = s_vActions[i];
if (a->getTarget() == pTargetNode)
{
SafeReleaseAndClear(&a);
SafeRelease(&a);
s_vActions.erase(s_vActions.begin() + i);
}
else
@ -144,7 +144,7 @@ void e2d::EActionManager::ActionProc()
if (action->_isEnding())
{
// 动作已经结束
SafeReleaseAndClear(&action);
SafeRelease(&action);
s_vActions.erase(s_vActions.begin() + i);
}
else

View File

@ -24,7 +24,7 @@ void e2d::EMsgManager::MouseProc(UINT message, WPARAM wParam, LPARAM lParam)
if (EApp::isPaused() && !mlistener->m_bAlways)
continue;
if (mlistener->isRunning())
if (mlistener->m_bAlways || mlistener->isRunning())
{
if (mlistener->getParentNode() &&
mlistener->getParentNode()->getParentScene() == EApp::getCurrentScene())
@ -49,7 +49,7 @@ void e2d::EMsgManager::KeyboardProc(UINT message, WPARAM wParam, LPARAM lParam)
if (EApp::isPaused() && !klistener->m_bAlways)
continue;
if (klistener->isRunning())
if (klistener->m_bAlways || klistener->isRunning())
{
if (klistener->getParentNode() &&
klistener->getParentNode()->getParentScene() == EApp::getCurrentScene())
@ -140,7 +140,7 @@ void e2d::EMsgManager::delMouseListeners(const EString & name)
{
if ((*mIter)->getName() == name)
{
SafeReleaseAndClear(&(*mIter));
SafeRelease(&(*mIter));
mIter = s_vMouseListeners.erase(mIter);
}
else
@ -182,7 +182,7 @@ void e2d::EMsgManager::delKeyboardListeners(const EString & name)
{
if ((*kIter)->getName() == name)
{
SafeReleaseAndClear(&(*kIter));
SafeRelease(&(*kIter));
kIter = s_vKeyboardListeners.erase(kIter);
}
else
@ -279,7 +279,7 @@ void e2d::EMsgManager::_clearAllMouseListenersBindedWith(ENode * pParentNode)
auto t = s_vMouseListeners[i];
if (t->getParentNode() == pParentNode)
{
SafeReleaseAndClear(&t);
SafeRelease(&t);
s_vMouseListeners.erase(s_vMouseListeners.begin() + i);
}
else
@ -296,7 +296,7 @@ void e2d::EMsgManager::_clearAllKeyboardListenersBindedWith(ENode * pParentNode)
auto t = s_vKeyboardListeners[i];
if (t->getParentNode() == pParentNode)
{
SafeReleaseAndClear(&t);
SafeRelease(&t);
s_vKeyboardListeners.erase(s_vKeyboardListeners.begin() + i);
}
else

View File

@ -23,9 +23,9 @@ void e2d::EObjectManager::__flush()
// 循环遍历容器中的所有对象
for (iter = s_vPool.begin(); iter != s_vPool.end();)
{
if ((*iter)->m_bAutoRelease && (*iter)->m_nRefCount <= 0)
if ((*iter)->m_nRefCount <= 0)
{
// 若对象的引用的计数 0, 释放该对象
// 若对象的引用的计数小于等于 0, 释放该对象
delete (*iter);
// 从释放池中删除该对象
iter = s_vPool.erase(iter);

View File

@ -9,41 +9,26 @@ e2d::EVector<e2d::EPhysicsListener*> s_vListeners;
e2d::EVector<e2d::EGeometry*> s_vGeometries;
void e2d::EPhysicsManager::PhysicsProc()
void e2d::EPhysicsManager::PhysicsGeometryProc(EGeometry * pActiveGeometry)
{
if (s_vListeners.empty() || s_vGeometries.empty() || EApp::isPaused())
return;
for (auto &geometry : s_vGeometries)
{
if (!geometry->getParentNode() ||
(geometry->getParentNode()->getParentScene() != EApp::getCurrentScene()))
continue;
// 只对进行了变化了对象进行判断
if (geometry->m_bTransformed)
{
// 判断变化后的图形情况
PhysicsGeometryProc(geometry);
// 取消变化标志
geometry->m_bTransformed = false;
}
}
}
void e2d::EPhysicsManager::PhysicsGeometryProc(EGeometry * pActiveGeometry)
{
// pActiveGeometry 为主动方
EPhysicsMsg::s_pActiveGeometry = pActiveGeometry;
// 判断变化后的状态
for (auto &pPassiveGeometry : s_vGeometries)
{
// 不与其他场景的物体判断
if (!pPassiveGeometry->getParentNode() ||
(pPassiveGeometry->getParentNode()->getParentScene() != EApp::getCurrentScene()))
continue;
if (pActiveGeometry != pPassiveGeometry)
{
// 判断两物体是否会产生接触消息
if (!pActiveGeometry->isContactWith(pPassiveGeometry))
continue;
// pPassiveGeometry 为被动方
EPhysicsMsg::s_pPassiveGeometry = pPassiveGeometry;
// 获取两方的关系
@ -101,7 +86,7 @@ void e2d::EPhysicsManager::bindListener(EPhysicsListener * listener, ENode * pPa
}
}
void e2d::EPhysicsManager::addGeometry(EGeometry * geometry)
void e2d::EPhysicsManager::_addGeometry(EGeometry * geometry)
{
if (geometry)
{
@ -110,7 +95,7 @@ void e2d::EPhysicsManager::addGeometry(EGeometry * geometry)
}
}
void e2d::EPhysicsManager::delGeometry(EGeometry * geometry)
void e2d::EPhysicsManager::_delGeometry(EGeometry * geometry)
{
if (geometry)
{
@ -118,7 +103,7 @@ void e2d::EPhysicsManager::delGeometry(EGeometry * geometry)
{
if (s_vGeometries[i] == geometry)
{
SafeReleaseAndClear(&geometry);
SafeRelease(&geometry);
s_vGeometries.erase(s_vGeometries.begin() + i);
return;
}
@ -155,7 +140,7 @@ void e2d::EPhysicsManager::delListeners(const EString & name)
{
if ((*iter)->getName() == name)
{
SafeReleaseAndClear(&(*iter));
SafeRelease(&(*iter));
iter = s_vListeners.erase(iter);
}
else
@ -227,7 +212,7 @@ void e2d::EPhysicsManager::_clearAllListenersBindedWith(ENode * pParentNode)
auto listener = s_vListeners[i];
if (listener->getParentNode() == pParentNode)
{
SafeReleaseAndClear(&listener);
SafeRelease(&listener);
s_vListeners.erase(s_vListeners.begin() + i);
}
else

View File

@ -81,7 +81,7 @@ void e2d::ETimerManager::delTimers(const EString & name)
{
if ((*mIter)->getName() == name)
{
SafeReleaseAndClear(&(*mIter));
SafeRelease(&(*mIter));
mIter = s_vTimers.erase(mIter);
}
else
@ -138,7 +138,7 @@ void e2d::ETimerManager::_clearAllTimersBindedWith(ENode * pParentNode)
auto t = s_vTimers[i];
if (t->getParentNode() == pParentNode)
{
SafeReleaseAndClear(&t);
SafeRelease(&t);
s_vTimers.erase(s_vTimers.begin() + i);
}
else

View File

@ -42,10 +42,10 @@ e2d::ENode::~ENode()
EMsgManager::_clearAllKeyboardListenersBindedWith(this);
EActionManager::_clearAllActionsBindedWith(this);
EPhysicsManager::_clearAllListenersBindedWith(this);
EPhysicsManager::delGeometry(m_pGeometry);
EPhysicsManager::_delGeometry(m_pGeometry);
for (auto child : m_vChildren)
{
SafeReleaseAndClear(&child);
SafeRelease(&child);
}
}
@ -112,7 +112,7 @@ void e2d::ENode::_onRender()
void e2d::ENode::_drawGeometry()
{
// 绘制自身的几何形状
if (m_pGeometry)
if (m_pGeometry && m_pGeometry->m_bIsVisiable)
{
m_pGeometry->_onRender();
}
@ -501,9 +501,9 @@ void e2d::ENode::setAnchor(float anchorX, float anchorY)
void e2d::ENode::setGeometry(EGeometry * geometry)
{
// 删除旧的形状
EPhysicsManager::delGeometry(m_pGeometry);
EPhysicsManager::_delGeometry(m_pGeometry);
// 添加新的形状
EPhysicsManager::addGeometry(geometry);
EPhysicsManager::_addGeometry(geometry);
if (geometry)
{
@ -589,15 +589,15 @@ e2d::ENode * e2d::ENode::getChild(const EString & name)
return nullptr;
}
void e2d::ENode::removeFromParent(bool release /* = false */)
void e2d::ENode::removeFromParent()
{
if (m_pParent)
{
m_pParent->removeChild(this, release);
m_pParent->removeChild(this);
}
}
bool e2d::ENode::removeChild(ENode * child, bool release /* = true */)
bool e2d::ENode::removeChild(ENode * child)
{
WARN_IF(child == nullptr, "ENode::removeChild NULL pointer exception.");
@ -621,10 +621,6 @@ bool e2d::ENode::removeChild(ENode * child, bool release /* = true */)
}
child->_onExit();
child->release();
if (release)
{
child->autoRelease();
}
return true;
}
}
@ -632,7 +628,7 @@ bool e2d::ENode::removeChild(ENode * child, bool release /* = true */)
return false;
}
void e2d::ENode::removeChild(const EString & childName, bool release /* = true */)
void e2d::ENode::removeChild(const EString & childName)
{
WARN_IF(childName.empty(), "Invalid ENode name.");
@ -659,26 +655,18 @@ void e2d::ENode::removeChild(const EString & childName, bool release /* = true *
}
child->_onExit();
child->release();
if (release)
{
child->autoRelease();
}
return;
}
}
}
void e2d::ENode::clearAllChildren(bool release /* = true */)
void e2d::ENode::clearAllChildren()
{
// 所有节点的引用计数减一
for (auto child : m_vChildren)
{
child->_onExit();
child->release();
if (release)
{
child->autoRelease();
}
}
// 清空储存节点的容器
m_vChildren.clear();

View File

@ -47,14 +47,14 @@ e2d::ESprite::ESprite(const EString & resourceName, const EString & resourceType
e2d::ESprite::~ESprite()
{
SafeReleaseAndClear(&m_pTexture);
SafeRelease(&m_pTexture);
}
void e2d::ESprite::loadFrom(ETexture * texture)
{
if (texture)
{
SafeReleaseAndClear(&m_pTexture);
SafeRelease(&m_pTexture);
m_pTexture = texture;
m_pTexture->retain();

View File

@ -37,7 +37,7 @@ e2d::EText::EText(const EString & text, EString fontFamily, float fontSize, UINT
e2d::EText::~EText()
{
SafeReleaseAndClear(&m_pFont);
SafeRelease(&m_pFont);
}
e2d::EString e2d::EText::getText() const
@ -70,7 +70,7 @@ void e2d::EText::setFont(EFont * font)
{
if (font)
{
SafeReleaseAndClear(&m_pFont);
SafeRelease(&m_pFont);
m_pFont = font;
font->retain();

View File

@ -33,6 +33,21 @@ e2d::EString e2d::EFileUtils::getLocalAppDataPath()
return L"";
}
e2d::EString e2d::EFileUtils::getTempPath()
{
// 获取临时文件目录
TCHAR path[_MAX_PATH];
::GetTempPath(_MAX_PATH, path);
// 创建临时文件目录
e2d::EString tempFilePath = path + e2d::EApp::getAppName();
if (_waccess(tempFilePath.c_str(), 0) == -1)
{
_wmkdir(tempFilePath.c_str());
}
return tempFilePath;
}
e2d::EString e2d::EFileUtils::getDefaultSavePath()
{
EString path = EFileUtils::getLocalAppDataPath();

View File

@ -1,10 +1,12 @@
#include "..\etools.h"
#include "..\Win\winbase.h"
#include <map>
#include <mmsystem.h>
#include <Digitalv.h>
#pragma comment(lib , "winmm.lib")
#include <map>
#include <Digitalv.h>
static size_t Hash(const e2d::EString & key);
static bool ExtractResource(LPCTSTR strDstFile, LPCTSTR strResType, LPCTSTR strResName);
////////////////////////////////////////////////////////////////////
@ -18,8 +20,8 @@ public:
~MciPlayer();
void close();
void open(const e2d::EString & pFileName, UINT uId);
void open(const e2d::EString & pResouceName, const e2d::EString & pResouceType, const e2d::EString & musicExtension, UINT uId);
bool open(const e2d::EString & pFileName, UINT uId);
bool open(const e2d::EString & pResouceName, const e2d::EString & pResouceType, const e2d::EString & musicExtension, UINT uId);
void play(bool bLoop = false);
void pause();
void resume();
@ -36,7 +38,7 @@ private:
UINT m_nSoundID;
bool m_bPlaying;
bool m_bLoop;
e2d::EString m_sTmpFileName;
e2d::EString m_sTempFileName;
};
@ -53,78 +55,67 @@ MciPlayer::~MciPlayer()
close(); // 关闭播放器
}
void MciPlayer::open(const e2d::EString & pFileName, UINT uId)
bool MciPlayer::open(const e2d::EString & pFileName, UINT uId)
{
// 忽略不存在的文件
if (pFileName.empty()) return;
if (pFileName.empty())
return false;
// 停止当前音乐
close();
// 设置 MCI_OPEN_PARMS 参数
MCI_OPEN_PARMS mciOpen = { 0 };
mciOpen.lpstrDeviceType = (LPCTSTR)-1;
mciOpen.lpstrElementName = pFileName.c_str();
// 打开这个文件
MCIERROR mciError;
mciError = mciSendCommand(0, MCI_OPEN, MCI_OPEN_ELEMENT, reinterpret_cast<DWORD_PTR>(&mciOpen));
// 出现错误时,忽略这次操作
if (mciError) return;
mciError = mciSendCommand(
0,
MCI_OPEN,
MCI_OPEN_ELEMENT | MCI_NOTIFY,
reinterpret_cast<DWORD_PTR>(&mciOpen)
);
// 保存设备等信息
m_dev = mciOpen.wDeviceID;
m_nSoundID = uId;
m_bPlaying = false;
}
void MciPlayer::open(const e2d::EString & pResouceName, const e2d::EString & pResouceType, const e2d::EString & musicExtension, UINT uId)
{
bool ExtractResource(LPCTSTR strDstFile, LPCTSTR strResType, LPCTSTR strResName);
// 忽略不存在的文件
if (pResouceName.empty() || pResouceType.empty()) return;
// 获取临时文件目录
TCHAR tmpFilePath[_MAX_PATH];
::GetTempPath(_MAX_PATH, tmpFilePath);
// 创建临时文件目录
e2d::EString tmpFileName = tmpFilePath + e2d::EApp::getAppName();
if (_waccess(tmpFileName.c_str(), 0) == -1)
if (mciError)
{
_wmkdir(tmpFileName.c_str());
return false;
}
// 产生临时文件的文件名
tmpFileName.append(L"\\");
tmpFileName.append(std::to_wstring(uId));
tmpFileName.append(L"." + musicExtension);
// 导出资源为临时文件
if (ExtractResource(tmpFileName.c_str(), pResouceType.c_str(), pResouceName.c_str()))
else
{
// 停止当前音乐
close();
// 设置 MCI_OPEN_PARMS 参数
MCI_OPEN_PARMS mciOpen = { 0 };
mciOpen.lpstrDeviceType = (LPCTSTR)-1;
mciOpen.lpstrElementName = tmpFileName.c_str();
// 打开这个文件
MCIERROR mciError;
mciError = mciSendCommand(0, MCI_OPEN, MCI_OPEN_ELEMENT, reinterpret_cast<DWORD_PTR>(&mciOpen));
// 出现错误时,忽略这次操作
if (mciError) return;
// 保存设备等信息
m_dev = mciOpen.wDeviceID;
m_nSoundID = uId;
m_bPlaying = false;
m_sTmpFileName = tmpFileName;
return true;
}
}
bool MciPlayer::open(const e2d::EString & pResouceName, const e2d::EString & pResouceType, const e2d::EString & musicExtension, UINT uId)
{
// 忽略不存在的文件
if (pResouceName.empty() || pResouceType.empty() || musicExtension.empty()) return false;
// 获取临时文件目录
e2d::EString tempFileName = e2d::EFileUtils::getTempPath();
// 产生临时文件的文件名
tempFileName.append(L"\\");
tempFileName.append(std::to_wstring(uId));
tempFileName.append(L"." + musicExtension);
// 导出资源为临时文件
if (ExtractResource(tempFileName.c_str(), pResouceType.c_str(), pResouceName.c_str()))
{
if (open(tempFileName, uId))
{
m_sTempFileName = tempFileName;
return true;
}
}
return false;
}
void MciPlayer::play(bool bLoop)
{
// 设备为空时,忽略这次操作
@ -135,8 +126,15 @@ void MciPlayer::play(bool bLoop)
// 设置播放参数
MCI_PLAY_PARMS mciPlay = { 0 };
MCIERROR s_mciError;
// 播放声音
s_mciError = mciSendCommand(m_dev, MCI_PLAY, MCI_FROM | (bLoop ? MCI_DGV_PLAY_REPEAT : 0), reinterpret_cast<DWORD_PTR>(&mciPlay));
s_mciError = mciSendCommand(
m_dev,
MCI_PLAY,
MCI_FROM | MCI_NOTIFY | (bLoop ? MCI_DGV_PLAY_REPEAT : 0),
reinterpret_cast<DWORD_PTR>(&mciPlay)
);
// 未出错时,置 m_bPlaying 为 true
if (!s_mciError)
{
@ -158,10 +156,10 @@ void MciPlayer::close()
_sendCommand(MCI_CLOSE);
}
// 删除临时文件
if (!m_sTmpFileName.empty())
if (!m_sTempFileName.empty())
{
DeleteFile(m_sTmpFileName.c_str());
m_sTmpFileName.clear();
DeleteFile(m_sTempFileName.c_str());
m_sTempFileName.clear();
}
// 恢复默认属性
m_dev = 0;
@ -197,10 +195,24 @@ void MciPlayer::rewind()
return;
}
// 重置播放位置
mciSendCommand(m_dev, MCI_SEEK, MCI_SEEK_TO_START, 0);
mciSendCommand(
m_dev,
MCI_SEEK,
MCI_SEEK_TO_START | MCI_NOTIFY,
0
);
// 播放音乐
MCI_PLAY_PARMS mciPlay = { 0 };
m_bPlaying = mciSendCommand(m_dev, MCI_PLAY, (m_bLoop ? MCI_DGV_PLAY_REPEAT : 0), reinterpret_cast<DWORD_PTR>(&mciPlay)) ? false : true;
MCIERROR s_mciError;
// 播放声音
s_mciError = mciSendCommand(
m_dev,
MCI_PLAY,
MCI_NOTIFY | (m_bLoop ? MCI_DGV_PLAY_REPEAT : 0),
reinterpret_cast<DWORD_PTR>(&mciPlay)
);
m_bPlaying = s_mciError ? false : true;
}
void MciPlayer::setVolume(float volume)
@ -208,7 +220,12 @@ void MciPlayer::setVolume(float volume)
MCI_DGV_SETAUDIO_PARMS mciSetAudioPara = { 0 };
mciSetAudioPara.dwItem = MCI_DGV_SETAUDIO_VOLUME;
mciSetAudioPara.dwValue = DWORD(1000 * min(max(volume, 0), 1));
mciSendCommand(m_dev, MCI_SETAUDIO, MCI_DGV_SETAUDIO_VALUE | MCI_DGV_SETAUDIO_ITEM, (DWORD_PTR)&mciSetAudioPara);
mciSendCommand(
m_dev,
MCI_SETAUDIO,
MCI_NOTIFY | MCI_DGV_SETAUDIO_VALUE | MCI_DGV_SETAUDIO_ITEM,
(DWORD_PTR)&mciSetAudioPara
);
}
bool MciPlayer::isPlaying()
@ -243,8 +260,6 @@ void MciPlayer::_sendCommand(int nCommand, DWORD_PTR param1, DWORD_PTR parma2)
typedef std::map<unsigned int, MciPlayer *> MusicList;
typedef std::pair<unsigned int, MciPlayer *> Music;
static size_t Hash(const e2d::EString & key);
static MusicList& getMciPlayerList()
{

View File

@ -17,55 +17,71 @@ HWND &GetHWnd()
ID2D1Factory * &GetFactory()
{
return s_pDirect2dFactory;
}
IWICImagingFactory * &GetImagingFactory()
{
if (!s_pIWICFactory)
if (!s_pDirect2dFactory)
{
CoCreateInstance(
CLSID_WICImagingFactory,
NULL,
CLSCTX_INPROC_SERVER,
IID_IWICImagingFactory,
reinterpret_cast<void **>(&s_pIWICFactory)
);
// 创建设备无关资源,它们的生命周期和程序的时长相同
HRESULT hr = S_OK;
// 创建一个 Direct2D 工厂
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &s_pDirect2dFactory);
ASSERT(SUCCEEDED(hr), "Create Device Independent Resources Failed!");
}
return s_pIWICFactory;
return s_pDirect2dFactory;
}
ID2D1HwndRenderTarget * &GetRenderTarget()
{
if (!s_pRenderTarget)
{
// 创建设备相关资源。这些资源应在 Direct3D 设备消失时重建,
// 比如当 isVisiable 被修改,等等
RECT rc;
GetClientRect(s_HWnd, &rc);
GetClientRect(GetHWnd(), &rc);
D2D1_SIZE_U size = D2D1::SizeU(
rc.right - rc.left,
rc.bottom - rc.top
);
// Create a Direct2D render target.
// 创建一个 Direct2D 渲染目标
HRESULT hr;
hr = GetFactory()->CreateHwndRenderTarget(
D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(s_HWnd, size),
D2D1::HwndRenderTargetProperties(
GetHWnd(),
size),
&s_pRenderTarget
);
ASSERT(SUCCEEDED(hr), "Create Render Target Failed!");
ASSERT(SUCCEEDED(hr), "Create Render Target Failed! Maybe you should initalize EApp first.");
}
return s_pRenderTarget;
}
IWICImagingFactory * &GetImagingFactory()
{
if (!s_pIWICFactory)
{
// 创建 WIC 绘图工厂,用于统一处理各种格式的图片
HRESULT hr = CoCreateInstance(
CLSID_WICImagingFactory,
NULL,
CLSCTX_INPROC_SERVER,
IID_IWICImagingFactory,
reinterpret_cast<void**>(&s_pIWICFactory)
);
ASSERT(SUCCEEDED(hr), "Create WICImagingFactory Failed!");
}
return s_pIWICFactory;
}
IDWriteFactory * &GetDirectWriteFactory()
{
if (!s_pDWriteFactory)
{
HRESULT hr;
hr = DWriteCreateFactory(
// 创建 DirectWrite 工厂
HRESULT hr = DWriteCreateFactory(
DWRITE_FACTORY_TYPE_SHARED,
__uuidof(IDWriteFactory),
reinterpret_cast<IUnknown**>(&s_pDWriteFactory)

View File

@ -27,8 +27,7 @@ public:
bool init(
const EString &title, /* 窗口标题 */
UINT32 width, /* 窗口宽度 */
UINT32 height, /* 窗口高度 */
bool showConsole = false/* 是否显示控制台 */
UINT32 height /* 窗口高度 */
);
// 初始化游戏界面
@ -36,8 +35,7 @@ public:
const EString &title, /* 窗口标题 */
UINT32 width, /* 窗口宽度 */
UINT32 height, /* 窗口高度 */
EWindowStyle wStyle, /* 窗口样式 */
bool showConsole = false/* 是否显示控制台 */
EWindowStyle wStyle /* 窗口样式 */
);
// 启动程序
@ -61,7 +59,7 @@ public:
// 继续游戏
static void resume();
// 获取游戏是否暂停
// 游戏是否暂停
static bool isPaused();
// 切换场景
@ -77,12 +75,9 @@ public:
bool saveCurrentScene = true /* 是否保存当前场景 */
);
// 返回上一场景
static void backScene();
// 返回上一场景
static void backScene(
ETransition * transition /* 场景切换动画 */
ETransition * transition = nullptr /* 场景切换动画 */
);
// 清空保存的所有场景
@ -96,7 +91,7 @@ public:
// 是否打开控制台
static void showConsole(
bool show
bool show = true
);
// 终止程序
@ -158,15 +153,6 @@ public:
);
protected:
// 创建设备无关资源
HRESULT _createDeviceIndependentResources();
// 创建设备相关资源
HRESULT _createDeviceResources();
// 释放设备相关资源
void _discardDeviceResources();
// 游戏主循环
void _mainLoop();
@ -179,12 +165,6 @@ protected:
// 进入下一场景
void _enterNextScene();
// 重定 render target 大小
void _onResize(
UINT32 width,
UINT32 height
);
// 窗口程序
static LRESULT CALLBACK WndProc(
HWND hWnd,
@ -199,6 +179,7 @@ protected:
bool m_bManualPaused;
bool m_bTransitional;
bool m_bTopMost;
bool m_bShowConsole;
EString m_sTitle;
EString m_sAppName;
UINT32 m_ClearColor;
@ -223,13 +204,9 @@ public:
// 引用计数减一
void release();
// 让引擎自动释放这个对象
void autoRelease();
private:
int m_nRefCount;
bool m_bManaged;
bool m_bAutoRelease;
};
@ -266,14 +243,12 @@ public:
// 删除子节点
bool remove(
ENode * child,
bool release = false
ENode * child
);
// 根据名称删除子节点
// 删除相同名称的子节点
void remove(
const EString &childName,
bool release = false
const EString &childName
);
// 获取所有子节点

View File

@ -49,9 +49,35 @@ public:
virtual ~EGeometry();
// 判断是否可以和另一几何图形产生接触消息
bool isContactWith(
EGeometry * geometry
);
// 获取父节点
ENode * getParentNode() const;
// 获取类别掩码
UINT32 getCategoryBitmask() const;
// 获取接触掩码
UINT32 getContactBitmask() const;
// 设置类别掩码
void setCategoryBitmask(
UINT32 mask
);
// 设置接触掩码
void setContactBitmask(
UINT32 mask
);
// 设置几何形状的可见性
void setVisiable(
bool bVisiable
);
// 设置绘制颜色
void setColor(
UINT32 color
@ -78,6 +104,9 @@ protected:
protected:
bool m_bTransformed;
bool m_bIsVisiable;
UINT32 m_nCategoryBitmask;
UINT32 m_nContactBitmask;
UINT32 m_nColor;
float m_fOpacity;
ENode * m_pParentNode;

View File

@ -375,23 +375,23 @@ protected:
};
class ECollisionListener :
class EContactListener :
public EPhysicsListener
{
friend EMsgManager;
public:
ECollisionListener();
EContactListener();
ECollisionListener(
EContactListener(
const EString &name
);
ECollisionListener(
EContactListener(
const COLLISION_LISTENER_CALLBACK &callback
);
ECollisionListener(
EContactListener(
const EString &name,
const COLLISION_LISTENER_CALLBACK &callback
);

View File

@ -64,8 +64,5 @@
template<typename T>
inline void SafeDelete(T** p) { if (*p) { delete *p; *p = nullptr; } }
template<typename T>
inline void SafeReleaseAndClear(T** p) { if (*p) { (*p)->autoRelease(); (*p)->release(); *p = nullptr; } }
template<typename T>
inline void SafeRelease(T** p) { if (*p) { (*p)->release(); *p = nullptr; } }

View File

@ -321,18 +321,9 @@ class EPhysicsManager
friend EApp;
friend EScene;
friend ENode;
friend EGeometry;
public:
// 添加形状
static void addGeometry(
EGeometry * geometry
);
// 删除已绑定的形状
static void delGeometry(
EGeometry * geometry
);
// 将监听器与场景绑定
static void bindListener(
EPhysicsListener * listener,
@ -390,14 +381,21 @@ private:
// 清空监听器管理器
static void _clearManager();
// 添加形状
static void _addGeometry(
EGeometry * geometry
);
// 删除已绑定的形状
static void _delGeometry(
EGeometry * geometry
);
// 清空绑定在节点上的所有监听器
static void _clearAllListenersBindedWith(
ENode * pParentNode
);
// 物理引擎执行程序
static void PhysicsProc();
// 几何图形判断程序
static void PhysicsGeometryProc(
EGeometry * pActiveGeometry

View File

@ -244,26 +244,20 @@ public:
);
// 从父节点移除
virtual void removeFromParent(
bool release = false
);
virtual void removeFromParent();
// 移除子节点
virtual bool removeChild(
ENode * child,
bool release = true
ENode * child
);
// 移除子节点
virtual void removeChild(
const EString & childName,
bool release = true
const EString & childName
);
// 移除所有节点
virtual void clearAllChildren(
bool release = true
);
virtual void clearAllChildren();
// 执行动画
virtual void runAction(

View File

@ -102,9 +102,12 @@ protected:
class EFileUtils
{
public:
// 获取系统的 AppData\Local 路径
// 获取系统的 AppData Local 路径
static EString getLocalAppDataPath();
// 获取临时文件目录
static EString getTempPath();
// 获取默认的保存路径
static EString getDefaultSavePath();

View File

@ -8,8 +8,6 @@ class ETransition :
public EObject
{
friend EApp;
public:
ETransition() { this->autoRelease(); }
protected:
// 保存当前场景和下一场景的指针,和控制场景切换的变量