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
Easy2D/Win32/
Easy2D/x64/
Easy2D/x64/
Win32
x64
backup
*.lnk
.vs

View File

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

View File

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

View File

@ -35,9 +35,6 @@
<UniqueIdentifier>{bdcd902b-b53d-4537-9632-76ea14c141a0}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<Text Include="ReadMe.txt" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="Scene.cpp">
<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);
}
bool easy2d::KeyMsg::delListener(tstring name)
bool KeyMsg::delListener(tstring name)
{
// 创建迭代器
std::vector<KeyMsg*>::iterator iter;
@ -154,12 +154,12 @@ bool easy2d::KeyMsg::delListener(tstring name)
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();

View File

@ -1,13 +1,16 @@
#include "..\easy2d.h"
#include "..\EasyX\easyx.h"
// 鼠标监听回调函数的容器
static std::vector<MouseMsg*> s_vMouseMsg;
// 鼠标消息
static MouseMsg s_mouseMsg = MouseMsg();
// 将 EasyX 的 MOUSEMSG 转换为 MouseMsg
static void ConvertMsg(MOUSEMSG msg);
void easy2d::MouseMsg::__exec()
void MouseMsg::__exec()
{
// 获取鼠标消息
while (MouseHit())
@ -16,9 +19,72 @@ void easy2d::MouseMsg::__exec()
ConvertMsg(GetMouseMsg());
// 执行场景程序
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()
{
return s_mouseMsg; // 获取当前鼠标消息

View File

@ -14,7 +14,7 @@ Button::~Button()
bool Button::_exec(bool active)
{
// 按钮是否启用
if (!m_bEnable || !m_bDisplay)
if (!m_bEnable)
{
return false;
}
@ -33,27 +33,6 @@ void Button::_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()
{
return m_bEnable;

View File

@ -52,10 +52,25 @@ float Image::getScaleY() const
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);
// 加载失败
if (m_Image.IsNull())
{
return false;
}
// 获取扩展名,对 PNG 图片进行特殊处理
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());
// 裁剪图片大小
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
m_Image.LoadFromResource(GetModuleHandle(NULL), pResName);
// 加载失败
if (m_Image.IsNull())
{
return false;
}
// 重置缩放属性
m_fScaleX = 0, m_fScaleY = 0;
// 设置目标矩形(即绘制到窗口的位置和大小)
m_rDest.SetRect(0, 0, m_Image.GetWidth(), m_Image.GetHeight());
// 裁剪图片大小
crop(x, y, width, height);
return true;
}
void Image::crop(int x, int y, int width, int height)

View File

@ -4,7 +4,11 @@
MouseNode::MouseNode() :
m_bBlock(true),
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;
}
// 判断节点状态
_judge();
// 鼠标在节点上(被选中时鼠标也在节点上)
if (m_eStatus == MOUSEIN || m_eStatus == SELECTED)
// 判断节点当前的状态
// 若节点未取得焦点,则重新判断节点状态
if (!m_bTarget)
{
// 节点被鼠标选中,且鼠标左键抬起
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;
@ -61,26 +90,36 @@ void MouseNode::_onDraw()
}
}
void MouseNode::_setNormal()
bool MouseNode::_judge()
{
m_bTarget = false; // 失去焦点标记
m_eStatus = NORMAL;
return (MouseMsg::getMsg().x >= m_nX && MouseMsg::getMsg().x <= m_nX + m_nWidth) &&
(MouseMsg::getMsg().y >= m_nY && MouseMsg::getMsg().y <= m_nY + m_nHeight);
}
void MouseNode::_setMouseIn()
void MouseNode::_setStatus(Status status)
{
m_eStatus = MOUSEIN;
}
void MouseNode::_setSelected()
{
m_bTarget = true; // 取得焦点标记
m_eStatus = SELECTED;
}
void MouseNode::onClicked()
{
m_callback();
if (m_eStatus != status)
{
// 退出某个状态的回调函数
if (m_eStatus == MOUSEIN)
{
m_OnMouseOutCallback();
}
else if (m_eStatus == SELECTED)
{
m_OnUnselectCallback();
}
// 进入某个状态的回调函数
if (status == MOUSEIN)
{
m_OnMouseInCallback();
}
else if (status == SELECTED)
{
m_OnSelectCallback();
}
m_eStatus = status;
}
}
bool MouseNode::isMouseIn()
@ -93,14 +132,35 @@ bool MouseNode::isSelected()
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()
{
m_eStatus = NORMAL;
m_bTarget = false; // 失去焦点标记
_setStatus(NORMAL); // 恢复默认状态
}
void MouseNode::setBlock(bool block)

View File

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

View File

@ -266,6 +266,14 @@ void MusicUtils::end()
// BackgroundMusic
//////////////////////////////////////////////////////////////////////////
/*
void MusicUtils::setVolume(float volume)
{
if (volume < 0 || volume > 1) return;
waveOutSetVolume(NULL, DWORD(volume * 65535));
}
*/
void MusicUtils::playBackgroundMusic(tstring pszFilePath, bool bLoop)
{
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
*
* Depends on EasyX (Ver:20170827(beta))
@ -31,6 +31,7 @@
#define SAFE_DELETE_ARRAY(p) { if (p) { delete[] (p); (p) = nullptr; } }
#define SAFE_RELEASE(p) { if (p) p->release(); }
#pragma warning (disable: 4099)
#include <windows.h>
#include <tchar.h>
@ -83,10 +84,12 @@ class TextButton;
class ImageButton;
typedef BatchNode Layer;
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(MouseMsg)> MOUSE_CALLBACK;
class App
@ -101,7 +104,6 @@ protected:
int m_nHeight;
int m_nWindowMode;
bool m_bRunning;
bool m_bPause;
bool m_bSaveScene;
protected:
@ -125,8 +127,6 @@ public:
static int getOriginY();
// 启动程序
int run();
// 暂停程序
void pause();
// 终止程序
void quit();
// 终止程序
@ -151,8 +151,6 @@ public:
void backScene();
// 修改窗口背景色
void setBkColor(COLORREF color);
// 游戏是否正在运行
bool isRunning();
// 设置帧率
void setFPS(DWORD fps);
// 重置绘图样式为默认值
@ -170,13 +168,13 @@ public:
class FreePool
{
friend class App;
friend class Object;
private:
// 刷新内存池
static void __flush();
public:
// 将一个节点放入释放池
static void add(Object * nptr);
static void __add(Object * nptr);
};
class Scene
@ -211,6 +209,10 @@ class MouseMsg
private:
static void __exec();
protected:
tstring m_sName;
MOUSE_CALLBACK m_callback;
public:
UINT uMsg; // 当前鼠标消息
bool mkLButton; // 鼠标左键是否按下
@ -220,6 +222,21 @@ public:
short y; // 当前鼠标 y 坐标
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:
// 获取当前鼠标消息
static MouseMsg getMsg();
@ -530,7 +547,6 @@ class Node :
public virtual Object
{
friend class Scene;
friend class Layer;
friend class BatchNode;
protected:
@ -634,13 +650,15 @@ public:
/**
* (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)
*
*
*/
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 拉伸)
void crop(int x = 0, int y = 0, int width = 0, int height = 0);
// 将图片拉伸到固定宽高
@ -711,19 +729,25 @@ class MouseNode :
private:
bool m_bTarget;
bool m_bBlock;
enum { NORMAL, MOUSEIN, SELECTED } m_eStatus;
CLICK_CALLBACK m_callback;
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:
int m_nWidth;
int m_nHeight;
protected:
virtual bool _exec(bool active) override;
virtual void _onDraw() override;
void _setNormal();
void _setMouseIn();
void _setSelected();
// 重写该函数,实现鼠标位置的判定
virtual void _judge() = 0;
// 重写这个方法可以自定义按钮的判断方法
virtual bool _judge();
// 切换状态
void _setStatus(Status status);
// 正常状态
virtual void _onNormal() = 0;
// 鼠标移入时
@ -735,14 +759,20 @@ public:
MouseNode();
virtual ~MouseNode();
// 鼠标点击时
virtual void onClicked();
// 鼠标是否移入
virtual bool isMouseIn();
// 鼠标是否选中
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();
// 设置节点是否阻塞鼠标消息
@ -754,14 +784,11 @@ class Button :
public virtual MouseNode
{
protected:
int m_nWidth;
int m_nHeight;
bool m_bEnable;
protected:
virtual bool _exec(bool active) override;
virtual void _onDraw() override;
virtual void _judge() override;
virtual void _onNormal() = 0;
virtual void _onMouseIn() = 0;