This commit is contained in:
werelone 2017-09-16 23:09:11 +08:00
parent 9471ff79c5
commit 9dc0b67544
13 changed files with 260 additions and 109 deletions

7
.gitignore vendored
View File

@ -1,3 +1,8 @@
# ignore all files in the /Easy2D/** directory # ignore all files in the /Easy2D/** directory
Easy2D/Win32/ Easy2D/Win32/
Easy2D/x64/ Easy2D/x64/
Win32
x64
backup
*.lnk
.vs

View File

@ -18,7 +18,6 @@ App::App() :
m_currentScene(nullptr), m_currentScene(nullptr),
m_nextScene(nullptr), m_nextScene(nullptr),
m_bRunning(false), m_bRunning(false),
m_bPause(false),
m_nWidth(0), m_nWidth(0),
m_nHeight(0), m_nHeight(0),
m_nWindowMode(0) m_nWindowMode(0)
@ -154,11 +153,6 @@ void App::_initGraph()
void App::_mainLoop() void App::_mainLoop()
{ {
// ÓÎÏ·ÔÝÍ£
if (m_bPause)
{
return;
}
// 进入下一场景 // 进入下一场景
if (m_nextScene) if (m_nextScene)
{ {
@ -294,16 +288,6 @@ void App::end()
m_bRunning = false; m_bRunning = false;
} }
void App::pause()
{
m_bPause = true;
}
bool App::isRunning()
{
return m_bRunning && !m_bPause;
}
void App::reset() void App::reset()
{ {
// 重置绘图环境 // 重置绘图环境
@ -320,7 +304,7 @@ Scene * App::getCurrentScene()
LPCTSTR easy2d::App::getVersion() LPCTSTR easy2d::App::getVersion()
{ {
return _T("1.0.0"); return _T("1.0.2");
} }
void App::setFPS(DWORD fps) void App::setFPS(DWORD fps)

View File

@ -334,9 +334,6 @@
<AdditionalLibraryDirectories>EasyX\x64</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>EasyX\x64</AdditionalLibraryDirectories>
</Lib> </Lib>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup>
<Text Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="App.cpp" /> <ClCompile Include="App.cpp" />
<ClCompile Include="FreePool.cpp" /> <ClCompile Include="FreePool.cpp" />

View File

@ -35,9 +35,6 @@
<UniqueIdentifier>{bdcd902b-b53d-4537-9632-76ea14c141a0}</UniqueIdentifier> <UniqueIdentifier>{bdcd902b-b53d-4537-9632-76ea14c141a0}</UniqueIdentifier>
</Filter> </Filter>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Text Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="Scene.cpp"> <ClCompile Include="Scene.cpp">
<Filter>源文件</Filter> <Filter>源文件</Filter>

View File

@ -32,7 +32,11 @@ void FreePool::__flush()
} }
} }
void FreePool::add(Object * nptr) void FreePool::__add(Object * nptr)
{ {
pool.push_back(nptr); // 将一个对象放入释放池中 for (auto o : pool)
{
if (o == nptr) return; // 不得有重复的指针存在
}
pool.push_back(nptr); // 将一个对象放入释放池中
} }

View File

@ -134,7 +134,7 @@ void KeyMsg::addListener(tstring name, const KEY_CALLBACK & callback)
s_vKeyMsg.push_back(key); s_vKeyMsg.push_back(key);
} }
bool easy2d::KeyMsg::delListener(tstring name) bool KeyMsg::delListener(tstring name)
{ {
// 创建迭代器 // 创建迭代器
std::vector<KeyMsg*>::iterator iter; std::vector<KeyMsg*>::iterator iter;
@ -154,12 +154,12 @@ bool easy2d::KeyMsg::delListener(tstring name)
return false; return false;
} }
void easy2d::KeyMsg::clearAllListener() void KeyMsg::clearAllListener()
{ {
// 删除所有监听器 // 删除所有监听器
for (auto t : s_vKeyMsg) for (auto k : s_vKeyMsg)
{ {
delete t; delete k;
} }
// 清空容器 // 清空容器
s_vKeyMsg.clear(); s_vKeyMsg.clear();

View File

@ -1,13 +1,16 @@
#include "..\easy2d.h" #include "..\easy2d.h"
#include "..\EasyX\easyx.h" #include "..\EasyX\easyx.h"
// 鼠标监听回调函数的容器
static std::vector<MouseMsg*> s_vMouseMsg;
// 鼠标消息 // 鼠标消息
static MouseMsg s_mouseMsg = MouseMsg(); static MouseMsg s_mouseMsg = MouseMsg();
// 将 EasyX 的 MOUSEMSG 转换为 MouseMsg // 将 EasyX 的 MOUSEMSG 转换为 MouseMsg
static void ConvertMsg(MOUSEMSG msg); static void ConvertMsg(MOUSEMSG msg);
void easy2d::MouseMsg::__exec() void MouseMsg::__exec()
{ {
// 获取鼠标消息 // 获取鼠标消息
while (MouseHit()) while (MouseHit())
@ -16,9 +19,72 @@ void easy2d::MouseMsg::__exec()
ConvertMsg(GetMouseMsg()); ConvertMsg(GetMouseMsg());
// 执行场景程序 // 执行场景程序
App::get()->getCurrentScene()->_exec(); App::get()->getCurrentScene()->_exec();
// 执行鼠标监听回调函数
for (auto m : s_vMouseMsg) // 循环遍历所有的鼠标监听
{
m->onMouseMsg(s_mouseMsg); // 执行回调函数
}
} }
} }
MouseMsg::MouseMsg()
{
}
MouseMsg::MouseMsg(tstring name, const MOUSE_CALLBACK & callback)
{
m_sName = name;
m_callback = callback;
}
MouseMsg::~MouseMsg()
{
}
void MouseMsg::onMouseMsg(MouseMsg mouse)
{
m_callback(mouse);
}
void MouseMsg::addListener(tstring name, const MOUSE_CALLBACK & callback)
{
// 创建新的监听对象
auto mouse = new MouseMsg(name, callback);
// 添加新的按键回调函数
s_vMouseMsg.push_back(mouse);
}
bool MouseMsg::delListener(tstring name)
{
// 创建迭代器
std::vector<MouseMsg*>::iterator iter;
// 循环遍历所有监听器
for (iter = s_vMouseMsg.begin(); iter != s_vMouseMsg.end(); iter++)
{
// 查找相同名称的监听器
if ((*iter)->m_sName == name)
{
// 删除该定时器
delete (*iter);
s_vMouseMsg.erase(iter);
return true;
}
}
// 若未找到同样名称的监听器,返回 false
return false;
}
void MouseMsg::clearAllListener()
{
// 删除所有监听器
for (auto m : s_vMouseMsg)
{
delete m;
}
// 清空容器
s_vMouseMsg.clear();
}
MouseMsg MouseMsg::getMsg() MouseMsg MouseMsg::getMsg()
{ {
return s_mouseMsg; // 获取当前鼠标消息 return s_mouseMsg; // 获取当前鼠标消息

View File

@ -14,7 +14,7 @@ Button::~Button()
bool Button::_exec(bool active) bool Button::_exec(bool active)
{ {
// 按钮是否启用 // 按钮是否启用
if (!m_bEnable || !m_bDisplay) if (!m_bEnable)
{ {
return false; return false;
} }
@ -33,27 +33,6 @@ void Button::_onDraw()
MouseNode::_onDraw(); MouseNode::_onDraw();
} }
void Button::_judge()
{
// 判断按钮当前的状态
// 若鼠标位置在按钮所在的矩形区域中
if (MouseMsg::getMsg().x >= m_nX && MouseMsg::getMsg().x <= m_nX + m_nWidth &&
MouseMsg::getMsg().y >= m_nY && MouseMsg::getMsg().y <= m_nY + m_nHeight)
{
_setMouseIn();
// 若鼠标在按钮上,且鼠标左键按下
if (MouseMsg::isLButtonDown())
{
_setSelected();
}
}
else
{
_setNormal();
}
}
bool Button::isEnable() bool Button::isEnable()
{ {
return m_bEnable; return m_bEnable;

View File

@ -52,10 +52,25 @@ float Image::getScaleY() const
return m_fScaleY; return m_fScaleY;
} }
void Image::setImageFile(LPCTSTR ImageFile, int x, int y, int width, int height) bool Image::setImageFile(LPCTSTR ImageFile, int x, int y, int width, int height)
{ {
//判断图片路径是否存在
if (!PathFileExists(ImageFile))
{
return false;
}
// 清空原资源
if (!m_Image.IsNull())
{
m_Image.Destroy();
}
// 加载图片 // 加载图片
m_Image.Load(ImageFile); m_Image.Load(ImageFile);
// 加载失败
if (m_Image.IsNull())
{
return false;
}
// 获取扩展名,对 PNG 图片进行特殊处理 // 获取扩展名,对 PNG 图片进行特殊处理
if (_T(".png") == FileUtils::getFileExtension(ImageFile)) if (_T(".png") == FileUtils::getFileExtension(ImageFile))
{ {
@ -68,18 +83,27 @@ void Image::setImageFile(LPCTSTR ImageFile, int x, int y, int width, int height)
m_rDest.SetRect(0, 0, m_Image.GetWidth(), m_Image.GetHeight()); m_rDest.SetRect(0, 0, m_Image.GetWidth(), m_Image.GetHeight());
// 裁剪图片大小 // 裁剪图片大小
crop(x, y, width, height); crop(x, y, width, height);
return true;
} }
void Image::setImageRes(LPCTSTR pResName, int x, int y, int width, int height) bool Image::setImageRes(LPCTSTR pResName, int x, int y, int width, int height)
{ {
// 从资源加载图片(不支持 PNG // 从资源加载图片(不支持 PNG
m_Image.LoadFromResource(GetModuleHandle(NULL), pResName); m_Image.LoadFromResource(GetModuleHandle(NULL), pResName);
// 加载失败
if (m_Image.IsNull())
{
return false;
}
// 重置缩放属性 // 重置缩放属性
m_fScaleX = 0, m_fScaleY = 0; m_fScaleX = 0, m_fScaleY = 0;
// 设置目标矩形(即绘制到窗口的位置和大小) // 设置目标矩形(即绘制到窗口的位置和大小)
m_rDest.SetRect(0, 0, m_Image.GetWidth(), m_Image.GetHeight()); m_rDest.SetRect(0, 0, m_Image.GetWidth(), m_Image.GetHeight());
// 裁剪图片大小 // 裁剪图片大小
crop(x, y, width, height); crop(x, y, width, height);
return true;
} }
void Image::crop(int x, int y, int width, int height) void Image::crop(int x, int y, int width, int height)

View File

@ -4,7 +4,11 @@
MouseNode::MouseNode() : MouseNode::MouseNode() :
m_bBlock(true), m_bBlock(true),
m_bTarget(false), m_bTarget(false),
m_callback([]() {}) m_ClickCallback([]() {}),
m_OnMouseInCallback([]() {}),
m_OnMouseOutCallback([]() {}),
m_OnSelectCallback([]() {}),
m_OnUnselectCallback([]() {})
{ {
} }
@ -19,15 +23,40 @@ bool MouseNode::_exec(bool active)
{ {
return false; return false;
} }
// 判断节点状态 // 判断节点当前的状态
_judge(); // 若节点未取得焦点,则重新判断节点状态
// 鼠标在节点上(被选中时鼠标也在节点上) if (!m_bTarget)
if (m_eStatus == MOUSEIN || m_eStatus == SELECTED)
{ {
// 节点被鼠标选中,且鼠标左键抬起 // 若鼠标位置在节点所在的矩形区域中
if (m_bTarget && MouseMsg::isOnLButtonUp()) if (_judge())
{ {
onClicked(); // 执行回调函数 // 状态设为 MOUSEIN
_setStatus(MOUSEIN);
// 若此时按下鼠标左键
if (MouseMsg::isOnLButtonDown())
{
m_bTarget = true; // 取得焦点标记
_setStatus(SELECTED); // 状态设为 SELECTED
}
// 若节点不阻塞鼠标消息,则取得画面焦点
if (!m_bBlock) return true;
}
else
{
reset(); // 恢复默认状态
}
}
else
{
// 节点取得焦点时鼠标左键抬起
if (MouseMsg::isOnLButtonUp())
{
// 若左键抬起时鼠标仍在节点内
if (_judge())
{
m_ClickCallback(); // 执行回调函数
}
reset(); // 恢复默认状态
} }
// 若节点不阻塞鼠标消息,则取得画面焦点 // 若节点不阻塞鼠标消息,则取得画面焦点
if (!m_bBlock) return true; if (!m_bBlock) return true;
@ -61,26 +90,36 @@ void MouseNode::_onDraw()
} }
} }
void MouseNode::_setNormal() bool MouseNode::_judge()
{ {
m_bTarget = false; // 失去焦点标记 return (MouseMsg::getMsg().x >= m_nX && MouseMsg::getMsg().x <= m_nX + m_nWidth) &&
m_eStatus = NORMAL; (MouseMsg::getMsg().y >= m_nY && MouseMsg::getMsg().y <= m_nY + m_nHeight);
} }
void MouseNode::_setMouseIn() void MouseNode::_setStatus(Status status)
{ {
m_eStatus = MOUSEIN; if (m_eStatus != status)
} {
// 退出某个状态的回调函数
void MouseNode::_setSelected() if (m_eStatus == MOUSEIN)
{ {
m_bTarget = true; // 取得焦点标记 m_OnMouseOutCallback();
m_eStatus = SELECTED; }
} else if (m_eStatus == SELECTED)
{
void MouseNode::onClicked() m_OnUnselectCallback();
{ }
m_callback(); // 进入某个状态的回调函数
if (status == MOUSEIN)
{
m_OnMouseInCallback();
}
else if (status == SELECTED)
{
m_OnSelectCallback();
}
m_eStatus = status;
}
} }
bool MouseNode::isMouseIn() bool MouseNode::isMouseIn()
@ -93,14 +132,35 @@ bool MouseNode::isSelected()
return m_eStatus == SELECTED; return m_eStatus == SELECTED;
} }
void MouseNode::setOnMouseClicked(const CLICK_CALLBACK & callback) void MouseNode::setClickedCallback(const CLICK_CALLBACK & callback)
{ {
m_callback = callback; m_ClickCallback = callback;
}
void MouseNode::setMouseInCallback(const CLICK_CALLBACK & callback)
{
m_OnMouseInCallback = callback;
}
void MouseNode::setMouseOutCallback(const CLICK_CALLBACK & callback)
{
m_OnMouseOutCallback = callback;
}
void MouseNode::setSelectCallback(const CLICK_CALLBACK & callback)
{
m_OnSelectCallback = callback;
}
void MouseNode::setUnselectCallback(const CLICK_CALLBACK & callback)
{
m_OnUnselectCallback = callback;
} }
void MouseNode::reset() void MouseNode::reset()
{ {
m_eStatus = NORMAL; m_bTarget = false; // 失去焦点标记
_setStatus(NORMAL); // 恢复默认状态
} }
void MouseNode::setBlock(bool block) void MouseNode::setBlock(bool block)

View File

@ -3,7 +3,7 @@
Object::Object() : Object::Object() :
m_nRef(0) m_nRef(0)
{ {
FreePool::add(this); // 将该对象放入释放池中 FreePool::__add(this); // 将该对象放入释放池中
} }
Object::~Object() Object::~Object()

View File

@ -266,6 +266,14 @@ void MusicUtils::end()
// BackgroundMusic // BackgroundMusic
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
/*
void MusicUtils::setVolume(float volume)
{
if (volume < 0 || volume > 1) return;
waveOutSetVolume(NULL, DWORD(volume * 65535));
}
*/
void MusicUtils::playBackgroundMusic(tstring pszFilePath, bool bLoop) void MusicUtils::playBackgroundMusic(tstring pszFilePath, bool bLoop)
{ {
if (pszFilePath.empty()) if (pszFilePath.empty())

View File

@ -1,5 +1,5 @@
/****************************************************** /******************************************************
* Easy2D Game Engine (v1.0.0) * Easy2D Game Engine (v1.0.2)
* http://www.easy2d.cn * http://www.easy2d.cn
* *
* Depends on EasyX (Ver:20170827(beta)) * Depends on EasyX (Ver:20170827(beta))
@ -31,6 +31,7 @@
#define SAFE_DELETE_ARRAY(p) { if (p) { delete[] (p); (p) = nullptr; } } #define SAFE_DELETE_ARRAY(p) { if (p) { delete[] (p); (p) = nullptr; } }
#define SAFE_RELEASE(p) { if (p) p->release(); } #define SAFE_RELEASE(p) { if (p) p->release(); }
#pragma warning (disable: 4099)
#include <windows.h> #include <windows.h>
#include <tchar.h> #include <tchar.h>
@ -83,10 +84,12 @@ class TextButton;
class ImageButton; class ImageButton;
typedef BatchNode Layer;
typedef unsigned int VK_KEY; typedef unsigned int VK_KEY;
typedef std::function<void()> CLICK_CALLBACK; typedef std::function<void()> CLICK_CALLBACK;
typedef std::function<void()> TIMER_CALLBACK; typedef std::function<void()> TIMER_CALLBACK;
typedef std::function<void(VK_KEY)> KEY_CALLBACK; typedef std::function<void(VK_KEY)> KEY_CALLBACK;
typedef std::function<void(MouseMsg)> MOUSE_CALLBACK;
class App class App
@ -101,7 +104,6 @@ protected:
int m_nHeight; int m_nHeight;
int m_nWindowMode; int m_nWindowMode;
bool m_bRunning; bool m_bRunning;
bool m_bPause;
bool m_bSaveScene; bool m_bSaveScene;
protected: protected:
@ -125,8 +127,6 @@ public:
static int getOriginY(); static int getOriginY();
// 启动程序 // 启动程序
int run(); int run();
// 暂停程序
void pause();
// 终止程序 // 终止程序
void quit(); void quit();
// 终止程序 // 终止程序
@ -151,8 +151,6 @@ public:
void backScene(); void backScene();
// 修改窗口背景色 // 修改窗口背景色
void setBkColor(COLORREF color); void setBkColor(COLORREF color);
// 游戏是否正在运行
bool isRunning();
// 设置帧率 // 设置帧率
void setFPS(DWORD fps); void setFPS(DWORD fps);
// 重置绘图样式为默认值 // 重置绘图样式为默认值
@ -170,13 +168,13 @@ public:
class FreePool class FreePool
{ {
friend class App; friend class App;
friend class Object;
private: private:
// 刷新内存池
static void __flush(); static void __flush();
public:
// 将一个节点放入释放池 // 将一个节点放入释放池
static void add(Object * nptr); static void __add(Object * nptr);
}; };
class Scene class Scene
@ -211,6 +209,10 @@ class MouseMsg
private: private:
static void __exec(); static void __exec();
protected:
tstring m_sName;
MOUSE_CALLBACK m_callback;
public: public:
UINT uMsg; // 当前鼠标消息 UINT uMsg; // 当前鼠标消息
bool mkLButton; // 鼠标左键是否按下 bool mkLButton; // 鼠标左键是否按下
@ -220,6 +222,21 @@ public:
short y; // 当前鼠标 y 坐标 short y; // 当前鼠标 y 坐标
short wheel; // 鼠标滚轮滚动值 (120 的倍数) short wheel; // 鼠标滚轮滚动值 (120 的倍数)
public:
MouseMsg();
MouseMsg(tstring name, const MOUSE_CALLBACK& callback);
~MouseMsg();
// 执行回调函数
void onMouseMsg(MouseMsg mouse);
// 添加键盘监听
static void addListener(tstring name, const MOUSE_CALLBACK& callback);
// 删除键盘监听
static bool delListener(tstring name);
// 删除所有键盘监听
static void clearAllListener();
public: public:
// 获取当前鼠标消息 // 获取当前鼠标消息
static MouseMsg getMsg(); static MouseMsg getMsg();
@ -530,7 +547,6 @@ class Node :
public virtual Object public virtual Object
{ {
friend class Scene; friend class Scene;
friend class Layer;
friend class BatchNode; friend class BatchNode;
protected: protected:
@ -634,13 +650,15 @@ public:
/** /**
* (png/bmp/jpg/gif/emf/wmf/ico) * (png/bmp/jpg/gif/emf/wmf/ico)
* *
*
*/ */
void setImageFile(LPCTSTR ImageFile, int x = 0, int y = 0, int width = 0, int height = 0); bool setImageFile(LPCTSTR ImageFile, int x = 0, int y = 0, int width = 0, int height = 0);
/** /**
* png (bmp/jpg/gif/emf/wmf/ico) * png (bmp/jpg/gif/emf/wmf/ico)
* *
*
*/ */
void setImageRes(LPCTSTR pResName, int x = 0, int y = 0, int width = 0, int height = 0); bool setImageRes(LPCTSTR pResName, int x = 0, int y = 0, int width = 0, int height = 0);
// 裁剪图片(裁剪后会恢复 stretch 拉伸) // 裁剪图片(裁剪后会恢复 stretch 拉伸)
void crop(int x = 0, int y = 0, int width = 0, int height = 0); void crop(int x = 0, int y = 0, int width = 0, int height = 0);
// 将图片拉伸到固定宽高 // 将图片拉伸到固定宽高
@ -711,19 +729,25 @@ class MouseNode :
private: private:
bool m_bTarget; bool m_bTarget;
bool m_bBlock; bool m_bBlock;
enum { NORMAL, MOUSEIN, SELECTED } m_eStatus; enum Status { NORMAL, MOUSEIN, SELECTED } m_eStatus;
CLICK_CALLBACK m_callback; CLICK_CALLBACK m_OnMouseInCallback;
CLICK_CALLBACK m_OnMouseOutCallback;
CLICK_CALLBACK m_OnSelectCallback;
CLICK_CALLBACK m_OnUnselectCallback;
CLICK_CALLBACK m_ClickCallback;
protected:
int m_nWidth;
int m_nHeight;
protected: protected:
virtual bool _exec(bool active) override; virtual bool _exec(bool active) override;
virtual void _onDraw() override; virtual void _onDraw() override;
void _setNormal(); // 重写这个方法可以自定义按钮的判断方法
void _setMouseIn(); virtual bool _judge();
void _setSelected(); // 切换状态
void _setStatus(Status status);
// 重写该函数,实现鼠标位置的判定
virtual void _judge() = 0;
// 正常状态 // 正常状态
virtual void _onNormal() = 0; virtual void _onNormal() = 0;
// 鼠标移入时 // 鼠标移入时
@ -735,14 +759,20 @@ public:
MouseNode(); MouseNode();
virtual ~MouseNode(); virtual ~MouseNode();
// 鼠标点击时
virtual void onClicked();
// 鼠标是否移入 // 鼠标是否移入
virtual bool isMouseIn(); virtual bool isMouseIn();
// 鼠标是否选中 // 鼠标是否选中
virtual bool isSelected(); virtual bool isSelected();
// 设置回调函数 // 设置回调函数
virtual void setOnMouseClicked(const CLICK_CALLBACK & callback); 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(); virtual void reset();
// 设置节点是否阻塞鼠标消息 // 设置节点是否阻塞鼠标消息
@ -754,14 +784,11 @@ class Button :
public virtual MouseNode public virtual MouseNode
{ {
protected: protected:
int m_nWidth;
int m_nHeight;
bool m_bEnable; bool m_bEnable;
protected: protected:
virtual bool _exec(bool active) override; virtual bool _exec(bool active) override;
virtual void _onDraw() override; virtual void _onDraw() override;
virtual void _judge() override;
virtual void _onNormal() = 0; virtual void _onNormal() = 0;
virtual void _onMouseIn() = 0; virtual void _onMouseIn() = 0;