Easy2D v1.0.4

This commit is contained in:
werelone 2017-09-20 14:52:50 +08:00
parent 471ee23c3d
commit 35227bb85b
9 changed files with 621 additions and 514 deletions

View File

@ -7,6 +7,8 @@
#include <mmsystem.h> #include <mmsystem.h>
#pragma comment(lib, "winmm.lib") #pragma comment(lib, "winmm.lib")
// Easy2D °æ±¾ºÅ
#define E2D_VERSION _T("1.0.4")
// App 的唯一实例 // App 的唯一实例
static App * s_pInstance = nullptr; static App * s_pInstance = nullptr;
@ -144,10 +146,11 @@ void App::_initGraph()
TCHAR title[31]; TCHAR title[31];
GetWindowText(GetHWnd(), title, 30); GetWindowText(GetHWnd(), title, 30);
m_sTitle = title; m_sTitle = title;
m_sAppName = title;
} }
else else
{ {
setWindowText(m_sTitle); setWindowTitle(m_sTitle);
} }
} }
@ -197,6 +200,7 @@ void App::createWindow(tstring title, int width, int height, int mode)
m_nHeight = height; m_nHeight = height;
m_nWindowMode = mode; m_nWindowMode = mode;
m_sTitle = title; m_sTitle = title;
m_sAppName = title;
// 创建窗口 // 创建窗口
_initGraph(); _initGraph();
} }
@ -231,7 +235,7 @@ void App::setWindowSize(int width, int height)
reset(); reset();
} }
void App::setWindowText(tstring title) void App::setWindowTitle(tstring title)
{ {
// 设置窗口标题 // 设置窗口标题
SetWindowText(GetHWnd(), title.c_str()); SetWindowText(GetHWnd(), title.c_str());
@ -239,6 +243,11 @@ void App::setWindowText(tstring title)
m_sTitle = title; m_sTitle = title;
} }
tstring App::getWindowTitle()
{
return m_sTitle;
}
void App::close() void App::close()
{ {
closegraph(); // 关闭绘图环境 closegraph(); // 关闭绘图环境
@ -271,6 +280,16 @@ void App::clearScene()
} }
} }
void App::setAppName(tstring appname)
{
m_sAppName = appname;
}
tstring App::getAppName() const
{
return m_sAppName;
}
void App::setBkColor(COLORREF color) void App::setBkColor(COLORREF color)
{ {
setbkcolor(color); setbkcolor(color);
@ -321,9 +340,9 @@ Scene * App::getCurrentScene()
return m_currentScene; return m_currentScene;
} }
LPCTSTR easy2d::App::getVersion() LPCTSTR App::getVersion()
{ {
return _T("1.0.2"); return E2D_VERSION;
} }
void App::setFPS(DWORD fps) void App::setFPS(DWORD fps)

View File

@ -116,7 +116,7 @@ void KeyMsg::addListener(tstring name, const KEY_CALLBACK & callback)
s_vKeyMsg.push_back(key); s_vKeyMsg.push_back(key);
} }
bool KeyMsg::deleteListener(tstring name) bool KeyMsg::delListener(tstring name)
{ {
// 创建迭代器 // 创建迭代器
std::vector<KeyMsg*>::iterator iter; std::vector<KeyMsg*>::iterator iter;
@ -136,7 +136,7 @@ bool KeyMsg::deleteListener(tstring name)
return false; return false;
} }
void KeyMsg::clearAllListener() void KeyMsg::clearAllListeners()
{ {
// 删除所有监听器 // 删除所有监听器
for (auto k : s_vKeyMsg) for (auto k : s_vKeyMsg)
@ -156,18 +156,26 @@ bool KeyMsg::isKeyDown(VK_KEY key)
VK_KEY convert(int ascii) VK_KEY convert(int ascii)
{ {
if (ascii >= 'a' && ascii <= 'z' || ascii >= 'A' && ascii <= 'Z') // 字母键
if (ascii >= 'a' && ascii <= 'z')
{
return VK_KEY(ascii - ('a' - 'A'));
}
else if (ascii >= 'A' && ascii <= 'Z')
{ {
return VK_KEY(ascii); return VK_KEY(ascii);
} }
// 数字键
else if (ascii >= '0' && ascii <= '9') else if (ascii >= '0' && ascii <= '9')
{ {
return VK_KEY(ascii); return VK_KEY(ascii);
} }
// 回车、空格、Esc键
else if (ascii == 0x0D || ascii == 0x20 || ascii == 0x1B) else if (ascii == 0x0D || ascii == 0x20 || ascii == 0x1B)
{ {
return VK_KEY(ascii); return VK_KEY(ascii);
} }
// 功能键
else if (ascii == 0 || ascii == 0xE0) else if (ascii == 0 || ascii == 0xE0)
{ {
switch (_getch()) switch (_getch())

View File

@ -5,24 +5,21 @@
static std::vector<MouseMsg*> s_vMouseMsg; static std::vector<MouseMsg*> s_vMouseMsg;
// 鼠标消息 // 鼠标消息
static MouseMsg s_mouseMsg = MouseMsg(); static MOUSEMSG s_mouseMsg;
// 将 EasyX 的 MOUSEMSG 转换为 MouseMsg
static void ConvertMsg(MOUSEMSG msg);
void MouseMsg::__exec() void MouseMsg::__exec()
{ {
// 获取鼠标消息 // 获取鼠标消息
while (MouseHit()) while (MouseHit())
{ {
// 转换鼠标消息 // 获取鼠标消息
ConvertMsg(GetMouseMsg()); s_mouseMsg = GetMouseMsg();
// 执行场景程序 // 执行场景程序
App::get()->getCurrentScene()->_exec(); App::get()->getCurrentScene()->_exec();
// 执行鼠标监听回调函数 // 执行鼠标监听回调函数
for (auto m : s_vMouseMsg) // 循环遍历所有的鼠标监听 for (auto m : s_vMouseMsg) // 循环遍历所有的鼠标监听
{ {
m->onMouseMsg(s_mouseMsg); // 执行回调函数 m->onMouseMsg(); // 执行回调函数
} }
} }
} }
@ -41,9 +38,9 @@ MouseMsg::~MouseMsg()
{ {
} }
void MouseMsg::onMouseMsg(MouseMsg mouse) void MouseMsg::onMouseMsg()
{ {
m_callback(mouse); m_callback();
} }
void MouseMsg::addListener(tstring name, const MOUSE_CALLBACK & callback) void MouseMsg::addListener(tstring name, const MOUSE_CALLBACK & callback)
@ -54,7 +51,7 @@ void MouseMsg::addListener(tstring name, const MOUSE_CALLBACK & callback)
s_vMouseMsg.push_back(mouse); s_vMouseMsg.push_back(mouse);
} }
bool MouseMsg::deleteListener(tstring name) bool MouseMsg::delListener(tstring name)
{ {
// 创建迭代器 // 创建迭代器
std::vector<MouseMsg*>::iterator iter; std::vector<MouseMsg*>::iterator iter;
@ -74,7 +71,7 @@ bool MouseMsg::deleteListener(tstring name)
return false; return false;
} }
void MouseMsg::clearAllListener() void MouseMsg::clearAllListeners()
{ {
// 删除所有监听器 // 删除所有监听器
for (auto m : s_vMouseMsg) for (auto m : s_vMouseMsg)
@ -85,11 +82,6 @@ void MouseMsg::clearAllListener()
s_vMouseMsg.clear(); s_vMouseMsg.clear();
} }
MouseMsg MouseMsg::getMsg()
{
return s_mouseMsg; // 获取当前鼠标消息
}
bool MouseMsg::isLButtonDown() bool MouseMsg::isLButtonDown()
{ {
return s_mouseMsg.mkLButton; return s_mouseMsg.mkLButton;
@ -105,17 +97,17 @@ bool MouseMsg::isMButtonDown()
return s_mouseMsg.mkMButton; return s_mouseMsg.mkMButton;
} }
int MouseMsg::getMouseX() int MouseMsg::getX()
{ {
return s_mouseMsg.x; return s_mouseMsg.x;
} }
int MouseMsg::getMouseY() int MouseMsg::getY()
{ {
return s_mouseMsg.y; return s_mouseMsg.y;
} }
int MouseMsg::getMouseWheel() int MouseMsg::getWheel()
{ {
return s_mouseMsg.wheel; return s_mouseMsg.wheel;
} }
@ -179,17 +171,3 @@ void MouseMsg::resetMouseMsg()
{ {
s_mouseMsg.uMsg = 0; s_mouseMsg.uMsg = 0;
} }
void ConvertMsg(MOUSEMSG msg)
{
// 将 MOUSEMSG 转换为 MouseMsg
/// 虽然 MOUSEMSG 和 MouseMsg 本质上是一样的
/// 但是为了实现 Easy2D 与 EasyX 的分离,所以定义了新的 MouseMsg
s_mouseMsg.uMsg = msg.uMsg;
s_mouseMsg.mkLButton = msg.mkLButton;
s_mouseMsg.mkMButton = msg.mkMButton;
s_mouseMsg.mkRButton = msg.mkRButton;
s_mouseMsg.wheel = msg.wheel;
s_mouseMsg.x = msg.x;
s_mouseMsg.y = msg.y;
}

View File

@ -10,6 +10,13 @@ Image::Image() :
{ {
} }
Image::Image(LPCTSTR ImageFile) :
m_fScaleX(1),
m_fScaleY(1)
{
setImage(ImageFile); // 设置图片资源
}
Image::Image(LPCTSTR ImageFile, int x, int y, int width, int height) : Image::Image(LPCTSTR ImageFile, int x, int y, int width, int height) :
m_fScaleX(1), m_fScaleX(1),
m_fScaleY(1) m_fScaleY(1)
@ -82,6 +89,9 @@ bool Image::setImage(LPCTSTR ImageFile)
// 设置目标矩形(即绘制到窗口的位置和大小) // 设置目标矩形(即绘制到窗口的位置和大小)
m_rDest.SetRect(m_nX, m_nY, m_nX + m_Image.GetWidth(), m_nY + m_Image.GetHeight()); 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_rSrc.SetRect(0, 0, m_Image.GetWidth(), m_Image.GetHeight());
// 重置缩放属性
m_fScaleX = 1;
m_fScaleY = 1;
return true; return true;
} }
@ -110,6 +120,9 @@ bool Image::setImageFromRes(LPCTSTR pResName)
// 设置目标矩形(即绘制到窗口的位置和大小) // 设置目标矩形(即绘制到窗口的位置和大小)
m_rDest.SetRect(m_nX, m_nY, m_nX + m_Image.GetWidth(), m_nY + m_Image.GetHeight()); 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_rSrc.SetRect(0, 0, m_Image.GetWidth(), m_Image.GetHeight());
// 重置缩放属性
m_fScaleX = 1;
m_fScaleY = 1;
return true; return true;
} }
@ -128,25 +141,23 @@ bool Image::setImageFromRes(LPCTSTR pResName, int x, int y, int width, int heigh
void Image::crop(int x, int y, int width, int height) 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( m_rSrc.SetRect(x, y, x + width, y + height);
x, y,
x + (width ? width : m_Image.GetWidth() - x),
y + (height ? height : m_Image.GetHeight() - y));
// 设置目标矩形(即绘制到窗口的位置和大小) // 设置目标矩形(即绘制到窗口的位置和大小)
m_rDest.SetRect( m_rDest.SetRect(m_nX, m_nY, m_nX + int(width * m_fScaleX), m_nY + int(height * m_fScaleY));
m_nX, m_nY,
m_nX + (width ? width : int(m_rSrc.Width() * m_fScaleX)),
m_nY + (height ? height : int(m_rSrc.Height() * m_fScaleY)));
} }
void Image::stretch(int width, int height) void Image::stretch(int width, int height)
{ {
width = max(width, 0);
height = max(height, 0);
// 设置目标矩形的位置和大小(即绘制到窗口的位置和大小,用于拉伸图片) // 设置目标矩形的位置和大小(即绘制到窗口的位置和大小,用于拉伸图片)
m_rDest.SetRect( m_rDest.SetRect(m_nX, m_nY, m_nX + width, m_nY + height);
m_nX, m_nY, // 重置比例缩放属性
m_nX + (width ? width : m_Image.GetWidth()), m_fScaleX = 1;
m_nY + (height ? height : m_Image.GetHeight())); m_fScaleY = 1;
} }
void Image::scale(float scaleX, float scaleY) void Image::scale(float scaleX, float scaleY)
@ -155,8 +166,8 @@ void Image::scale(float scaleX, float scaleY)
m_fScaleY = max(scaleY, 0); m_fScaleY = max(scaleY, 0);
m_rDest.SetRect( m_rDest.SetRect(
m_nX, m_nY, m_nX, m_nY,
m_nX + int(m_Image.GetWidth() * scaleX), m_nX + int(m_rSrc.Width() * scaleX),
m_nY + int(m_Image.GetHeight() * scaleY)); m_nY + int(m_rSrc.Height() * scaleY));
} }
void Image::setPos(int x, int y) void Image::setPos(int x, int y)
@ -195,7 +206,7 @@ void Image::setTransparentColor(COLORREF value)
m_Image.SetTransparentColor(value); m_Image.SetTransparentColor(value);
} }
void Image::screenshot() void Image::saveScreenshot()
{ {
tstring savePath; tstring savePath;
// 获取保存位置 // 获取保存位置

View File

@ -98,8 +98,8 @@ void MouseNode::_onDraw()
bool MouseNode::_judge() bool MouseNode::_judge()
{ {
return (MouseMsg::getMsg().x >= m_nX && MouseMsg::getMsg().x <= m_nX + m_nWidth) && return (MouseMsg::getX() >= m_nX && MouseMsg::getX() <= m_nX + m_nWidth) &&
(MouseMsg::getMsg().y >= m_nY && MouseMsg::getMsg().y <= m_nY + m_nHeight); (MouseMsg::getY() >= m_nY && MouseMsg::getY() <= m_nY + m_nHeight);
} }
void MouseNode::_setStatus(Status status) void MouseNode::_setStatus(Status status)

View File

@ -1,7 +1,130 @@
#include "..\Easy2d.h" #include "..\Easy2d.h"
#include "..\EasyX\easyx.h" #include "..\EasyX\easyx.h"
#include <algorithm> #include <algorithm>
#include <sstream>
#include <Shlobj.h>
#pragma comment(lib, "shell32.lib")
#ifndef UNICODE
#include <io.h>
#include <direct.h>
#endif
tstring FileUtils::getLocalAppDataPath()
{
TCHAR m_lpszDefaultDir[MAX_PATH] = { 0 };
TCHAR szDocument[MAX_PATH] = { 0 };
// 获取 AppData\Local 文件夹的 ID
LPITEMIDLIST pidl = NULL;
SHGetSpecialFolderLocation(NULL, CSIDL_LOCAL_APPDATA, &pidl);
if (pidl && SHGetPathFromIDList(pidl, szDocument))
{
// 获取文件夹路径
GetShortPathName(szDocument, m_lpszDefaultDir, _MAX_PATH);
}
return m_lpszDefaultDir;
}
tstring FileUtils::getDefaultSavePath()
{
TCHAR m_lpszDefaultDir[MAX_PATH] = { 0 };
TCHAR szDocument[MAX_PATH] = { 0 };
// 获取 AppData\Local 文件夹的 ID
LPITEMIDLIST pidl = NULL;
SHGetSpecialFolderLocation(NULL, CSIDL_LOCAL_APPDATA, &pidl);
if (pidl && SHGetPathFromIDList(pidl, szDocument))
{
// 获取文件夹路径
GetShortPathName(szDocument, m_lpszDefaultDir, _MAX_PATH);
}
tstring path = m_lpszDefaultDir;
path.append(_T("\\"));
path.append(App::get()->getAppName());
#ifdef UNICODE
if (_waccess(path.c_str(), 0) == -1)
{
_wmkdir(path.c_str());
}
#else
if (_access(path.c_str(), 0) == -1)
{
_mkdir(path.c_str());
}
#endif
path.append(_T("\\DefaultData.ini"));
return path;
}
void FileUtils::saveInt(LPCTSTR key, int value)
{
#ifdef UNICODE
std::wstringstream ss;
#else
std::stringstream ss;
#endif
ss << value;
::WritePrivateProfileString(_T("Default"), key, ss.str().c_str(), getDefaultSavePath().c_str());
}
void FileUtils::saveDouble(LPCTSTR key, double value)
{
#ifdef UNICODE
std::wstringstream ss;
#else
std::stringstream ss;
#endif
ss << value;
::WritePrivateProfileString(_T("Default"), key, ss.str().c_str(), getDefaultSavePath().c_str());
}
void FileUtils::saveString(LPCTSTR key, tstring value)
{
::WritePrivateProfileString(_T("Default"), key, value.c_str(), getDefaultSavePath().c_str());
}
int FileUtils::getInt(LPCTSTR key, int default)
{
return ::GetPrivateProfileInt(_T("Default"), key, default, getDefaultSavePath().c_str());
}
#include <iostream>
using namespace std;
double FileUtils::getDouble(LPCTSTR key, double default)
{
// 将 default 参数转化为字符串
#ifdef UNICODE
std::wstringstream ss;
#else
std::stringstream ss;
#endif
ss << default;
// 读取数据
TCHAR temp[128] = { 0 };
::GetPrivateProfileString(_T("Default"), key, ss.str().c_str(), temp, 128, getDefaultSavePath().c_str());
// 转换为字符串流
ss.str(_T(""));
ss << temp;
// 将字符串转化为 double
#ifdef UNICODE
double d = _wtof(ss.str().c_str());
#else
double d = atof(ss.str().c_str());
#endif
return d;
}
tstring FileUtils::getString(LPCTSTR key, tstring default)
{
TCHAR temp[128] = { 0 };
::GetPrivateProfileString(_T("Default"), key, default.c_str(), temp, 128, getDefaultSavePath().c_str());
return tstring(temp);
}
tstring FileUtils::getFileExtension(const tstring & filePath) tstring FileUtils::getFileExtension(const tstring & filePath)
{ {

View File

@ -1,8 +1,5 @@
#include "..\Easy2d.h" #include "..\Easy2d.h"
#include <Digitalv.h>
/* 注MusicUtils 类完全仿照 Cocos2dx 中的 SimpleAudioEngine 实现 */
#include <mmsystem.h> #include <mmsystem.h>
#pragma comment(lib , "winmm.lib") #pragma comment(lib , "winmm.lib")
#include <map> #include <map>
@ -17,210 +14,184 @@ public:
MciPlayer(); MciPlayer();
~MciPlayer(); ~MciPlayer();
void Close(); void close();
void Open(tstring pFileName, UINT uId); void open(tstring pFileName, UINT uId);
void Play(UINT uTimes = 1); void play(bool bLoop = false);
void Pause(); void pause();
void Resume(); void resume();
void Stop(); void stop();
void Rewind(); void rewind();
bool IsPlaying(); void setVolume(float volume);
UINT GetSoundID(); bool isPlaying();
UINT getSoundID();
private: private:
friend LRESULT WINAPI _SoundPlayProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); void _sendCommand(int nCommand, DWORD_PTR param1 = 0, DWORD_PTR parma2 = 0);
void _SendGenericCommand(int nCommand, DWORD_PTR param1 = 0, DWORD_PTR parma2 = 0); MCIDEVICEID m_dev;
UINT m_nSoundID;
HWND _wnd; bool m_bPlaying;
MCIDEVICEID _dev; bool m_bLoop;
UINT _soundID; tstring m_sExt;
UINT _times;
bool _playing;
tstring strExt;
}; };
MciPlayer::MciPlayer() :
#define WIN_CLASS_NAME "Easy2dCallbackWnd" m_dev(0L),
m_nSoundID(0),
static HINSTANCE s_hInstance; m_bPlaying(false),
static MCIERROR s_mciError; m_bLoop(false),
m_sExt(_T(""))
LRESULT WINAPI _SoundPlayProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
MciPlayer::MciPlayer()
: _wnd(NULL)
, _dev(0L)
, _soundID(0)
, _times(0)
, _playing(false)
, strExt(_T(""))
{ {
if (!s_hInstance)
{
s_hInstance = GetModuleHandle(NULL); // Grab An Instance For Our Window
WNDCLASS wc; // Windows Class Structure
// Redraw On Size, And Own DC For Window.
wc.style = 0;
wc.lpfnWndProc = _SoundPlayProc; // WndProc Handles Messages
wc.cbClsExtra = 0; // No Extra Window Data
wc.cbWndExtra = 0; // No Extra Window Data
wc.hInstance = s_hInstance; // Set The Instance
wc.hIcon = 0; // Load The Default Icon
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load The Arrow Pointer
wc.hbrBackground = NULL; // No Background Required For GL
wc.lpszMenuName = NULL; // We Don't Want A Menu
wc.lpszClassName = _T(WIN_CLASS_NAME); // Set The Class Name
if (!RegisterClass(&wc) // Register Our Class
&& GetLastError() != 1410) // Class is Already Existent
{
return;
}
}
_wnd = CreateWindowEx(
WS_EX_APPWINDOW, // Extended Style For The Window
_T(WIN_CLASS_NAME), // Class Name
NULL, // Window Title
WS_POPUPWINDOW, // Defined Window Style
0, 0, // Window Position
0, 0, // Window Width And Height
NULL, // No Parent Window
NULL, // No Menu
s_hInstance, // Instance
NULL); // No Param
if (_wnd)
{
SetWindowLongPtr(_wnd, GWLP_USERDATA, (LONG_PTR)this);
}
} }
MciPlayer::~MciPlayer() MciPlayer::~MciPlayer()
{ {
Close(); close(); // 关闭播放器
DestroyWindow(_wnd);
} }
void MciPlayer::Open(tstring pFileName, UINT uId) void MciPlayer::open(tstring pFileName, UINT uId)
{ {
if (pFileName.empty() || !_wnd) return; // 忽略不存在的文件
int nLen = (int)pFileName.size(); if (pFileName.empty() || !PathFileExists(pFileName.c_str())) return;
if (!nLen) return; // 获取文件后缀名
m_sExt = FileUtils::getFileExtension(pFileName);
strExt = FileUtils::getFileExtension(pFileName); // 停止当前音乐
close();
Close();
// 设置 MCI_OPEN_PARMS 参数
MCI_OPEN_PARMS mciOpen = { 0 }; MCI_OPEN_PARMS mciOpen = { 0 };
MCIERROR mciError;
mciOpen.lpstrDeviceType = (LPCTSTR)MCI_ALL_DEVICE_ID; mciOpen.lpstrDeviceType = (LPCTSTR)MCI_ALL_DEVICE_ID;
mciOpen.lpstrElementName = pFileName.c_str(); mciOpen.lpstrElementName = pFileName.c_str();
// 打开这个文件
MCIERROR mciError;
mciError = mciSendCommand(0, MCI_OPEN, MCI_OPEN_ELEMENT, reinterpret_cast<DWORD_PTR>(&mciOpen)); mciError = mciSendCommand(0, MCI_OPEN, MCI_OPEN_ELEMENT, reinterpret_cast<DWORD_PTR>(&mciOpen));
// 出现错误时,忽略这次操作
if (mciError) return; if (mciError) return;
_dev = mciOpen.wDeviceID; // 保存设备等信息
_soundID = uId; m_dev = mciOpen.wDeviceID;
_playing = false; m_nSoundID = uId;
m_bPlaying = false;
} }
void MciPlayer::Play(UINT uTimes /* = 1 */) void MciPlayer::play(bool bLoop)
{ {
if (!_dev) // 设备为空时,忽略这次操作
if (!m_dev)
{ {
return; return;
} }
// 设置播放参数
MCI_PLAY_PARMS mciPlay = { 0 }; MCI_PLAY_PARMS mciPlay = { 0 };
mciPlay.dwCallback = reinterpret_cast<DWORD_PTR>(_wnd); MCIERROR s_mciError;
s_mciError = mciSendCommand(_dev, MCI_PLAY, MCI_FROM | MCI_NOTIFY, reinterpret_cast<DWORD_PTR>(&mciPlay)); // 播放声音
s_mciError = mciSendCommand(m_dev, MCI_PLAY, MCI_FROM | (bLoop ? MCI_DGV_PLAY_REPEAT : 0), reinterpret_cast<DWORD_PTR>(&mciPlay));
// 未出错时,置 m_bPlaying 为 true
if (!s_mciError) if (!s_mciError)
{ {
_playing = true; m_bPlaying = true;
_times = uTimes; m_bLoop = bLoop;
} }
} }
void MciPlayer::Close() void MciPlayer::close()
{ {
if (_playing) // 停止音乐
if (m_bPlaying)
{ {
Stop(); stop();
} }
if (_dev) // 关闭设备
if (m_dev)
{ {
_SendGenericCommand(MCI_CLOSE); _sendCommand(MCI_CLOSE);
} }
_dev = 0; // 恢复默认属性
_playing = false; m_dev = 0;
m_bPlaying = false;
} }
void MciPlayer::Pause() void MciPlayer::pause()
{ {
_SendGenericCommand(MCI_PAUSE); // 暂停音乐
_playing = false; _sendCommand(MCI_PAUSE);
m_bPlaying = false;
} }
void MciPlayer::Resume() void MciPlayer::resume()
{ {
if (strExt == _T(".mid")) // 继续音乐
if (m_sExt == _T(".mid"))
{ {
// midi not support MCI_RESUME, should get the position and use MCI_FROM // midi 不支持 MCI_RESUME 参数,应使用 MCI_FROM 设置播放起始位置
// 获取 MCI 状态
MCI_STATUS_PARMS mciStatusParms; MCI_STATUS_PARMS mciStatusParms;
MCI_PLAY_PARMS mciPlayParms;
mciStatusParms.dwItem = MCI_STATUS_POSITION; mciStatusParms.dwItem = MCI_STATUS_POSITION;
_SendGenericCommand(MCI_STATUS, MCI_STATUS_ITEM, reinterpret_cast<DWORD_PTR>(&mciStatusParms)); // MCI_STATUS _sendCommand(MCI_STATUS, MCI_STATUS_ITEM, reinterpret_cast<DWORD_PTR>(&mciStatusParms));
mciPlayParms.dwFrom = mciStatusParms.dwReturn; // get position // 设置播放起始位置,并开始播放
_SendGenericCommand(MCI_PLAY, MCI_FROM, reinterpret_cast<DWORD_PTR>(&mciPlayParms)); // MCI_FROM MCI_PLAY_PARMS mciPlayParms;
mciPlayParms.dwFrom = mciStatusParms.dwReturn;
_sendCommand(MCI_PLAY, MCI_FROM, reinterpret_cast<DWORD_PTR>(&mciPlayParms));
} }
else else
{ {
_SendGenericCommand(MCI_RESUME); // 继续播放音乐
_playing = true; _sendCommand(MCI_RESUME);
m_bPlaying = true;
} }
} }
void MciPlayer::Stop() void MciPlayer::stop()
{ {
_SendGenericCommand(MCI_STOP); // 停止音乐
_playing = false; _sendCommand(MCI_STOP);
_times = 0; m_bPlaying = false;
} }
void MciPlayer::Rewind() void MciPlayer::rewind()
{ {
if (!_dev) // 设备为空时,忽略这次操作
if (!m_dev)
{ {
return; return;
} }
mciSendCommand(_dev, MCI_SEEK, MCI_SEEK_TO_START, 0); // 重置播放位置
mciSendCommand(m_dev, MCI_SEEK, MCI_SEEK_TO_START, 0);
// 播放音乐
MCI_PLAY_PARMS mciPlay = { 0 }; MCI_PLAY_PARMS mciPlay = { 0 };
mciPlay.dwCallback = reinterpret_cast<DWORD_PTR>(_wnd); m_bPlaying = mciSendCommand(m_dev, MCI_PLAY, (m_bLoop ? MCI_DGV_PLAY_REPEAT : 0), reinterpret_cast<DWORD_PTR>(&mciPlay)) ? false : true;
_playing = mciSendCommand(_dev, MCI_PLAY, MCI_NOTIFY, reinterpret_cast<DWORD_PTR>(&mciPlay)) ? false : true;
} }
bool MciPlayer::IsPlaying() void MciPlayer::setVolume(float volume)
{ {
return _playing; volume = min(max(volume, 0), 1);
MCI_DGV_SETAUDIO_PARMS mciSetAudioPara = { 0 };
mciSetAudioPara.dwItem = MCI_DGV_SETAUDIO_VOLUME;
mciSetAudioPara.dwValue = DWORD(1000 * volume);
mciSendCommand(m_dev, MCI_SETAUDIO, MCI_DGV_SETAUDIO_VALUE | MCI_DGV_SETAUDIO_ITEM, (DWORD)(LPVOID)&mciSetAudioPara);
} }
UINT MciPlayer::GetSoundID() bool MciPlayer::isPlaying()
{ {
return _soundID; return m_bPlaying;
} }
void MciPlayer::_SendGenericCommand(int nCommand, DWORD_PTR param1 /*= 0*/, DWORD_PTR parma2 /*= 0*/) UINT MciPlayer::getSoundID()
{ {
if (!_dev) return m_nSoundID;
}
void MciPlayer::_sendCommand(int nCommand, DWORD_PTR param1, DWORD_PTR parma2)
{
// 空设备时忽略这次操作
if (!m_dev)
{ {
return; return;
} }
mciSendCommand(_dev, nCommand, param1, parma2); // 向当前设备发送操作
mciSendCommand(m_dev, nCommand, param1, parma2);
} }
@ -234,17 +205,16 @@ void MciPlayer::_SendGenericCommand(int nCommand, DWORD_PTR param1 /*= 0*/, DWOR
typedef std::map<unsigned int, MciPlayer *> MusicList; typedef std::map<unsigned int, MciPlayer *> MusicList;
typedef std::pair<unsigned int, MciPlayer *> Music; typedef std::pair<unsigned int, MciPlayer *> Music;
static unsigned int _Hash(tstring key); static unsigned int _Hash(tstring key);
static MusicList& sharedList() static MusicList& getMciPlayerList()
{ {
static MusicList s_List; static MusicList s_List;
return s_List; return s_List;
} }
static MciPlayer& sharedMusic() static MciPlayer& getBgMciPlayer()
{ {
static MciPlayer s_Music; static MciPlayer s_Music;
return s_Music; return s_Music;
@ -252,27 +222,39 @@ static MciPlayer& sharedMusic()
void MusicUtils::end() void MusicUtils::end()
{ {
sharedMusic().Close(); // 停止背景音乐
getBgMciPlayer().close();
for (auto& iter : sharedList()) // 停止其他所有音乐
for (auto& iter : getMciPlayerList())
{ {
SAFE_DELETE(iter.second); SAFE_DELETE(iter.second);
} }
sharedList().clear(); // 清空音乐列表
getMciPlayerList().clear();
return; return;
} }
//////////////////////////////////////////////////////////////////////////
// BackgroundMusic
//////////////////////////////////////////////////////////////////////////
/*
void MusicUtils::setVolume(float volume) void MusicUtils::setVolume(float volume)
{ {
if (volume < 0 || volume > 1) return; // 设置背景音乐音量
waveOutSetVolume(NULL, DWORD(volume * 65535)); getBgMciPlayer().setVolume(volume);
// 设置其他音乐音量
for (auto& iter : getMciPlayerList())
{
iter.second->setVolume(volume);
}
}
void MusicUtils::setVolume(tstring pszFilePath, float volume)
{
unsigned int nRet = ::_Hash(pszFilePath);
MusicList::iterator p = getMciPlayerList().find(nRet);
if (p != getMciPlayerList().end())
{
p->second->setVolume(volume);
}
} }
*/
void MusicUtils::playBackgroundMusic(tstring pszFilePath, bool bLoop) void MusicUtils::playBackgroundMusic(tstring pszFilePath, bool bLoop)
{ {
@ -281,45 +263,46 @@ void MusicUtils::playBackgroundMusic(tstring pszFilePath, bool bLoop)
return; return;
} }
sharedMusic().Open(pszFilePath, ::_Hash(pszFilePath)); getBgMciPlayer().open(pszFilePath, ::_Hash(pszFilePath));
sharedMusic().Play((bLoop) ? -1 : 1); getBgMciPlayer().play(bLoop);
} }
void MusicUtils::stopBackgroundMusic(bool bReleaseData) void MusicUtils::stopBackgroundMusic(bool bReleaseData)
{ {
if (bReleaseData) if (bReleaseData)
{ {
sharedMusic().Close(); getBgMciPlayer().close();
} }
else else
{ {
sharedMusic().Stop(); getBgMciPlayer().stop();
} }
} }
void MusicUtils::pauseBackgroundMusic() void MusicUtils::pauseBackgroundMusic()
{ {
sharedMusic().Pause(); getBgMciPlayer().pause();
} }
void MusicUtils::resumeBackgroundMusic() void MusicUtils::resumeBackgroundMusic()
{ {
sharedMusic().Resume(); getBgMciPlayer().resume();
} }
void MusicUtils::rewindBackgroundMusic() void MusicUtils::rewindBackgroundMusic()
{ {
sharedMusic().Rewind(); getBgMciPlayer().rewind();
} }
bool MusicUtils::isBackgroundMusicPlaying() bool MusicUtils::isBackgroundMusicPlaying()
{ {
return sharedMusic().IsPlaying(); return getBgMciPlayer().isPlaying();
} }
////////////////////////////////////////////////////////////////////////// void MusicUtils::setBackgroundMusicVolume(float volume)
// effect function {
////////////////////////////////////////////////////////////////////////// getBgMciPlayer().setVolume(volume);
}
unsigned int MusicUtils::playMusic(tstring pszFilePath, bool bLoop) unsigned int MusicUtils::playMusic(tstring pszFilePath, bool bLoop)
{ {
@ -327,20 +310,20 @@ unsigned int MusicUtils::playMusic(tstring pszFilePath, bool bLoop)
preloadMusic(pszFilePath); preloadMusic(pszFilePath);
MusicList::iterator p = sharedList().find(nRet); MusicList::iterator p = getMciPlayerList().find(nRet);
if (p != sharedList().end()) if (p != getMciPlayerList().end())
{ {
p->second->Play((bLoop) ? -1 : 1); p->second->play(bLoop);
} }
return nRet; return nRet;
} }
void MusicUtils::stopMusic(unsigned int nSoundId) void MusicUtils::stopMusic(unsigned int nSoundId)
{ {
MusicList::iterator p = sharedList().find(nSoundId); MusicList::iterator p = getMciPlayerList().find(nSoundId);
if (p != sharedList().end()) if (p != getMciPlayerList().end())
{ {
p->second->Stop(); p->second->stop();
} }
} }
@ -350,58 +333,58 @@ void MusicUtils::preloadMusic(tstring pszFilePath)
int nRet = ::_Hash(pszFilePath); int nRet = ::_Hash(pszFilePath);
if (sharedList().end() != sharedList().find(nRet)) return; if (getMciPlayerList().end() != getMciPlayerList().find(nRet)) return;
sharedList().insert(Music(nRet, new MciPlayer())); getMciPlayerList().insert(Music(nRet, new MciPlayer()));
MciPlayer * pPlayer = sharedList()[nRet]; MciPlayer * pPlayer = getMciPlayerList()[nRet];
pPlayer->Open(pszFilePath, nRet); pPlayer->open(pszFilePath, nRet);
if (nRet == pPlayer->GetSoundID()) return; if (nRet == pPlayer->getSoundID()) return;
delete pPlayer; delete pPlayer;
sharedList().erase(nRet); getMciPlayerList().erase(nRet);
nRet = 0; nRet = 0;
} }
void MusicUtils::pauseMusic(unsigned int nSoundId) void MusicUtils::pauseMusic(unsigned int nSoundId)
{ {
MusicList::iterator p = sharedList().find(nSoundId); MusicList::iterator p = getMciPlayerList().find(nSoundId);
if (p != sharedList().end()) if (p != getMciPlayerList().end())
{ {
p->second->Pause(); p->second->pause();
} }
} }
void MusicUtils::pauseAllMusics() void MusicUtils::pauseAllMusics()
{ {
for (auto& iter : sharedList()) for (auto& iter : getMciPlayerList())
{ {
iter.second->Pause(); iter.second->pause();
} }
} }
void MusicUtils::resumeMusic(unsigned int nSoundId) void MusicUtils::resumeMusic(unsigned int nSoundId)
{ {
MusicList::iterator p = sharedList().find(nSoundId); MusicList::iterator p = getMciPlayerList().find(nSoundId);
if (p != sharedList().end()) if (p != getMciPlayerList().end())
{ {
p->second->Resume(); p->second->resume();
} }
} }
void MusicUtils::resumeAllMusics() void MusicUtils::resumeAllMusics()
{ {
for (auto& iter : sharedList()) for (auto& iter : getMciPlayerList())
{ {
iter.second->Resume(); iter.second->resume();
} }
} }
void MusicUtils::stopAllMusics() void MusicUtils::stopAllMusics()
{ {
for (auto& iter : sharedList()) for (auto& iter : getMciPlayerList())
{ {
iter.second->Stop(); iter.second->stop();
} }
} }
@ -409,49 +392,16 @@ void MusicUtils::unloadMusic(LPCTSTR pszFilePath)
{ {
unsigned int nID = ::_Hash(pszFilePath); unsigned int nID = ::_Hash(pszFilePath);
MusicList::iterator p = sharedList().find(nID); MusicList::iterator p = getMciPlayerList().find(nID);
if (p != sharedList().end()) if (p != getMciPlayerList().end())
{ {
SAFE_DELETE(p->second); SAFE_DELETE(p->second);
sharedList().erase(nID); getMciPlayerList().erase(nID);
} }
} }
//////////////////////////////////////////////////////////////////////////
// static function
//////////////////////////////////////////////////////////////////////////
LRESULT WINAPI _SoundPlayProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
MciPlayer * pPlayer = NULL;
if (MM_MCINOTIFY == Msg
&& MCI_NOTIFY_SUCCESSFUL == wParam
&& (pPlayer = (MciPlayer *)GetWindowLongPtr(hWnd, GWLP_USERDATA)))
{
if (pPlayer->_times)
{
--pPlayer->_times;
}
if (pPlayer->_times)
{
mciSendCommand(lParam, MCI_SEEK, MCI_SEEK_TO_START, 0);
MCI_PLAY_PARMS mciPlay = { 0 };
mciPlay.dwCallback = reinterpret_cast<DWORD_PTR>(hWnd);
mciSendCommand(lParam, MCI_PLAY, MCI_NOTIFY, reinterpret_cast<DWORD_PTR>(&mciPlay));
}
else
{
pPlayer->_playing = false;
}
return 0;
}
return DefWindowProc(hWnd, Msg, wParam, lParam);
}
unsigned int _Hash(tstring key) unsigned int _Hash(tstring key)
{ {
unsigned int len = unsigned(key.size()); unsigned int len = unsigned(key.size());

View File

@ -151,7 +151,7 @@ bool Timer::stopTimer(tstring name)
return false; return false;
} }
bool Timer::deleteTimer(tstring name) bool Timer::delTimer(tstring name)
{ {
// 创建迭代器 // 创建迭代器
std::vector<Timer*>::iterator iter; std::vector<Timer*>::iterator iter;

View File

@ -1,5 +1,5 @@
/****************************************************** /******************************************************
* Easy2D Game Engine (v1.0.3) * Easy2D Game Engine (v1.0.4)
* http://www.easy2d.cn * http://www.easy2d.cn
* *
* Depends on EasyX (Ver:20170827(beta)) * Depends on EasyX (Ver:20170827(beta))
@ -89,34 +89,18 @@ 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; typedef std::function<void()> MOUSE_CALLBACK;
class App class App
{ {
protected:
tstring m_sTitle;
Scene* m_currentScene;
Scene* m_nextScene;
std::stack<Scene*> m_sceneStack;
LARGE_INTEGER m_nAnimationInterval;
int m_nWidth;
int m_nHeight;
int m_nWindowMode;
bool m_bRunning;
bool m_bSaveScene;
protected:
void _initGraph();
void _mainLoop();
void _enterNextScene();
public: public:
App(); App();
~App(); ~App();
// 窗口可选模式 // 窗口可选模式
enum { SHOW_CONSOLE = 1, NO_CLOSE = 2, NO_MINI_MIZE = 4 }; enum { SHOW_CONSOLE = 1, NO_CLOSE = 2, NO_MINI_MIZE = 4 };
// 获取程序实例 // 获取程序实例
static App * get(); static App * get();
// 设置坐标原点 // 设置坐标原点
@ -140,7 +124,9 @@ public:
// 修改窗口大小 // 修改窗口大小
void setWindowSize(int width, int height); void setWindowSize(int width, int height);
// 设置窗口标题 // 设置窗口标题
void setWindowText(tstring title); void setWindowTitle(tstring title);
// 获取窗口标题
tstring getWindowTitle();
// 获取窗口宽度 // 获取窗口宽度
int getWidth() const; int getWidth() const;
// 获取窗口高度 // 获取窗口高度
@ -151,6 +137,10 @@ public:
void backScene(); void backScene();
// 清空之前保存的所有场景 // 清空之前保存的所有场景
void clearScene(); void clearScene();
// 设置 AppName
void setAppName(tstring appname);
// 获取 AppName
tstring getAppName() const;
// 修改窗口背景色 // 修改窗口背景色
void setBkColor(COLORREF color); void setBkColor(COLORREF color);
// 设置帧率 // 设置帧率
@ -165,6 +155,24 @@ public:
Scene * getCurrentScene(); Scene * getCurrentScene();
// 获取 Easy2D 版本号 // 获取 Easy2D 版本号
LPCTSTR getVersion(); LPCTSTR getVersion();
protected:
tstring m_sTitle;
tstring m_sAppName;
Scene* m_currentScene;
Scene* m_nextScene;
std::stack<Scene*> m_sceneStack;
LARGE_INTEGER m_nAnimationInterval;
int m_nWidth;
int m_nHeight;
int m_nWindowMode;
bool m_bRunning;
bool m_bSaveScene;
protected:
void _initGraph();
void _mainLoop();
void _enterNextScene();
}; };
class FreePool class FreePool
@ -184,13 +192,6 @@ class Scene
friend class App; friend class App;
friend class MouseMsg; friend class MouseMsg;
protected:
std::vector<Node*> m_vChildren;
protected:
void _exec();
void _onDraw();
public: public:
Scene(); Scene();
~Scene(); ~Scene();
@ -205,6 +206,13 @@ public:
bool del(Node * child); bool del(Node * child);
// 清空所有子成员 // 清空所有子成员
void clearAllChildren(); void clearAllChildren();
protected:
std::vector<Node*> m_vChildren;
protected:
void _exec();
void _onDraw();
}; };
@ -212,40 +220,17 @@ class MouseMsg
{ {
friend class App; friend class App;
private:
static void __exec();
protected:
tstring m_sName;
MOUSE_CALLBACK m_callback;
public:
UINT uMsg; // 当前鼠标消息
bool mkLButton; // 鼠标左键是否按下
bool mkMButton; // 鼠标中键是否按下
bool mkRButton; // 鼠标右键是否按下
short x; // 当前鼠标 x 坐标
short y; // 当前鼠标 y 坐标
short wheel; // 鼠标滚轮滚动值 (120 的倍数)
public: public:
MouseMsg(); MouseMsg();
MouseMsg(tstring name, const MOUSE_CALLBACK& callback); MouseMsg(tstring name, const MOUSE_CALLBACK& callback);
~MouseMsg(); ~MouseMsg();
// 执行回调函数
void onMouseMsg(MouseMsg mouse);
// 添加键盘监听 // 添加键盘监听
static void addListener(tstring name, const MOUSE_CALLBACK& callback); static void addListener(tstring name, const MOUSE_CALLBACK& callback);
// 删除键盘监听 // 删除键盘监听
static bool deleteListener(tstring name); static bool delListener(tstring name);
// 删除所有键盘监听 // 删除所有键盘监听
static void clearAllListener(); static void clearAllListeners();
public:
// 获取当前鼠标消息
static MouseMsg getMsg();
// 左键是否按下 // 左键是否按下
static bool isLButtonDown(); static bool isLButtonDown();
// 右键是否按下 // 右键是否按下
@ -253,11 +238,11 @@ public:
// 中键是否按下 // 中键是否按下
static bool isMButtonDown(); static bool isMButtonDown();
// 获取鼠标X坐标 // 获取鼠标X坐标
static int getMouseX(); static int getX();
// 获取鼠标Y坐标 // 获取鼠标Y坐标
static int getMouseY(); static int getY();
// 获取鼠标滚轮值 // 获取鼠标滚轮值
static int getMouseWheel(); static int getWheel();
// 鼠标移动消息 // 鼠标移动消息
static bool isOnMouseMoved(); static bool isOnMouseMoved();
// 左键双击消息 // 左键双击消息
@ -282,6 +267,17 @@ public:
static bool isOnWheel(); static bool isOnWheel();
// 清空鼠标消息 // 清空鼠标消息
static void resetMouseMsg(); static void resetMouseMsg();
private:
static void __exec();
protected:
tstring m_sName;
MOUSE_CALLBACK m_callback;
protected:
// 执行回调函数
void onMouseMsg();
}; };
@ -289,6 +285,22 @@ class KeyMsg
{ {
friend class App; 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: 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 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;
@ -307,28 +319,28 @@ private:
protected: protected:
tstring m_sName; tstring m_sName;
KEY_CALLBACK m_callback; KEY_CALLBACK m_callback;
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 deleteListener(tstring name);
// 删除所有键盘监听
static void clearAllListener();
// 判断键是否被按下按下返回true
static bool isKeyDown(VK_KEY key);
}; };
class FileUtils class FileUtils
{ {
public: 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); static tstring getFileExtension(const tstring& filePath);
/** /**
@ -343,7 +355,7 @@ class MusicUtils
{ {
public: public:
// 播放背景音乐 // 播放背景音乐
static void playBackgroundMusic(tstring pszFilePath, bool bLoop = false); static void playBackgroundMusic(tstring pszFilePath, bool bLoop = true);
// 停止背景音乐 // 停止背景音乐
static void stopBackgroundMusic(bool bReleaseData = false); static void stopBackgroundMusic(bool bReleaseData = false);
// 暂停背景音乐 // 暂停背景音乐
@ -354,6 +366,8 @@ public:
static void rewindBackgroundMusic(); static void rewindBackgroundMusic();
// 背景音乐是否正在播放 // 背景音乐是否正在播放
static bool isBackgroundMusicPlaying(); static bool isBackgroundMusicPlaying();
// 设置背景音乐音量0 ~ 1.0f
static void setBackgroundMusicVolume(float volume);
// 播放音效 // 播放音效
static unsigned int playMusic(tstring pszFilePath, bool loop = false); static unsigned int playMusic(tstring pszFilePath, bool loop = false);
@ -367,6 +381,8 @@ public:
static void resumeMusic(unsigned int nSoundId); static void resumeMusic(unsigned int nSoundId);
// 卸载音效 // 卸载音效
static void unloadMusic(LPCTSTR pszFilePath); static void unloadMusic(LPCTSTR pszFilePath);
// 设置特定音乐的音量0 ~ 1.0f
static void setVolume(tstring pszFilePath, float volume);
// 暂停所有音乐 // 暂停所有音乐
static void pauseAllMusics(); static void pauseAllMusics();
@ -376,6 +392,8 @@ public:
static void stopAllMusics(); static void stopAllMusics();
// 停止所有音乐,并释放内存 // 停止所有音乐,并释放内存
static void end(); static void end();
// 设置总音量0 ~ 1.0f
static void setVolume(float volume);
}; };
@ -383,17 +401,6 @@ class Timer
{ {
friend class App; friend class App;
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();
public: public:
Timer(tstring name, UINT ms, const TIMER_CALLBACK & callback); Timer(tstring name, UINT ms, const TIMER_CALLBACK & callback);
~Timer(); ~Timer();
@ -410,7 +417,6 @@ public:
void setCallback(const TIMER_CALLBACK& callback); void setCallback(const TIMER_CALLBACK& callback);
// 设置定时器名称 // 设置定时器名称
void setName(tstring name); void setName(tstring name);
// 获取定时器间隔时间 // 获取定时器间隔时间
UINT getInterval() const; UINT getInterval() const;
// 获取定时器名称 // 获取定时器名称
@ -427,9 +433,20 @@ public:
// 停止特定定时器 // 停止特定定时器
static bool stopTimer(tstring name); static bool stopTimer(tstring name);
// 删除特定定时器 // 删除特定定时器
static bool deleteTimer(tstring name); static bool delTimer(tstring name);
// 删除所有定时器 // 删除所有定时器
static void clearAllTimers(); 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();
}; };
@ -475,15 +492,15 @@ class Object
{ {
friend class FreePool; friend class FreePool;
protected:
int m_nRef;
public: public:
Object(); Object();
virtual ~Object(); virtual ~Object();
void retain(); void retain();
void release(); void release();
protected:
int m_nRef;
}; };
@ -492,9 +509,6 @@ class FontStyle :
{ {
friend class Text; friend class Text;
protected:
LOGFONT m_font;
public: public:
FontStyle(); FontStyle();
/** /**
@ -528,6 +542,9 @@ public:
void setOrientation(LONG value); void setOrientation(LONG value);
// 设置字体抗锯齿默认为true // 设置字体抗锯齿默认为true
void setQuality(bool value); void setQuality(bool value);
protected:
LOGFONT m_font;
}; };
@ -555,18 +572,6 @@ class Node :
friend class Scene; friend class Scene;
friend class BatchNode; friend class BatchNode;
protected:
int m_nZOrder;
bool m_bDisplay;
Scene* m_pScene;
int m_nX;
int m_nY;
protected:
virtual bool _exec(bool active);
virtual void _onDraw() = 0;
void setParentScene(Scene * scene);
public: public:
Node(); Node();
Node(int x, int y); Node(int x, int y);
@ -594,19 +599,24 @@ public:
virtual void setZOrder(int z); virtual void setZOrder(int z);
// 获取节点所在场景 // 获取节点所在场景
Scene * getParentScene(); Scene * getParentScene();
protected:
int m_nZOrder;
bool m_bDisplay;
Scene* m_pScene;
int m_nX;
int m_nY;
protected:
virtual bool _exec(bool active);
virtual void _onDraw() = 0;
void setParentScene(Scene * scene);
}; };
class BatchNode : class BatchNode :
public virtual Node public virtual Node
{ {
protected:
std::vector<Node*> m_vChildren;
protected:
virtual bool _exec(bool active) override;
virtual void _onDraw() override;
public: public:
BatchNode(); BatchNode();
virtual ~BatchNode(); virtual ~BatchNode();
@ -617,18 +627,19 @@ public:
bool del(Node * child); bool del(Node * child);
// 清空所有子节点 // 清空所有子节点
void clearAllChildren(); void clearAllChildren();
protected:
std::vector<Node*> m_vChildren;
protected:
virtual bool _exec(bool active) override;
virtual void _onDraw() override;
}; };
class Layer : class Layer :
public virtual BatchNode public virtual BatchNode
{ {
protected:
bool m_bBlock;
protected:
virtual bool _exec(bool active) override;
public: public:
Layer(); Layer();
virtual ~Layer(); virtual ~Layer();
@ -637,6 +648,12 @@ public:
int getBlock() const; int getBlock() const;
// 设置图层是否阻塞消息 // 设置图层是否阻塞消息
void setBlock(bool block); void setBlock(bool block);
protected:
bool m_bBlock;
protected:
virtual bool _exec(bool active) override;
}; };
@ -645,23 +662,15 @@ class Image :
{ {
friend class ImageButton; friend class ImageButton;
protected:
CImage m_Image;
CRect m_rDest;
CRect m_rSrc;
float m_fScaleX;
float m_fScaleY;
protected:
virtual void _onDraw() override;
public: public:
Image(); Image();
// 从图片文件获取图像
Image(LPCTSTR ImageFile);
/** /**
* (png/bmp/jpg/gif/emf/wmf/ico) *
* *
*/ */
Image(LPCTSTR ImageFile, int x = 0, int y = 0, int width = 0, int height = 0); Image(LPCTSTR ImageFile, int x, int y, int width, int height);
virtual ~Image(); virtual ~Image();
// 获取图像宽度 // 获取图像宽度
@ -674,23 +683,23 @@ public:
float getScaleY() const; float getScaleY() const;
/** /**
* (png/bmp/jpg/gif/emf/wmf/ico) *
* *
*/ */
bool setImage(LPCTSTR ImageFile); bool setImage(LPCTSTR ImageFile);
/** /**
* (png/bmp/jpg/gif/emf/wmf/ico) *
* *
* *
*/ */
bool setImage(LPCTSTR ImageFile, int x, int y, int width, int height); bool setImage(LPCTSTR ImageFile, int x, int y, int width, int height);
/** /**
* png (bmp/jpg/gif/emf/wmf/ico) * png
* *
*/ */
bool setImageFromRes(LPCTSTR pResName); bool setImageFromRes(LPCTSTR pResName);
/** /**
* png (bmp/jpg/gif/emf/wmf/ico) * png
* *
* *
*/ */
@ -698,7 +707,7 @@ public:
// 裁剪图片(裁剪后会恢复 stretch 拉伸) // 裁剪图片(裁剪后会恢复 stretch 拉伸)
void crop(int x, int y, int width, int height); void crop(int x, int y, int width, int height);
// 将图片拉伸到固定宽高 // 将图片拉伸到固定宽高
void stretch(int width = 0, int height = 0); void stretch(int width, int height);
// 按比例拉伸图片 // 按比例拉伸图片
void scale(float scaleX = 1.0f, float scaleY = 1.0f); void scale(float scaleX = 1.0f, float scaleY = 1.0f);
// 设置图片位置 // 设置图片位置
@ -711,8 +720,18 @@ public:
void setY(int y) override; void setY(int y) override;
// 设置透明色 // 设置透明色
void setTransparentColor(COLORREF value); void setTransparentColor(COLORREF value);
// 保存到截图 // 保存游戏截图
static void screenshot(); static void saveScreenshot();
protected:
CImage m_Image;
CRect m_rDest;
CRect m_rSrc;
float m_fScaleX;
float m_fScaleY;
protected:
virtual void _onDraw() override;
}; };
@ -721,14 +740,6 @@ class Text :
{ {
friend class TextButton; friend class TextButton;
protected:
tstring m_sText;
COLORREF m_color;
FontStyle * m_pFontStyle;
protected:
virtual void _onDraw() override;
public: public:
Text(); Text();
// 根据字符串、颜色和字体创建文字 // 根据字符串、颜色和字体创建文字
@ -756,12 +767,43 @@ public:
void setColor(COLORREF color); void setColor(COLORREF color);
// 设置字体 // 设置字体
void setFontStyle(FontStyle * style); void setFontStyle(FontStyle * style);
protected:
tstring m_sText;
COLORREF m_color;
FontStyle * m_pFontStyle;
protected:
virtual void _onDraw() override;
}; };
class MouseNode : class MouseNode :
public virtual Node public virtual Node
{ {
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);
private: private:
bool m_bTarget; bool m_bTarget;
bool m_bBlock; bool m_bBlock;
@ -790,35 +832,21 @@ protected:
virtual void _onMouseIn() = 0; virtual void _onMouseIn() = 0;
// 鼠标选中时 // 鼠标选中时
virtual void _onSelected() = 0; virtual void _onSelected() = 0;
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);
}; };
class Button : class Button :
public virtual MouseNode public virtual MouseNode
{ {
public:
Button();
virtual ~Button();
// 按钮是否启用
virtual bool isEnable();
// 设置是否启用
virtual void setEnable(bool enable);
protected: protected:
bool m_bEnable; bool m_bEnable;
@ -830,15 +858,6 @@ protected:
virtual void _onMouseIn() = 0; virtual void _onMouseIn() = 0;
virtual void _onSelected() = 0; virtual void _onSelected() = 0;
virtual void _onDisable() = 0; virtual void _onDisable() = 0;
public:
Button();
virtual ~Button();
// 按钮是否启用
virtual bool isEnable();
// 设置是否启用
virtual void setEnable(bool enable);
}; };
@ -846,21 +865,6 @@ public:
class TextButton : class TextButton :
public virtual Button public virtual Button
{ {
protected:
Text * m_pNormalText;
Text * m_pMouseInText;
Text * m_pSelectedText;
Text * m_pUnableText;
protected:
// 重置文字位置(居中显示)
void resetTextPosition();
virtual void _onNormal() override;
virtual void _onMouseIn() override;
virtual void _onSelected() override;
virtual void _onDisable() override;
public: public:
TextButton(); TextButton();
TextButton(tstring text); TextButton(tstring text);
@ -882,6 +886,21 @@ public:
virtual void setY(int y) override; virtual void setY(int y) override;
// 设置按钮横纵坐标 // 设置按钮横纵坐标
virtual void setPos(int x, int y) override; virtual void setPos(int x, int y) override;
protected:
Text * m_pNormalText;
Text * m_pMouseInText;
Text * m_pSelectedText;
Text * m_pUnableText;
protected:
// 重置文字位置(居中显示)
void resetTextPosition();
virtual void _onNormal() override;
virtual void _onMouseIn() override;
virtual void _onSelected() override;
virtual void _onDisable() override;
}; };
@ -889,21 +908,6 @@ public:
class ImageButton : class ImageButton :
public virtual Button public virtual Button
{ {
protected:
Image * m_pNormalImage;
Image * m_pMouseInImage;
Image * m_pSelectedImage;
Image * m_pUnableImage;
protected:
// 重置图片位置(居中显示)
void resetImagePosition();
virtual void _onNormal() override;
virtual void _onMouseIn() override;
virtual void _onSelected() override;
virtual void _onDisable() override;
public: public:
ImageButton(); ImageButton();
ImageButton(LPCTSTR image); ImageButton(LPCTSTR image);
@ -925,29 +929,33 @@ public:
virtual void setY(int y) override; virtual void setY(int y) override;
// 设置按钮横纵坐标 // 设置按钮横纵坐标
virtual void setPos(int x, int y) override; virtual void setPos(int x, int y) override;
protected:
Image * m_pNormalImage;
Image * m_pMouseInImage;
Image * m_pSelectedImage;
Image * m_pUnableImage;
protected:
// 重置图片位置(居中显示)
void resetImagePosition();
virtual void _onNormal() override;
virtual void _onMouseIn() override;
virtual void _onSelected() override;
virtual void _onDisable() override;
}; };
class Shape : class Shape :
public virtual Node public virtual Node
{ {
protected:
COLORREF fillColor;
COLORREF lineColor;
protected:
virtual void _onDraw() override;
virtual void solidShape() = 0;
virtual void fillShape() = 0;
virtual void roundShape() = 0;
public:
enum STYLE { ROUND, SOLID, FILL } m_eStyle; // 形状填充样式
public: public:
Shape(); Shape();
virtual ~Shape(); virtual ~Shape();
enum STYLE { ROUND, SOLID, FILL } m_eStyle; // 形状填充样式
// 获取形状的填充颜色 // 获取形状的填充颜色
COLORREF getFillColor() const; COLORREF getFillColor() const;
// 获取形状的线条颜色 // 获取形状的线条颜色
@ -958,21 +966,22 @@ public:
void setLineColor(COLORREF color); void setLineColor(COLORREF color);
// 设置填充样式 // 设置填充样式
void setStyle(STYLE style); 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 : class Rect :
public virtual Shape public virtual Shape
{ {
protected:
int m_nWidth;
int m_nHeight;
protected:
virtual void solidShape() override;
virtual void fillShape() override;
virtual void roundShape() override;
public: public:
Rect(); Rect();
Rect(int x, int y, int width, int height); Rect(int x, int y, int width, int height);
@ -988,20 +997,21 @@ public:
void setHeight(int height); void setHeight(int height);
// 设置矩形大小 // 设置矩形大小
void setSize(int width, int height); void setSize(int width, int height);
protected:
int m_nWidth;
int m_nHeight;
protected:
virtual void solidShape() override;
virtual void fillShape() override;
virtual void roundShape() override;
}; };
class Circle : class Circle :
public virtual Shape public virtual Shape
{ {
protected:
int m_nRadius;
protected:
virtual void solidShape() override;
virtual void fillShape() override;
virtual void roundShape() override;
public: public:
Circle(); Circle();
Circle(int x, int y, int radius); Circle(int x, int y, int radius);
@ -1011,6 +1021,14 @@ public:
int getRadius() const; int getRadius() const;
// 设置圆形半径 // 设置圆形半径
void setRadius(int m_nRadius); 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 } // End of easy2d namespace