Easy2D v1.1.0

This commit is contained in:
werelone 2017-09-27 17:56:28 +08:00
parent 35227bb85b
commit 96b0dbd551
52 changed files with 3255 additions and 1399 deletions

56
Easy2D/Action/Action.cpp Normal file
View File

@ -0,0 +1,56 @@
#include "..\easy2d.h"
#include <assert.h>
Action::Action() :
m_bRunning(true),
m_bStop(false),
m_pParent(nullptr)
{
// 默认动作 15ms 运行一次
setInterval(15);
}
Action::~Action()
{
}
bool Action::isRunning()
{
return m_bRunning;
}
void Action::start()
{
m_bRunning = true;
}
void Action::resume()
{
m_bRunning = true;
}
void Action::pause()
{
m_bRunning = false;
}
void Action::stop()
{
m_bStop = true;
}
void Action::setInterval(UINT ms)
{
// 设置动作的时间间隔
LARGE_INTEGER nFreq;
QueryPerformanceFrequency(&nFreq);
m_nAnimationInterval.QuadPart = (LONGLONG)(ms / 1000.0 * nFreq.QuadPart);
// 保存时间间隔的时长
this->m_nMilliSeconds = ms;
}
Action * Action::reverse() const
{
assert(0);
return nullptr;
}

View File

@ -0,0 +1,32 @@
#include "..\easy2d.h"
ActionCallback::ActionCallback(const std::function<void()>& callback) :
m_Callback(callback)
{
}
ActionCallback::~ActionCallback()
{
}
ActionCallback * ActionCallback::copy()
{
return new ActionCallback(m_Callback);
}
void ActionCallback::_init()
{
}
bool ActionCallback::_exec(LARGE_INTEGER nNow)
{
if (!m_bStop)
{
m_Callback();
}
return true;
}
void ActionCallback::_reset()
{
}

View File

@ -0,0 +1,40 @@
#include "..\easy2d.h"
ActionDelay::ActionDelay(float duration)
{
setInterval(UINT(duration * 1000));
}
ActionDelay::~ActionDelay()
{
}
ActionDelay * easy2d::ActionDelay::copy()
{
return new ActionDelay(*this);
}
void ActionDelay::_init()
{
// 记录当前时间
QueryPerformanceCounter(&m_nLast);
}
bool ActionDelay::_exec(LARGE_INTEGER nNow)
{
if (m_bStop) return true;
if (!m_bRunning) return false;
// 判断时间间隔是否足够
if (nNow.QuadPart - m_nLast.QuadPart > m_nAnimationInterval.QuadPart)
{
return true;
}
return false;
}
void ActionDelay::_reset()
{
// 重新记录当前时间
QueryPerformanceCounter(&m_nLast);
}

View File

@ -0,0 +1,74 @@
#include "..\easy2d.h"
ActionFrames::ActionFrames() :
m_nFrameIndex(0)
{
// 帧动画默认 .5s 刷新一次
setInterval(500);
}
ActionFrames::~ActionFrames()
{
for (auto frame : m_vFrames)
{
frame->release();
}
}
void ActionFrames::_init()
{
// 记录当前时间
QueryPerformanceCounter(&m_nLast);
}
bool ActionFrames::_exec(LARGE_INTEGER nNow)
{
if (m_bStop) return true;
if (!m_bRunning) return false;
// 判断时间间隔是否足够
while (nNow.QuadPart - m_nLast.QuadPart > m_nAnimationInterval.QuadPart)
{
// 用求余的方法重新记录时间
m_nLast.QuadPart = nNow.QuadPart - (nNow.QuadPart % m_nAnimationInterval.QuadPart);
m_pParent->setImage(m_vFrames[m_nFrameIndex]);
m_nFrameIndex++;
if (m_nFrameIndex == m_vFrames.size())
{
return true;
}
}
return false;
}
void ActionFrames::_reset()
{
m_nFrameIndex = 0;
}
void ActionFrames::addFrame(Image * frame)
{
if (frame)
{
m_vFrames.push_back(frame);
frame->retain();
}
}
ActionFrames * ActionFrames::copy()
{
auto a = new ActionFrames();
for (auto f : m_vFrames)
{
a->addFrame(f);
}
return a;
}
ActionFrames * ActionFrames::reverse() const
{
auto a = new ActionFrames();
a->m_vFrames = this->m_vFrames;
a->m_vFrames.reserve(m_vFrames.size());
return a;
}

View File

@ -0,0 +1,55 @@
#include "..\easy2d.h"
ActionMoveBy::ActionMoveBy(float duration, CVector vec) :
Animation(duration)
{
m_MoveVector = vec;
}
ActionMoveBy::~ActionMoveBy()
{
}
void ActionMoveBy::_init()
{
Animation::_init();
m_BeginPos = m_pParent->getPos();
}
bool ActionMoveBy::_exec(LARGE_INTEGER nNow)
{
if (m_bStop) return true;
if (!m_bRunning) return false;
while (Animation::_exec(nNow))
{
// 计算移动位置
float scale = float(m_nDuration) / m_nTotalDuration;
// 移动 Sprite
m_pParent->setPos(int(m_BeginPos.x + m_MoveVector.x * scale),
int(m_BeginPos.y + m_MoveVector.y * scale));
// 判断动作是否结束
if (m_nDuration >= m_nTotalDuration)
{
return true;
}
}
return false;
}
void ActionMoveBy::_reset()
{
Animation::_reset();
}
ActionMoveBy * ActionMoveBy::copy()
{
auto a = new ActionMoveBy(*this);
a->_reset();
return a;
}
ActionMoveBy * ActionMoveBy::reverse() const
{
return new ActionMoveBy(m_nTotalDuration / 1000.0f, CVector(-m_MoveVector.x, -m_MoveVector.y));
}

View File

@ -0,0 +1,29 @@
#include "..\easy2d.h"
ActionMoveTo::ActionMoveTo(float duration, CPoint pos) :
ActionMoveBy(duration, CVector())
{
m_EndPos = pos;
}
ActionMoveTo::~ActionMoveTo()
{
}
ActionMoveTo * ActionMoveTo::copy()
{
auto a = new ActionMoveTo(*this);
a->_reset();
return a;
}
void ActionMoveTo::_init()
{
ActionMoveBy::_init();
m_MoveVector = m_EndPos - m_BeginPos;
}
void ActionMoveTo::_reset()
{
ActionMoveBy::_reset();
}

View File

@ -0,0 +1,41 @@
#include "..\easy2d.h"
ActionNeverStop::ActionNeverStop(Action * action) :
m_Action(action)
{
m_Action->retain();
}
ActionNeverStop::~ActionNeverStop()
{
SAFE_RELEASE(m_Action);
}
ActionNeverStop * ActionNeverStop::copy()
{
return new ActionNeverStop(m_Action->copy());
}
void ActionNeverStop::_init()
{
m_Action->m_pParent = m_pParent;
m_Action->_init();
}
bool ActionNeverStop::_exec(LARGE_INTEGER nNow)
{
if (m_bStop) return true;
if (!m_bRunning) return false;
if (m_Action->_exec(nNow))
{
m_Action->_reset();
}
// ÓÀ²»½áÊø
return false;
}
void ActionNeverStop::_reset()
{
m_Action->_reset();
}

View File

@ -0,0 +1,54 @@
#include "..\easy2d.h"
ActionOpacityBy::ActionOpacityBy(float duration, float opacity) :
Animation(duration)
{
m_nVariation = opacity;
}
ActionOpacityBy::~ActionOpacityBy()
{
}
void ActionOpacityBy::_init()
{
Animation::_init();
m_nBeginVal = m_pParent->getOpacity();
}
bool ActionOpacityBy::_exec(LARGE_INTEGER nNow)
{
if (m_bStop) return true;
if (!m_bRunning) return false;
while (Animation::_exec(nNow))
{
// 计算移动位置
float scale = float(m_nDuration) / m_nTotalDuration;
// 移动 Sprite
m_pParent->setOpacity(m_nBeginVal + m_nVariation * scale);
// 判断动作是否结束
if (m_nDuration >= m_nTotalDuration)
{
return true;
}
}
return false;
}
void ActionOpacityBy::_reset()
{
Animation::_reset();
}
ActionOpacityBy * ActionOpacityBy::copy()
{
auto a = new ActionOpacityBy(*this);
a->_reset();
return a;
}
ActionOpacityBy * ActionOpacityBy::reverse() const
{
return new ActionOpacityBy(m_nTotalDuration / 1000.0f, -m_nVariation);
}

View File

@ -0,0 +1,29 @@
#include "..\easy2d.h"
ActionOpacityTo::ActionOpacityTo(float duration, float opacity) :
ActionOpacityBy(duration, 0)
{
m_nEndVal = opacity;
}
ActionOpacityTo::~ActionOpacityTo()
{
}
ActionOpacityTo * ActionOpacityTo::copy()
{
auto a = new ActionOpacityTo(*this);
a->_reset();
return a;
}
void ActionOpacityTo::_init()
{
ActionOpacityBy::_init();
m_nVariation = m_nEndVal - m_nBeginVal;
}
void ActionOpacityTo::_reset()
{
ActionOpacityBy::_reset();
}

View File

@ -0,0 +1,56 @@
#include "..\easy2d.h"
ActionScaleBy::ActionScaleBy(float duration, float scaleX, float scaleY) :
Animation(duration)
{
m_nVariationX = scaleX;
m_nVariationY = scaleY;
}
ActionScaleBy::~ActionScaleBy()
{
}
void ActionScaleBy::_init()
{
Animation::_init();
m_nBeginScaleX = m_pParent->getScaleX();
m_nBeginScaleY = m_pParent->getScaleY();
}
bool ActionScaleBy::_exec(LARGE_INTEGER nNow)
{
if (m_bStop) return true;
if (!m_bRunning) return false;
while (Animation::_exec(nNow))
{
// 计算移动位置
float scale = float(m_nDuration) / m_nTotalDuration;
// 移动 Sprite
m_pParent->setScale(m_nBeginScaleX + m_nVariationX * scale, m_nBeginScaleX + m_nVariationX * scale);
// 判断动作是否结束
if (m_nDuration >= m_nTotalDuration)
{
return true;
}
}
return false;
}
void ActionScaleBy::_reset()
{
Animation::_reset();
}
ActionScaleBy * ActionScaleBy::copy()
{
auto a = new ActionScaleBy(*this);
a->_reset();
return a;
}
ActionScaleBy * ActionScaleBy::reverse() const
{
return new ActionScaleBy(m_nTotalDuration / 1000.0f, -m_nVariationX, -m_nVariationY);
}

View File

@ -0,0 +1,31 @@
#include "..\easy2d.h"
ActionScaleTo::ActionScaleTo(float duration, float scaleX, float scaleY) :
ActionScaleBy(duration, 0, 0)
{
m_nEndScaleX = scaleX;
m_nEndScaleY = scaleY;
}
ActionScaleTo::~ActionScaleTo()
{
}
ActionScaleTo * ActionScaleTo::copy()
{
auto a = new ActionScaleTo(*this);
a->_reset();
return a;
}
void ActionScaleTo::_init()
{
ActionScaleBy::_init();
m_nVariationX = m_nEndScaleX - m_nBeginScaleX;
m_nVariationY = m_nEndScaleY - m_nBeginScaleY;
}
void ActionScaleTo::_reset()
{
ActionScaleBy::_reset();
}

View File

@ -0,0 +1,89 @@
#include "..\easy2d.h"
#include <stdarg.h>
ActionSequence::ActionSequence(int number, Action * action1, ...) :
m_nActionIndex(0)
{
va_list params;
va_start(params, number);
while (number > 0)
{
Action* arg = va_arg(params, Action*);
arg->retain();
m_vActions.push_back(arg);
number--;
}
va_end(params);
}
ActionSequence::~ActionSequence()
{
for (auto action : m_vActions)
{
SAFE_RELEASE(action);
}
}
void ActionSequence::_init()
{
for (auto action : m_vActions)
{
action->m_pParent = m_pParent;
}
m_vActions[0]->_init();
}
bool ActionSequence::_exec(LARGE_INTEGER nNow)
{
if (m_bStop) return true;
if (!m_bRunning) return false;
if (m_vActions[m_nActionIndex]->_exec(nNow))
{
m_nActionIndex++;
if (m_nActionIndex == m_vActions.size())
{
return true;
}
else
{
m_vActions[m_nActionIndex]->_init();
}
}
return false;
}
void ActionSequence::_reset()
{
for (auto action : m_vActions)
{
action->_reset();
}
m_nActionIndex = 0;
}
ActionSequence * ActionSequence::copy()
{
auto a = new ActionSequence(*this);
a->_reset();
return a;
}
ActionSequence * ActionSequence::reverse() const
{
// 复制一个相同的动作
auto a = new ActionSequence(*this);
a->_reset();
a->m_bRunning = true;
a->m_bStop = false;
// 将动作顺序逆序排列
a->m_vActions.reserve(m_vActions.size());
// 将所有动作逆向运行
for (auto action : a->m_vActions)
{
action->reverse();
}
return a;
}

View File

@ -0,0 +1,73 @@
#include "..\easy2d.h"
ActionTwo::ActionTwo(Action * actionFirst, Action * actionSecond) :
m_FirstAction(actionFirst),
m_SecondAction(actionSecond)
{
if (m_FirstAction) m_FirstAction->retain();
if (m_SecondAction) m_SecondAction->retain();
}
ActionTwo::~ActionTwo()
{
SAFE_RELEASE(m_FirstAction);
SAFE_RELEASE(m_SecondAction);
}
ActionTwo * ActionTwo::copy()
{
auto a = new ActionTwo(*this);
a->_reset();
return a;
}
ActionTwo * ActionTwo::reverse() const
{
return new ActionTwo(m_SecondAction->copy(), m_FirstAction->copy());
}
void ActionTwo::_init()
{
m_FirstAction->m_pParent = m_pParent;
m_FirstAction->_init();
m_SecondAction->m_pParent = m_pParent;
}
bool ActionTwo::_exec(LARGE_INTEGER nNow)
{
if (m_bStop) return true;
if (!m_bRunning) return false;
if (m_FirstAction)
{
if (m_FirstAction->_exec(nNow))
{
// 返回 true 表示第一个动作已经结束,删除这个
// 动作,并初始化第二个动作
SAFE_RELEASE(m_FirstAction);
m_FirstAction = nullptr;
m_SecondAction->_init();
}
}
else if (m_SecondAction)
{
if (m_SecondAction->_exec(nNow))
{
SAFE_RELEASE(m_SecondAction);
m_SecondAction = nullptr;
return true;
}
}
else
{
return true;
}
return false;
}
void ActionTwo::_reset()
{
if (m_FirstAction) m_FirstAction->_reset();
if (m_SecondAction) m_SecondAction->_reset();
}

View File

@ -0,0 +1,37 @@
#include "..\easy2d.h"
Animation::Animation(float duration)
{
m_nDuration = 0;
m_nTotalDuration = UINT(duration * 1000);
}
Animation::~Animation()
{
}
void Animation::_init()
{
// 记录当前时间
QueryPerformanceCounter(&m_nLast);
}
bool Animation::_exec(LARGE_INTEGER nNow)
{
// 判断时间间隔是否足够
if (nNow.QuadPart - m_nLast.QuadPart > m_nAnimationInterval.QuadPart)
{
// 用求余的方法重新记录时间
m_nLast.QuadPart = nNow.QuadPart - (nNow.QuadPart % m_nAnimationInterval.QuadPart);
m_nDuration += m_nMilliSeconds;
return true;
}
return false;
}
void Animation::_reset()
{
m_nDuration = 0;
// 重新记录当前时间
QueryPerformanceCounter(&m_nLast);
}

View File

@ -1,5 +1,5 @@
#include "easy2d.h"
#include "EasyX\easyx.h"
#include "..\easy2d.h"
#include "..\EasyX\easyx.h"
#include <time.h>
#include <assert.h>
#include <imm.h>
@ -7,9 +7,6 @@
#include <mmsystem.h>
#pragma comment(lib, "winmm.lib")
// Easy2D 版本号
#define E2D_VERSION _T("1.0.4")
// App 的唯一实例
static App * s_pInstance = nullptr;
// 坐标原点的物理坐标
@ -17,11 +14,9 @@ static int originX = 0;
static int originY = 0;
App::App() :
m_currentScene(nullptr),
m_nextScene(nullptr),
m_CurrentScene(nullptr),
m_NextScene(nullptr),
m_bRunning(false),
m_nWidth(0),
m_nHeight(0),
m_nWindowMode(0)
{
assert(!s_pInstance); // 不能同时存在两个 App 实例
@ -119,7 +114,7 @@ int App::run()
void App::_initGraph()
{
// 创建绘图环境
initgraph(m_nWidth, m_nHeight, m_nWindowMode);
initgraph(m_Size.cx, m_Size.cy, m_nWindowMode);
// 隐藏当前窗口(防止在加载阶段显示黑窗口)
ShowWindow(GetHWnd(), SW_HIDE);
// 获取屏幕分辨率
@ -157,47 +152,53 @@ void App::_initGraph()
void App::_mainLoop()
{
// 下一场景指针不为空时,切换场景
if (m_nextScene)
if (m_NextScene)
{
// 执行当前场景的 onExit 函数
if (m_currentScene)
if (m_CurrentScene)
{
m_currentScene->onExit();
m_CurrentScene->onExit();
}
// 进入下一场景
_enterNextScene();
// 执行当前场景的 onEnter 函数
m_currentScene->onEnter();
m_CurrentScene->onEnter();
}
// 断言当前场景非空
assert(m_currentScene);
assert(m_CurrentScene);
cleardevice(); // 清空画面
m_currentScene->_onDraw(); // 绘制当前场景
m_CurrentScene->_onDraw(); // 绘制当前场景
FlushBatchDraw(); // 刷新画面
// 其他执行程序
MouseMsg::__exec(); // 鼠标检测
KeyMsg::__exec(); // 键盘按键检测
Timer::__exec(); // 定时器执行程序
ActionManager::__exec(); // 动作管理器执行程序
FreePool::__flush(); // 刷新内存池
}
void App::createWindow(int width, int height, int mode)
{
// 保存窗口信息
m_nWidth = width;
m_nHeight = height;
m_Size.cx = width;
m_Size.cy = height;
m_nWindowMode = mode;
// 创建窗口
_initGraph();
}
void App::createWindow(CSize size, int mode)
{
createWindow(size.cx, size.cy, mode);
}
void App::createWindow(tstring title, int width, int height, int mode)
{
// 保存窗口信息
m_nWidth = width;
m_nHeight = height;
m_Size.cx = width;
m_Size.cy = height;
m_nWindowMode = mode;
m_sTitle = title;
m_sAppName = title;
@ -205,10 +206,15 @@ void App::createWindow(tstring title, int width, int height, int mode)
_initGraph();
}
void App::createWindow(tstring title, CSize size, int mode)
{
createWindow(title, size.cx, size.cy, mode);
}
void App::setWindowSize(int width, int height)
{
// 游戏正在运行时才允许修改窗口大小
assert(m_bRunning);
assert(s_pInstance->m_bRunning);
// 获取屏幕分辨率
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
@ -235,17 +241,22 @@ void App::setWindowSize(int width, int height)
reset();
}
void App::setWindowSize(CSize size)
{
setWindowSize(size.cx, size.cy);
}
void App::setWindowTitle(tstring title)
{
// 设置窗口标题
SetWindowText(GetHWnd(), title.c_str());
// 保存当前标题,用于修改窗口大小时恢复标题
m_sTitle = title;
s_pInstance->m_sTitle = title;
}
tstring App::getWindowTitle()
{
return m_sTitle;
return s_pInstance->m_sTitle;
}
void App::close()
@ -256,38 +267,38 @@ void App::close()
void App::enterScene(Scene * scene, bool save)
{
// 保存下一场景的指针
m_nextScene = scene;
s_pInstance->m_NextScene = scene;
// 切换场景时,是否保存当前场景
m_bSaveScene = save;
s_pInstance->m_bSaveScene = save;
}
void App::backScene()
{
// 从栈顶取出场景指针,作为下一场景
m_nextScene = m_sceneStack.top();
s_pInstance->m_NextScene = s_pInstance->m_SceneStack.top();
// 不保存当前场景
m_bSaveScene = false;
s_pInstance->m_bSaveScene = false;
}
void App::clearScene()
{
// 清空场景栈
while (m_sceneStack.size())
while (s_pInstance->m_SceneStack.size())
{
auto temp = m_sceneStack.top();
auto temp = s_pInstance->m_SceneStack.top();
SAFE_DELETE(temp);
m_sceneStack.pop();
s_pInstance->m_SceneStack.pop();
}
}
void App::setAppName(tstring appname)
{
m_sAppName = appname;
s_pInstance->m_sAppName = appname;
}
tstring App::getAppName() const
tstring App::getAppName()
{
return m_sAppName;
return s_pInstance->m_sAppName;
}
void App::setBkColor(COLORREF color)
@ -298,32 +309,32 @@ void App::setBkColor(COLORREF color)
void App::_enterNextScene()
{
// 若下一场景处于栈顶,说明正在返回上一场景
if (m_sceneStack.size() && m_nextScene == m_sceneStack.top())
if (m_SceneStack.size() && m_NextScene == m_SceneStack.top())
{
m_sceneStack.pop(); // 删除栈顶场景
m_SceneStack.pop(); // 删除栈顶场景
}
if (m_bSaveScene)
{
m_sceneStack.push(m_currentScene); // 若要保存当前场景,把它的指针放到栈顶
m_SceneStack.push(m_CurrentScene); // 若要保存当前场景,把它的指针放到栈顶
}
else
{
SAFE_DELETE(m_currentScene); // 否则删除当前场景
SAFE_DELETE(m_CurrentScene); // 否则删除当前场景
}
m_currentScene = m_nextScene; // 切换场景
m_nextScene = nullptr; // 下一场景置空
m_CurrentScene = m_NextScene; // 切换场景
m_NextScene = nullptr; // 下一场景置空
}
void App::quit()
{
m_bRunning = false;
s_pInstance->m_bRunning = false;
}
void App::end()
{
m_bRunning = false;
s_pInstance->m_bRunning = false;
}
void App::reset()
@ -337,12 +348,7 @@ void App::reset()
Scene * App::getCurrentScene()
{
// 获取当前场景的指针
return m_currentScene;
}
LPCTSTR App::getVersion()
{
return E2D_VERSION;
return s_pInstance->m_CurrentScene;
}
void App::setFPS(DWORD fps)
@ -350,30 +356,30 @@ void App::setFPS(DWORD fps)
// 设置画面帧率,以毫秒为单位
LARGE_INTEGER nFreq;
QueryPerformanceFrequency(&nFreq);
m_nAnimationInterval.QuadPart = (LONGLONG)(1.0 / fps * nFreq.QuadPart);
s_pInstance->m_nAnimationInterval.QuadPart = (LONGLONG)(1.0 / fps * nFreq.QuadPart);
}
int App::getWidth() const
int App::getWidth()
{
return m_nWidth;
return s_pInstance->m_Size.cx;
}
int App::getHeight() const
int App::getHeight()
{
return m_nHeight;
return s_pInstance->m_Size.cy;
}
void App::free()
{
// 释放场景内存
SAFE_DELETE(m_currentScene);
SAFE_DELETE(m_nextScene);
SAFE_DELETE(m_CurrentScene);
SAFE_DELETE(m_NextScene);
// 清空场景栈
while (m_sceneStack.size())
while (m_SceneStack.size())
{
auto temp = m_sceneStack.top();
auto temp = m_SceneStack.top();
SAFE_DELETE(temp);
m_sceneStack.pop();
m_SceneStack.pop();
}
// 删除所有定时器
Timer::clearAllTimers();

View File

@ -1,4 +1,5 @@
#include "easy2d.h"
#include "..\easy2d.h"
#include <assert.h>
// FreePool 释放池的实现机制:
/// Object 类中的引用计数m_nRef保证了指针的使用安全
@ -34,9 +35,12 @@ void FreePool::__flush()
void FreePool::__add(Object * nptr)
{
#ifdef _DEBUG
for (auto o : pool)
{
if (o == nptr) return; // 不得有重复的指针存在
assert(o != nptr); // 不得有重复的指针存在
}
#endif
pool.push_back(nptr); // 将一个对象放入释放池中
}

View File

@ -1,4 +1,4 @@
#include "easy2d.h"
#include "..\easy2d.h"
#include <assert.h>
Scene::Scene()
@ -77,8 +77,7 @@ void Scene::add(Node * child, int zOrder)
bool Scene::del(Node * child)
{
// 断言节点非空
assert(child);
if (child == nullptr) return false;
// 寻找是否有相同节点
std::vector<Node*>::iterator iter;

View File

@ -335,35 +335,57 @@
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="App.cpp" />
<ClCompile Include="FreePool.cpp" />
<ClCompile Include="Action\Action.cpp" />
<ClCompile Include="Action\ActionCallback.cpp" />
<ClCompile Include="Action\ActionDelay.cpp" />
<ClCompile Include="Action\ActionFrames.cpp" />
<ClCompile Include="Action\ActionMoveTo.cpp" />
<ClCompile Include="Action\ActionMoveBy.cpp" />
<ClCompile Include="Action\ActionNeverStop.cpp" />
<ClCompile Include="Action\ActionOpacityTo.cpp" />
<ClCompile Include="Action\ActionOpacityBy.cpp" />
<ClCompile Include="Action\ActionScaleBy.cpp" />
<ClCompile Include="Action\ActionScaleTo.cpp" />
<ClCompile Include="Action\ActionSequence.cpp" />
<ClCompile Include="Action\ActionTwo.cpp" />
<ClCompile Include="Action\Animation.cpp" />
<ClCompile Include="Base\App.cpp" />
<ClCompile Include="Base\FreePool.cpp" />
<ClCompile Include="Base\Scene.cpp" />
<ClCompile Include="Msg\KeyMsg.cpp" />
<ClCompile Include="Msg\MouseMsg.cpp" />
<ClCompile Include="Node\BatchNode.cpp" />
<ClCompile Include="Node\Button\Button.cpp" />
<ClCompile Include="Node\Button\ImageButton.cpp" />
<ClCompile Include="Node\Button\TextButton.cpp" />
<ClCompile Include="Node\Image.cpp" />
<ClCompile Include="Node\Layer.cpp" />
<ClCompile Include="Node\MouseNode.cpp" />
<ClCompile Include="Node\Node.cpp" />
<ClCompile Include="Node\Shape\Circle.cpp" />
<ClCompile Include="Node\Shape\Rectangle.cpp" />
<ClCompile Include="Node\Shape\Shape.cpp" />
<ClCompile Include="Node\Sprite\Sprite.cpp" />
<ClCompile Include="Node\Sprite\SpriteFrame.cpp" />
<ClCompile Include="Node\Text.cpp" />
<ClCompile Include="Object.cpp" />
<ClCompile Include="Scene.cpp" />
<ClCompile Include="Object\BatchNode.cpp" />
<ClCompile Include="Object\BatchSprite.cpp" />
<ClCompile Include="Object\Button\Button.cpp" />
<ClCompile Include="Object\Button\ImageButton.cpp" />
<ClCompile Include="Object\Button\TextButton.cpp" />
<ClCompile Include="Object\Image.cpp" />
<ClCompile Include="Object\Layer.cpp" />
<ClCompile Include="Object\MouseNode.cpp" />
<ClCompile Include="Object\Node.cpp" />
<ClCompile Include="Object\RectNode.cpp" />
<ClCompile Include="Object\Shape\Circle.cpp" />
<ClCompile Include="Object\Shape\Rectangle.cpp" />
<ClCompile Include="Object\Shape\Shape.cpp" />
<ClCompile Include="Object\Sprite.cpp" />
<ClCompile Include="Object\Text.cpp" />
<ClCompile Include="Object\Object.cpp" />
<ClCompile Include="Style\Color.cpp" />
<ClCompile Include="Style\FillStyle.cpp" />
<ClCompile Include="Style\FontStyle.cpp" />
<ClCompile Include="Style\LineStyle.cpp" />
<ClCompile Include="Tool\ActionManager.cpp" />
<ClCompile Include="Tool\FileUtils.cpp" />
<ClCompile Include="Tool\MusicUtils.cpp" />
<ClCompile Include="Tool\Timer.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="e2daction.h" />
<ClInclude Include="e2dbase.h" />
<ClInclude Include="e2dmsg.h" />
<ClInclude Include="e2dobj.h" />
<ClInclude Include="e2dstyle.h" />
<ClInclude Include="e2dtool.h" />
<ClInclude Include="easy2d.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

View File

@ -19,26 +19,26 @@
<Filter Include="源文件\Tool">
<UniqueIdentifier>{682a1a3c-39d8-4ac9-ba03-fa90c089c9ab}</UniqueIdentifier>
</Filter>
<Filter Include="源文件\Node">
<Filter Include="源文件\Object">
<UniqueIdentifier>{d6778635-8947-4f9b-9388-dd088642b5b2}</UniqueIdentifier>
</Filter>
<Filter Include="源文件\Node\Sprite">
<UniqueIdentifier>{e5ec6183-113b-4140-8285-18b18ea37d15}</UniqueIdentifier>
</Filter>
<Filter Include="源文件\Node\Shape">
<Filter Include="源文件\Object\Shape">
<UniqueIdentifier>{065a3244-7169-4a45-bc9f-f2a80d8a9759}</UniqueIdentifier>
</Filter>
<Filter Include="源文件\Msg">
<UniqueIdentifier>{72dbabab-8278-4ee4-917f-bfffb474a51b}</UniqueIdentifier>
</Filter>
<Filter Include="源文件\Node\Button">
<Filter Include="源文件\Object\Button">
<UniqueIdentifier>{bdcd902b-b53d-4537-9632-76ea14c141a0}</UniqueIdentifier>
</Filter>
<Filter Include="源文件\Action">
<UniqueIdentifier>{e1501580-8f69-4ad6-a9f1-76d825572c3d}</UniqueIdentifier>
</Filter>
<Filter Include="源文件\Base">
<UniqueIdentifier>{261633d3-3814-40c7-bd6d-201ede6c6ade}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Scene.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="Style\Color.cpp">
<Filter>源文件\Style</Filter>
</ClCompile>
@ -54,44 +54,35 @@
<ClCompile Include="Style\FontStyle.cpp">
<Filter>源文件\Style</Filter>
</ClCompile>
<ClCompile Include="Node\BatchNode.cpp">
<Filter>源文件\Node</Filter>
<ClCompile Include="Object\BatchNode.cpp">
<Filter>源文件\Object</Filter>
</ClCompile>
<ClCompile Include="Node\Image.cpp">
<Filter>源文件\Node</Filter>
<ClCompile Include="Object\Image.cpp">
<Filter>源文件\Object</Filter>
</ClCompile>
<ClCompile Include="Node\Node.cpp">
<Filter>源文件\Node</Filter>
<ClCompile Include="Object\Node.cpp">
<Filter>源文件\Object</Filter>
</ClCompile>
<ClCompile Include="Node\Text.cpp">
<Filter>源文件\Node</Filter>
<ClCompile Include="Object\Text.cpp">
<Filter>源文件\Object</Filter>
</ClCompile>
<ClCompile Include="Node\Sprite\Sprite.cpp">
<Filter>源文件\Node\Sprite</Filter>
<ClCompile Include="Object\Shape\Circle.cpp">
<Filter>源文件\Object\Shape</Filter>
</ClCompile>
<ClCompile Include="Node\Sprite\SpriteFrame.cpp">
<Filter>源文件\Node\Sprite</Filter>
<ClCompile Include="Object\Shape\Rectangle.cpp">
<Filter>源文件\Object\Shape</Filter>
</ClCompile>
<ClCompile Include="Node\Shape\Circle.cpp">
<Filter>源文件\Node\Shape</Filter>
<ClCompile Include="Object\Shape\Shape.cpp">
<Filter>源文件\Object\Shape</Filter>
</ClCompile>
<ClCompile Include="Node\Shape\Rectangle.cpp">
<Filter>源文件\Node\Shape</Filter>
</ClCompile>
<ClCompile Include="Node\Shape\Shape.cpp">
<Filter>源文件\Node\Shape</Filter>
</ClCompile>
<ClCompile Include="Node\MouseNode.cpp">
<Filter>源文件\Node</Filter>
<ClCompile Include="Object\MouseNode.cpp">
<Filter>源文件\Object</Filter>
</ClCompile>
<ClCompile Include="Style\LineStyle.cpp">
<Filter>源文件\Style</Filter>
</ClCompile>
<ClCompile Include="FreePool.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="Object.cpp">
<Filter>源文件</Filter>
<ClCompile Include="Object\Object.cpp">
<Filter>源文件\Object</Filter>
</ClCompile>
<ClCompile Include="Style\FillStyle.cpp">
<Filter>源文件\Style</Filter>
@ -102,23 +93,101 @@
<ClCompile Include="Msg\KeyMsg.cpp">
<Filter>源文件\Msg</Filter>
</ClCompile>
<ClCompile Include="App.cpp">
<Filter>源文件</Filter>
<ClCompile Include="Object\Button\Button.cpp">
<Filter>源文件\Object\Button</Filter>
</ClCompile>
<ClCompile Include="Node\Button\Button.cpp">
<Filter>源文件\Node\Button</Filter>
<ClCompile Include="Object\Button\ImageButton.cpp">
<Filter>源文件\Object\Button</Filter>
</ClCompile>
<ClCompile Include="Node\Button\ImageButton.cpp">
<Filter>源文件\Node\Button</Filter>
<ClCompile Include="Object\Button\TextButton.cpp">
<Filter>源文件\Object\Button</Filter>
</ClCompile>
<ClCompile Include="Node\Button\TextButton.cpp">
<Filter>源文件\Node\Button</Filter>
<ClCompile Include="Object\Layer.cpp">
<Filter>源文件\Object</Filter>
</ClCompile>
<ClCompile Include="Node\Layer.cpp">
<Filter>源文件\Node</Filter>
<ClCompile Include="Action\Action.cpp">
<Filter>源文件\Action</Filter>
</ClCompile>
<ClCompile Include="Base\App.cpp">
<Filter>源文件\Base</Filter>
</ClCompile>
<ClCompile Include="Base\FreePool.cpp">
<Filter>源文件\Base</Filter>
</ClCompile>
<ClCompile Include="Base\Scene.cpp">
<Filter>源文件\Base</Filter>
</ClCompile>
<ClCompile Include="Action\ActionMoveBy.cpp">
<Filter>源文件\Action</Filter>
</ClCompile>
<ClCompile Include="Action\ActionMoveTo.cpp">
<Filter>源文件\Action</Filter>
</ClCompile>
<ClCompile Include="Action\ActionTwo.cpp">
<Filter>源文件\Action</Filter>
</ClCompile>
<ClCompile Include="Action\ActionNeverStop.cpp">
<Filter>源文件\Action</Filter>
</ClCompile>
<ClCompile Include="Object\Sprite.cpp">
<Filter>源文件\Object</Filter>
</ClCompile>
<ClCompile Include="Action\ActionCallback.cpp">
<Filter>源文件\Action</Filter>
</ClCompile>
<ClCompile Include="Action\ActionDelay.cpp">
<Filter>源文件\Action</Filter>
</ClCompile>
<ClCompile Include="Tool\ActionManager.cpp">
<Filter>源文件\Tool</Filter>
</ClCompile>
<ClCompile Include="Action\ActionSequence.cpp">
<Filter>源文件\Action</Filter>
</ClCompile>
<ClCompile Include="Action\ActionFrames.cpp">
<Filter>源文件\Action</Filter>
</ClCompile>
<ClCompile Include="Action\ActionScaleBy.cpp">
<Filter>源文件\Action</Filter>
</ClCompile>
<ClCompile Include="Action\ActionScaleTo.cpp">
<Filter>源文件\Action</Filter>
</ClCompile>
<ClCompile Include="Action\Animation.cpp">
<Filter>源文件\Action</Filter>
</ClCompile>
<ClCompile Include="Action\ActionOpacityTo.cpp">
<Filter>源文件\Action</Filter>
</ClCompile>
<ClCompile Include="Action\ActionOpacityBy.cpp">
<Filter>源文件\Action</Filter>
</ClCompile>
<ClCompile Include="Object\BatchSprite.cpp">
<Filter>源文件\Object</Filter>
</ClCompile>
<ClCompile Include="Object\RectNode.cpp">
<Filter>源文件\Object</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="e2daction.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="e2dbase.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="e2dmsg.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="e2dobj.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="e2dstyle.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="e2dtool.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="easy2d.h">
<Filter>头文件</Filter>
</ClInclude>

View File

@ -1,5 +1,6 @@
#include "..\easy2d.h"
#include "..\EasyX\easyx.h"
#include "..\e2dmsg.h"
// 鼠标监听回调函数的容器
static std::vector<MouseMsg*> s_vMouseMsg;
@ -107,6 +108,11 @@ int MouseMsg::getY()
return s_mouseMsg.y;
}
CPoint MouseMsg::getPos()
{
return CPoint(s_mouseMsg.x, s_mouseMsg.y);
}
int MouseMsg::getWheel()
{
return s_mouseMsg.wheel;

View File

@ -1,44 +0,0 @@
#include "..\..\Easy2d.h"
#include "..\..\EasyX\easyx.h"
Button::Button() :
m_bEnable(true)
{
}
Button::~Button()
{
}
bool Button::_exec(bool active)
{
// 按钮是否启用
if (!m_bEnable)
{
return false;
}
return MouseNode::_exec(active);
}
void Button::_onDraw()
{
// 按钮是否启用
if (!m_bEnable)
{
// 未启用时,绘制 Disable 状态
_onDisable();
return;
}
MouseNode::_onDraw();
}
bool Button::isEnable()
{
return m_bEnable;
}
void Button::setEnable(bool enable)
{
m_bEnable = enable;
}

View File

@ -1,6 +1,5 @@
#include "..\easy2d.h"
#include "..\EasyX\easyx.h"
#include <assert.h>
BatchNode::BatchNode()
{
@ -22,7 +21,6 @@ bool BatchNode::_exec(bool active)
// 逆序遍历所有子节点
for (int i = int(m_vChildren.size() - 1); i >= 0; i--)
{
assert(m_vChildren[i]);
if (m_vChildren[i]->_exec(active))
{
active = false;
@ -41,19 +39,18 @@ void BatchNode::_onDraw()
}
// 在相对位置绘制子节点
App::setOrigin(App::getOriginX() + m_nX, App::getOriginY() + m_nY);
App::setOrigin(App::getOriginX() + getX(), App::getOriginY() + getY());
for (auto child : m_vChildren)
{
assert(child);
child->_onDraw();
}
App::setOrigin(App::getOriginX() - m_nX, App::getOriginY() - m_nY);
App::setOrigin(App::getOriginX() - getX(), App::getOriginY() - getY());
}
void BatchNode::add(Node * child, int z_Order)
{
// 断言添加的节点非空
assert(child);
if (child == nullptr) return;
// 设置节点的父场景
child->setParentScene(this->getParentScene());
// 设置节点在批量节点中的 z 轴顺序
@ -83,8 +80,7 @@ void BatchNode::add(Node * child, int z_Order)
bool BatchNode::del(Node * child)
{
// 断言节点非空
assert(child);
if (child == nullptr) return false;
// 寻找是否有相同节点
std::vector<Node*>::iterator iter;

View File

@ -0,0 +1,174 @@
#include "..\easy2d.h"
BatchSprite::BatchSprite()
{
}
BatchSprite::~BatchSprite()
{
}
void BatchSprite::addSprite(Sprite * sprite, int z_Order)
{
if (sprite == nullptr) return;
// 设置节点的父场景
sprite->setParentScene(this->getParentScene());
// 设置节点在批量节点中的 z 轴顺序
sprite->setZOrder(z_Order);
// 对象的引用计数加一
sprite->retain();
// 按 z 轴顺序插入节点
size_t size = m_vSprites.size();
for (unsigned i = 0; i <= size; i++)
{
if (i != size)
{
if (z_Order < m_vSprites.at(i)->getZOrder())
{
m_vSprites.insert(m_vSprites.begin() + i, sprite);
break;
}
}
else
{
m_vSprites.push_back(sprite);
break;
}
}
}
bool BatchSprite::delSprite(Sprite * sprite)
{
if (sprite == nullptr) return false;
// 寻找是否有相同节点
std::vector<Sprite*>::iterator iter;
for (iter = m_vSprites.begin(); iter != m_vSprites.end(); iter++)
{
// 找到相同节点
if ((*iter) == sprite)
{
// 对象的引用计数减一
(*iter)->release();
// 去掉该节点
m_vSprites.erase(iter);
return true;
}
}
return false;
}
void BatchSprite::clearAllSprites()
{
// 所有节点的引用计数减一
for (auto s : m_vSprites)
{
s->release();
}
// 清空储存节点的容器
m_vSprites.clear();
}
bool BatchSprite::_exec(bool active)
{
// 批量节点是否显示
if (!m_bDisplay)
{
return false;
}
// 逆序遍历所有子节点
for (int i = int(m_vSprites.size() - 1); i >= 0; i--)
{
if (m_vSprites[i]->_exec(active))
{
active = false;
}
}
// 若子节点取得了画面焦点,则该节点也取得了焦点
return !active;
}
void BatchSprite::_onDraw()
{
// 节点是否显示
if (!m_bDisplay)
{
return;
}
// 在相对位置绘制子节点
App::setOrigin(App::getOriginX() + getX(), App::getOriginY() + getY());
for (auto sprite : m_vSprites)
{
sprite->_onDraw();
}
App::setOrigin(App::getOriginX() - getX(), App::getOriginY() - getY());
}
Sprite * BatchSprite::isCollisionWith(Sprite * sprite)
{
for (int i = int(m_vSprites.size() - 1); i >= 0; i--)
{
if (m_vSprites[i]->isCollisionWith(sprite))
{
return m_vSprites[i];
}
}
return nullptr;
}
Sprite * BatchSprite::isPointIn(CPoint point)
{
for (int i = int(m_vSprites.size() - 1); i >= 0; i--)
{
if (m_vSprites[i]->isPointIn(point))
{
return m_vSprites[i];
}
}
return nullptr;
}
float BatchSprite::getScaleX() const
{
return m_fScaleX;
}
float BatchSprite::getScaleY() const
{
return m_fScaleY;
}
float BatchSprite::getOpacity() const
{
return m_nAlpha / 255.0f;
}
void BatchSprite::setScale(float scaleX, float scaleY)
{
m_fScaleX = scaleX;
m_fScaleY = scaleY;
for (auto s : m_vSprites)
{
s->setScale(scaleX, scaleY);
}
}
void BatchSprite::setOpacity(float opacity)
{
m_nAlpha = BYTE(min(max(opacity, 0), 1) * 255);
for (auto s : m_vSprites)
{
s->setOpacity(opacity);
}
}
void BatchSprite::setImage(Image * image)
{
for (auto s : m_vSprites)
{
s->setImage(image);
}
}

View File

@ -0,0 +1,81 @@
#include "..\..\easy2d.h"
#include "..\..\EasyX\easyx.h"
#include "..\..\e2dobj.h"
Button::Button() :
m_bEnable(true)
{
}
Button::~Button()
{
}
bool Button::_exec(bool active)
{
// 按钮是否启用
if (!m_bEnable)
{
return false;
}
return MouseNode::_exec(active);
}
void Button::_onDraw()
{
// 按钮是否启用
if (!m_bEnable)
{
// 未启用时,绘制 Disable 状态
_onDisable();
return;
}
MouseNode::_onDraw();
}
bool Button::isEnable()
{
return m_bEnable;
}
void Button::setEnable(bool enable)
{
m_bEnable = enable;
}
void Button::setX(int x)
{
MouseNode::setX(x);
_resetPosition();
}
void Button::setY(int y)
{
MouseNode::setY(y);
_resetPosition();
}
void Button::setPos(int x, int y)
{
MouseNode::setPos(x, y);
_resetPosition();
}
void Button::setPos(CPoint p)
{
MouseNode::setPos(p);
_resetPosition();
}
void Button::move(int x, int y)
{
MouseNode::move(x, y);
_resetPosition();
}
void Button::move(CVector v)
{
MouseNode::move(v);
_resetPosition();
}

View File

@ -1,4 +1,4 @@
#include "..\..\Easy2d.h"
#include "..\..\easy2d.h"
ImageButton::ImageButton() :
@ -7,8 +7,6 @@ ImageButton::ImageButton() :
m_pSelectedImage(nullptr),
m_pUnableImage(nullptr)
{
m_nWidth = 0;
m_nHeight = 0;
}
ImageButton::ImageButton(LPCTSTR image) :
@ -32,6 +30,26 @@ ImageButton::~ImageButton()
SAFE_RELEASE(m_pUnableImage);
}
void ImageButton::_setStatus(Status status)
{
if (m_eStatus != status)
{
if (status == MOUSEIN)
{
if (m_pMouseInImage) setRect(m_pMouseInImage->getRect());
}
else if (status == SELECTED)
{
if (m_pSelectedImage) setRect(m_pSelectedImage->getRect());
}
else
{
setRect(m_pNormalImage->getRect());
}
}
MouseNode::_setStatus(status);
}
void ImageButton::_onNormal()
{
if (m_pNormalImage)
@ -86,8 +104,10 @@ void ImageButton::setNormal(Image * image)
m_pNormalImage = image;
// 现图片引用计数加一
m_pNormalImage->retain();
// 根据图片宽高设定按钮大小
setSize(m_pNormalImage->getSize());
// 重新计算图片位置
resetImagePosition();
_resetPosition();
}
}
@ -98,7 +118,7 @@ void ImageButton::setMouseIn(Image * image)
SAFE_RELEASE(m_pMouseInImage);
m_pMouseInImage = image;
m_pMouseInImage->retain();
resetImagePosition();
_resetPosition();
}
}
@ -109,7 +129,7 @@ void ImageButton::setSelected(Image * image)
SAFE_RELEASE(m_pSelectedImage);
m_pSelectedImage = image;
m_pSelectedImage->retain();
resetImagePosition();
_resetPosition();
}
}
@ -120,54 +140,33 @@ void ImageButton::setUnable(Image * image)
SAFE_RELEASE(m_pUnableImage);
m_pUnableImage = image;
m_pUnableImage->retain();
resetImagePosition();
_resetPosition();
}
}
void ImageButton::setX(int x)
{
Node::setX(x);
resetImagePosition();
}
void ImageButton::setY(int y)
{
Node::setY(y);
resetImagePosition();
}
void ImageButton::setPos(int x, int y)
{
Node::setPos(x, y);
resetImagePosition();
}
void ImageButton::resetImagePosition()
void ImageButton::_resetPosition()
{
if (m_pNormalImage)
{
// 根据图片宽高设定按钮大小
m_nWidth = m_pNormalImage->getWidth();
m_nHeight = m_pNormalImage->getHeight();
// 根据按钮位置和图片宽高设置图片位置居中显示
m_pNormalImage->setPos(m_nX, m_nY);
m_pNormalImage->setPos(getX(), getY());
}
if (m_pMouseInImage)
{
m_pMouseInImage->setPos(
m_nX + (m_nWidth - m_pMouseInImage->getWidth()) / 2,
m_nY + (m_nHeight - m_pMouseInImage->getHeight()) / 2);
getX() + (getWidth() - m_pMouseInImage->getWidth()) / 2,
getY() + (getHeight() - m_pMouseInImage->getHeight()) / 2);
}
if (m_pSelectedImage)
{
m_pSelectedImage->setPos(
m_nX + (m_nWidth - m_pSelectedImage->getWidth()) / 2,
m_nY + (m_nHeight - m_pSelectedImage->getHeight()) / 2);
getX() + (getWidth() - m_pSelectedImage->getWidth()) / 2,
getY() + (getHeight() - m_pSelectedImage->getHeight()) / 2);
}
if (m_pUnableImage)
{
m_pUnableImage->setPos(
m_nX + (m_nWidth - m_pUnableImage->getWidth()) / 2,
m_nY + (m_nHeight - m_pUnableImage->getHeight()) / 2);
getX() + (getWidth() - m_pUnableImage->getWidth()) / 2,
getY() + (getHeight() - m_pUnableImage->getHeight()) / 2);
}
}

View File

@ -1,4 +1,4 @@
#include "..\..\Easy2d.h"
#include "..\..\easy2d.h"
TextButton::TextButton() :
@ -7,8 +7,6 @@ TextButton::TextButton() :
m_pSelectedText(nullptr),
m_pUnableText(nullptr)
{
m_nWidth = 0;
m_nHeight = 0;
}
TextButton::TextButton(tstring text) :
@ -32,6 +30,26 @@ TextButton::~TextButton()
SAFE_RELEASE(m_pUnableText);
}
void TextButton::_setStatus(Status status)
{
if (m_eStatus != status)
{
if (status == MOUSEIN)
{
if (m_pMouseInText) setRect(m_pMouseInText->getRect());
}
else if (status == SELECTED)
{
if (m_pSelectedText) setRect(m_pSelectedText->getRect());
}
else
{
setRect(m_pNormalText->getRect());
}
}
MouseNode::_setStatus(status);
}
void TextButton::_onNormal()
{
if (m_pNormalText)
@ -86,8 +104,10 @@ void TextButton::setNormal(Text * text)
m_pNormalText = text;
// 现文本引用计数加一
m_pNormalText->retain();
// 根据文字宽高设定按钮大小
setSize(m_pNormalText->getSize());
// 重新计算文本位置
resetTextPosition();
_resetPosition();
}
}
@ -98,7 +118,7 @@ void TextButton::setMouseIn(Text * text)
SAFE_RELEASE(m_pMouseInText);
m_pMouseInText = text;
m_pMouseInText->retain();
resetTextPosition();
_resetPosition();
}
}
@ -109,7 +129,7 @@ void TextButton::setSelected(Text * text)
SAFE_RELEASE(m_pSelectedText);
m_pSelectedText = text;
m_pSelectedText->retain();
resetTextPosition();
_resetPosition();
}
}
@ -120,54 +140,33 @@ void TextButton::setUnable(Text * text)
SAFE_RELEASE(m_pUnableText);
m_pUnableText = text;
m_pUnableText->retain();
resetTextPosition();
_resetPosition();
}
}
void TextButton::setX(int x)
{
Node::setX(x);
resetTextPosition();
}
void TextButton::setY(int y)
{
Node::setY(y);
resetTextPosition();
}
void TextButton::setPos(int x, int y)
{
Node::setPos(x, y);
resetTextPosition();
}
void TextButton::resetTextPosition()
void TextButton::_resetPosition()
{
if (m_pNormalText)
{
// 根据文字宽高设定按钮大小
m_nWidth = m_pNormalText->getWidth();
m_nHeight = m_pNormalText->getHeight();
// 根据按钮位置和文字宽高设置文字位置居中显示
m_pNormalText->setPos(m_nX , m_nY);
m_pNormalText->setPos(getX() , getY());
}
if (m_pMouseInText)
{
m_pMouseInText->setPos(
m_nX + (m_nWidth - m_pMouseInText->getWidth()) / 2,
m_nY + (m_nHeight - m_pMouseInText->getHeight()) / 2);
getX() + (getWidth() - m_pMouseInText->getWidth()) / 2,
getY() + (getHeight() - m_pMouseInText->getHeight()) / 2);
}
if (m_pSelectedText)
{
m_pSelectedText->setPos(
m_nX + (m_nWidth - m_pSelectedText->getWidth()) / 2,
m_nY + (m_nHeight - m_pSelectedText->getHeight()) / 2);
getX() + (getWidth() - m_pSelectedText->getWidth()) / 2,
getY() + (getHeight() - m_pSelectedText->getHeight()) / 2);
}
if (m_pUnableText)
{
m_pUnableText->setPos(
m_nX + (m_nWidth - m_pUnableText->getWidth()) / 2,
m_nY + (m_nHeight - m_pUnableText->getHeight()) / 2);
getX() + (getWidth() - m_pUnableText->getWidth()) / 2,
getY() + (getHeight() - m_pUnableText->getHeight()) / 2);
}
}

View File

@ -1,25 +1,24 @@
#include "..\Easy2d.h"
#include "..\easy2d.h"
#include "..\EasyX\easyx.h"
// 对 PNG 图像进行像素转换
static void CrossImage(CImage &img);
Image::Image() :
m_nAlpha(255),
m_fScaleX(1),
m_fScaleY(1)
{
}
Image::Image(LPCTSTR ImageFile) :
m_fScaleX(1),
m_fScaleY(1)
Image()
{
setImage(ImageFile); // 设置图片资源
}
Image::Image(LPCTSTR ImageFile, int x, int y, int width, int height) :
m_fScaleX(1),
m_fScaleY(1)
Image()
{
setImage(ImageFile, x, y, width, height); // 设置图片资源和裁剪大小
}
@ -36,17 +35,14 @@ void Image::_onDraw()
return;
}
// 绘制图片
m_Image.Draw(GetImageHDC(), m_rDest, m_rSrc);
}
int Image::getWidth() const
{
return m_rDest.Width(); // 目标矩形的宽度
}
int Image::getHeight() const
{
return m_rDest.Height(); // 目标矩形的高度
if (m_Image.GetBPP() == 32)
{
m_Image.AlphaBlend(GetImageHDC(), m_Rect, m_SrcRect, m_nAlpha, AC_SRC_OVER);
}
else
{
m_Image.Draw(GetImageHDC(), m_Rect, m_SrcRect);
}
}
float Image::getScaleX() const
@ -59,6 +55,11 @@ float Image::getScaleY() const
return m_fScaleY;
}
float Image::getOpacity() const
{
return m_nAlpha / 255.0f;
}
bool Image::setImage(LPCTSTR ImageFile)
{
//判断图片路径是否存在
@ -78,20 +79,13 @@ bool Image::setImage(LPCTSTR ImageFile)
{
return false;
}
// 获取扩展名,对 PNG 图片进行特殊处理
if (_T(".png") == FileUtils::getFileExtension(ImageFile))
// 确认该图像包含 Alpha 通道
if (m_Image.GetBPP() == 32)
{
// 像素转换
// 透明图片处理
CrossImage(m_Image);
// Alpha 通道
m_Image.AlphaBlend(GetImageHDC(), 15, 30);
}
// 设置目标矩形(即绘制到窗口的位置和大小)
m_rDest.SetRect(m_nX, m_nY, m_nX + m_Image.GetWidth(), m_nY + m_Image.GetHeight());
m_rSrc.SetRect(0, 0, m_Image.GetWidth(), m_Image.GetHeight());
// 重置缩放属性
m_fScaleX = 1;
m_fScaleY = 1;
reset();
return true;
}
@ -117,12 +111,7 @@ bool Image::setImageFromRes(LPCTSTR pResName)
{
return false;
}
// 设置目标矩形(即绘制到窗口的位置和大小)
m_rDest.SetRect(m_nX, m_nY, m_nX + m_Image.GetWidth(), m_nY + m_Image.GetHeight());
m_rSrc.SetRect(0, 0, m_Image.GetWidth(), m_Image.GetHeight());
// 重置缩放属性
m_fScaleX = 1;
m_fScaleY = 1;
reset();
return true;
}
@ -144,60 +133,33 @@ void Image::crop(int x, int y, int width, int height)
width = min(max(width, 0), m_Image.GetWidth());
height = min(max(height, 0), m_Image.GetHeight());
// 设置源矩形的位置和大小(用于裁剪)
m_rSrc.SetRect(x, y, x + width, y + height);
m_SrcRect.SetRect(x, y, x + width, y + height);
// 设置目标矩形(即绘制到窗口的位置和大小)
m_rDest.SetRect(m_nX, m_nY, m_nX + int(width * m_fScaleX), m_nY + int(height * m_fScaleY));
setSize(int(width * m_fScaleX), int(height * m_fScaleY));
}
void Image::stretch(int width, int height)
{
width = max(width, 0);
height = max(height, 0);
// 设置目标矩形的位置和大小(即绘制到窗口的位置和大小,用于拉伸图片)
m_rDest.SetRect(m_nX, m_nY, m_nX + width, m_nY + height);
setSize(max(width, 0), max(height, 0));
// 重置比例缩放属性
m_fScaleX = 1;
m_fScaleY = 1;
}
void Image::scale(float scaleX, float scaleY)
void Image::setScale(float scaleX, float scaleY)
{
m_fScaleX = max(scaleX, 0);
m_fScaleY = max(scaleY, 0);
m_rDest.SetRect(
m_nX, m_nY,
m_nX + int(m_rSrc.Width() * scaleX),
m_nY + int(m_rSrc.Height() * scaleY));
setSize(int(m_SrcRect.Width() * scaleX), int(m_SrcRect.Height() * scaleY));
}
void Image::setPos(int x, int y)
void Image::setOpacity(float value)
{
// 移动目标矩形
m_rDest.MoveToXY(x, y);
m_nX = x;
m_nY = y;
}
void Image::move(int x, int y)
{
// 移动目标矩形
m_rDest.OffsetRect(x, y);
m_nX += x;
m_nY += y;
}
void Image::setX(int x)
{
// 移动目标矩形
m_rDest.MoveToX(x);
m_nX = x;
}
void Image::setY(int y)
{
// 移动目标矩形
m_rDest.MoveToY(y);
m_nY = y;
if (m_Image.GetBPP() == 32)
{
m_nAlpha = BYTE(min(max(value, 0), 1) * 255);
}
}
void Image::setTransparentColor(COLORREF value)
@ -206,6 +168,19 @@ void Image::setTransparentColor(COLORREF value)
m_Image.SetTransparentColor(value);
}
void Image::reset()
{
// 设置目标矩形(即绘制到窗口的位置和大小)
setSize(m_Image.GetWidth(), m_Image.GetHeight());
// 设置源矩形(即截取图片的大小)
m_SrcRect.SetRect(0, 0, m_Image.GetWidth(), m_Image.GetHeight());
// 重置缩放属性
m_fScaleX = 1;
m_fScaleY = 1;
// 重置透明度
m_nAlpha = 255;
}
void Image::saveScreenshot()
{
tstring savePath;
@ -223,6 +198,7 @@ void Image::saveScreenshot()
// 对 PNG 图像进行像素转换
void CrossImage(CImage &img)
{
// 进行像素转换
for (int i = 0; i < img.GetWidth(); i++)
{
for (int j = 0; j < img.GetHeight(); j++)

View File

@ -1,4 +1,5 @@
#include "..\easy2d.h"
#include "..\e2dobj.h"
MouseNode::MouseNode() :
@ -34,7 +35,7 @@ bool MouseNode::_exec(bool active)
if (!m_bTarget)
{
// 若鼠标位置在节点所在的矩形区域中
if (_judge())
if (_isMouseIn())
{
// 状态设为 MOUSEIN
_setStatus(MOUSEIN);
@ -58,7 +59,7 @@ bool MouseNode::_exec(bool active)
if (MouseMsg::isOnLButtonUp())
{
// 若左键抬起时鼠标仍在节点内
if (_judge())
if (_isMouseIn())
{
m_ClickCallback(); // 执行回调函数
}
@ -96,10 +97,9 @@ void MouseNode::_onDraw()
}
}
bool MouseNode::_judge()
bool MouseNode::_isMouseIn()
{
return (MouseMsg::getX() >= m_nX && MouseMsg::getX() <= m_nX + m_nWidth) &&
(MouseMsg::getY() >= m_nY && MouseMsg::getY() <= m_nY + m_nHeight);
return isPointIn(MouseMsg::getPos());
}
void MouseNode::_setStatus(Status status)

View File

@ -1,18 +1,19 @@
#include "..\Easy2d.h"
#include "..\easy2d.h"
Node::Node() :
m_nZOrder(0),
m_bDisplay(true),
m_nX(0),
m_nY(0)
m_bDisplay(true)
{
}
Node::Node(CPoint p) :
m_Pos(p)
{
}
Node::Node(int x, int y) :
m_nZOrder(0),
m_bDisplay(true),
m_nX(x),
m_nY(y)
m_bDisplay(true)
{
}
@ -29,36 +30,49 @@ void Node::_onDraw()
{
}
const int Node::getX() const
int Node::getX() const
{
return m_nX;
return m_Pos.x;
}
const int Node::getY() const
int Node::getY() const
{
return m_nY;
return m_Pos.y;
}
CPoint Node::getPos() const
{
return m_Pos;
}
void Node::setX(int x)
{
m_nX = x;
m_Pos.x = x;
}
void Node::setY(int y)
{
m_nY = y;
m_Pos.y = y;
}
void Node::setPos(int x, int y)
{
m_nX = x;
m_nY = y;
m_Pos.SetPoint(x, y);
}
void Node::setPos(CPoint p)
{
m_Pos = p;
}
void Node::move(int x, int y)
{
m_nX += x;
m_nY += y;
m_Pos.Offset(x, y);
}
void Node::move(CVector v)
{
m_Pos.Offset(v);
}
int Node::getZOrder() const

138
Easy2D/Object/RectNode.cpp Normal file
View File

@ -0,0 +1,138 @@
#include "..\easy2d.h"
RectNode::RectNode() :
m_Rect(0, 0, 0, 0)
{
}
RectNode::~RectNode()
{
}
bool RectNode::isCollisionWith(RectNode * rectNode) const
{
return IntersectRect(NULL, &m_Rect, &rectNode->m_Rect);
}
bool RectNode::isPointIn(CPoint p) const
{
return m_Rect.PtInRect(p);
}
void RectNode::setWindowCenterX()
{
setX((App::getWidth() - getWidth()) / 2);
}
void RectNode::setWindowCenterY()
{
setY((App::getHeight() - getHeight()) / 2);
}
void RectNode::setWindowCenter()
{
setWindowCenterX();
setWindowCenterY();
}
int RectNode::getX() const
{
return m_Rect.left;
}
int RectNode::getY() const
{
return m_Rect.top;
}
CPoint RectNode::getPos() const
{
return m_Rect.TopLeft();
}
int RectNode::getWidth() const
{
return m_Rect.Width(); // 矩形宽度
}
int RectNode::getHeight() const
{
return m_Rect.Height(); // 矩形高度
}
CSize RectNode::getSize() const
{
return m_Rect.Size();
}
CRect RectNode::getRect() const
{
return m_Rect;
}
void RectNode::setX(int x)
{
m_Rect.MoveToX(x);
}
void RectNode::setY(int y)
{
m_Rect.MoveToY(y);
}
void RectNode::setPos(int x, int y)
{
m_Rect.MoveToXY(x, y); // 修改矩形位置
}
void RectNode::setPos(CPoint p)
{
m_Rect.MoveToXY(p); // 修改矩形位置
}
void RectNode::move(int x, int y)
{
m_Rect.OffsetRect(x, y); // 移动矩形
}
void RectNode::move(CVector v)
{
m_Rect.OffsetRect(v); // 移动矩形
}
void RectNode::setWidth(int width)
{
m_Rect.right = max(m_Rect.left + width, 0);
}
void RectNode::setHeight(int height)
{
m_Rect.bottom = max(m_Rect.top + height, 0);
}
void RectNode::setSize(int width, int height)
{
setWidth(width);
setHeight(height);
}
void RectNode::setSize(CSize size)
{
setSize(size.cx, size.cy);
}
void RectNode::setRect(int x1, int y1, int x2, int y2)
{
m_Rect.SetRect(x1, y1, x2, y2);
}
void RectNode::setRect(CPoint leftTop, CPoint rightBottom)
{
m_Rect.SetRect(leftTop, rightBottom);
}
void RectNode::setRect(CRect rect)
{
m_Rect.CopyRect(&rect);
}

View File

@ -8,9 +8,9 @@ Circle::Circle() :
}
Circle::Circle(int x, int y, int radius) :
Node(x, y),
m_nRadius(radius)
{
setPos(x, y);
}
Circle::~Circle()
@ -19,17 +19,17 @@ Circle::~Circle()
void Circle::solidShape()
{
solidcircle(m_nX, m_nY, m_nRadius);
solidcircle(getX(), getY(), m_nRadius);
}
void Circle::fillShape()
{
fillcircle(m_nX, m_nY, m_nRadius);
fillcircle(getX(), getY(), m_nRadius);
}
void Circle::roundShape()
{
circle(m_nX, m_nY, m_nRadius);
circle(getX(), getY(), m_nRadius);
}
int Circle::getRadius() const

View File

@ -2,17 +2,14 @@
#include "..\..\EasyX\easyx.h"
Rect::Rect() :
m_nWidth(0),
m_nHeight(0)
Rect::Rect()
{
}
Rect::Rect(int x, int y, int width, int height) :
Node(x, y),
m_nWidth(width),
m_nHeight(height)
m_Size(width, height)
{
setPos(x, y);
}
Rect::~Rect()
@ -21,41 +18,41 @@ Rect::~Rect()
void Rect::solidShape()
{
solidrectangle(m_nX, m_nY, m_nX + m_nWidth, m_nY + m_nHeight);
solidrectangle(getX(), getY(), getX() + m_Size.cx, getY() + m_Size.cy);
}
void Rect::fillShape()
{
fillrectangle(m_nX, m_nY, m_nX + m_nWidth, m_nY + m_nHeight);
fillrectangle(getX(), getY(), getX() + m_Size.cx, getY() + m_Size.cy);
}
void Rect::roundShape()
{
rectangle(m_nX, m_nY, m_nX + m_nWidth, m_nY + m_nHeight);
rectangle(getX(), getY(), getX() + m_Size.cx, getY() + m_Size.cy);
}
int Rect::getWidth() const
{
return m_nWidth;
return m_Size.cx;
}
int Rect::getHeight() const
{
return m_nHeight;
return m_Size.cy;
}
void Rect::setWidth(int width)
{
m_nWidth = width;
m_Size.cx = width;
}
void Rect::setHeight(int height)
{
m_nHeight = height;
m_Size.cy = height;
}
void Rect::setSize(int width, int height)
{
m_nWidth = width;
m_nHeight = height;
m_Size.cx = width;
m_Size.cy = height;
}

View File

@ -1,4 +1,4 @@
#include "..\..\Easy2d.h"
#include "..\..\easy2d.h"
#include "..\..\EasyX\easyx.h"
Shape::Shape() :

117
Easy2D/Object/Sprite.cpp Normal file
View File

@ -0,0 +1,117 @@
#include "..\easy2d.h"
#include "..\EasyX\easyx.h"
Sprite::Sprite() :
m_nAlpha(255),
m_fScaleX(1),
m_fScaleY(1),
m_pImage(nullptr)
{
}
Sprite::Sprite(Image * image) :
Sprite()
{
setImage(image);
}
Sprite::Sprite(LPCTSTR imageFileName) :
Sprite()
{
setImage(new Image(imageFileName));
}
Sprite::~Sprite()
{
SAFE_RELEASE(m_pImage);
}
bool Sprite::_exec(bool active)
{
return false;
}
void Sprite::_onDraw()
{
// display 属性为 false或未设置图片资源时不绘制该图片
if (!m_bDisplay || m_pImage->m_Image.IsNull())
{
return;
}
// 绘制图片
if (m_pImage->m_Image.GetBPP() == 32)
{
m_pImage->m_Image.AlphaBlend(GetImageHDC(), getRect(), m_pImage->m_SrcRect, m_nAlpha, AC_SRC_OVER);
}
else
{
m_pImage->m_Image.Draw(GetImageHDC(), getRect(), m_pImage->m_SrcRect);
}
}
void Sprite::setImage(Image * image)
{
SAFE_RELEASE(m_pImage);
m_pImage = image;
setSize(int(m_pImage->getWidth() * m_fScaleX), int(m_pImage->getHeight() * m_fScaleY));
m_pImage->retain();
}
bool Sprite::isCollisionWith(Sprite * sprite)
{
return IntersectRect(NULL, &getRect(), &sprite->getRect());
}
void Sprite::addAction(Action * action)
{
if (action)
{
// 将动作与 Sprite 绑定
action->m_pParent = this;
// 将动作加入动作管理器,管理器会处理这个动作
ActionManager::addAction(action);
}
}
void Sprite::pauseAllAction()
{
ActionManager::pauseSpriteAllActions(this);
}
void Sprite::resumeAllAction()
{
ActionManager::resumeSpriteAllActions(this);
}
void Sprite::stopAllAction()
{
ActionManager::stopSpriteAllActions(this);
}
float Sprite::getScaleX() const
{
return m_fScaleX;
}
float Sprite::getScaleY() const
{
return m_fScaleY;
}
float Sprite::getOpacity() const
{
return m_nAlpha / 255.0f;
}
void Sprite::setScale(float scaleX, float scaleY)
{
m_fScaleX = max(scaleX, 0);
m_fScaleY = max(scaleY, 0);
setSize(int(m_pImage->getWidth() * scaleX), int(m_pImage->getHeight() * scaleY));
}
void Sprite::setOpacity(float opacity)
{
m_nAlpha = BYTE(min(max(opacity, 0), 1) * 255);
}

View File

@ -1,4 +1,4 @@
#include "..\Easy2d.h"
#include "..\easy2d.h"
#include "..\EasyX\easyx.h"
@ -11,19 +11,19 @@ Text::Text() :
}
Text::Text(tstring text, COLORREF color, FontStyle * font) :
m_sText(text),
m_color(color),
m_pFontStyle(font)
{
setText(text);
m_pFontStyle->retain(); // 字体引用计数加一
}
Text::Text(int x, int y, tstring text, COLORREF color, FontStyle * font) :
Node(x, y),
m_sText(text),
m_color(color),
m_pFontStyle(font)
{
setText(text);
setPos(x, y);
m_pFontStyle->retain(); // 字体引用计数加一
}
@ -44,7 +44,7 @@ void Text::_onDraw()
// 设置文本颜色
settextcolor(m_color);
// 输出文字
outtextxy(m_nX, m_nY, m_sText.c_str());
outtextxy(getX(), getY(), m_sText.c_str());
}
COLORREF Text::getColor() const
@ -62,20 +62,6 @@ FontStyle * Text::getFontStyle()
return m_pFontStyle;
}
int Text::getWidth()
{
// 先设置字体,然后获取该文本在该字体下的宽度
settextstyle(&m_pFontStyle->m_font);
return textwidth(getText().c_str());
}
int Text::getHeight()
{
// 先设置字体,然后获取该文本在该字体下的高度
settextstyle(&m_pFontStyle->m_font);
return textheight(getText().c_str());
}
bool Text::isEmpty() const
{
return m_sText.empty(); // 文本是否为空
@ -84,6 +70,9 @@ bool Text::isEmpty() const
void Text::setText(tstring text)
{
m_sText = text;
// 先设置字体,然后获取该文本在该字体下的宽度和高度
settextstyle(&m_pFontStyle->m_font);
setSize(textwidth(getText().c_str()), textheight(getText().c_str()));
}
void Text::setColor(COLORREF color)
@ -96,4 +85,7 @@ void Text::setFontStyle(FontStyle * style)
SAFE_RELEASE(m_pFontStyle); // 原字体引用计数减一
m_pFontStyle = style; // 修改字体
m_pFontStyle->retain(); // 现字体引用计数加一
// 先设置字体,然后获取该文本在该字体下的宽度和高度
settextstyle(&m_pFontStyle->m_font);
setSize(textwidth(getText().c_str()), textheight(getText().c_str()));
}

View File

@ -1,4 +1,4 @@
#include "..\Easy2d.h"
#include "..\easy2d.h"
#include "..\EasyX\easyx.h"
// 常用颜色值的定义

View File

@ -1,4 +1,4 @@
#include "..\Easy2d.h"
#include "..\easy2d.h"
// 常用字体粗细值的定义
const LONG FontWeight::dontcare = 0;

View File

@ -0,0 +1,140 @@
#include "..\easy2d.h"
static std::vector<Action*> s_vActions;
void ActionManager::__exec()
{
// 获取当前时间
static LARGE_INTEGER nNow;
QueryPerformanceCounter(&nNow);
// 循环遍历所有正在运行的动作
std::vector<Action*>::iterator iter;
for (iter = s_vActions.begin(); iter != s_vActions.end();)
{
if ((*iter)->isRunning() && (*iter)->_exec(nNow))
{
// _exec 返回 true 时说明动作已经结束
(*iter)->release();
iter = s_vActions.erase(iter);
}
else
{
iter++;
}
}
}
void ActionManager::addAction(Action * action)
{
if (action)
{
action->_init();
s_vActions.push_back(action);
action->retain();
}
}
void ActionManager::startAction(Action * action)
{
resumeAction(action);
}
void ActionManager::resumeAction(Action * action)
{
for (auto act : s_vActions)
{
if (act == action)
{
act->resume();
}
}
}
void ActionManager::pauseAction(Action * action)
{
for (auto act : s_vActions)
{
if (act == action)
{
act->pause();
}
}
}
void ActionManager::stopAction(Action * action)
{
for (auto act : s_vActions)
{
if (act == action)
{
act->stop();
}
}
}
void ActionManager::startSpriteAllActions(Sprite * sprite)
{
resumeSpriteAllActions(sprite);
}
void ActionManager::resumeSpriteAllActions(Sprite * sprite)
{
for (auto action : s_vActions)
{
if (action->m_pParent == sprite)
{
action->resume();
}
}
}
void ActionManager::pauseSpriteAllActions(Sprite * sprite)
{
for (auto action : s_vActions)
{
if (action->m_pParent == sprite)
{
action->pause();
}
}
}
void ActionManager::stopSpriteAllActions(Sprite * sprite)
{
for (auto action : s_vActions)
{
if (action->m_pParent == sprite)
{
action->stop();
}
}
}
void ActionManager::startAllActions()
{
resumeAllActions();
}
void ActionManager::resumeAllActions()
{
for (auto action : s_vActions)
{
action->resume();
}
}
void ActionManager::pauseAllActions()
{
for (auto action : s_vActions)
{
action->pause();
}
}
void ActionManager::stopAllActions()
{
for (auto action : s_vActions)
{
action->stop();
}
}

View File

@ -1,9 +1,9 @@
#include "..\Easy2d.h"
#include "..\easy2d.h"
#include "..\EasyX\easyx.h"
#include <algorithm>
#include <sstream>
#include <Shlobj.h>
#pragma comment(lib, "shell32.lib")
#include <sstream>
#include <algorithm>
#ifndef UNICODE
#include <io.h>

View File

@ -1,7 +1,8 @@
#include "..\Easy2d.h"
#include <Digitalv.h>
#include "..\easy2d.h"
#include <mmsystem.h>
#pragma comment(lib , "winmm.lib")
#include <Digitalv.h>
#include <map>
////////////////////////////////////////////////////////////////////

View File

@ -1,4 +1,4 @@
#include "..\Easy2d.h"
#include "..\easy2d.h"
// 储存所有定时器的容器
static std::vector<Timer*> s_nTimers;

313
Easy2D/e2daction.h Normal file
View File

@ -0,0 +1,313 @@
#pragma once
#include <e2dbase.h>
namespace easy2d
{
class Action :
public Object
{
friend class Sprite;
friend class ActionManager;
friend class ActionTwo;
friend class ActionNeverStop;
friend class ActionSequence;
public:
Action();
virtual ~Action();
bool isRunning();
void start();
void resume();
void pause();
void stop();
void setInterval(UINT ms);
virtual Action * copy() = 0;
virtual Action * reverse() const;
protected:
bool m_bRunning;
bool m_bStop;
Sprite * m_pParent;
UINT m_nMilliSeconds;
LARGE_INTEGER m_nLast;
LARGE_INTEGER m_nAnimationInterval;
protected:
virtual void _init() = 0;
virtual bool _exec(LARGE_INTEGER nNow) = 0;
virtual void _reset() = 0;
};
class Animation :
public Action
{
public:
Animation(float duration);
virtual ~Animation();
protected:
UINT m_nDuration;
UINT m_nTotalDuration;
protected:
virtual void _init() override;
virtual bool _exec(LARGE_INTEGER nNow) override;
virtual void _reset() override;
};
class ActionMoveBy :
public Animation
{
public:
ActionMoveBy(float duration, CVector vec);
virtual ~ActionMoveBy();
virtual ActionMoveBy * copy() override;
virtual ActionMoveBy * reverse() const override;
protected:
CPoint m_BeginPos;
CVector m_MoveVector;
protected:
virtual void _init() override;
virtual bool _exec(LARGE_INTEGER nNow) override;
virtual void _reset() override;
};
class ActionMoveTo :
public ActionMoveBy
{
public:
ActionMoveTo(float duration, CPoint pos);
virtual ~ActionMoveTo();
virtual ActionMoveTo * copy() override;
protected:
CPoint m_EndPos;
protected:
virtual void _init() override;
virtual void _reset() override;
};
class ActionScaleBy :
public Animation
{
public:
ActionScaleBy(float duration, float scaleX, float scaleY);
virtual ~ActionScaleBy();
virtual ActionScaleBy * copy() override;
virtual ActionScaleBy * reverse() const override;
protected:
float m_nBeginScaleX;
float m_nBeginScaleY;
float m_nVariationX;
float m_nVariationY;
protected:
virtual void _init() override;
virtual bool _exec(LARGE_INTEGER nNow) override;
virtual void _reset() override;
};
class ActionScaleTo :
public ActionScaleBy
{
public:
ActionScaleTo(float duration, float scaleX, float scaleY);
virtual ~ActionScaleTo();
virtual ActionScaleTo * copy() override;
protected:
float m_nEndScaleX;
float m_nEndScaleY;
protected:
virtual void _init() override;
virtual void _reset() override;
};
class ActionOpacityBy :
public Animation
{
public:
ActionOpacityBy(float duration, float opacity);
virtual ~ActionOpacityBy();
virtual ActionOpacityBy * copy() override;
virtual ActionOpacityBy * reverse() const override;
protected:
float m_nBeginVal;
float m_nVariation;
protected:
virtual void _init() override;
virtual bool _exec(LARGE_INTEGER nNow) override;
virtual void _reset() override;
};
class ActionOpacityTo :
public ActionOpacityBy
{
public:
ActionOpacityTo(float duration, float opacity);
virtual ~ActionOpacityTo();
virtual ActionOpacityTo * copy() override;
protected:
float m_nEndVal;
protected:
virtual void _init() override;
virtual void _reset() override;
};
class ActionFadeIn :
public ActionOpacityTo
{
public:
ActionFadeIn(float duration) : ActionOpacityTo(duration, 1) {}
};
class ActionFadeOut :
public ActionOpacityTo
{
public:
ActionFadeOut(float duration) : ActionOpacityTo(duration, 0) {}
};
class ActionTwo :
public Action
{
public:
ActionTwo(Action * actionFirst, Action * actionSecond);
virtual ~ActionTwo();
virtual ActionTwo * copy() override;
virtual ActionTwo * reverse() const override;
protected:
Action * m_FirstAction;
Action * m_SecondAction;
protected:
virtual void _init() override;
virtual bool _exec(LARGE_INTEGER nNow) override;
virtual void _reset() override;
};
class ActionSequence :
public Action
{
public:
ActionSequence(int number, Action * action1, ...);
virtual ~ActionSequence();
virtual ActionSequence * copy() override;
virtual ActionSequence * reverse() const override;
protected:
UINT m_nActionIndex;
std::vector<Action*> m_vActions;
protected:
virtual void _init() override;
virtual bool _exec(LARGE_INTEGER nNow) override;
virtual void _reset() override;
};
class ActionDelay :
public Action
{
public:
ActionDelay(float duration);
virtual ~ActionDelay();
virtual ActionDelay * copy() override;
protected:
virtual void _init() override;
virtual bool _exec(LARGE_INTEGER nNow) override;
virtual void _reset() override;
};
class ActionNeverStop :
public Action
{
public:
ActionNeverStop(Action * action);
virtual ~ActionNeverStop();
virtual ActionNeverStop * copy() override;
protected:
Action * m_Action;
protected:
virtual void _init() override;
virtual bool _exec(LARGE_INTEGER nNow) override;
virtual void _reset() override;
};
class ActionFrames :
public Action
{
public:
ActionFrames();
~ActionFrames();
void addFrame(Image * frame);
virtual ActionFrames * copy() override;
virtual ActionFrames * reverse() const override;
protected:
UINT m_nFrameIndex;
std::vector<Image*> m_vFrames;
protected:
virtual void _init() override;
virtual bool _exec(LARGE_INTEGER nNow) override;
virtual void _reset() override;
};
class ActionCallback :
public Action
{
public:
ActionCallback(const std::function<void()>& callback);
~ActionCallback();
virtual ActionCallback * copy() override;
protected:
std::function<void()> m_Callback;
protected:
virtual void _init() override;
virtual bool _exec(LARGE_INTEGER nNow) override;
virtual void _reset() override;
};
} // End of easy2d namespace

184
Easy2D/e2dbase.h Normal file
View File

@ -0,0 +1,184 @@
#pragma once
#include <Windows.h>
#include <tchar.h>
#include <atltypes.h>
#include <vector>
#include <stack>
#include <functional>
// String macros
#ifdef UNICODE
#define tstring std::wstring
#else
#define tstring std::string
#endif
// Safe macros
#define SAFE_DELETE(p) { delete (p); (p) = nullptr; }
#define SAFE_DELETE_ARRAY(p) { if (p) { delete[] (p); (p) = nullptr; } }
#define SAFE_RELEASE(p) { if (p) p->release(); }
// Type Declare
typedef CPoint CVector;
typedef unsigned int VK_KEY;
typedef std::function<void()> CLICK_CALLBACK;
typedef std::function<void()> TIMER_CALLBACK;
typedef std::function<void(VK_KEY)> KEY_CALLBACK;
typedef std::function<void()> MOUSE_CALLBACK;
// Classes Declare
namespace easy2d
{
class Scene;
class Node;
class App
{
public:
App();
~App();
// 窗口可选模式
enum MODE { SHOW_CONSOLE = 1, NO_CLOSE = 2, NO_MINI_MIZE = 4 };
// 定义绘图窗口
void createWindow(int width, int height, int mode = 0);
// 定义绘图窗口
void createWindow(CSize size, int mode = 0);
// 定义绘图窗口
void createWindow(tstring title, int width, int height, int mode = 0);
// 定义绘图窗口
void createWindow(tstring title, CSize size, int mode = 0);
// 启动程序
int run();
// 释放所有内存资源
void free();
// 销毁该对象
void destory();
// 获取程序实例
static App * get();
// 设置坐标原点
static void setOrigin(int originX, int originY);
// 获取坐标原点的物理横坐标
static int getOriginX();
// 获取坐标原点的物理纵坐标
static int getOriginY();
// 终止程序
static void quit();
// 终止程序
static void end();
// 修改窗口大小
static void setWindowSize(int width, int height);
// 修改窗口大小
static void setWindowSize(CSize size);
// 关闭窗口
static void close();
// 设置窗口标题
static void setWindowTitle(tstring title);
// 获取窗口标题
static tstring getWindowTitle();
// 获取窗口宽度
static int getWidth();
// 获取窗口高度
static int getHeight();
// 切换场景
static void enterScene(Scene *scene, bool save = true);
// 返回上一场景
static void backScene();
// 清空之前保存的所有场景
static void clearScene();
// 设置 AppName
static void setAppName(tstring appname);
// 获取 AppName
static tstring getAppName();
// 修改窗口背景色
static void setBkColor(COLORREF color);
// 设置帧率
static void setFPS(DWORD fps);
// 重置绘图样式为默认值
static void reset();
// 获取当前场景
static Scene * getCurrentScene();
protected:
tstring m_sTitle;
tstring m_sAppName;
Scene* m_CurrentScene;
Scene* m_NextScene;
std::stack<Scene*> m_SceneStack;
LARGE_INTEGER m_nAnimationInterval;
CSize m_Size;
int m_nWindowMode;
bool m_bRunning;
bool m_bSaveScene;
protected:
void _initGraph();
void _mainLoop();
void _enterNextScene();
};
class FreePool
{
friend class App;
friend class Object;
private:
// 刷新内存池
static void __flush();
// 将一个节点放入释放池
static void __add(Object * nptr);
};
class Scene
{
friend class App;
friend class MouseMsg;
public:
Scene();
~Scene();
// 重写这个函数,它将在进入这个场景时自动执行
virtual void onEnter();
// 重写这个函数,它将在离开这个场景时自动执行
virtual void onExit();
// 添加子成员到场景
void add(Node * child, int zOrder = 0);
// 删除子成员
bool del(Node * child);
// 清空所有子成员
void clearAllChildren();
protected:
std::vector<Node*> m_vChildren;
protected:
void _exec();
void _onDraw();
};
class Object
{
friend class FreePool;
public:
Object();
virtual ~Object();
void retain();
void release();
protected:
int m_nRef;
};
} // End of easy2d namespace

112
Easy2D/e2dmsg.h Normal file
View File

@ -0,0 +1,112 @@
#pragma once
#include <e2dbase.h>
namespace easy2d
{
class MouseMsg
{
friend class App;
public:
MouseMsg();
MouseMsg(tstring name, const MOUSE_CALLBACK& callback);
~MouseMsg();
// 添加键盘监听
static void addListener(tstring name, const MOUSE_CALLBACK& callback);
// 删除键盘监听
static bool delListener(tstring name);
// 删除所有键盘监听
static void clearAllListeners();
// 左键是否按下
static bool isLButtonDown();
// 右键是否按下
static bool isRButtonDown();
// 中键是否按下
static bool isMButtonDown();
// 获取鼠标X坐标
static int getX();
// 获取鼠标Y坐标
static int getY();
// 获取鼠标坐标
static CPoint getPos();
// 获取鼠标滚轮值
static int getWheel();
// 鼠标移动消息
static bool isOnMouseMoved();
// 左键双击消息
static bool isOnLButtonDBClicked();
// 右键按下消息
static bool isOnLButtonDown();
// 左键弹起消息
static bool isOnLButtonUp();
// 右键双击消息
static bool isOnRButtonDBClicked();
// 右键按下消息
static bool isOnRButtonDown();
// 右键弹起消息
static bool isOnRButtonUp();
// 中键双击消息
static bool isOnMButtonDBClicked();
// 中键按下消息
static bool isOnMButtonDown();
// 中键弹起消息
static bool isOnMButtonUp();
// 鼠标滚轮拨动消息
static bool isOnWheel();
// 清空鼠标消息
static void resetMouseMsg();
private:
static void __exec();
protected:
tstring m_sName;
MOUSE_CALLBACK m_callback;
protected:
// 执行回调函数
void onMouseMsg();
};
class KeyMsg
{
friend class App;
public:
KeyMsg(tstring name, const KEY_CALLBACK& callback);
~KeyMsg();
// 执行回调函数
void onKbHit(VK_KEY key);
// 添加键盘监听
static void addListener(tstring name, const KEY_CALLBACK& callback);
// 删除键盘监听
static bool delListener(tstring name);
// 删除所有键盘监听
static void clearAllListeners();
// 判断键是否被按下按下返回true
static bool isKeyDown(VK_KEY key);
public:
// 字母键值
static const VK_KEY A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z;
// 数字键值
static const VK_KEY NUM_1, NUM_2, NUM_3, NUM_4, NUM_5, NUM_6, NUM_7, NUM_8, NUM_9, NUM_0;
// 小数字键盘值
static const VK_KEY NUMPAD_1, NUMPAD_2, NUMPAD_3, NUMPAD_4, NUMPAD_5, NUMPAD_6, NUMPAD_7, NUMPAD_8, NUMPAD_9, NUMPAD_0;
// 控制键值
static const VK_KEY Enter, Space, Up, Down, Left, Right, Esc, Shift, LShift, RShift, Ctrl, LCtrl, RCtrl;
// F 键值
static const VK_KEY F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12;
private:
static void __exec();
protected:
tstring m_sName;
KEY_CALLBACK m_callback;
};
} // End of easy2d namespace

589
Easy2D/e2dobj.h Normal file
View File

@ -0,0 +1,589 @@
#pragma once
#include <e2dbase.h>
#include <atlimage.h>
namespace easy2d
{
class FontStyle;
class Color;
class Action;
class Node :
public Object
{
friend class Scene;
friend class BatchNode;
public:
Node();
Node(CPoint p);
Node(int x, int y);
virtual ~Node();
// 获取节点横坐标
virtual int getX() const;
// 获取节点纵坐标
virtual int getY() const;
// 获取节点坐标
virtual CPoint getPos() const;
// 设置节点横坐标
virtual void setX(int x);
// 设置节点纵坐标
virtual void setY(int y);
// 设置节点横纵坐标
virtual void setPos(int x, int y);
// 设置节点横纵坐标
virtual void setPos(CPoint p);
// 移动节点
virtual void move(int x, int y);
// 设置节点横纵坐标
virtual void move(CVector v);
// 节点是否显示
virtual bool display() const;
// 设置节点是否显示
virtual void setDisplay(bool value);
// 获取节点绘图顺序
virtual int getZOrder() const;
// 设置节点绘图顺序0为最先绘制显示在最底层
virtual void setZOrder(int z);
// 获取节点所在场景
Scene * getParentScene();
protected:
int m_nZOrder;
bool m_bDisplay;
Scene* m_pScene;
CPoint m_Pos;
protected:
virtual bool _exec(bool active);
virtual void _onDraw() = 0;
void setParentScene(Scene * scene);
};
class BatchNode :
public Node
{
public:
BatchNode();
virtual ~BatchNode();
// 添加子节点
void add(Node *child, int z_Order = 0);
// 删除子节点
bool del(Node * child);
// 清空所有子节点
void clearAllChildren();
protected:
std::vector<Node*> m_vChildren;
protected:
virtual bool _exec(bool active) override;
virtual void _onDraw() override;
};
class Layer :
public BatchNode
{
public:
Layer();
virtual ~Layer();
// 图层是否阻塞消息
int getBlock() const;
// 设置图层是否阻塞消息
void setBlock(bool block);
protected:
bool m_bBlock;
protected:
virtual bool _exec(bool active) override;
};
class RectNode :
public Node
{
public:
RectNode();
~RectNode();
virtual bool isCollisionWith(RectNode * rectNode) const;
virtual bool isPointIn(CPoint p) const;
virtual void setWindowCenterX();
virtual void setWindowCenterY();
virtual void setWindowCenter();
virtual int getX() const override;
virtual int getY() const override;
virtual CPoint getPos() const override;
virtual int getWidth() const;
virtual int getHeight() const;
virtual CSize getSize() const;
virtual CRect getRect() const;
virtual void setX(int x) override;
virtual void setY(int y) override;
virtual void setPos(int x, int y) override;
virtual void setPos(CPoint p) override;
virtual void move(int x, int y) override;
virtual void move(CVector v) override;
virtual void setWidth(int width);
virtual void setHeight(int height);
virtual void setSize(int width, int height);
virtual void setSize(CSize size);
virtual void setRect(int x1, int y1, int x2, int y2);
virtual void setRect(CPoint leftTop, CPoint rightBottom);
virtual void setRect(CRect rect);
protected:
CRect m_Rect;
};
class Text :
public RectNode
{
friend class TextButton;
public:
Text();
// 根据字符串、颜色和字体创建文字
Text(tstring text, COLORREF color = Color::white, FontStyle * font = FontStyle::getDefault());
// 根据横纵坐标、字符串、颜色和字体创建文字
Text(int x, int y, tstring text, COLORREF color = Color::white, FontStyle * font = FontStyle::getDefault());
virtual ~Text();
// 获取当前颜色
COLORREF getColor() const;
// 获取当前文字
tstring getText() const;
// 获取当前字体
FontStyle * getFontStyle();
// 文本是否为空
bool isEmpty() const;
// 设置文字
void setText(tstring text);
// 设置文字颜色
void setColor(COLORREF color);
// 设置字体
void setFontStyle(FontStyle * style);
protected:
tstring m_sText;
COLORREF m_color;
FontStyle * m_pFontStyle;
protected:
virtual void _onDraw() override;
};
class Image :
public RectNode
{
friend class Sprite;
friend class ImageButton;
public:
Image();
// 从图片文件获取图像
Image(LPCTSTR ImageFile);
/**
*
*
*/
Image(LPCTSTR ImageFile, int x, int y, int width, int height);
virtual ~Image();
// 获取横向拉伸比例
float getScaleX() const;
// 获取纵向拉伸比例
float getScaleY() const;
// 获取透明度
float getOpacity() const;
/**
*
*
*/
bool setImage(LPCTSTR ImageFile);
/**
*
*
*
*/
bool setImage(LPCTSTR ImageFile, int x, int y, int width, int height);
/**
* png
*
*/
bool setImageFromRes(LPCTSTR pResName);
/**
* png
*
*
*/
bool setImageFromRes(LPCTSTR pResName, int x, int y, int width, int height);
// 裁剪图片(裁剪后会恢复 stretch 拉伸)
void crop(int x, int y, int width, int height);
// 将图片拉伸到固定宽高
void stretch(int width, int height);
// 按比例拉伸图片
void setScale(float scaleX, float scaleY);
// 设置透明度,范围 0~1.0f(只对 png 图片生效)
void setOpacity(float value);
// 设置透明色
void setTransparentColor(COLORREF value);
// 重置图片属性
void reset();
// 保存游戏截图
static void saveScreenshot();
protected:
CImage m_Image;
CRect m_SrcRect;
BYTE m_nAlpha;
float m_fScaleX;
float m_fScaleY;
protected:
virtual void _onDraw() override;
};
class Sprite :
public RectNode
{
friend class BatchSprite;
public:
Sprite();
Sprite(Image * image);
Sprite(LPCTSTR imageFileName);
virtual ~Sprite();
// 判断是否和另一个精灵碰撞
bool isCollisionWith(Sprite * sprite);
// 修改精灵图片
virtual void setImage(Image * image);
// 添加动作
virtual void addAction(Action * action);
// 暂停所有动作
virtual void pauseAllAction();
// 继续所有动作
virtual void resumeAllAction();
// 停止所有动作
virtual void stopAllAction();
virtual float getScaleX() const;
virtual float getScaleY() const;
virtual float getOpacity() const;
virtual void setScale(float scaleX, float scaleY);
virtual void setOpacity(float opacity);
protected:
float m_fScaleX;
float m_fScaleY;
BYTE m_nAlpha;
Image * m_pImage;
protected:
bool _exec(bool active) override;
void _onDraw() override;
};
class BatchSprite :
public Node
{
public:
BatchSprite();
virtual ~BatchSprite();
// 添加精灵
void addSprite(Sprite * sprite, int z_Order = 0);
// 删除精灵
bool delSprite(Sprite * child);
// 删除所有精灵
void clearAllSprites();
// 判断是否有精灵产生碰撞
// 返回值:若有碰撞,返回第一个产生碰撞的精灵,否则返回空指针
Sprite * isCollisionWith(Sprite * sprite);
// 判断点是否在精灵内部
// 返回值:若这个点在任意一个精灵内部,返回这个精灵,否则返回空指针
Sprite * isPointIn(CPoint point);
// 同时修改所有精灵的图片
virtual void setImage(Image * image);
virtual float getScaleX() const;
virtual float getScaleY() const;
virtual float getOpacity() const;
virtual void setScale(float scaleX, float scaleY);
virtual void setOpacity(float opacity);
protected:
std::vector<Sprite*> m_vSprites;
float m_fScaleX;
float m_fScaleY;
BYTE m_nAlpha;
protected:
bool _exec(bool active) override;
void _onDraw() override;
};
class MouseNode :
public RectNode
{
public:
MouseNode();
virtual ~MouseNode();
// 鼠标是否移入
virtual bool isMouseIn();
// 鼠标是否选中
virtual bool isSelected();
// 设置回调函数
virtual void setClickedCallback(const CLICK_CALLBACK & callback);
// 设置回调函数
virtual void setMouseInCallback(const CLICK_CALLBACK & callback);
// 设置回调函数
virtual void setMouseOutCallback(const CLICK_CALLBACK & callback);
// 设置回调函数
virtual void setSelectCallback(const CLICK_CALLBACK & callback);
// 设置回调函数
virtual void setUnselectCallback(const CLICK_CALLBACK & callback);
// 重置状态
virtual void reset();
// 设置节点是否阻塞鼠标消息
void setBlock(bool block);
protected:
bool m_bTarget;
bool m_bBlock;
enum Status { NORMAL, MOUSEIN, SELECTED } m_eStatus;
CLICK_CALLBACK m_OnMouseInCallback;
CLICK_CALLBACK m_OnMouseOutCallback;
CLICK_CALLBACK m_OnSelectCallback;
CLICK_CALLBACK m_OnUnselectCallback;
CLICK_CALLBACK m_ClickCallback;
protected:
virtual bool _exec(bool active) override;
virtual void _onDraw() override;
// 重写这个方法可以自定义按钮的判断方法
virtual bool _isMouseIn();
// 切换状态
virtual void _setStatus(Status status);
// 正常状态
virtual void _onNormal() = 0;
// 鼠标移入时
virtual void _onMouseIn() = 0;
// 鼠标选中时
virtual void _onSelected() = 0;
};
class Button :
public MouseNode
{
public:
Button();
virtual ~Button();
// 按钮是否启用
virtual bool isEnable();
// 设置是否启用
virtual void setEnable(bool enable);
// 设置按钮横坐标
virtual void setX(int x) override;
// 设置按钮纵坐标
virtual void setY(int y) override;
// 设置按钮坐标
virtual void setPos(int x, int y) override;
// 设置按钮坐标
virtual void setPos(CPoint p) override;
// 移动按钮
virtual void move(int x, int y) override;
// 移动按钮
virtual void move(CVector v) override;
protected:
bool m_bEnable;
protected:
virtual bool _exec(bool active) override;
virtual void _onDraw() override;
virtual void _resetPosition() = 0;
virtual void _onNormal() = 0;
virtual void _onMouseIn() = 0;
virtual void _onSelected() = 0;
virtual void _onDisable() = 0;
};
class TextButton :
public Button
{
public:
TextButton();
TextButton(tstring text);
TextButton(Text * text);
virtual ~TextButton();
// 设置按钮文字
void setNormal(Text * text);
// 设置鼠标移入时的按钮文字
void setMouseIn(Text * text);
// 设置鼠标选中时的按钮文字
void setSelected(Text * text);
// 设置按钮禁用时的按钮文字
void setUnable(Text * text);
protected:
Text * m_pNormalText;
Text * m_pMouseInText;
Text * m_pSelectedText;
Text * m_pUnableText;
protected:
virtual void _resetPosition() override;
virtual void _setStatus(Status status) override;
virtual void _onNormal() override;
virtual void _onMouseIn() override;
virtual void _onSelected() override;
virtual void _onDisable() override;
};
class ImageButton :
public Button
{
public:
ImageButton();
ImageButton(LPCTSTR image);
ImageButton(Image * image);
virtual ~ImageButton();
// 设置按钮图片
void setNormal(Image * image);
// 设置鼠标移入时的按钮图片
void setMouseIn(Image * image);
// 设置鼠标选中时的按钮图片
void setSelected(Image * image);
// 设置按钮禁用时的按钮图片
void setUnable(Image * image);
protected:
Image * m_pNormalImage;
Image * m_pMouseInImage;
Image * m_pSelectedImage;
Image * m_pUnableImage;
protected:
virtual void _resetPosition() override;
virtual void _setStatus(Status status) override;
virtual void _onNormal() override;
virtual void _onMouseIn() override;
virtual void _onSelected() override;
virtual void _onDisable() override;
};
class Shape :
public Node
{
public:
Shape();
virtual ~Shape();
// 形状填充样式
enum STYLE { ROUND, SOLID, FILL } m_eStyle;
// 获取形状的填充颜色
COLORREF getFillColor() const;
// 获取形状的线条颜色
COLORREF getLineColor() const;
// 设置填充颜色
void setFillColor(COLORREF color);
// 设置线条颜色
void setLineColor(COLORREF color);
// 设置填充样式
void setStyle(STYLE style);
protected:
COLORREF fillColor;
COLORREF lineColor;
protected:
virtual void _onDraw() override;
virtual void solidShape() = 0;
virtual void fillShape() = 0;
virtual void roundShape() = 0;
};
class Rect :
public Shape
{
public:
Rect();
Rect(int x, int y, int width, int height);
virtual ~Rect();
// 获取矩形宽度
int getWidth() const;
// 获取矩形高度
int getHeight() const;
// 设置矩形宽度
void setWidth(int width);
// 设置矩形高度
void setHeight(int height);
// 设置矩形大小
void setSize(int width, int height);
protected:
CSize m_Size;
protected:
virtual void solidShape() override;
virtual void fillShape() override;
virtual void roundShape() override;
};
class Circle :
public Shape
{
public:
Circle();
Circle(int x, int y, int radius);
virtual ~Circle();
// 获取圆形半径
int getRadius() const;
// 设置圆形半径
void setRadius(int m_nRadius);
protected:
int m_nRadius;
protected:
virtual void solidShape() override;
virtual void fillShape() override;
virtual void roundShape() override;
};
} // End of easy2d namespace

104
Easy2D/e2dstyle.h Normal file
View File

@ -0,0 +1,104 @@
#pragma once
#include <e2dbase.h>
namespace easy2d
{
class FontStyle :
public Object
{
friend class Text;
public:
FontStyle();
/**
* 使 [线线
* 齿]
*/
FontStyle(LPCTSTR fontfamily, LONG height = 18, LONG weight = 0, LONG width = 0,
bool italic = 0, bool underline = 0, bool strikeout = 0, LONG escapement = 0,
LONG orientation = 0, bool quality = true);
virtual ~FontStyle();
// 获取默认字体
static FontStyle * getDefault();
// 设置字符平均高度
void setHeight(LONG value);
// 设置字符平均宽度0表示自适应
void setWidth(LONG value);
// 设置字体
void setFontFamily(LPCTSTR value);
// 设置字符笔画粗细范围0~1000默认为0
void setWeight(LONG value);
// 设置斜体
void setItalic(bool value);
// 设置下划线
void setUnderline(bool value);
// 设置删除线
void setStrikeOut(bool value);
// 设置字符串的书写角度单位0.1度默认为0
void setEscapement(LONG value);
// 设置每个字符的书写角度单位0.1度默认为0
void setOrientation(LONG value);
// 设置字体抗锯齿默认为true
void setQuality(bool value);
protected:
LOGFONT m_font;
};
class FontWeight
{
public:
static const LONG dontcare; // 粗细值 0
static const LONG thin; // 粗细值 100
static const LONG extraLight; // 粗细值 200
static const LONG light; // 粗细值 300
static const LONG normal; // 粗细值 400
static const LONG regular; // 粗细值 400
static const LONG medium; // 粗细值 500
static const LONG demiBlod; // 粗细值 600
static const LONG blod; // 粗细值 700
static const LONG extraBold; // 粗细值 800
static const LONG black; // 粗细值 900
static const LONG heavy; // 粗细值 900
};
class Color
{
public:
static const COLORREF black; // 黑色
static const COLORREF blue; // 蓝色
static const COLORREF green; // 绿色
static const COLORREF cyan; // 青色
static const COLORREF red; // 红色
static const COLORREF magenta; // 紫色
static const COLORREF brown; // 棕色
static const COLORREF lightgray; // 亮灰色
static const COLORREF darkgray; // 深灰色
static const COLORREF lightblue; // 亮蓝色
static const COLORREF lightgreen; // 亮绿色
static const COLORREF lightcyan; // 亮青色
static const COLORREF lightred; // 亮红色
static const COLORREF lightmagenta; // 亮紫色
static const COLORREF yellow; // 亮黄色
static const COLORREF white; // 白色
// 通过红、绿、蓝颜色分量合成颜色
static COLORREF getFromRGB(BYTE r, BYTE g, BYTE b);
// 通过色相、饱和度、亮度合成颜色
static COLORREF getFromHSL(float H, float S, float L);
// 通过色相、饱和度、明度合成颜色
static COLORREF getFromHSV(float H, float S, float V);
// 返回指定颜色中的红色值
static BYTE getRValue(COLORREF color);
// 返回指定颜色中的绿色值
static BYTE getGValue(COLORREF color);
// 返回指定颜色中的蓝色值
static BYTE getBValue(COLORREF color);
// 返回与指定颜色对应的灰度值颜色
static COLORREF getGray(COLORREF color);
};
} // End of easy2d namespace

174
Easy2D/e2dtool.h Normal file
View File

@ -0,0 +1,174 @@
#pragma once
#include <e2dbase.h>
namespace easy2d
{
class Action;
class FileUtils
{
public:
// 获取系统的 AppData\Local 路径
static tstring getLocalAppDataPath();
// 获取默认的保存路径
static tstring getDefaultSavePath();
// 保存 int 型的值
static void saveInt(LPCTSTR key, int value);
// 保存 double 型的值
static void saveDouble(LPCTSTR key, double value);
// 保存 字符串 型的值(不要在 Unicode 字符集下保存中文字符)
static void saveString(LPCTSTR key, tstring value);
// 获取 int 型的值(若不存在则返回 default 参数的值)
static int getInt(LPCTSTR key, int default);
// 获取 double 型的值(若不存在则返回 default 参数的值)
static double getDouble(LPCTSTR key, double default);
// 获取 字符串 型的值(若不存在则返回 default 参数的值)
static tstring getString(LPCTSTR key, tstring default);
// 得到文件扩展名(小写)
static tstring getFileExtension(const tstring& filePath);
/**
* true
*
*/
static bool getSaveFilePath(tstring& path, LPCTSTR title = _T("保存到"), LPCTSTR defExt = NULL);
};
class MusicUtils
{
public:
// 播放背景音乐
static void playBackgroundMusic(tstring pszFilePath, bool bLoop = true);
// 停止背景音乐
static void stopBackgroundMusic(bool bReleaseData = false);
// 暂停背景音乐
static void pauseBackgroundMusic();
// 继续播放背景音乐
static void resumeBackgroundMusic();
// 从头播放背景音乐
static void rewindBackgroundMusic();
// 背景音乐是否正在播放
static bool isBackgroundMusicPlaying();
// 设置背景音乐音量0 ~ 1.0f
static void setBackgroundMusicVolume(float volume);
// 播放音效
static unsigned int playMusic(tstring pszFilePath, bool loop = false);
// 停止音效
static void stopMusic(unsigned int nSoundId);
// 预加载音效
static void preloadMusic(tstring pszFilePath);
// 暂停音效
static void pauseMusic(unsigned int nSoundId);
// 继续播放音效
static void resumeMusic(unsigned int nSoundId);
// 卸载音效
static void unloadMusic(LPCTSTR pszFilePath);
// 设置特定音乐的音量0 ~ 1.0f
static void setVolume(tstring pszFilePath, float volume);
// 暂停所有音乐
static void pauseAllMusics();
// 继续播放所有音乐
static void resumeAllMusics();
// 停止所有音乐
static void stopAllMusics();
// 停止所有音乐,并释放内存
static void end();
// 设置总音量0 ~ 1.0f
static void setVolume(float volume);
};
class Timer
{
friend class App;
public:
Timer(tstring name, UINT ms, const TIMER_CALLBACK & callback);
~Timer();
// 启动定时器
void start();
// 停止定时器
void stop();
// 定时器是否正在运行
bool isRunning();
// 设置间隔时间
void setInterval(UINT ms);
// 设置回调函数
void setCallback(const TIMER_CALLBACK& callback);
// 设置定时器名称
void setName(tstring name);
// 获取定时器间隔时间
UINT getInterval() const;
// 获取定时器名称
tstring getName() const;
// 添加定时器
static void addTimer(Timer * timer);
// 添加定时器
static void addTimer(tstring name, UINT ms, const TIMER_CALLBACK & callback);
// 根据名称获取定时器
static Timer * getTimer(tstring name);
// 启动特定定时器
static bool startTimer(tstring name);
// 停止特定定时器
static bool stopTimer(tstring name);
// 删除特定定时器
static bool delTimer(tstring name);
// 删除所有定时器
static void clearAllTimers();
protected:
bool m_bRunning;
tstring m_sName;
TIMER_CALLBACK m_callback;
LARGE_INTEGER m_nLast;
LARGE_INTEGER m_nAnimationInterval;
UINT m_nMilliSeconds;
private:
static void __exec();
};
class ActionManager
{
friend class App;
friend class Sprite;
public:
// 继续一个特定的动作
static void startAction(Action * action);
// 继续一个特定的动作
static void resumeAction(Action * action);
// 暂停一个特定的动作
static void pauseAction(Action * action);
// 停止一个特定的动作
static void stopAction(Action * action);
// 继续一个 Sprite 的所有动作
static void startSpriteAllActions(Sprite * sprite);
// 继续一个 Sprite 的所有动作
static void resumeSpriteAllActions(Sprite * sprite);
// 暂停一个 Sprite 的所有动作
static void pauseSpriteAllActions(Sprite * sprite);
// 停止一个 Sprite 的所有动作
static void stopSpriteAllActions(Sprite * sprite);
// 继续当前存在的所有动作
static void startAllActions();
// 继续当前存在的所有动作
static void resumeAllActions();
// 暂停当前存在的所有动作
static void pauseAllActions();
// 停止当前存在的所有动作
static void stopAllActions();
private:
static void __exec();
// 将一个动作添加进动作管理器
static void addAction(Action * action);
};
} // End of easy2d namespace

File diff suppressed because it is too large Load Diff