The earliest release version
This commit is contained in:
parent
849298b242
commit
183c7bfcea
|
|
@ -0,0 +1,3 @@
|
|||
# ignore all files in the /Easy2D/** directory
|
||||
Easy2D/Win32/
|
||||
Easy2D/x64/
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26730.12
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Easy2D", "Easy2D\Easy2D.vcxproj", "{FF7F943D-A89C-4E6C-97CF-84F7D8FF8EDF}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
DebugW|x64 = DebugW|x64
|
||||
DebugW|x86 = DebugW|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
ReleaseW|x64 = ReleaseW|x64
|
||||
ReleaseW|x86 = ReleaseW|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{FF7F943D-A89C-4E6C-97CF-84F7D8FF8EDF}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{FF7F943D-A89C-4E6C-97CF-84F7D8FF8EDF}.Debug|x64.Build.0 = Debug|x64
|
||||
{FF7F943D-A89C-4E6C-97CF-84F7D8FF8EDF}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{FF7F943D-A89C-4E6C-97CF-84F7D8FF8EDF}.Debug|x86.Build.0 = Debug|Win32
|
||||
{FF7F943D-A89C-4E6C-97CF-84F7D8FF8EDF}.DebugW|x64.ActiveCfg = DebugW|x64
|
||||
{FF7F943D-A89C-4E6C-97CF-84F7D8FF8EDF}.DebugW|x64.Build.0 = DebugW|x64
|
||||
{FF7F943D-A89C-4E6C-97CF-84F7D8FF8EDF}.DebugW|x86.ActiveCfg = DebugW|Win32
|
||||
{FF7F943D-A89C-4E6C-97CF-84F7D8FF8EDF}.DebugW|x86.Build.0 = DebugW|Win32
|
||||
{FF7F943D-A89C-4E6C-97CF-84F7D8FF8EDF}.Release|x64.ActiveCfg = Release|x64
|
||||
{FF7F943D-A89C-4E6C-97CF-84F7D8FF8EDF}.Release|x64.Build.0 = Release|x64
|
||||
{FF7F943D-A89C-4E6C-97CF-84F7D8FF8EDF}.Release|x86.ActiveCfg = Release|Win32
|
||||
{FF7F943D-A89C-4E6C-97CF-84F7D8FF8EDF}.Release|x86.Build.0 = Release|Win32
|
||||
{FF7F943D-A89C-4E6C-97CF-84F7D8FF8EDF}.ReleaseW|x64.ActiveCfg = ReleaseW|x64
|
||||
{FF7F943D-A89C-4E6C-97CF-84F7D8FF8EDF}.ReleaseW|x64.Build.0 = ReleaseW|x64
|
||||
{FF7F943D-A89C-4E6C-97CF-84F7D8FF8EDF}.ReleaseW|x86.ActiveCfg = ReleaseW|Win32
|
||||
{FF7F943D-A89C-4E6C-97CF-84F7D8FF8EDF}.ReleaseW|x86.Build.0 = ReleaseW|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {FAC2BE2F-19AF-477A-8DC6-4645E66868A4}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
@ -0,0 +1,368 @@
|
|||
#include "easy2d.h"
|
||||
#include "EasyX\easyx.h"
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
#include <imm.h>
|
||||
#pragma comment(lib, "imm32.lib")
|
||||
#include <mmsystem.h>
|
||||
#pragma comment(lib, "winmm.lib")
|
||||
|
||||
|
||||
// Application 的唯一实例
|
||||
static Application * s_pInstance = nullptr;
|
||||
// 坐标原点的物理坐标
|
||||
static int originX = 0;
|
||||
static int originY = 0;
|
||||
|
||||
Application::Application() :
|
||||
m_currentScene(nullptr),
|
||||
m_nextScene(nullptr),
|
||||
m_bRunning(false),
|
||||
m_bPause(false),
|
||||
m_nWidth(0),
|
||||
m_nHeight(0),
|
||||
m_nWindowMode(0)
|
||||
{
|
||||
assert(!s_pInstance); // 不能同时存在两个 Application 实例
|
||||
s_pInstance = this; // 保存实例对象
|
||||
setFPS(60); // 默认 FPS 为 60
|
||||
}
|
||||
|
||||
Application::~Application()
|
||||
{
|
||||
destory(); // 销毁 Application
|
||||
}
|
||||
|
||||
Application * Application::get()
|
||||
{
|
||||
assert(s_pInstance); // 断言实例存在
|
||||
return s_pInstance; // 获取 Application 的唯一实例
|
||||
}
|
||||
|
||||
void Application::setOrigin(int originX, int originY)
|
||||
{
|
||||
::originX = originX;
|
||||
::originY = originY;
|
||||
setorigin(originX, originY);
|
||||
}
|
||||
|
||||
int Application::getOriginX()
|
||||
{
|
||||
return ::originX;
|
||||
}
|
||||
|
||||
int Application::getOriginY()
|
||||
{
|
||||
return ::originY;
|
||||
}
|
||||
|
||||
int Application::run()
|
||||
{
|
||||
// 开启批量绘图
|
||||
BeginBatchDraw();
|
||||
// 修改时间精度
|
||||
timeBeginPeriod(1);
|
||||
// 获取 CPU 每秒滴答声个数
|
||||
LARGE_INTEGER freq;
|
||||
QueryPerformanceFrequency(&freq);
|
||||
// 创建时间变量
|
||||
LARGE_INTEGER nLast;
|
||||
LARGE_INTEGER nNow;
|
||||
// 记录当前时间
|
||||
QueryPerformanceCounter(&nLast);
|
||||
// 时间间隔
|
||||
LONGLONG interval = 0LL;
|
||||
// 挂起时长
|
||||
LONG waitMS = 0L;
|
||||
// 将隐藏的窗口显示
|
||||
ShowWindow(GetHWnd(), SW_NORMAL);
|
||||
// 运行游戏
|
||||
m_bRunning = true;
|
||||
|
||||
// 进入主循环
|
||||
while (m_bRunning)
|
||||
{
|
||||
// 获取当前时间
|
||||
QueryPerformanceCounter(&nNow);
|
||||
// 计算时间间隔
|
||||
interval = nNow.QuadPart - nLast.QuadPart;
|
||||
// 判断间隔时间是否足够
|
||||
if (interval >= m_nAnimationInterval.QuadPart)
|
||||
{
|
||||
// 记录当前时间
|
||||
nLast.QuadPart = nNow.QuadPart;
|
||||
// 执行游戏逻辑
|
||||
_mainLoop();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 计算挂起时长
|
||||
waitMS = LONG((m_nAnimationInterval.QuadPart - interval) * 1000LL / freq.QuadPart) - 1L;
|
||||
// 挂起线程,释放 CPU 占用
|
||||
if (waitMS > 1L)
|
||||
Sleep(waitMS);
|
||||
}
|
||||
}
|
||||
// 停止批量绘图
|
||||
EndBatchDraw();
|
||||
// 关闭窗口
|
||||
close();
|
||||
// 释放所有内存占用
|
||||
destory();
|
||||
// 重置时间精度
|
||||
timeEndPeriod(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Application::_initGraph()
|
||||
{
|
||||
// 创建绘图环境
|
||||
initgraph(m_nWidth, m_nHeight, m_nWindowMode);
|
||||
// 隐藏当前窗口(防止在加载阶段显示黑窗口)
|
||||
ShowWindow(GetHWnd(), SW_HIDE);
|
||||
// 获取屏幕分辨率
|
||||
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
|
||||
int screenHeight = GetSystemMetrics(SM_CYSCREEN);
|
||||
// 获取窗口大小
|
||||
CRect rcWindow;
|
||||
GetWindowRect(GetHWnd(), &rcWindow);
|
||||
// 设置窗口在屏幕居中
|
||||
SetWindowPos(GetHWnd(), HWND_TOP,
|
||||
(screenWidth - rcWindow.Size().cx) / 2,
|
||||
(screenHeight - rcWindow.Size().cy) / 2,
|
||||
rcWindow.Size().cx,
|
||||
rcWindow.Size().cy,
|
||||
SWP_HIDEWINDOW | SWP_NOACTIVATE | SWP_NOSIZE);
|
||||
// 禁用输入法
|
||||
ImmAssociateContext(GetHWnd(), NULL);
|
||||
// 重置绘图环境
|
||||
reset();
|
||||
// 设置窗口标题
|
||||
if (m_sTitle.empty())
|
||||
{
|
||||
// 保存当前标题
|
||||
TCHAR title[31];
|
||||
GetWindowText(GetHWnd(), title, 30);
|
||||
m_sTitle = title;
|
||||
}
|
||||
else
|
||||
{
|
||||
setWindowText(m_sTitle);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::_mainLoop()
|
||||
{
|
||||
// 游戏暂停
|
||||
if (m_bPause)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// 进入下一场景
|
||||
if (m_nextScene)
|
||||
{
|
||||
_enterNextScene();
|
||||
}
|
||||
// 断言当前场景非空
|
||||
assert(m_currentScene);
|
||||
|
||||
cleardevice(); // 清空画面
|
||||
m_currentScene->_onDraw(); // 绘制当前场景
|
||||
FlushBatchDraw(); // 刷新画面
|
||||
|
||||
// 其他执行程序
|
||||
MouseMsg::__exec(); // 鼠标检测
|
||||
KeyMsg::__exec(); // 键盘按键检测
|
||||
Timer::__exec(); // 定时器执行程序
|
||||
FreePool::__flush(); // 刷新内存池
|
||||
}
|
||||
|
||||
void Application::createWindow(int width, int height, int mode)
|
||||
{
|
||||
// 保存窗口信息
|
||||
m_nWidth = width;
|
||||
m_nHeight = height;
|
||||
m_nWindowMode = mode;
|
||||
// 创建窗口
|
||||
_initGraph();
|
||||
}
|
||||
|
||||
void Application::createWindow(tstring title, int width, int height, int mode)
|
||||
{
|
||||
// 保存窗口信息
|
||||
m_nWidth = width;
|
||||
m_nHeight = height;
|
||||
m_nWindowMode = mode;
|
||||
m_sTitle = title;
|
||||
// 创建窗口
|
||||
_initGraph();
|
||||
}
|
||||
|
||||
void Application::setWindowSize(int width, int height)
|
||||
{
|
||||
// 游戏正在运行时才允许修改窗口大小
|
||||
assert(m_bRunning);
|
||||
|
||||
// 重启窗口
|
||||
closegraph();
|
||||
/* 重启窗口会导致内存占用急剧增加,也许是 EasyX 遗留的 BUG,已向 yangw80 报告了这个情况 */
|
||||
initgraph(width, height, m_nWindowMode);
|
||||
|
||||
/* EasyX 不支持用 Windows API 修改窗口大小 */
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// // 获取屏幕分辨率
|
||||
// int screenWidth = GetSystemMetrics(SM_CXSCREEN);
|
||||
// int screenHeight = GetSystemMetrics(SM_CYSCREEN);
|
||||
// // 获取窗口大小(包含菜单栏)
|
||||
// CRect rcWindow;
|
||||
// GetWindowRect(GetHWnd(), &rcWindow);
|
||||
// // 获取客户区大小
|
||||
// CRect rcClient;
|
||||
// GetClientRect(GetHWnd(), &rcClient);
|
||||
// // 计算边框大小
|
||||
// width += (rcWindow.right - rcWindow.left) - (rcClient.right - rcClient.left);
|
||||
// height += (rcWindow.bottom - rcWindow.top) - (rcClient.bottom - rcClient.top);
|
||||
// // 修改窗口大小,并设置窗口在屏幕居中
|
||||
// SetWindowPos(
|
||||
// GetHWnd(),
|
||||
// HWND_TOP,
|
||||
// (screenWidth - width) / 2,
|
||||
// (screenHeight - height) / 2,
|
||||
// width,
|
||||
// height,
|
||||
// SWP_SHOWWINDOW | SWP_NOREDRAW);
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
}
|
||||
|
||||
void Application::setWindowText(tstring title)
|
||||
{
|
||||
// 设置窗口标题
|
||||
SetWindowText(GetHWnd(), title.c_str());
|
||||
// 保存当前标题,用于修改窗口大小时恢复标题
|
||||
m_sTitle = title;
|
||||
}
|
||||
|
||||
void Application::close()
|
||||
{
|
||||
// 关闭绘图环境
|
||||
closegraph();
|
||||
}
|
||||
|
||||
void Application::enterScene(Scene * scene, bool save)
|
||||
{
|
||||
// 保存下一场景的指针
|
||||
m_nextScene = scene;
|
||||
// 切换场景时,是否保存当前场景
|
||||
m_bSaveScene = save;
|
||||
}
|
||||
|
||||
void Application::backScene()
|
||||
{
|
||||
// 从栈顶取出场景指针,作为下一场景
|
||||
m_nextScene = m_sceneStack.top();
|
||||
// 不保存当前场景
|
||||
m_bSaveScene = false;
|
||||
}
|
||||
|
||||
void Application::_enterNextScene()
|
||||
{
|
||||
// 若下一场景处于栈顶,说明正在返回上一场景
|
||||
if (m_sceneStack.size() && m_nextScene == m_sceneStack.top())
|
||||
{
|
||||
m_sceneStack.pop(); // 删除栈顶场景
|
||||
}
|
||||
|
||||
if (m_bSaveScene)
|
||||
{
|
||||
m_sceneStack.push(m_currentScene); // 若要保存当前场景,把它的指针放到栈顶
|
||||
}
|
||||
else
|
||||
{
|
||||
SAFE_DELETE(m_currentScene); // 否则删除当前场景
|
||||
}
|
||||
|
||||
m_currentScene = m_nextScene; // 切换场景
|
||||
m_nextScene = nullptr; // 下一场景置空
|
||||
}
|
||||
|
||||
void Application::quit()
|
||||
{
|
||||
m_bRunning = false;
|
||||
}
|
||||
|
||||
void Application::end()
|
||||
{
|
||||
m_bRunning = false;
|
||||
}
|
||||
|
||||
void Application::pause()
|
||||
{
|
||||
m_bPause = true;
|
||||
}
|
||||
|
||||
bool Application::isRunning()
|
||||
{
|
||||
return m_bRunning && !m_bPause;
|
||||
}
|
||||
|
||||
void Application::reset()
|
||||
{
|
||||
// 重置绘图环境
|
||||
graphdefaults();
|
||||
setbkmode(TRANSPARENT);
|
||||
setbkcolor(Color::black);
|
||||
}
|
||||
|
||||
Scene * Application::getCurrentScene()
|
||||
{
|
||||
// 获取当前场景的指针
|
||||
return m_currentScene;
|
||||
}
|
||||
|
||||
LPCTSTR easy2d::Application::getVersion()
|
||||
{
|
||||
return _T("1.0.0");
|
||||
}
|
||||
|
||||
void Application::setFPS(DWORD fps)
|
||||
{
|
||||
// 设置画面帧率,以毫秒为单位
|
||||
LARGE_INTEGER nFreq;
|
||||
QueryPerformanceFrequency(&nFreq);
|
||||
m_nAnimationInterval.QuadPart = (LONGLONG)(1.0 / fps * nFreq.QuadPart);
|
||||
}
|
||||
|
||||
int Application::getWidth() const
|
||||
{
|
||||
return m_nWidth;
|
||||
}
|
||||
|
||||
int Application::getHeight() const
|
||||
{
|
||||
return m_nHeight;
|
||||
}
|
||||
|
||||
void Application::free()
|
||||
{
|
||||
// 释放场景内存
|
||||
SAFE_DELETE(m_currentScene);
|
||||
SAFE_DELETE(m_nextScene);
|
||||
// 清空场景栈
|
||||
while (m_sceneStack.size())
|
||||
{
|
||||
auto temp = m_sceneStack.top();
|
||||
SAFE_DELETE(temp);
|
||||
m_sceneStack.pop();
|
||||
}
|
||||
// 删除所有定时器
|
||||
Timer::clearAllTimers();
|
||||
}
|
||||
|
||||
void Application::destory()
|
||||
{
|
||||
// 释放所有内存
|
||||
free();
|
||||
// 实例指针置空
|
||||
s_pInstance = nullptr;
|
||||
}
|
||||
|
|
@ -0,0 +1,374 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="DebugW|Win32">
|
||||
<Configuration>DebugW</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="DebugW|x64">
|
||||
<Configuration>DebugW</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="ReleaseW|Win32">
|
||||
<Configuration>ReleaseW</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="ReleaseW|x64">
|
||||
<Configuration>ReleaseW</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
<ProjectGuid>{FF7F943D-A89C-4E6C-97CF-84F7D8FF8EDF}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>Easy2D</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugW|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseW|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugW|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseW|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugW|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseW|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugW|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseW|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<TargetName>Easy2Dd</TargetName>
|
||||
<OutDir>$(SolutionDir)$(Platform)\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugW|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<TargetName>Easy2Ddw</TargetName>
|
||||
<OutDir>$(SolutionDir)$(Platform)\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<TargetName>Easy2Dd</TargetName>
|
||||
<OutDir>$(SolutionDir)$(Platform)\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugW|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<TargetName>Easy2Ddw</TargetName>
|
||||
<OutDir>$(SolutionDir)$(Platform)\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetName>Easy2D</TargetName>
|
||||
<OutDir>$(SolutionDir)$(Platform)\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseW|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetName>Easy2Dw</TargetName>
|
||||
<OutDir>$(SolutionDir)$(Platform)\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetName>Easy2D</TargetName>
|
||||
<OutDir>$(SolutionDir)$(Platform)\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseW|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetName>Easy2Dw</TargetName>
|
||||
<OutDir>$(SolutionDir)$(Platform)\</OutDir>
|
||||
<IntDir>$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<ProjectReference>
|
||||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
||||
</ProjectReference>
|
||||
<Lib>
|
||||
<AdditionalDependencies>EasyXa.lib;GdiPlus.lib</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>EasyX\x86</AdditionalLibraryDirectories>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugW|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalDependencies>EasyXw.lib;GdiPlus.lib</AdditionalDependencies>
|
||||
<IgnoreAllDefaultLibraries>
|
||||
</IgnoreAllDefaultLibraries>
|
||||
<AdditionalLibraryDirectories>EasyX\x86</AdditionalLibraryDirectories>
|
||||
</Lib>
|
||||
<ProjectReference>
|
||||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
||||
</ProjectReference>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalLibraryDirectories>EasyX\x64</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>EasyXa.lib;GdiPlus.lib</AdditionalDependencies>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugW|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalDependencies>EasyXw.lib;GdiPlus.lib</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>EasyX\x64</AdditionalLibraryDirectories>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalLibraryDirectories>EasyX\x86</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>EasyXa.lib;GdiPlus.lib</AdditionalDependencies>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseW|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalDependencies>EasyXw.lib;GdiPlus.lib</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>EasyX\x86</AdditionalLibraryDirectories>
|
||||
<IgnoreSpecificDefaultLibraries>
|
||||
</IgnoreSpecificDefaultLibraries>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalLibraryDirectories>EasyX\x64</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>EasyXa.lib;GdiPlus.lib</AdditionalDependencies>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseW|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalDependencies>EasyXw.lib;GdiPlus.lib</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>EasyX\x64</AdditionalLibraryDirectories>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="ReadMe.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Application.cpp" />
|
||||
<ClCompile Include="FreePool.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\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="Style\Color.cpp" />
|
||||
<ClCompile Include="Style\FillStyle.cpp" />
|
||||
<ClCompile Include="Style\FontStyle.cpp" />
|
||||
<ClCompile Include="Style\LineStyle.cpp" />
|
||||
<ClCompile Include="Tool\FileUtils.cpp" />
|
||||
<ClCompile Include="Tool\MusicUtils.cpp" />
|
||||
<ClCompile Include="Tool\Timer.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="easy2d.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="源文件">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="头文件">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="资源文件">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="源文件\Style">
|
||||
<UniqueIdentifier>{18e7fd5c-0935-47bb-9a2e-38da40377f7d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="源文件\Tool">
|
||||
<UniqueIdentifier>{682a1a3c-39d8-4ac9-ba03-fa90c089c9ab}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="源文件\Node">
|
||||
<UniqueIdentifier>{d6778635-8947-4f9b-9388-dd088642b5b2}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="源文件\Node\Sprite">
|
||||
<UniqueIdentifier>{e5ec6183-113b-4140-8285-18b18ea37d15}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="源文件\Node\Button">
|
||||
<UniqueIdentifier>{051f9343-e5a5-4491-8110-f13fc27c3827}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="源文件\Node\Shape">
|
||||
<UniqueIdentifier>{065a3244-7169-4a45-bc9f-f2a80d8a9759}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="源文件\Msg">
|
||||
<UniqueIdentifier>{72dbabab-8278-4ee4-917f-bfffb474a51b}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="ReadMe.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Application.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Scene.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Style\Color.cpp">
|
||||
<Filter>源文件\Style</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Tool\Timer.cpp">
|
||||
<Filter>源文件\Tool</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Tool\MusicUtils.cpp">
|
||||
<Filter>源文件\Tool</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Tool\FileUtils.cpp">
|
||||
<Filter>源文件\Tool</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Style\FontStyle.cpp">
|
||||
<Filter>源文件\Style</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Node\BatchNode.cpp">
|
||||
<Filter>源文件\Node</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Node\Image.cpp">
|
||||
<Filter>源文件\Node</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Node\Node.cpp">
|
||||
<Filter>源文件\Node</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Node\Text.cpp">
|
||||
<Filter>源文件\Node</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Node\Sprite\Sprite.cpp">
|
||||
<Filter>源文件\Node\Sprite</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Node\Sprite\SpriteFrame.cpp">
|
||||
<Filter>源文件\Node\Sprite</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Node\Shape\Circle.cpp">
|
||||
<Filter>源文件\Node\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\Button\Button.cpp">
|
||||
<Filter>源文件\Node\Button</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Node\MouseNode.cpp">
|
||||
<Filter>源文件\Node</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Node\Button\TextButton.cpp">
|
||||
<Filter>源文件\Node\Button</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Node\Button\ImageButton.cpp">
|
||||
<Filter>源文件\Node\Button</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>
|
||||
<ClCompile Include="Style\FillStyle.cpp">
|
||||
<Filter>源文件\Style</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Msg\MouseMsg.cpp">
|
||||
<Filter>源文件\Msg</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Msg\KeyMsg.cpp">
|
||||
<Filter>源文件\Msg</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="easy2d.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,321 @@
|
|||
/******************************************************
|
||||
* EasyX Library for C++ (Ver:20170827(beta))
|
||||
* http://www.easyx.cn
|
||||
*
|
||||
* EasyX.h
|
||||
* 在 VC 下实现简单的绘图
|
||||
******************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef WINVER
|
||||
#define WINVER 0x0400 // Specifies that the minimum required platform is Windows 95 and Windows NT 4.0.
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0500 // Specifies that the minimum required platform is Windows 2000.
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32_WINDOWS
|
||||
#define _WIN32_WINDOWS 0x0410 // Specifies that the minimum required platform is Windows 98.
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error EasyX is only for C++
|
||||
#endif
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
|
||||
// 绘图窗口初始化参数
|
||||
#define SHOWCONSOLE 1 // 创建图形窗口时,保留控制台的显示
|
||||
#define NOCLOSE 2 // 没有关闭功能
|
||||
#define NOMINIMIZE 4 // 没有最小化功能
|
||||
|
||||
// 颜色
|
||||
#define BLACK 0
|
||||
#define BLUE 0xAA0000
|
||||
#define GREEN 0x00AA00
|
||||
#define CYAN 0xAAAA00
|
||||
#define RED 0x0000AA
|
||||
#define MAGENTA 0xAA00AA
|
||||
#define BROWN 0x0055AA
|
||||
#define LIGHTGRAY 0xAAAAAA
|
||||
#define DARKGRAY 0x555555
|
||||
#define LIGHTBLUE 0xFF5555
|
||||
#define LIGHTGREEN 0x55FF55
|
||||
#define LIGHTCYAN 0xFFFF55
|
||||
#define LIGHTRED 0x5555FF
|
||||
#define LIGHTMAGENTA 0xFF55FF
|
||||
#define YELLOW 0x55FFFF
|
||||
#define WHITE 0xFFFFFF
|
||||
|
||||
// 定义颜色转换宏
|
||||
#define BGR(color) ( (((color) & 0xFF) << 16) | ((color) & 0xFF00FF00) | (((color) & 0xFF0000) >> 16) )
|
||||
|
||||
|
||||
class IMAGE;
|
||||
|
||||
// 定义线的样式
|
||||
class LINESTYLE
|
||||
{
|
||||
public:
|
||||
LINESTYLE();
|
||||
LINESTYLE(const LINESTYLE &style);
|
||||
LINESTYLE& operator = (const LINESTYLE &style); // 赋值运算符重载函数
|
||||
virtual ~LINESTYLE();
|
||||
|
||||
DWORD style;
|
||||
DWORD thickness;
|
||||
DWORD *puserstyle;
|
||||
DWORD userstylecount;
|
||||
};
|
||||
|
||||
class FILLSTYLE
|
||||
{
|
||||
public:
|
||||
FILLSTYLE();
|
||||
FILLSTYLE(const FILLSTYLE &style);
|
||||
FILLSTYLE& operator = (const FILLSTYLE &style); // 赋值运算符重载函数
|
||||
virtual ~FILLSTYLE();
|
||||
|
||||
int style; // 填充形式
|
||||
long hatch; // 填充图案样式
|
||||
IMAGE* ppattern; // 填充图像
|
||||
};
|
||||
|
||||
// 定义图像对象
|
||||
class IMAGE
|
||||
{
|
||||
public:
|
||||
int getwidth() const; // 获取对象的宽度
|
||||
int getheight() const; // 获取对象的高度
|
||||
|
||||
private:
|
||||
int width, height; // 对象的宽高
|
||||
HBITMAP m_hBmp;
|
||||
HDC m_hMemDC;
|
||||
int m_MemCurX; // 当前点X坐标
|
||||
int m_MemCurY; // 当前点Y坐标
|
||||
float m_data[6];
|
||||
COLORREF m_LineColor; // 当前线条颜色
|
||||
COLORREF m_FillColor; // 当前填充颜色
|
||||
COLORREF m_TextColor; // 当前文字颜色
|
||||
COLORREF m_BkColor; // 当前背景颜色
|
||||
DWORD* m_pBuffer; // 绘图区的内存
|
||||
|
||||
LINESTYLE m_LineStyle; // 画线样式
|
||||
FILLSTYLE m_FillStyle; // 填充样式
|
||||
|
||||
virtual void SetDefault(); // 设置为默认状态
|
||||
|
||||
public:
|
||||
IMAGE(int _width = 0, int _height = 0); // 创建图像
|
||||
IMAGE(const IMAGE &img); // 拷贝构造函数
|
||||
IMAGE& operator = (const IMAGE &img); // 赋值运算符重载函数
|
||||
virtual ~IMAGE();
|
||||
virtual void Resize(int _width, int _height); // 调整尺寸
|
||||
};
|
||||
|
||||
|
||||
|
||||
// 绘图模式相关函数
|
||||
|
||||
HWND initgraph(int width, int height, int flag = NULL); // 初始化图形环境
|
||||
void closegraph(); // 关闭图形环境
|
||||
|
||||
// 绘图环境设置
|
||||
|
||||
void cleardevice(); // 清屏
|
||||
void setcliprgn(HRGN hrgn); // 设置当前绘图设备的裁剪区
|
||||
void clearcliprgn(); // 清除裁剪区的屏幕内容
|
||||
|
||||
void getlinestyle(LINESTYLE* pstyle); // 获取当前画线样式
|
||||
void setlinestyle(const LINESTYLE* pstyle); // 设置当前画线样式
|
||||
void setlinestyle(int style, int thickness = 1, const DWORD *puserstyle = NULL, DWORD userstylecount = 0); // 设置当前画线样式
|
||||
void getfillstyle(FILLSTYLE* pstyle); // 获取当前填充样式
|
||||
void setfillstyle(const FILLSTYLE* pstyle); // 设置当前填充样式
|
||||
void setfillstyle(int style, long hatch = NULL, IMAGE* ppattern = NULL); // 设置当前填充样式
|
||||
void setfillstyle(BYTE* ppattern8x8); // 设置当前填充样式
|
||||
|
||||
void setorigin(int x, int y); // 设置坐标原点
|
||||
void getaspectratio(float *pxasp, float *pyasp); // 获取当前缩放因子
|
||||
void setaspectratio(float xasp, float yasp); // 设置当前缩放因子
|
||||
|
||||
int getrop2(); // 获取前景的二元光栅操作模式
|
||||
void setrop2(int mode); // 设置前景的二元光栅操作模式
|
||||
int getpolyfillmode(); // 获取多边形填充模式
|
||||
void setpolyfillmode(int mode); // 设置多边形填充模式
|
||||
|
||||
void graphdefaults(); // 重置所有绘图设置为默认值
|
||||
|
||||
COLORREF getlinecolor(); // 获取当前线条颜色
|
||||
void setlinecolor(COLORREF color); // 设置当前线条颜色
|
||||
COLORREF gettextcolor(); // 获取当前文字颜色
|
||||
void settextcolor(COLORREF color); // 设置当前文字颜色
|
||||
COLORREF getfillcolor(); // 获取当前填充颜色
|
||||
void setfillcolor(COLORREF color); // 设置当前填充颜色
|
||||
COLORREF getbkcolor(); // 获取当前绘图背景色
|
||||
void setbkcolor(COLORREF color); // 设置当前绘图背景色
|
||||
int getbkmode(); // 获取背景混合模式
|
||||
void setbkmode(int mode); // 设置背景混合模式
|
||||
|
||||
// 颜色模型转换函数
|
||||
COLORREF RGBtoGRAY(COLORREF rgb);
|
||||
void RGBtoHSL(COLORREF rgb, float *H, float *S, float *L);
|
||||
void RGBtoHSV(COLORREF rgb, float *H, float *S, float *V);
|
||||
COLORREF HSLtoRGB(float H, float S, float L);
|
||||
COLORREF HSVtoRGB(float H, float S, float V);
|
||||
|
||||
|
||||
// 绘图函数
|
||||
|
||||
COLORREF getpixel(int x, int y); // 获取点的颜色
|
||||
void putpixel(int x, int y, COLORREF color); // 画点
|
||||
|
||||
void moveto(int x, int y); // 移动当前点(绝对坐标)
|
||||
void moverel(int dx, int dy); // 移动当前点(相对坐标)
|
||||
|
||||
void line(int x1, int y1, int x2, int y2); // 画线
|
||||
void linerel(int dx, int dy); // 画线(至相对坐标)
|
||||
void lineto(int x, int y); // 画线(至绝对坐标)
|
||||
|
||||
void rectangle (int left, int top, int right, int bottom); // 画矩形
|
||||
void fillrectangle (int left, int top, int right, int bottom); // 画填充矩形(有边框)
|
||||
void solidrectangle(int left, int top, int right, int bottom); // 画填充矩形(无边框)
|
||||
void clearrectangle(int left, int top, int right, int bottom); // 清空矩形区域
|
||||
|
||||
void circle (int x, int y, int radius); // 画圆
|
||||
void fillcircle (int x, int y, int radius); // 画填充圆(有边框)
|
||||
void solidcircle(int x, int y, int radius); // 画填充圆(无边框)
|
||||
void clearcircle(int x, int y, int radius); // 清空圆形区域
|
||||
|
||||
void ellipse (int left, int top, int right, int bottom); // 画椭圆
|
||||
void fillellipse (int left, int top, int right, int bottom); // 画填充椭圆(有边框)
|
||||
void solidellipse(int left, int top, int right, int bottom); // 画填充椭圆(无边框)
|
||||
void clearellipse(int left, int top, int right, int bottom); // 清空椭圆形区域
|
||||
|
||||
void roundrect (int left, int top, int right, int bottom, int ellipsewidth, int ellipseheight); // 画圆角矩形
|
||||
void fillroundrect (int left, int top, int right, int bottom, int ellipsewidth, int ellipseheight); // 画填充圆角矩形(有边框)
|
||||
void solidroundrect(int left, int top, int right, int bottom, int ellipsewidth, int ellipseheight); // 画填充圆角矩形(无边框)
|
||||
void clearroundrect(int left, int top, int right, int bottom, int ellipsewidth, int ellipseheight); // 清空圆角矩形区域
|
||||
|
||||
void arc (int left, int top, int right, int bottom, double stangle, double endangle); // 画椭圆弧(起始角度和终止角度为弧度制)
|
||||
void pie (int left, int top, int right, int bottom, double stangle, double endangle); // 画椭圆扇形(起始角度和终止角度为弧度制)
|
||||
void fillpie (int left, int top, int right, int bottom, double stangle, double endangle); // 画填充椭圆扇形(有边框)
|
||||
void solidpie(int left, int top, int right, int bottom, double stangle, double endangle); // 画填充椭圆扇形(无边框)
|
||||
void clearpie(int left, int top, int right, int bottom, double stangle, double endangle); // 清空椭圆扇形区域
|
||||
|
||||
void polyline (const POINT *points, int num); // 画多条连续的线
|
||||
void polygon (const POINT *points, int num); // 画多边形
|
||||
void fillpolygon (const POINT *points, int num); // 画填充的多边形(有边框)
|
||||
void solidpolygon(const POINT *points, int num); // 画填充的多边形(无边框)
|
||||
void clearpolygon(const POINT *points, int num); // 清空多边形区域
|
||||
|
||||
void floodfill(int x, int y, int border); // 填充区域
|
||||
|
||||
|
||||
|
||||
// 文字相关函数
|
||||
|
||||
void outtext(LPCTSTR str); // 在当前位置输出字符串
|
||||
void outtext(TCHAR c); // 在当前位置输出字符
|
||||
void outtextxy(int x, int y, LPCTSTR str); // 在指定位置输出字符串
|
||||
void outtextxy(int x, int y, TCHAR c); // 在指定位置输出字符
|
||||
int textwidth(LPCTSTR str); // 获取字符串占用的像素宽
|
||||
int textwidth(TCHAR c); // 获取字符占用的像素宽
|
||||
int textheight(LPCTSTR str); // 获取字符串占用的像素高
|
||||
int textheight(TCHAR c); // 获取字符占用的像素高
|
||||
int drawtext(LPCTSTR str, RECT* pRect, UINT uFormat); // 在指定区域内以指定格式输出字符串
|
||||
int drawtext(TCHAR c, RECT* pRect, UINT uFormat); // 在指定区域内以指定格式输出字符
|
||||
|
||||
// 设置当前字体样式(详见帮助)
|
||||
// nHeight: 字符的平均高度;
|
||||
// nWidth: 字符的平均宽度(0 表示自适应);
|
||||
// lpszFace: 字体名称;
|
||||
// nEscapement: 字符串的书写角度(单位 0.1 度);
|
||||
// nOrientation: 每个字符的书写角度(单位 0.1 度);
|
||||
// nWeight: 字符的笔画粗细(0 表示默认粗细);
|
||||
// bItalic: 是否斜体;
|
||||
// bUnderline: 是否下划线;
|
||||
// bStrikeOut: 是否删除线;
|
||||
// fbCharSet: 指定字符集;
|
||||
// fbOutPrecision: 指定文字的输出精度;
|
||||
// fbClipPrecision: 指定文字的剪辑精度;
|
||||
// fbQuality: 指定文字的输出质量;
|
||||
// fbPitchAndFamily: 指定以常规方式描述字体的字体系列。
|
||||
void settextstyle(int nHeight, int nWidth, LPCTSTR lpszFace);
|
||||
void settextstyle(int nHeight, int nWidth, LPCTSTR lpszFace, int nEscapement, int nOrientation, int nWeight, bool bItalic, bool bUnderline, bool bStrikeOut);
|
||||
void settextstyle(int nHeight, int nWidth, LPCTSTR lpszFace, int nEscapement, int nOrientation, int nWeight, bool bItalic, bool bUnderline, bool bStrikeOut, BYTE fbCharSet, BYTE fbOutPrecision, BYTE fbClipPrecision, BYTE fbQuality, BYTE fbPitchAndFamily);
|
||||
void settextstyle(const LOGFONT *font); // 设置当前字体样式
|
||||
void gettextstyle(LOGFONT *font); // 获取当前字体样式
|
||||
|
||||
|
||||
|
||||
// 图像处理函数
|
||||
void loadimage(IMAGE *pDstImg, LPCTSTR pImgFile, int nWidth = 0, int nHeight = 0, bool bResize = false); // 从图片文件获取图像(bmp/jpg/gif/emf/wmf)
|
||||
void loadimage(IMAGE *pDstImg, LPCTSTR pResType, LPCTSTR pResName, int nWidth = 0, int nHeight = 0, bool bResize = false); // 从资源文件获取图像(bmp/jpg/gif/emf/wmf)
|
||||
void saveimage(LPCTSTR pImgFile, IMAGE* pImg = NULL); // 保存图像
|
||||
void getimage(IMAGE *pDstImg, int srcX, int srcY, int srcWidth, int srcHeight); // 从当前绘图设备获取图像
|
||||
void putimage(int dstX, int dstY, const IMAGE *pSrcImg, DWORD dwRop = SRCCOPY); // 绘制图像到屏幕
|
||||
void putimage(int dstX, int dstY, int dstWidth, int dstHeight, const IMAGE *pSrcImg, int srcX, int srcY, DWORD dwRop = SRCCOPY); // 绘制图像到屏幕(指定宽高)
|
||||
void rotateimage(IMAGE *dstimg, IMAGE *srcimg, double radian, COLORREF bkcolor = BLACK, bool autosize = false, bool highquality = true);// 旋转图像
|
||||
void Resize(IMAGE* pImg, int width, int height); // 调整绘图设备的大小
|
||||
DWORD* GetImageBuffer(IMAGE* pImg = NULL); // 获取绘图设备的显存指针
|
||||
IMAGE* GetWorkingImage(); // 获取当前绘图设备
|
||||
void SetWorkingImage(IMAGE* pImg = NULL); // 设置当前绘图设备
|
||||
HDC GetImageHDC(IMAGE* pImg = NULL); // 获取绘图设备句柄(HDC)
|
||||
|
||||
|
||||
// 其它函数
|
||||
|
||||
int getwidth(); // 获取绘图区宽度
|
||||
int getheight(); // 获取绘图区高度
|
||||
int getx(); // 获取当前 x 坐标
|
||||
int gety(); // 获取当前 y 坐标
|
||||
|
||||
void BeginBatchDraw(); // 开始批量绘制
|
||||
void FlushBatchDraw(); // 执行未完成的绘制任务
|
||||
void FlushBatchDraw(int left, int top, int right, int bottom); // 执行指定区域内未完成的绘制任务
|
||||
void EndBatchDraw(); // 结束批量绘制,并执行未完成的绘制任务
|
||||
void EndBatchDraw(int left, int top, int right, int bottom); // 结束批量绘制,并执行指定区域内未完成的绘制任务
|
||||
|
||||
HWND GetHWnd(); // 获取绘图窗口句柄(HWND)
|
||||
TCHAR* GetEasyXVer(); // 获取 EasyX 当前版本
|
||||
|
||||
// 获取用户输入
|
||||
bool InputBox(LPTSTR pString, int nMaxCount, LPCTSTR pPrompt = NULL, LPCTSTR pTitle = NULL, LPCTSTR pDefault = NULL, int width = 0, int height = 0, bool bOnlyOK = true);
|
||||
|
||||
|
||||
|
||||
// 鼠标消息
|
||||
// 支持如下消息:
|
||||
// WM_MOUSEMOVE 鼠标移动
|
||||
// WM_MOUSEWHEEL 鼠标滚轮拨动
|
||||
// WM_LBUTTONDOWN 左键按下
|
||||
// WM_LBUTTONUP 左键弹起
|
||||
// WM_LBUTTONDBLCLK 左键双击
|
||||
// WM_MBUTTONDOWN 中键按下
|
||||
// WM_MBUTTONUP 中键弹起
|
||||
// WM_MBUTTONDBLCLK 中键双击
|
||||
// WM_RBUTTONDOWN 右键按下
|
||||
// WM_RBUTTONUP 右键弹起
|
||||
// WM_RBUTTONDBLCLK 右键双击
|
||||
struct MOUSEMSG
|
||||
{
|
||||
UINT uMsg; // 当前鼠标消息
|
||||
bool mkCtrl; // Ctrl 键是否按下
|
||||
bool mkShift; // Shift 键是否按下
|
||||
bool mkLButton; // 鼠标左键是否按下
|
||||
bool mkMButton; // 鼠标中键是否按下
|
||||
bool mkRButton; // 鼠标右键是否按下
|
||||
short x; // 当前鼠标 x 坐标
|
||||
short y; // 当前鼠标 y 坐标
|
||||
short wheel; // 鼠标滚轮滚动值 (120 的倍数)
|
||||
};
|
||||
|
||||
bool MouseHit(); // 检查是否存在鼠标消息
|
||||
MOUSEMSG GetMouseMsg(); // 获取一个鼠标消息。如果没有,就等待
|
||||
void FlushMouseMsgBuffer(); // 清空鼠标消息缓冲区
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,39 @@
|
|||
#include "easy2d.h"
|
||||
|
||||
// FreePool 释放池的实现机制:
|
||||
/// Object 类中的引用计数(m_nRef)引用计数保证了指针的使用安全
|
||||
/// 它记录了对象被使用的次数,当计数为 0 时,FreePool 会自动释放这个对象
|
||||
/// 所有的 Object 对象都应在被使用时(例如 Text 添加到了场景中)
|
||||
/// 调用 retain 函数保证该对象不被删除,并在不再使用时调用 release 函数
|
||||
/// 让其自动释放
|
||||
|
||||
// 释放池容器
|
||||
static std::vector<Object*> pool;
|
||||
|
||||
void FreePool::__flush()
|
||||
{
|
||||
// 创建迭代器
|
||||
std::vector<Object*>::iterator iter;
|
||||
// 循环遍历容器中的所有对象
|
||||
for (iter = pool.begin(); iter != pool.end();)
|
||||
{
|
||||
// 若对象的引用的计数为 0
|
||||
if ((*iter)->m_nRef == 0)
|
||||
{
|
||||
// 释放该对象
|
||||
delete (*iter);
|
||||
// 从释放池中删除该对象
|
||||
iter = pool.erase(iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
iter++; // 移动迭代器
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FreePool::add(Object * nptr)
|
||||
{
|
||||
// 将一个对象放入释放池中
|
||||
pool.push_back(nptr);
|
||||
}
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
#include "..\easy2d.h"
|
||||
#include "..\EasyX\easyx.h"
|
||||
#include <conio.h>
|
||||
|
||||
// 按键监听回调函数的容器
|
||||
static std::vector<KeyMsg*> s_vKeyMsg;
|
||||
|
||||
// 虚拟键值的容器
|
||||
static std::vector<VK_KEY> s_vKeys = {
|
||||
KeyMsg::A, KeyMsg::B, KeyMsg::C, KeyMsg::D, KeyMsg::E, KeyMsg::F, KeyMsg::G, KeyMsg::H, KeyMsg::I, KeyMsg::J,
|
||||
KeyMsg::K, KeyMsg::L, KeyMsg::M, KeyMsg::N, KeyMsg::O, KeyMsg::P, KeyMsg::Q, KeyMsg::R, KeyMsg::S, KeyMsg::T,
|
||||
KeyMsg::U, KeyMsg::V, KeyMsg::W, KeyMsg::X, KeyMsg::Y, KeyMsg::Z,
|
||||
KeyMsg::NUM_1, KeyMsg::NUM_2, KeyMsg::NUM_3, KeyMsg::NUM_4, KeyMsg::NUM_5,
|
||||
KeyMsg::NUM_6, KeyMsg::NUM_7, KeyMsg::NUM_8, KeyMsg::NUM_9, KeyMsg::NUM_0,
|
||||
KeyMsg::NUMPAD_1, KeyMsg::NUMPAD_2, KeyMsg::NUMPAD_3, KeyMsg::NUMPAD_4, KeyMsg::NUMPAD_5,
|
||||
KeyMsg::NUMPAD_6, KeyMsg::NUMPAD_7, KeyMsg::NUMPAD_8, KeyMsg::NUMPAD_9, KeyMsg::NUMPAD_0,
|
||||
KeyMsg::Enter, KeyMsg::Space, KeyMsg::Up, KeyMsg::Down, KeyMsg::Left, KeyMsg::Right, KeyMsg::Esc,
|
||||
KeyMsg::Decimal, KeyMsg::Shift, KeyMsg::LShift, KeyMsg::RShift, KeyMsg::Ctrl, KeyMsg::LCtrl, KeyMsg::RCtrl,
|
||||
KeyMsg::F1, KeyMsg::F2, KeyMsg::F3, KeyMsg::F4, KeyMsg::F5, KeyMsg::F6,
|
||||
KeyMsg::F7, KeyMsg::F8, KeyMsg::F9, KeyMsg::F10, KeyMsg::F11, KeyMsg::F12
|
||||
};
|
||||
|
||||
// 虚拟键值的定义
|
||||
const VK_KEY KeyMsg::A = 'A';
|
||||
const VK_KEY KeyMsg::B = 'B';
|
||||
const VK_KEY KeyMsg::C = 'C';
|
||||
const VK_KEY KeyMsg::D = 'D';
|
||||
const VK_KEY KeyMsg::E = 'E';
|
||||
const VK_KEY KeyMsg::F = 'F';
|
||||
const VK_KEY KeyMsg::G = 'G';
|
||||
const VK_KEY KeyMsg::H = 'H';
|
||||
const VK_KEY KeyMsg::I = 'I';
|
||||
const VK_KEY KeyMsg::J = 'J';
|
||||
const VK_KEY KeyMsg::K = 'K';
|
||||
const VK_KEY KeyMsg::L = 'L';
|
||||
const VK_KEY KeyMsg::M = 'M';
|
||||
const VK_KEY KeyMsg::N = 'N';
|
||||
const VK_KEY KeyMsg::O = 'O';
|
||||
const VK_KEY KeyMsg::P = 'P';
|
||||
const VK_KEY KeyMsg::Q = 'Q';
|
||||
const VK_KEY KeyMsg::R = 'R';
|
||||
const VK_KEY KeyMsg::S = 'S';
|
||||
const VK_KEY KeyMsg::T = 'T';
|
||||
const VK_KEY KeyMsg::U = 'U';
|
||||
const VK_KEY KeyMsg::V = 'V';
|
||||
const VK_KEY KeyMsg::W = 'W';
|
||||
const VK_KEY KeyMsg::X = 'X';
|
||||
const VK_KEY KeyMsg::Y = 'Y';
|
||||
const VK_KEY KeyMsg::Z = 'Z';
|
||||
const VK_KEY KeyMsg::NUM_0 = '0';
|
||||
const VK_KEY KeyMsg::NUM_1 = '1';
|
||||
const VK_KEY KeyMsg::NUM_2 = '2';
|
||||
const VK_KEY KeyMsg::NUM_3 = '3';
|
||||
const VK_KEY KeyMsg::NUM_4 = '4';
|
||||
const VK_KEY KeyMsg::NUM_5 = '5';
|
||||
const VK_KEY KeyMsg::NUM_6 = '6';
|
||||
const VK_KEY KeyMsg::NUM_7 = '7';
|
||||
const VK_KEY KeyMsg::NUM_8 = '8';
|
||||
const VK_KEY KeyMsg::NUM_9 = '9';
|
||||
const VK_KEY KeyMsg::NUMPAD_0 = VK_NUMPAD0;
|
||||
const VK_KEY KeyMsg::NUMPAD_1 = VK_NUMPAD1;
|
||||
const VK_KEY KeyMsg::NUMPAD_2 = VK_NUMPAD2;
|
||||
const VK_KEY KeyMsg::NUMPAD_3 = VK_NUMPAD3;
|
||||
const VK_KEY KeyMsg::NUMPAD_4 = VK_NUMPAD4;
|
||||
const VK_KEY KeyMsg::NUMPAD_5 = VK_NUMPAD5;
|
||||
const VK_KEY KeyMsg::NUMPAD_6 = VK_NUMPAD6;
|
||||
const VK_KEY KeyMsg::NUMPAD_7 = VK_NUMPAD7;
|
||||
const VK_KEY KeyMsg::NUMPAD_8 = VK_NUMPAD8;
|
||||
const VK_KEY KeyMsg::NUMPAD_9 = VK_NUMPAD9;
|
||||
const VK_KEY KeyMsg::Enter = VK_RETURN;
|
||||
const VK_KEY KeyMsg::Space = VK_SPACE;
|
||||
const VK_KEY KeyMsg::Decimal = VK_DECIMAL;
|
||||
const VK_KEY KeyMsg::Ctrl = VK_CONTROL;
|
||||
const VK_KEY KeyMsg::LCtrl = VK_LCONTROL;
|
||||
const VK_KEY KeyMsg::RCtrl = VK_RCONTROL;
|
||||
const VK_KEY KeyMsg::Shift = VK_SHIFT;
|
||||
const VK_KEY KeyMsg::LShift = VK_LSHIFT;
|
||||
const VK_KEY KeyMsg::RShift = VK_RSHIFT;
|
||||
const VK_KEY KeyMsg::Up = VK_UP;
|
||||
const VK_KEY KeyMsg::Down = VK_DOWN;
|
||||
const VK_KEY KeyMsg::Left = VK_LEFT;
|
||||
const VK_KEY KeyMsg::Right = VK_RIGHT;
|
||||
const VK_KEY KeyMsg::Esc = VK_ESCAPE;
|
||||
const VK_KEY KeyMsg::F1 = VK_F1;
|
||||
const VK_KEY KeyMsg::F2 = VK_F2;
|
||||
const VK_KEY KeyMsg::F3 = VK_F3;
|
||||
const VK_KEY KeyMsg::F4 = VK_F4;
|
||||
const VK_KEY KeyMsg::F5 = VK_F5;
|
||||
const VK_KEY KeyMsg::F6 = VK_F6;
|
||||
const VK_KEY KeyMsg::F7 = VK_F7;
|
||||
const VK_KEY KeyMsg::F8 = VK_F8;
|
||||
const VK_KEY KeyMsg::F9 = VK_F9;
|
||||
const VK_KEY KeyMsg::F10 = VK_F10;
|
||||
const VK_KEY KeyMsg::F11 = VK_F11;
|
||||
const VK_KEY KeyMsg::F12 = VK_F12;
|
||||
|
||||
KeyMsg::KeyMsg(tstring name, const KEY_CALLBACK & callback)
|
||||
{
|
||||
m_sName = name;
|
||||
m_callback = callback;
|
||||
}
|
||||
|
||||
KeyMsg::~KeyMsg()
|
||||
{
|
||||
}
|
||||
|
||||
void KeyMsg::onKbHit(VK_KEY key)
|
||||
{
|
||||
m_callback(key);
|
||||
}
|
||||
|
||||
void KeyMsg::__exec()
|
||||
{
|
||||
if (_kbhit()) // 获取键盘消息
|
||||
{
|
||||
for (VK_KEY key : s_vKeys) // 循环遍历所有的虚拟键值
|
||||
{
|
||||
if (GetAsyncKeyState(key) & 0x8000) // 判断该键是否按下
|
||||
{
|
||||
for (auto k : s_vKeyMsg) // 分发该按键消息
|
||||
{
|
||||
k->onKbHit(key); // 执行按键回调函数
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KeyMsg::addListener(tstring name, const KEY_CALLBACK & callback)
|
||||
{
|
||||
// 创建新的监听对象
|
||||
auto key = new KeyMsg(name, callback);
|
||||
// 添加新的按键回调函数
|
||||
s_vKeyMsg.push_back(key);
|
||||
}
|
||||
|
||||
bool easy2d::KeyMsg::delListener(tstring name)
|
||||
{
|
||||
// 创建迭代器
|
||||
std::vector<KeyMsg*>::iterator iter;
|
||||
// 循环遍历所有监听器
|
||||
for (iter = s_vKeyMsg.begin(); iter != s_vKeyMsg.end(); iter++)
|
||||
{
|
||||
// 查找相同名称的监听器
|
||||
if ((*iter)->m_sName == name)
|
||||
{
|
||||
// 删除该定时器
|
||||
delete (*iter);
|
||||
s_vKeyMsg.erase(iter);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// 若未找到同样名称的监听器,返回 false
|
||||
return false;
|
||||
}
|
||||
|
||||
void easy2d::KeyMsg::clearAllListener()
|
||||
{
|
||||
// 删除所有监听器
|
||||
for (auto t : s_vKeyMsg)
|
||||
{
|
||||
delete t;
|
||||
}
|
||||
// 清空容器
|
||||
s_vKeyMsg.clear();
|
||||
}
|
||||
|
||||
bool KeyMsg::isKeyDown(VK_KEY key)
|
||||
{
|
||||
// 获取 key 的按下情况
|
||||
return (GetAsyncKeyState(key) & 0x8000);
|
||||
}
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
#include "..\easy2d.h"
|
||||
#include "..\EasyX\easyx.h"
|
||||
|
||||
// 鼠标消息
|
||||
static MouseMsg s_mouseMsg = MouseMsg();
|
||||
|
||||
// 将 EasyX 的 MOUSEMSG 转换为 MouseMsg
|
||||
static void ConvertMsg(MOUSEMSG msg);
|
||||
|
||||
void easy2d::MouseMsg::__exec()
|
||||
{
|
||||
// 获取鼠标消息
|
||||
while (MouseHit())
|
||||
{
|
||||
// 转换鼠标消息
|
||||
ConvertMsg(GetMouseMsg());
|
||||
// 执行场景程序
|
||||
Application::get()->getCurrentScene()->_exec();
|
||||
}
|
||||
}
|
||||
|
||||
MouseMsg MouseMsg::getMsg()
|
||||
{
|
||||
return s_mouseMsg; // 获取当前鼠标消息
|
||||
}
|
||||
|
||||
bool MouseMsg::getLButtonDown()
|
||||
{
|
||||
return s_mouseMsg.mkLButton;
|
||||
}
|
||||
|
||||
bool MouseMsg::getRButtonDown()
|
||||
{
|
||||
return s_mouseMsg.mkRButton;
|
||||
}
|
||||
|
||||
bool MouseMsg::getMButtonDown()
|
||||
{
|
||||
return s_mouseMsg.mkMButton;
|
||||
}
|
||||
|
||||
int MouseMsg::getMouseX()
|
||||
{
|
||||
return s_mouseMsg.x;
|
||||
}
|
||||
|
||||
int MouseMsg::getMouseY()
|
||||
{
|
||||
return s_mouseMsg.y;
|
||||
}
|
||||
|
||||
int MouseMsg::getMouseWheel()
|
||||
{
|
||||
return s_mouseMsg.wheel;
|
||||
}
|
||||
|
||||
bool MouseMsg::getMouseMovedMsg()
|
||||
{
|
||||
return s_mouseMsg.uMsg == WM_MOUSEMOVE;
|
||||
}
|
||||
|
||||
bool MouseMsg::getLButtonDBClickedMsg()
|
||||
{
|
||||
return s_mouseMsg.uMsg == WM_LBUTTONDBLCLK;
|
||||
}
|
||||
|
||||
bool MouseMsg::getLButtonDownMsg()
|
||||
{
|
||||
return s_mouseMsg.uMsg == WM_LBUTTONDOWN;
|
||||
}
|
||||
|
||||
bool MouseMsg::getLButtonUpMsg()
|
||||
{
|
||||
return s_mouseMsg.uMsg == WM_LBUTTONUP;
|
||||
}
|
||||
|
||||
bool MouseMsg::getRButtonDBClicked()
|
||||
{
|
||||
return s_mouseMsg.uMsg == WM_RBUTTONDBLCLK;
|
||||
}
|
||||
|
||||
bool MouseMsg::getRButtonDownMsg()
|
||||
{
|
||||
return s_mouseMsg.uMsg == WM_RBUTTONDOWN;
|
||||
}
|
||||
|
||||
bool MouseMsg::getRButtonUpMsg()
|
||||
{
|
||||
return s_mouseMsg.uMsg == WM_LBUTTONUP;
|
||||
}
|
||||
|
||||
bool MouseMsg::getMButtonDBClicked()
|
||||
{
|
||||
return s_mouseMsg.uMsg == WM_MBUTTONDBLCLK;
|
||||
}
|
||||
|
||||
bool MouseMsg::getMButtonDownMsg()
|
||||
{
|
||||
return s_mouseMsg.uMsg == WM_MBUTTONDOWN;
|
||||
}
|
||||
|
||||
bool MouseMsg::getMButtonUpMsg()
|
||||
{
|
||||
return s_mouseMsg.uMsg == WM_MBUTTONUP;
|
||||
}
|
||||
|
||||
bool MouseMsg::getWheelMsg()
|
||||
{
|
||||
return s_mouseMsg.uMsg == WM_MOUSEWHEEL;
|
||||
}
|
||||
|
||||
void MouseMsg::resetMouseMsg()
|
||||
{
|
||||
s_mouseMsg.uMsg = 0;
|
||||
}
|
||||
|
||||
void ConvertMsg(MOUSEMSG msg)
|
||||
{
|
||||
// 将 MOUSEMSG 转换为 MouseMsg
|
||||
/// 虽然 MOUSEMSG 和 MouseMsg 本质上是一样的
|
||||
/// 但是为了实现 Easy2D 与 EasyX 的相对隔离,所以定义了新的 MouseMsg
|
||||
/// 将来 Msg 对消息的处理会统一用 WinAPI实现,而不再用 EasyX 的函数
|
||||
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;
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
#include "..\easy2d.h"
|
||||
#include "..\EasyX\easyx.h"
|
||||
#include <assert.h>
|
||||
|
||||
BatchNode::BatchNode()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BatchNode::~BatchNode()
|
||||
{
|
||||
clearAllChildren();
|
||||
}
|
||||
|
||||
bool BatchNode::_exec(bool active)
|
||||
{
|
||||
// 批量节点是否显示
|
||||
if (!m_bDisplay)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// 逆序遍历所有子节点
|
||||
for (int i = int(m_vChildren.size() - 1); i >= 0; i--)
|
||||
{
|
||||
assert(m_vChildren[i]);
|
||||
if (m_vChildren[i]->_exec(active))
|
||||
{
|
||||
active = false;
|
||||
}
|
||||
}
|
||||
// 若子节点取得了画面焦点,则该节点也取得了焦点
|
||||
return !active;
|
||||
}
|
||||
|
||||
void BatchNode::_onDraw()
|
||||
{
|
||||
// 节点是否显示
|
||||
if (!m_bDisplay)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 在相对位置绘制子节点
|
||||
Application::setOrigin(Application::getOriginX() + m_nX, Application::getOriginY() + m_nY);
|
||||
for (auto child : m_vChildren)
|
||||
{
|
||||
assert(child);
|
||||
child->_onDraw();
|
||||
}
|
||||
Application::setOrigin(Application::getOriginX() - m_nX, Application::getOriginY() - m_nY);
|
||||
}
|
||||
|
||||
void BatchNode::add(Node * child, int z_Order)
|
||||
{
|
||||
// 断言添加的节点非空
|
||||
assert(child);
|
||||
// 设置节点的父场景
|
||||
child->setParentScene(this->getParentScene());
|
||||
// 设置节点在批量节点中的 z 轴顺序
|
||||
child->setZOrder(z_Order);
|
||||
// 对象的引用计数加一
|
||||
child->retain();
|
||||
|
||||
// 按 z 轴顺序插入节点
|
||||
size_t size = m_vChildren.size();
|
||||
for (unsigned i = 0; i <= size; i++)
|
||||
{
|
||||
if (i != size)
|
||||
{
|
||||
if (z_Order < m_vChildren.at(i)->getZOrder())
|
||||
{
|
||||
m_vChildren.insert(m_vChildren.begin() + i, child);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_vChildren.push_back(child);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool BatchNode::del(Node * child)
|
||||
{
|
||||
// 断言节点非空
|
||||
assert(child);
|
||||
|
||||
// 寻找是否有相同节点
|
||||
std::vector<Node*>::iterator iter;
|
||||
for (iter = m_vChildren.begin(); iter != m_vChildren.end(); iter++)
|
||||
{
|
||||
// 找到相同节点
|
||||
if ((*iter) == child)
|
||||
{
|
||||
// 对象的引用计数减一
|
||||
(*iter)->release();
|
||||
// 去掉该节点
|
||||
m_vChildren.erase(iter);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void BatchNode::clearAllChildren()
|
||||
{
|
||||
// 所有节点的引用计数减一
|
||||
for (auto child : m_vChildren)
|
||||
{
|
||||
child->release();
|
||||
}
|
||||
// 清空储存节点的容器
|
||||
m_vChildren.clear();
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
#include "..\..\Easy2d.h"
|
||||
#include "..\..\EasyX\easyx.h"
|
||||
|
||||
|
||||
Button::Button() :
|
||||
m_bEnable(true)
|
||||
{
|
||||
}
|
||||
|
||||
Button::~Button()
|
||||
{
|
||||
}
|
||||
|
||||
bool Button::_exec(bool active)
|
||||
{
|
||||
// 按钮是否启用
|
||||
if (!m_bEnable || !m_bDisplay)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return MouseNode::_exec(active);
|
||||
}
|
||||
|
||||
void Button::_onDraw()
|
||||
{
|
||||
// 按钮是否启用
|
||||
if (!m_bEnable)
|
||||
{
|
||||
// 未启用时,绘制 Disable 状态
|
||||
_onDisable();
|
||||
return;
|
||||
}
|
||||
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::getLButtonDownMsg())
|
||||
{
|
||||
_setSelected();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_setNormal();
|
||||
}
|
||||
}
|
||||
|
||||
bool Button::isEnable()
|
||||
{
|
||||
return m_bEnable;
|
||||
}
|
||||
|
||||
void Button::setEnable(bool enable)
|
||||
{
|
||||
m_bEnable = enable;
|
||||
}
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
#include "..\..\Easy2d.h"
|
||||
|
||||
|
||||
ImageButton::ImageButton() :
|
||||
m_pNormalImage(nullptr),
|
||||
m_pMouseInImage(nullptr),
|
||||
m_pSelectedImage(nullptr),
|
||||
m_pUnableImage(nullptr)
|
||||
{
|
||||
m_nWidth = 0;
|
||||
m_nHeight = 0;
|
||||
}
|
||||
|
||||
ImageButton::ImageButton(Image * image) :
|
||||
ImageButton()
|
||||
{
|
||||
setNormalImage(image); // 设置按钮在正常状态时的图片
|
||||
}
|
||||
|
||||
ImageButton::~ImageButton()
|
||||
{
|
||||
// 所有图片的引用计数减一
|
||||
SAFE_RELEASE(m_pNormalImage);
|
||||
SAFE_RELEASE(m_pMouseInImage);
|
||||
SAFE_RELEASE(m_pSelectedImage);
|
||||
SAFE_RELEASE(m_pUnableImage);
|
||||
}
|
||||
|
||||
void ImageButton::_onNormal()
|
||||
{
|
||||
if (m_pNormalImage)
|
||||
{
|
||||
m_pNormalImage->_onDraw();
|
||||
}
|
||||
}
|
||||
|
||||
void ImageButton::_onMouseIn()
|
||||
{
|
||||
if (m_pMouseInImage)
|
||||
{
|
||||
m_pMouseInImage->_onDraw();
|
||||
}
|
||||
else
|
||||
{
|
||||
_onNormal();
|
||||
}
|
||||
}
|
||||
|
||||
void ImageButton::_onSelected()
|
||||
{
|
||||
if (m_pSelectedImage)
|
||||
{
|
||||
m_pSelectedImage->_onDraw();
|
||||
}
|
||||
else
|
||||
{
|
||||
_onNormal();
|
||||
}
|
||||
}
|
||||
|
||||
void ImageButton::_onDisable()
|
||||
{
|
||||
if (m_pUnableImage)
|
||||
{
|
||||
m_pUnableImage->_onDraw();
|
||||
}
|
||||
else
|
||||
{
|
||||
_onNormal();
|
||||
}
|
||||
}
|
||||
|
||||
void ImageButton::setNormalImage(Image * image)
|
||||
{
|
||||
if (image)
|
||||
{
|
||||
// 原图片引用计数减一
|
||||
SAFE_RELEASE(m_pNormalImage);
|
||||
// 修改图片
|
||||
m_pNormalImage = image;
|
||||
// 现图片引用计数加一
|
||||
m_pNormalImage->retain();
|
||||
// 重新计算图片位置
|
||||
resetImagePosition();
|
||||
}
|
||||
}
|
||||
|
||||
void ImageButton::setMouseInImage(Image * image)
|
||||
{
|
||||
if (image)
|
||||
{
|
||||
SAFE_RELEASE(m_pMouseInImage);
|
||||
m_pMouseInImage = image;
|
||||
m_pMouseInImage->retain();
|
||||
resetImagePosition();
|
||||
}
|
||||
}
|
||||
|
||||
void ImageButton::setSelectedImage(Image * image)
|
||||
{
|
||||
if (image)
|
||||
{
|
||||
SAFE_RELEASE(m_pSelectedImage);
|
||||
m_pSelectedImage = image;
|
||||
m_pSelectedImage->retain();
|
||||
resetImagePosition();
|
||||
}
|
||||
}
|
||||
|
||||
void ImageButton::setUnableImage(Image * image)
|
||||
{
|
||||
if (image)
|
||||
{
|
||||
SAFE_RELEASE(m_pUnableImage);
|
||||
m_pUnableImage = image;
|
||||
m_pUnableImage->retain();
|
||||
resetImagePosition();
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
if (m_pNormalImage)
|
||||
{
|
||||
// 根据图片宽高设定按钮大小
|
||||
m_nWidth = m_pNormalImage->getWidth();
|
||||
m_nHeight = m_pNormalImage->getHeight();
|
||||
// 根据按钮位置和图片宽高设置图片位置居中显示
|
||||
m_pNormalImage->setPos(m_nX, m_nY);
|
||||
}
|
||||
if (m_pMouseInImage)
|
||||
{
|
||||
m_pMouseInImage->setPos(
|
||||
m_nX + (m_nWidth - m_pMouseInImage->getWidth()) / 2,
|
||||
m_nY + (m_nHeight - 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);
|
||||
}
|
||||
if (m_pUnableImage)
|
||||
{
|
||||
m_pUnableImage->setPos(
|
||||
m_nX + (m_nWidth - m_pUnableImage->getWidth()) / 2,
|
||||
m_nY + (m_nHeight - m_pUnableImage->getHeight()) / 2);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
#include "..\..\Easy2d.h"
|
||||
|
||||
|
||||
TextButton::TextButton() :
|
||||
m_pNormalText(nullptr),
|
||||
m_pMouseInText(nullptr),
|
||||
m_pSelectedText(nullptr),
|
||||
m_pUnableText(nullptr)
|
||||
{
|
||||
m_nWidth = 0;
|
||||
m_nHeight = 0;
|
||||
}
|
||||
|
||||
TextButton::TextButton(Text * text) :
|
||||
TextButton()
|
||||
{
|
||||
setNormalText(text); // 设置按钮在正常状态时的文字
|
||||
}
|
||||
|
||||
TextButton::~TextButton()
|
||||
{
|
||||
// 所有文本的引用计数减一
|
||||
SAFE_RELEASE(m_pNormalText);
|
||||
SAFE_RELEASE(m_pMouseInText);
|
||||
SAFE_RELEASE(m_pSelectedText);
|
||||
SAFE_RELEASE(m_pUnableText);
|
||||
}
|
||||
|
||||
void TextButton::_onNormal()
|
||||
{
|
||||
if (m_pNormalText)
|
||||
{
|
||||
m_pNormalText->_onDraw();
|
||||
}
|
||||
}
|
||||
|
||||
void TextButton::_onMouseIn()
|
||||
{
|
||||
if (m_pMouseInText)
|
||||
{
|
||||
m_pMouseInText->_onDraw();
|
||||
}
|
||||
else
|
||||
{
|
||||
_onNormal();
|
||||
}
|
||||
}
|
||||
|
||||
void TextButton::_onSelected()
|
||||
{
|
||||
if (m_pSelectedText)
|
||||
{
|
||||
m_pSelectedText->_onDraw();
|
||||
}
|
||||
else
|
||||
{
|
||||
_onNormal();
|
||||
}
|
||||
}
|
||||
|
||||
void TextButton::_onDisable()
|
||||
{
|
||||
if (m_pUnableText)
|
||||
{
|
||||
m_pUnableText->_onDraw();
|
||||
}
|
||||
else
|
||||
{
|
||||
_onNormal();
|
||||
}
|
||||
}
|
||||
|
||||
void TextButton::setNormalText(Text * text)
|
||||
{
|
||||
if (text)
|
||||
{
|
||||
// 原文本引用计数减一
|
||||
SAFE_RELEASE(m_pNormalText);
|
||||
// 修改文本
|
||||
m_pNormalText = text;
|
||||
// 现文本引用计数加一
|
||||
m_pNormalText->retain();
|
||||
// 重新计算文本位置
|
||||
resetTextPosition();
|
||||
}
|
||||
}
|
||||
|
||||
void TextButton::setMouseInText(Text * text)
|
||||
{
|
||||
if (text)
|
||||
{
|
||||
SAFE_RELEASE(m_pMouseInText);
|
||||
m_pMouseInText = text;
|
||||
m_pMouseInText->retain();
|
||||
resetTextPosition();
|
||||
}
|
||||
}
|
||||
|
||||
void TextButton::setSelectedText(Text * text)
|
||||
{
|
||||
if (text)
|
||||
{
|
||||
SAFE_RELEASE(m_pSelectedText);
|
||||
m_pSelectedText = text;
|
||||
m_pSelectedText->retain();
|
||||
resetTextPosition();
|
||||
}
|
||||
}
|
||||
|
||||
void TextButton::setUnableText(Text * text)
|
||||
{
|
||||
if (text)
|
||||
{
|
||||
SAFE_RELEASE(m_pUnableText);
|
||||
m_pUnableText = text;
|
||||
m_pUnableText->retain();
|
||||
resetTextPosition();
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
if (m_pNormalText)
|
||||
{
|
||||
// 根据文字宽高设定按钮大小
|
||||
m_nWidth = m_pNormalText->getWidth();
|
||||
m_nHeight = m_pNormalText->getHeight();
|
||||
// 根据按钮位置和文字宽高设置文字位置居中显示
|
||||
m_pNormalText->setPos(m_nX , m_nY);
|
||||
}
|
||||
if (m_pMouseInText)
|
||||
{
|
||||
m_pMouseInText->setPos(
|
||||
m_nX + (m_nWidth - m_pMouseInText->getWidth()) / 2,
|
||||
m_nY + (m_nHeight - 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);
|
||||
}
|
||||
if (m_pUnableText)
|
||||
{
|
||||
m_pUnableText->setPos(
|
||||
m_nX + (m_nWidth - m_pUnableText->getWidth()) / 2,
|
||||
m_nY + (m_nHeight - m_pUnableText->getHeight()) / 2);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,181 @@
|
|||
#include "..\Easy2d.h"
|
||||
#include "..\EasyX\easyx.h"
|
||||
|
||||
// 对 PNG 图像进行像素转换
|
||||
static void CrossImage(CImage &img);
|
||||
|
||||
Image::Image() :
|
||||
m_fScaleX(1),
|
||||
m_fScaleY(1)
|
||||
{
|
||||
}
|
||||
|
||||
Image::Image(LPCTSTR ImageFile, int x, int y, int width, int height) :
|
||||
m_fScaleX(1),
|
||||
m_fScaleY(1)
|
||||
{
|
||||
setImageFile(ImageFile, x, y, width, height); // 设置图片资源和裁剪大小
|
||||
}
|
||||
|
||||
Image::~Image()
|
||||
{
|
||||
}
|
||||
|
||||
void Image::_onDraw()
|
||||
{
|
||||
// display 属性为 false,或未设置图片资源时,不绘制该图片
|
||||
if (!m_bDisplay || m_Image.IsNull())
|
||||
{
|
||||
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(); // 目标矩形的高度
|
||||
}
|
||||
|
||||
float Image::getScaleX() const
|
||||
{
|
||||
return m_fScaleX;
|
||||
}
|
||||
|
||||
float Image::getScaleY() const
|
||||
{
|
||||
return m_fScaleY;
|
||||
}
|
||||
|
||||
void Image::setImageFile(LPCTSTR ImageFile, int x, int y, int width, int height)
|
||||
{
|
||||
// 加载图片
|
||||
m_Image.Load(ImageFile);
|
||||
// 获取扩展名,对 PNG 图片进行特殊处理
|
||||
if (_T(".png") == FileUtils::getFileExtension(ImageFile))
|
||||
{
|
||||
// 像素转换
|
||||
CrossImage(m_Image);
|
||||
// Alpha 通道
|
||||
m_Image.AlphaBlend(GetImageHDC(), 15, 30);
|
||||
}
|
||||
// 设置目标矩形(即绘制到窗口的位置和大小)
|
||||
m_rDest.SetRect(0, 0, m_Image.GetWidth(), m_Image.GetHeight());
|
||||
// 裁剪图片大小
|
||||
crop(x, y, width, height);
|
||||
}
|
||||
|
||||
void Image::setImageRes(LPCTSTR pResName, int x, int y, int width, int height)
|
||||
{
|
||||
// 从资源加载图片(不支持 PNG)
|
||||
m_Image.LoadFromResource(GetModuleHandle(NULL), pResName);
|
||||
// 重置缩放属性
|
||||
m_fScaleX = 0, m_fScaleY = 0;
|
||||
// 设置目标矩形(即绘制到窗口的位置和大小)
|
||||
m_rDest.SetRect(0, 0, m_Image.GetWidth(), m_Image.GetHeight());
|
||||
// 裁剪图片大小
|
||||
crop(x, y, width, height);
|
||||
}
|
||||
|
||||
void Image::crop(int x, int y, int width, int height)
|
||||
{
|
||||
// 设置源矩形的位置和大小(用于裁剪)
|
||||
m_rSrc.SetRect(
|
||||
x, y,
|
||||
x + (width ? width : m_Image.GetWidth() - x),
|
||||
y + (height ? height : m_Image.GetHeight() - y));
|
||||
// 设置目标矩形(即绘制到窗口的位置和大小)
|
||||
m_rDest.SetRect(
|
||||
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)
|
||||
{
|
||||
// 设置目标矩形的位置和大小(即绘制到窗口的位置和大小,用于拉伸图片)
|
||||
m_rDest.SetRect(
|
||||
m_nX, m_nY,
|
||||
m_nX + (width ? width : m_Image.GetWidth()),
|
||||
m_nY + (height ? height : m_Image.GetHeight()));
|
||||
}
|
||||
|
||||
void Image::scale(float scaleX, float scaleY)
|
||||
{
|
||||
m_fScaleX = min(max(scaleX, 0), 1.0f);
|
||||
m_fScaleY = min(max(scaleY, 0), 1.0f);
|
||||
m_rDest.SetRect(
|
||||
m_nX, m_nY,
|
||||
m_nX + int(m_Image.GetWidth() * scaleX),
|
||||
m_nY + int(m_Image.GetHeight() * scaleY));
|
||||
}
|
||||
|
||||
void Image::setPos(int x, int y)
|
||||
{
|
||||
// 移动目标矩形
|
||||
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;
|
||||
}
|
||||
|
||||
void Image::setTransparentColor(COLORREF value)
|
||||
{
|
||||
// 设置透明色
|
||||
m_Image.SetTransparentColor(value);
|
||||
}
|
||||
|
||||
void Image::screenshot()
|
||||
{
|
||||
tstring savePath;
|
||||
// 获取保存位置
|
||||
if (FileUtils::getSaveFilePath(savePath, _T("截图保存到"), _T("jpg")))
|
||||
{
|
||||
// 保存窗口截图
|
||||
IMAGE image;
|
||||
getimage(&image, 0, 0, Application::get()->getWidth(), Application::get()->getHeight());
|
||||
saveimage(savePath.c_str(), &image);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 对 PNG 图像进行像素转换
|
||||
void CrossImage(CImage &img)
|
||||
{
|
||||
for (int i = 0; i < img.GetWidth(); i++)
|
||||
{
|
||||
for (int j = 0; j < img.GetHeight(); j++)
|
||||
{
|
||||
UCHAR *cr = (UCHAR*)img.GetPixelAddress(i, j);
|
||||
cr[0] = cr[0] * cr[3] / 255;
|
||||
cr[1] = cr[1] * cr[3] / 255;
|
||||
cr[2] = cr[2] * cr[3] / 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
#include "..\easy2d.h"
|
||||
|
||||
|
||||
MouseNode::MouseNode() :
|
||||
m_bBlock(true),
|
||||
m_bTarget(false),
|
||||
m_callback([]() {})
|
||||
{
|
||||
}
|
||||
|
||||
MouseNode::~MouseNode()
|
||||
{
|
||||
}
|
||||
|
||||
bool MouseNode::_exec(bool active)
|
||||
{
|
||||
// 若画面已取得焦点,或 display 属性为 false,退出函数
|
||||
if (!active || !m_bDisplay)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// 判断节点状态
|
||||
_judge();
|
||||
// 鼠标在节点上(被选中时鼠标也在节点上)
|
||||
if (m_eStatus == MOUSEIN || m_eStatus == SELECTED)
|
||||
{
|
||||
// 节点被鼠标选中,且鼠标左键抬起
|
||||
if (m_bTarget && MouseMsg::getLButtonUpMsg())
|
||||
{
|
||||
onClicked(); // 执行回调函数
|
||||
}
|
||||
// 若节点不阻塞鼠标消息,则取得画面焦点
|
||||
if (!m_bBlock) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MouseNode::_onDraw()
|
||||
{
|
||||
// 节点是否显示
|
||||
if (!m_bDisplay)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// 节点是否被选中
|
||||
if (m_eStatus == SELECTED)
|
||||
{
|
||||
_onSelected();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 鼠标是否在节点上
|
||||
if (m_eStatus == MOUSEIN)
|
||||
{
|
||||
_onMouseIn();
|
||||
}
|
||||
else
|
||||
{
|
||||
_onNormal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MouseNode::_setNormal()
|
||||
{
|
||||
m_bTarget = false; // 失去焦点标记
|
||||
m_eStatus = NORMAL;
|
||||
}
|
||||
|
||||
void MouseNode::_setMouseIn()
|
||||
{
|
||||
m_eStatus = MOUSEIN;
|
||||
}
|
||||
|
||||
void MouseNode::_setSelected()
|
||||
{
|
||||
m_bTarget = true; // 取得焦点标记
|
||||
m_eStatus = SELECTED;
|
||||
}
|
||||
|
||||
void MouseNode::onClicked()
|
||||
{
|
||||
m_callback();
|
||||
}
|
||||
|
||||
bool MouseNode::isMouseIn()
|
||||
{
|
||||
return m_eStatus == MOUSEIN || m_eStatus == SELECTED;
|
||||
}
|
||||
|
||||
bool MouseNode::isSelected()
|
||||
{
|
||||
return m_eStatus == SELECTED;
|
||||
}
|
||||
|
||||
void MouseNode::setOnMouseClicked(const CLICK_CALLBACK & callback)
|
||||
{
|
||||
m_callback = callback;
|
||||
}
|
||||
|
||||
void MouseNode::reset()
|
||||
{
|
||||
m_eStatus = NORMAL;
|
||||
}
|
||||
|
||||
void MouseNode::setBlock(bool block)
|
||||
{
|
||||
m_bBlock = block;
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
#include "..\Easy2d.h"
|
||||
|
||||
Node::Node() :
|
||||
m_nZOrder(0),
|
||||
m_bDisplay(true),
|
||||
m_nX(0),
|
||||
m_nY(0)
|
||||
{
|
||||
}
|
||||
|
||||
Node::Node(int x, int y) :
|
||||
m_nZOrder(0),
|
||||
m_bDisplay(true),
|
||||
m_nX(x),
|
||||
m_nY(y)
|
||||
{
|
||||
}
|
||||
|
||||
Node::~Node()
|
||||
{
|
||||
}
|
||||
|
||||
bool Node::_exec(bool active)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void Node::_onDraw()
|
||||
{
|
||||
}
|
||||
|
||||
const int Node::getX() const
|
||||
{
|
||||
return m_nX;
|
||||
}
|
||||
|
||||
const int Node::getY() const
|
||||
{
|
||||
return m_nY;
|
||||
}
|
||||
|
||||
void Node::setX(int x)
|
||||
{
|
||||
m_nX = x;
|
||||
}
|
||||
|
||||
void Node::setY(int y)
|
||||
{
|
||||
m_nY = y;
|
||||
}
|
||||
|
||||
void Node::setPos(int x, int y)
|
||||
{
|
||||
m_nX = x;
|
||||
m_nY = y;
|
||||
}
|
||||
|
||||
void Node::move(int x, int y)
|
||||
{
|
||||
m_nX += x;
|
||||
m_nY += y;
|
||||
}
|
||||
|
||||
int Node::getZOrder() const
|
||||
{
|
||||
return m_nZOrder;
|
||||
}
|
||||
|
||||
void Node::setZOrder(int z)
|
||||
{
|
||||
m_nZOrder = z;
|
||||
}
|
||||
|
||||
Scene * Node::getParentScene()
|
||||
{
|
||||
return m_pScene;
|
||||
}
|
||||
|
||||
void Node::setParentScene(Scene * scene)
|
||||
{
|
||||
m_pScene = scene;
|
||||
}
|
||||
|
||||
void Node::setDisplay(bool value)
|
||||
{
|
||||
m_bDisplay = value;
|
||||
}
|
||||
|
||||
bool Node::display() const
|
||||
{
|
||||
return m_bDisplay;
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
#include "..\..\easy2d.h"
|
||||
#include "..\..\EasyX\easyx.h"
|
||||
|
||||
|
||||
Circle::Circle() :
|
||||
m_nRadius(0)
|
||||
{
|
||||
}
|
||||
|
||||
Circle::Circle(int x, int y, int radius) :
|
||||
Node(x, y),
|
||||
m_nRadius(radius)
|
||||
{
|
||||
}
|
||||
|
||||
Circle::~Circle()
|
||||
{
|
||||
}
|
||||
|
||||
void Circle::solidShape()
|
||||
{
|
||||
solidcircle(m_nX, m_nY, m_nRadius);
|
||||
}
|
||||
|
||||
void Circle::fillShape()
|
||||
{
|
||||
fillcircle(m_nX, m_nY, m_nRadius);
|
||||
}
|
||||
|
||||
void Circle::roundShape()
|
||||
{
|
||||
circle(m_nX, m_nY, m_nRadius);
|
||||
}
|
||||
|
||||
int Circle::getRadius() const
|
||||
{
|
||||
return m_nRadius;
|
||||
}
|
||||
|
||||
void Circle::setRadius(int r)
|
||||
{
|
||||
m_nRadius = r;
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
#include "..\..\easy2d.h"
|
||||
#include "..\..\EasyX\easyx.h"
|
||||
|
||||
|
||||
Rect::Rect() :
|
||||
m_nWidth(0),
|
||||
m_nHeight(0)
|
||||
{
|
||||
}
|
||||
|
||||
Rect::Rect(int x, int y, int width, int height) :
|
||||
Node(x, y),
|
||||
m_nWidth(width),
|
||||
m_nHeight(height)
|
||||
{
|
||||
}
|
||||
|
||||
Rect::~Rect()
|
||||
{
|
||||
}
|
||||
|
||||
void Rect::solidShape()
|
||||
{
|
||||
solidrectangle(m_nX, m_nY, m_nX + m_nWidth, m_nY + m_nHeight);
|
||||
}
|
||||
|
||||
void Rect::fillShape()
|
||||
{
|
||||
fillrectangle(m_nX, m_nY, m_nX + m_nWidth, m_nY + m_nHeight);
|
||||
}
|
||||
|
||||
void Rect::roundShape()
|
||||
{
|
||||
rectangle(m_nX, m_nY, m_nX + m_nWidth, m_nY + m_nHeight);
|
||||
}
|
||||
|
||||
int Rect::getWidth() const
|
||||
{
|
||||
return m_nWidth;
|
||||
}
|
||||
|
||||
int Rect::getHeight() const
|
||||
{
|
||||
return m_nHeight;
|
||||
}
|
||||
|
||||
void Rect::setWidth(int width)
|
||||
{
|
||||
m_nWidth = width;
|
||||
}
|
||||
|
||||
void Rect::setHeight(int height)
|
||||
{
|
||||
m_nHeight = height;
|
||||
}
|
||||
|
||||
void Rect::setSize(int width, int height)
|
||||
{
|
||||
m_nWidth = width;
|
||||
m_nHeight = height;
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
#include "..\..\Easy2d.h"
|
||||
#include "..\..\EasyX\easyx.h"
|
||||
|
||||
Shape::Shape()
|
||||
{
|
||||
}
|
||||
|
||||
Shape::~Shape()
|
||||
{
|
||||
}
|
||||
|
||||
void Shape::_onDraw()
|
||||
{
|
||||
// 形状是否显示
|
||||
if (!m_bDisplay)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// 设置线条和填充颜色
|
||||
setlinecolor(lineColor);
|
||||
setfillcolor(fillColor);
|
||||
|
||||
// 根据形状的样式进行不同的绘制
|
||||
if (_style == Shape::STYLE::round)
|
||||
{
|
||||
roundShape();
|
||||
}
|
||||
else if (_style == Shape::STYLE::solid)
|
||||
{
|
||||
solidShape();
|
||||
}
|
||||
else if (_style == Shape::STYLE::fill)
|
||||
{
|
||||
fillShape();
|
||||
}
|
||||
}
|
||||
|
||||
inline COLORREF Shape::getFillColor() const
|
||||
{
|
||||
return fillColor;
|
||||
}
|
||||
|
||||
inline COLORREF Shape::getLineColor() const
|
||||
{
|
||||
return lineColor;
|
||||
}
|
||||
|
||||
void Shape::setFillColor(COLORREF color)
|
||||
{
|
||||
fillColor = color;
|
||||
}
|
||||
|
||||
void Shape::setLineColor(COLORREF color)
|
||||
{
|
||||
lineColor = color;
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
#include "..\Easy2d.h"
|
||||
#include "..\EasyX\easyx.h"
|
||||
|
||||
|
||||
Text::Text() :
|
||||
m_sText(_T("")),
|
||||
m_color(Color::white),
|
||||
m_pFontStyle(FontStyle::getDefault())
|
||||
{
|
||||
m_pFontStyle->retain(); // 字体引用计数加一
|
||||
}
|
||||
|
||||
Text::Text(tstring text, COLORREF color, FontStyle * font) :
|
||||
m_sText(text),
|
||||
m_color(color),
|
||||
m_pFontStyle(font)
|
||||
{
|
||||
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)
|
||||
{
|
||||
m_pFontStyle->retain(); // 字体引用计数加一
|
||||
}
|
||||
|
||||
Text::~Text()
|
||||
{
|
||||
SAFE_RELEASE(m_pFontStyle); // 字体引用计数减一
|
||||
}
|
||||
|
||||
void Text::_onDraw()
|
||||
{
|
||||
// 若 display 属性为 false,不绘制这个文本
|
||||
if (!m_bDisplay)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// 设置字体
|
||||
settextstyle(&m_pFontStyle->m_font);
|
||||
// 设置文本颜色
|
||||
settextcolor(m_color);
|
||||
// 输出文字
|
||||
outtextxy(m_nX, m_nY, m_sText.c_str());
|
||||
}
|
||||
|
||||
COLORREF Text::getColor() const
|
||||
{
|
||||
return m_color;
|
||||
}
|
||||
|
||||
tstring Text::getText() const
|
||||
{
|
||||
return m_sText;
|
||||
}
|
||||
|
||||
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(); // 文本是否为空
|
||||
}
|
||||
|
||||
void Text::setText(tstring text)
|
||||
{
|
||||
m_sText = text;
|
||||
}
|
||||
|
||||
void Text::setColor(COLORREF color)
|
||||
{
|
||||
m_color = color;
|
||||
}
|
||||
|
||||
void Text::setFontStyle(FontStyle * style)
|
||||
{
|
||||
SAFE_RELEASE(m_pFontStyle); // 原字体引用计数减一
|
||||
m_pFontStyle = style; // 修改字体
|
||||
m_pFontStyle->retain(); // 现字体引用计数加一
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#include "easy2d.h"
|
||||
|
||||
Object::Object() :
|
||||
m_nRef(0)
|
||||
{
|
||||
FreePool::add(this); // 将该对象放入释放池中
|
||||
}
|
||||
|
||||
Object::~Object()
|
||||
{
|
||||
}
|
||||
|
||||
void Object::retain()
|
||||
{
|
||||
m_nRef++; // 引用计数加一
|
||||
}
|
||||
|
||||
void Object::release()
|
||||
{
|
||||
m_nRef--; // 引用计数减一
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
#include "easy2d.h"
|
||||
#include <assert.h>
|
||||
|
||||
Scene::Scene()
|
||||
{
|
||||
}
|
||||
|
||||
Scene::~Scene()
|
||||
{
|
||||
clearAllChildren();
|
||||
}
|
||||
|
||||
void Scene::_exec()
|
||||
{
|
||||
// active 标志画面是否取得焦点
|
||||
bool active = true;
|
||||
// 逆序执行,最后绘制的节点(即位于画面最上方)最先被访问
|
||||
for (int i = int(m_vChildren.size()) - 1; i >= 0; i--)
|
||||
{
|
||||
assert(m_vChildren[i]);
|
||||
if (m_vChildren[i]->_exec(active)) // 执行节点程序
|
||||
{
|
||||
active = false; // 若子节点取得焦点,将标志置 false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::_onDraw()
|
||||
{
|
||||
// 绘制所有节点
|
||||
for (auto child : m_vChildren)
|
||||
{
|
||||
assert(child);
|
||||
child->_onDraw();
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::add(Node * child, int zOrder)
|
||||
{
|
||||
// 断言添加的节点非空
|
||||
assert(child);
|
||||
// 设置节点的父场景
|
||||
child->setParentScene(this);
|
||||
// 设置 z 轴顺序
|
||||
child->setZOrder(zOrder);
|
||||
// 对象的引用计数加一
|
||||
child->retain();
|
||||
|
||||
// 按 z 轴顺序插入节点
|
||||
size_t size = m_vChildren.size();
|
||||
for (unsigned i = 0; i <= size; i++)
|
||||
{
|
||||
if (i == size)
|
||||
{
|
||||
m_vChildren.push_back(child);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto temp = m_vChildren.at(i);
|
||||
if (temp->getZOrder() > zOrder)
|
||||
{
|
||||
m_vChildren.insert(m_vChildren.begin() + i, child);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Scene::del(Node * child)
|
||||
{
|
||||
// 断言节点非空
|
||||
assert(child);
|
||||
|
||||
// 寻找是否有相同节点
|
||||
std::vector<Node*>::iterator iter;
|
||||
for (iter = m_vChildren.begin(); iter != m_vChildren.end(); iter++)
|
||||
{
|
||||
// 找到相同节点
|
||||
if (*iter == child)
|
||||
{
|
||||
// 对象的引用计数减一
|
||||
(*iter)->release();
|
||||
// 去掉该节点
|
||||
m_vChildren.erase(iter);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// 未找到该节点返回 false
|
||||
return false;
|
||||
}
|
||||
|
||||
void Scene::clearAllChildren()
|
||||
{
|
||||
// 所有节点的引用计数减一
|
||||
for (auto child : m_vChildren)
|
||||
{
|
||||
child->release();
|
||||
}
|
||||
// 清空储存节点的容器
|
||||
m_vChildren.clear();
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
#include "..\Easy2d.h"
|
||||
#include "..\EasyX\easyx.h"
|
||||
|
||||
// 常用颜色值的定义
|
||||
const COLORREF Color::black = BLACK;
|
||||
const COLORREF Color::blue = BLUE;
|
||||
const COLORREF Color::green = GREEN;
|
||||
const COLORREF Color::cyan = CYAN;
|
||||
const COLORREF Color::red = RED;
|
||||
const COLORREF Color::magenta = MAGENTA;
|
||||
const COLORREF Color::brown = BROWN;
|
||||
const COLORREF Color::lightgray = LIGHTGRAY;
|
||||
const COLORREF Color::darkgray = DARKGRAY;
|
||||
const COLORREF Color::lightblue = LIGHTBLUE;
|
||||
const COLORREF Color::lightgreen = LIGHTGREEN;
|
||||
const COLORREF Color::lightcyan = LIGHTCYAN;
|
||||
const COLORREF Color::lightred = LIGHTRED;
|
||||
const COLORREF Color::lightmagenta = LIGHTMAGENTA;
|
||||
const COLORREF Color::yellow = YELLOW;
|
||||
const COLORREF Color::white = WHITE;
|
||||
|
||||
|
||||
COLORREF Color::getFromRGB(BYTE r, BYTE g, BYTE b)
|
||||
{
|
||||
return RGB(r, g, b); // 从 (r, g, b) 三色值转化为颜色
|
||||
}
|
||||
|
||||
COLORREF Color::getFromHSL(float H, float S, float L)
|
||||
{
|
||||
return HSLtoRGB(H, S, L);
|
||||
}
|
||||
|
||||
COLORREF Color::getFromHSV(float H, float S, float V)
|
||||
{
|
||||
return HSVtoRGB(H, S, V);
|
||||
}
|
||||
|
||||
BYTE Color::getRValue(COLORREF color)
|
||||
{
|
||||
return GetRValue(color); // 返回颜色中的红色值
|
||||
}
|
||||
|
||||
BYTE Color::getGValue(COLORREF color)
|
||||
{
|
||||
return GetGValue(color); // 返回颜色中的绿色值
|
||||
}
|
||||
|
||||
BYTE Color::getBValue(COLORREF color)
|
||||
{
|
||||
return GetBValue(color); // 返回颜色中的蓝色值
|
||||
}
|
||||
|
||||
COLORREF Color::getGray(COLORREF color)
|
||||
{
|
||||
return RGBtoGRAY(color); // 获取颜色中的灰度值
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
/* FillStyle 是 EasyX 中的类,目前尚未考虑实现 */
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
#include "..\Easy2d.h"
|
||||
|
||||
// 常用字体粗细值的定义
|
||||
const LONG FontWeight::dontcare = 0;
|
||||
const LONG FontWeight::thin = 100;
|
||||
const LONG FontWeight::extraLight = 200;
|
||||
const LONG FontWeight::light = 300;
|
||||
const LONG FontWeight::normal = 400;
|
||||
const LONG FontWeight::regular = 400;
|
||||
const LONG FontWeight::medium = 500;
|
||||
const LONG FontWeight::demiBlod = 600;
|
||||
const LONG FontWeight::blod = 700;
|
||||
const LONG FontWeight::extraBold = 800;
|
||||
const LONG FontWeight::black = 900;
|
||||
const LONG FontWeight::heavy = 900;
|
||||
|
||||
// 默认字体
|
||||
static const FontStyle s_defaultFont(_T(""), 18, FontWeight::normal);
|
||||
|
||||
|
||||
FontStyle::FontStyle()
|
||||
{
|
||||
m_font = s_defaultFont.m_font;
|
||||
}
|
||||
|
||||
FontStyle::FontStyle(LPCTSTR fontfamily, LONG height, LONG weight, LONG width, bool italic, bool underline, bool strikeout, LONG escapement, LONG orientation, bool quality)
|
||||
{
|
||||
setFontFamily(fontfamily);
|
||||
m_font.lfWeight = weight;
|
||||
m_font.lfHeight = height;
|
||||
m_font.lfWidth = width;
|
||||
m_font.lfItalic = italic;
|
||||
m_font.lfUnderline = underline;
|
||||
m_font.lfStrikeOut = strikeout;
|
||||
m_font.lfEscapement = escapement;
|
||||
m_font.lfOrientation = orientation;
|
||||
setQuality(quality);
|
||||
}
|
||||
|
||||
FontStyle::~FontStyle()
|
||||
{
|
||||
}
|
||||
|
||||
FontStyle * FontStyle::getDefault()
|
||||
{
|
||||
return new FontStyle(s_defaultFont);
|
||||
}
|
||||
|
||||
void FontStyle::setHeight(LONG value)
|
||||
{
|
||||
m_font.lfHeight = value;
|
||||
}
|
||||
|
||||
void FontStyle::setWidth(LONG value)
|
||||
{
|
||||
m_font.lfWidth = value;
|
||||
}
|
||||
|
||||
void FontStyle::setFontFamily(LPCTSTR value)
|
||||
{
|
||||
_tcscpy_s(m_font.lfFaceName, 32, value);
|
||||
}
|
||||
|
||||
void FontStyle::setEscapement(LONG value)
|
||||
{
|
||||
m_font.lfEscapement = value;
|
||||
}
|
||||
|
||||
void FontStyle::setOrientation(LONG value)
|
||||
{
|
||||
m_font.lfOrientation = value;
|
||||
}
|
||||
|
||||
void FontStyle::setQuality(bool value)
|
||||
{
|
||||
m_font.lfQuality = value ? ANTIALIASED_QUALITY : DEFAULT_QUALITY;
|
||||
}
|
||||
|
||||
void FontStyle::setWeight(LONG value)
|
||||
{
|
||||
m_font.lfWeight = value;
|
||||
}
|
||||
|
||||
void FontStyle::setItalic(bool value)
|
||||
{
|
||||
m_font.lfItalic = value;
|
||||
}
|
||||
|
||||
void FontStyle::setUnderline(bool value)
|
||||
{
|
||||
m_font.lfUnderline = value;
|
||||
}
|
||||
|
||||
void FontStyle::setStrikeOut(bool value)
|
||||
{
|
||||
m_font.lfStrikeOut = value;
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
/* LineStyle 是 EasyX 中的类,目前尚未考虑实现 */
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
#include "..\Easy2d.h"
|
||||
#include "..\EasyX\easyx.h"
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
tstring FileUtils::getFileExtension(const tstring & filePath)
|
||||
{
|
||||
tstring fileExtension;
|
||||
// 找到文件名中的最后一个 '.' 的位置
|
||||
size_t pos = filePath.find_last_of('.');
|
||||
// 判断 pos 是否是个有效位置
|
||||
if (pos != tstring::npos)
|
||||
{
|
||||
// 截取扩展名
|
||||
fileExtension = filePath.substr(pos, filePath.length());
|
||||
// 转换为小写字母
|
||||
std::transform(fileExtension.begin(), fileExtension.end(), fileExtension.begin(), ::tolower);
|
||||
}
|
||||
|
||||
return fileExtension;
|
||||
}
|
||||
|
||||
bool FileUtils::getSaveFilePath(tstring& path, LPCTSTR title, LPCTSTR defExt)
|
||||
{
|
||||
// 弹出保存对话框
|
||||
OPENFILENAME ofn = { 0 };
|
||||
TCHAR strFilename[MAX_PATH] = { 0 }; // 用于接收文件名
|
||||
ofn.lStructSize = sizeof(OPENFILENAME); // 结构体大小
|
||||
ofn.hwndOwner = GetHWnd(); // 拥有着窗口句柄,NULL 表示对话框是非模态的
|
||||
ofn.lpstrFilter = _T("所有文件\0*.*\0\0"); // 设置过滤
|
||||
ofn.nFilterIndex = 1; // 过滤器索引
|
||||
ofn.lpstrFile = strFilename; // 接收返回的文件路径和文件名
|
||||
ofn.nMaxFile = sizeof(strFilename); // 缓冲区长度
|
||||
ofn.lpstrInitialDir = NULL; // 初始目录为默认
|
||||
ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;// 目录必须存在,覆盖文件前发出警告
|
||||
ofn.lpstrTitle = title; // 使用系统默认标题留空即可
|
||||
ofn.lpstrDefExt = defExt; // 默认追加的扩展名
|
||||
|
||||
if (GetSaveFileName(&ofn))
|
||||
{
|
||||
path = strFilename;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -0,0 +1,458 @@
|
|||
#include "..\Easy2d.h"
|
||||
|
||||
|
||||
/* 注:MusicUtils 类完全仿照 Cocos2dx 中的 SimpleAudioEngine 实现 */
|
||||
|
||||
#include <mmsystem.h>
|
||||
#pragma comment(lib , "winmm.lib")
|
||||
#include <map>
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// MciPlayer
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
class MciPlayer
|
||||
{
|
||||
public:
|
||||
MciPlayer();
|
||||
~MciPlayer();
|
||||
|
||||
void Close();
|
||||
void Open(tstring pFileName, UINT uId);
|
||||
void Play(UINT uTimes = 1);
|
||||
void Pause();
|
||||
void Resume();
|
||||
void Stop();
|
||||
void Rewind();
|
||||
bool IsPlaying();
|
||||
UINT GetSoundID();
|
||||
|
||||
private:
|
||||
friend LRESULT WINAPI _SoundPlayProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
void _SendGenericCommand(int nCommand, DWORD_PTR param1 = 0, DWORD_PTR parma2 = 0);
|
||||
|
||||
HWND _wnd;
|
||||
MCIDEVICEID _dev;
|
||||
UINT _soundID;
|
||||
UINT _times;
|
||||
bool _playing;
|
||||
tstring strExt;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define WIN_CLASS_NAME "Easy2dCallbackWnd"
|
||||
|
||||
static HINSTANCE s_hInstance;
|
||||
static MCIERROR s_mciError;
|
||||
|
||||
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()
|
||||
{
|
||||
Close();
|
||||
DestroyWindow(_wnd);
|
||||
}
|
||||
|
||||
void MciPlayer::Open(tstring pFileName, UINT uId)
|
||||
{
|
||||
if (pFileName.empty() || !_wnd) return;
|
||||
int nLen = (int)pFileName.size();
|
||||
if (!nLen) return;
|
||||
|
||||
strExt = FileUtils::getFileExtension(pFileName);
|
||||
|
||||
Close();
|
||||
|
||||
MCI_OPEN_PARMS mciOpen = { 0 };
|
||||
MCIERROR mciError;
|
||||
mciOpen.lpstrDeviceType = (LPCTSTR)MCI_ALL_DEVICE_ID;
|
||||
mciOpen.lpstrElementName = pFileName.c_str();
|
||||
|
||||
mciError = mciSendCommand(0, MCI_OPEN, MCI_OPEN_ELEMENT, reinterpret_cast<DWORD_PTR>(&mciOpen));
|
||||
if (mciError) return;
|
||||
|
||||
_dev = mciOpen.wDeviceID;
|
||||
_soundID = uId;
|
||||
_playing = false;
|
||||
}
|
||||
|
||||
void MciPlayer::Play(UINT uTimes /* = 1 */)
|
||||
{
|
||||
if (!_dev)
|
||||
{
|
||||
return;
|
||||
}
|
||||
MCI_PLAY_PARMS mciPlay = { 0 };
|
||||
mciPlay.dwCallback = reinterpret_cast<DWORD_PTR>(_wnd);
|
||||
s_mciError = mciSendCommand(_dev, MCI_PLAY, MCI_FROM | MCI_NOTIFY, reinterpret_cast<DWORD_PTR>(&mciPlay));
|
||||
if (!s_mciError)
|
||||
{
|
||||
_playing = true;
|
||||
_times = uTimes;
|
||||
}
|
||||
}
|
||||
|
||||
void MciPlayer::Close()
|
||||
{
|
||||
if (_playing)
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
if (_dev)
|
||||
{
|
||||
_SendGenericCommand(MCI_CLOSE);
|
||||
}
|
||||
_dev = 0;
|
||||
_playing = false;
|
||||
}
|
||||
|
||||
void MciPlayer::Pause()
|
||||
{
|
||||
_SendGenericCommand(MCI_PAUSE);
|
||||
_playing = false;
|
||||
}
|
||||
|
||||
void MciPlayer::Resume()
|
||||
{
|
||||
if (strExt == _T(".mid"))
|
||||
{
|
||||
// midi not support MCI_RESUME, should get the position and use MCI_FROM
|
||||
MCI_STATUS_PARMS mciStatusParms;
|
||||
MCI_PLAY_PARMS mciPlayParms;
|
||||
mciStatusParms.dwItem = MCI_STATUS_POSITION;
|
||||
_SendGenericCommand(MCI_STATUS, MCI_STATUS_ITEM, reinterpret_cast<DWORD_PTR>(&mciStatusParms)); // MCI_STATUS
|
||||
mciPlayParms.dwFrom = mciStatusParms.dwReturn; // get position
|
||||
_SendGenericCommand(MCI_PLAY, MCI_FROM, reinterpret_cast<DWORD_PTR>(&mciPlayParms)); // MCI_FROM
|
||||
}
|
||||
else
|
||||
{
|
||||
_SendGenericCommand(MCI_RESUME);
|
||||
_playing = true;
|
||||
}
|
||||
}
|
||||
|
||||
void MciPlayer::Stop()
|
||||
{
|
||||
_SendGenericCommand(MCI_STOP);
|
||||
_playing = false;
|
||||
_times = 0;
|
||||
}
|
||||
|
||||
void MciPlayer::Rewind()
|
||||
{
|
||||
if (!_dev)
|
||||
{
|
||||
return;
|
||||
}
|
||||
mciSendCommand(_dev, MCI_SEEK, MCI_SEEK_TO_START, 0);
|
||||
|
||||
MCI_PLAY_PARMS mciPlay = { 0 };
|
||||
mciPlay.dwCallback = reinterpret_cast<DWORD_PTR>(_wnd);
|
||||
_playing = mciSendCommand(_dev, MCI_PLAY, MCI_NOTIFY, reinterpret_cast<DWORD_PTR>(&mciPlay)) ? false : true;
|
||||
}
|
||||
|
||||
bool MciPlayer::IsPlaying()
|
||||
{
|
||||
return _playing;
|
||||
}
|
||||
|
||||
UINT MciPlayer::GetSoundID()
|
||||
{
|
||||
return _soundID;
|
||||
}
|
||||
|
||||
void MciPlayer::_SendGenericCommand(int nCommand, DWORD_PTR param1 /*= 0*/, DWORD_PTR parma2 /*= 0*/)
|
||||
{
|
||||
if (!_dev)
|
||||
{
|
||||
return;
|
||||
}
|
||||
mciSendCommand(_dev, nCommand, param1, parma2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// MusicUtils
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
typedef std::map<unsigned int, MciPlayer *> MusicList;
|
||||
typedef std::pair<unsigned int, MciPlayer *> Music;
|
||||
|
||||
|
||||
static unsigned int _Hash(tstring key);
|
||||
|
||||
|
||||
static MusicList& sharedList()
|
||||
{
|
||||
static MusicList s_List;
|
||||
return s_List;
|
||||
}
|
||||
|
||||
static MciPlayer& sharedMusic()
|
||||
{
|
||||
static MciPlayer s_Music;
|
||||
return s_Music;
|
||||
}
|
||||
|
||||
void MusicUtils::end()
|
||||
{
|
||||
sharedMusic().Close();
|
||||
|
||||
for (auto& iter : sharedList())
|
||||
{
|
||||
SAFE_DELETE(iter.second);
|
||||
}
|
||||
sharedList().clear();
|
||||
return;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// BackgroundMusic
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void MusicUtils::playBackgroundMusic(tstring pszFilePath, bool bLoop)
|
||||
{
|
||||
if (pszFilePath.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sharedMusic().Open(pszFilePath, ::_Hash(pszFilePath));
|
||||
sharedMusic().Play((bLoop) ? -1 : 1);
|
||||
}
|
||||
|
||||
void MusicUtils::stopBackgroundMusic(bool bReleaseData)
|
||||
{
|
||||
if (bReleaseData)
|
||||
{
|
||||
sharedMusic().Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
sharedMusic().Stop();
|
||||
}
|
||||
}
|
||||
|
||||
void MusicUtils::pauseBackgroundMusic()
|
||||
{
|
||||
sharedMusic().Pause();
|
||||
}
|
||||
|
||||
void MusicUtils::resumeBackgroundMusic()
|
||||
{
|
||||
sharedMusic().Resume();
|
||||
}
|
||||
|
||||
void MusicUtils::rewindBackgroundMusic()
|
||||
{
|
||||
sharedMusic().Rewind();
|
||||
}
|
||||
|
||||
bool MusicUtils::isBackgroundMusicPlaying()
|
||||
{
|
||||
return sharedMusic().IsPlaying();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// effect function
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
unsigned int MusicUtils::playMusic(tstring pszFilePath, bool bLoop)
|
||||
{
|
||||
unsigned int nRet = ::_Hash(pszFilePath);
|
||||
|
||||
preloadMusic(pszFilePath);
|
||||
|
||||
MusicList::iterator p = sharedList().find(nRet);
|
||||
if (p != sharedList().end())
|
||||
{
|
||||
p->second->Play((bLoop) ? -1 : 1);
|
||||
}
|
||||
return nRet;
|
||||
}
|
||||
|
||||
void MusicUtils::stopMusic(unsigned int nSoundId)
|
||||
{
|
||||
MusicList::iterator p = sharedList().find(nSoundId);
|
||||
if (p != sharedList().end())
|
||||
{
|
||||
p->second->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
void MusicUtils::preloadMusic(tstring pszFilePath)
|
||||
{
|
||||
if (pszFilePath.empty()) return;
|
||||
|
||||
int nRet = ::_Hash(pszFilePath);
|
||||
|
||||
if (sharedList().end() != sharedList().find(nRet)) return;
|
||||
|
||||
sharedList().insert(Music(nRet, new MciPlayer()));
|
||||
MciPlayer * pPlayer = sharedList()[nRet];
|
||||
pPlayer->Open(pszFilePath, nRet);
|
||||
|
||||
if (nRet == pPlayer->GetSoundID()) return;
|
||||
|
||||
delete pPlayer;
|
||||
sharedList().erase(nRet);
|
||||
nRet = 0;
|
||||
}
|
||||
|
||||
void MusicUtils::pauseMusic(unsigned int nSoundId)
|
||||
{
|
||||
MusicList::iterator p = sharedList().find(nSoundId);
|
||||
if (p != sharedList().end())
|
||||
{
|
||||
p->second->Pause();
|
||||
}
|
||||
}
|
||||
|
||||
void MusicUtils::pauseAllMusics()
|
||||
{
|
||||
for (auto& iter : sharedList())
|
||||
{
|
||||
iter.second->Pause();
|
||||
}
|
||||
}
|
||||
|
||||
void MusicUtils::resumeMusic(unsigned int nSoundId)
|
||||
{
|
||||
MusicList::iterator p = sharedList().find(nSoundId);
|
||||
if (p != sharedList().end())
|
||||
{
|
||||
p->second->Resume();
|
||||
}
|
||||
}
|
||||
|
||||
void MusicUtils::resumeAllMusics()
|
||||
{
|
||||
for (auto& iter : sharedList())
|
||||
{
|
||||
iter.second->Resume();
|
||||
}
|
||||
}
|
||||
|
||||
void MusicUtils::stopAllMusics()
|
||||
{
|
||||
for (auto& iter : sharedList())
|
||||
{
|
||||
iter.second->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
void MusicUtils::unloadMusic(LPCTSTR pszFilePath)
|
||||
{
|
||||
unsigned int nID = ::_Hash(pszFilePath);
|
||||
|
||||
MusicList::iterator p = sharedList().find(nID);
|
||||
if (p != sharedList().end())
|
||||
{
|
||||
SAFE_DELETE(p->second);
|
||||
sharedList().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 len = unsigned(key.size());
|
||||
unsigned int hash = 0;
|
||||
|
||||
for (unsigned i = 0; i < len; i++)
|
||||
{
|
||||
hash *= 16777619;
|
||||
hash ^= (unsigned int)(unsigned char)toupper(key[i]);
|
||||
}
|
||||
return (hash);
|
||||
}
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
#include "..\Easy2d.h"
|
||||
|
||||
// 储存所有定时器的容器
|
||||
static std::vector<Timer*> s_nTimers;
|
||||
|
||||
Timer::Timer(tstring name, UINT ms, const TIMER_CALLBACK & callback) :
|
||||
m_sName(name),
|
||||
m_bRunning(false),
|
||||
m_callback(callback)
|
||||
{
|
||||
setInterval(ms); // 设置定时器的时间间隔
|
||||
}
|
||||
|
||||
Timer::~Timer()
|
||||
{
|
||||
}
|
||||
|
||||
void Timer::start()
|
||||
{
|
||||
// 标志该定时器正在运行
|
||||
this->m_bRunning = true;
|
||||
// 记录当前时间
|
||||
QueryPerformanceCounter(&m_nLast);
|
||||
}
|
||||
|
||||
void Timer::stop()
|
||||
{
|
||||
this->m_bRunning = false; // 标志该定时器已停止
|
||||
}
|
||||
|
||||
bool Timer::isRunning()
|
||||
{
|
||||
return m_bRunning; // 获取该定时器的运行状态
|
||||
}
|
||||
|
||||
void Timer::setInterval(UINT ms)
|
||||
{
|
||||
// 设置定时器的时间间隔
|
||||
LARGE_INTEGER nFreq;
|
||||
QueryPerformanceFrequency(&nFreq);
|
||||
m_nAnimationInterval.QuadPart = (LONGLONG)(ms / 1000.0 * nFreq.QuadPart);
|
||||
// 保存时间间隔的时长
|
||||
this->m_nMilliSeconds = ms;
|
||||
}
|
||||
|
||||
void Timer::setCallback(const TIMER_CALLBACK & callback)
|
||||
{
|
||||
m_callback = callback; // 保存回调函数
|
||||
}
|
||||
|
||||
void Timer::setName(tstring name)
|
||||
{
|
||||
m_sName = name; // 修改定时器名称
|
||||
}
|
||||
|
||||
UINT Timer::getInterval() const
|
||||
{
|
||||
return m_nMilliSeconds; // 获取定时器的时间间隔
|
||||
}
|
||||
|
||||
tstring Timer::getName() const
|
||||
{
|
||||
return m_sName; // 获取定时器的名称
|
||||
}
|
||||
|
||||
void Timer::__exec()
|
||||
{
|
||||
// 定时器容器为空
|
||||
if (!s_nTimers.size())
|
||||
{
|
||||
return;
|
||||
}
|
||||
// 获取当前时间
|
||||
static LARGE_INTEGER nNow;
|
||||
QueryPerformanceCounter(&nNow);
|
||||
// 循环遍历所有的定时器
|
||||
for (auto timer : s_nTimers)
|
||||
{
|
||||
// 若定时器未运行,跳过这个定时器
|
||||
if (!timer->m_bRunning)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// 判断时间间隔是否足够
|
||||
if (nNow.QuadPart - timer->m_nLast.QuadPart > timer->m_nAnimationInterval.QuadPart)
|
||||
{
|
||||
// 用求余的方法重新记录时间
|
||||
timer->m_nLast.QuadPart = nNow.QuadPart - (nNow.QuadPart % timer->m_nAnimationInterval.QuadPart);
|
||||
// 运行回调函数
|
||||
timer->m_callback();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Timer::addTimer(Timer * timer)
|
||||
{
|
||||
// 启动定时器
|
||||
timer->start();
|
||||
// 将该定时器放入容器
|
||||
s_nTimers.push_back(timer);
|
||||
}
|
||||
|
||||
void Timer::addTimer(tstring name, UINT ms, const TIMER_CALLBACK & callback)
|
||||
{
|
||||
// 创建定时器
|
||||
auto timer = new Timer(name, ms, callback);
|
||||
// 添加定时器
|
||||
addTimer(timer);
|
||||
}
|
||||
|
||||
Timer * Timer::getTimer(tstring name)
|
||||
{
|
||||
// 查找是否有相同名称的定时器
|
||||
for (auto timer : s_nTimers)
|
||||
{
|
||||
if (timer->m_sName == name)
|
||||
{
|
||||
// 若找到,返回该定时器的指针
|
||||
return timer;
|
||||
}
|
||||
}
|
||||
// 若未找到,返回空指针
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool Timer::startTimer(tstring name)
|
||||
{
|
||||
// 启动指定名称的定时器,先找到该定时器
|
||||
auto t = getTimer(name);
|
||||
if (t)
|
||||
{
|
||||
// 启动定时器
|
||||
t->start();
|
||||
return true;
|
||||
}
|
||||
// 若未找到同样名称的定时器,返回 false
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Timer::stopTimer(tstring name)
|
||||
{
|
||||
// 停止指定名称的定时器,先找到该定时器
|
||||
auto t = getTimer(name);
|
||||
if (t)
|
||||
{
|
||||
// 停止定时器
|
||||
t->stop();
|
||||
return true;
|
||||
}
|
||||
// 若未找到同样名称的定时器,返回 false
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Timer::deleteTimer(tstring name)
|
||||
{
|
||||
// 创建迭代器
|
||||
std::vector<Timer*>::iterator iter;
|
||||
// 循环遍历所有定时器
|
||||
for (iter = s_nTimers.begin(); iter != s_nTimers.end(); iter++)
|
||||
{
|
||||
// 查找相同名称的定时器
|
||||
if ((*iter)->m_sName == name)
|
||||
{
|
||||
// 删除该定时器
|
||||
delete (*iter);
|
||||
s_nTimers.erase(iter);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// 若未找到同样名称的定时器,返回 false
|
||||
return false;
|
||||
}
|
||||
|
||||
void Timer::clearAllTimers()
|
||||
{
|
||||
// 删除所有定时器
|
||||
for (auto t : s_nTimers)
|
||||
{
|
||||
delete t;
|
||||
}
|
||||
// 清空容器
|
||||
s_nTimers.clear();
|
||||
}
|
||||
|
|
@ -0,0 +1,946 @@
|
|||
/******************************************************
|
||||
* Easy2D Game Engine (v1.0.0)
|
||||
* http://www.easy2d.cn
|
||||
*
|
||||
* Depends on EasyX (Ver:20170827(beta))
|
||||
******************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error Easy2D is only for C++
|
||||
#endif
|
||||
|
||||
|
||||
// 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(); }
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
#include <atlimage.h>
|
||||
#include <vector>
|
||||
#include <stack>
|
||||
#include <functional>
|
||||
|
||||
|
||||
#if defined(UNICODE) && (_DEBUG)
|
||||
#pragma comment(lib,"Easy2Ddw.lib")
|
||||
#elif !defined(UNICODE) && (_DEBUG)
|
||||
#pragma comment(lib,"Easy2Dd.lib")
|
||||
#elif defined(UNICODE)
|
||||
#pragma comment(lib,"Easy2Dw.lib")
|
||||
#elif !defined(UNICODE)
|
||||
#pragma comment(lib,"Easy2D.lib")
|
||||
#endif
|
||||
|
||||
|
||||
// Class Declare
|
||||
|
||||
namespace easy2d {
|
||||
|
||||
// 基础类
|
||||
class Application;
|
||||
class Scene;
|
||||
class KeyMsg;
|
||||
class MouseMsg;
|
||||
class FreePool;
|
||||
// 样式类
|
||||
class Color;
|
||||
class FontStyle;
|
||||
// 工具类
|
||||
class Timer;
|
||||
class MusicUtils;
|
||||
class FileUtils;
|
||||
// 对象
|
||||
class Object;
|
||||
class Node;
|
||||
class BatchNode;
|
||||
class MouseNode;
|
||||
class Image;
|
||||
class Text;
|
||||
class Shape;
|
||||
class Rect;
|
||||
class Circle;
|
||||
class Button;
|
||||
class TextButton;
|
||||
class ImageButton;
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
||||
class Application
|
||||
{
|
||||
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_bPause;
|
||||
bool m_bSaveScene;
|
||||
|
||||
protected:
|
||||
void _initGraph();
|
||||
void _mainLoop();
|
||||
void _enterNextScene();
|
||||
|
||||
public:
|
||||
Application();
|
||||
~Application();
|
||||
|
||||
// 窗口可选模式
|
||||
enum { SHOW_CONSOLE = 1, NO_CLOSE = 2, NO_MINI_MIZE = 4 };
|
||||
// 获取程序实例
|
||||
static Application * get();
|
||||
// 设置坐标原点
|
||||
static void setOrigin(int originX, int originY);
|
||||
// 获取坐标原点的物理横坐标
|
||||
static int getOriginX();
|
||||
// 获取坐标原点的物理纵坐标
|
||||
static int getOriginY();
|
||||
// 启动程序
|
||||
int run();
|
||||
// 暂停程序
|
||||
void pause();
|
||||
// 终止程序
|
||||
void quit();
|
||||
// 终止程序
|
||||
void end();
|
||||
// 定义绘图窗口
|
||||
void createWindow(int width, int height, int mode = 0);
|
||||
// 定义绘图窗口
|
||||
void createWindow(tstring title, int width, int height, int mode = 0);
|
||||
// 修改窗口大小
|
||||
void setWindowSize(int width, int height);
|
||||
// 设置窗口标题
|
||||
void setWindowText(tstring title);
|
||||
// 关闭窗口
|
||||
void close();
|
||||
// 获取窗口宽度
|
||||
int getWidth() const;
|
||||
// 获取窗口高度
|
||||
int getHeight() const;
|
||||
// 切换场景
|
||||
void enterScene(Scene *scene, bool save = true);
|
||||
// 返回上一场景
|
||||
void backScene();
|
||||
// 游戏是否正在运行
|
||||
bool isRunning();
|
||||
// 设置帧率
|
||||
void setFPS(DWORD fps);
|
||||
// 重置绘图样式为默认值
|
||||
void reset();
|
||||
// 释放所有内存资源
|
||||
void free();
|
||||
// 销毁该对象
|
||||
void destory();
|
||||
// 获取当前场景
|
||||
Scene * getCurrentScene();
|
||||
// 获取 Easy2D 版本号
|
||||
LPCTSTR getVersion();
|
||||
};
|
||||
|
||||
class FreePool
|
||||
{
|
||||
friend class Application;
|
||||
|
||||
private:
|
||||
static void __flush();
|
||||
|
||||
public:
|
||||
// 将一个节点放入释放池
|
||||
static void add(Object * nptr);
|
||||
};
|
||||
|
||||
class Scene
|
||||
{
|
||||
friend class Application;
|
||||
friend class MouseMsg;
|
||||
|
||||
protected:
|
||||
std::vector<Node*> m_vChildren;
|
||||
|
||||
protected:
|
||||
void _exec();
|
||||
void _onDraw();
|
||||
|
||||
public:
|
||||
Scene();
|
||||
~Scene();
|
||||
|
||||
// 添加子成员到场景
|
||||
void add(Node * child, int zOrder = 0);
|
||||
// 删除子成员
|
||||
bool del(Node * child);
|
||||
// 清空所有子成员
|
||||
void clearAllChildren();
|
||||
};
|
||||
|
||||
|
||||
class MouseMsg
|
||||
{
|
||||
friend class Application;
|
||||
|
||||
private:
|
||||
static void __exec();
|
||||
|
||||
public:
|
||||
UINT uMsg; // 当前鼠标消息
|
||||
bool mkLButton; // 鼠标左键是否按下
|
||||
bool mkMButton; // 鼠标中键是否按下
|
||||
bool mkRButton; // 鼠标右键是否按下
|
||||
short x; // 当前鼠标 x 坐标
|
||||
short y; // 当前鼠标 y 坐标
|
||||
short wheel; // 鼠标滚轮滚动值 (120 的倍数)
|
||||
|
||||
public:
|
||||
// 获取当前鼠标消息
|
||||
static MouseMsg getMsg();
|
||||
// 左键是否按下
|
||||
static bool getLButtonDown();
|
||||
// 右键是否按下
|
||||
static bool getRButtonDown();
|
||||
// 中键是否按下
|
||||
static bool getMButtonDown();
|
||||
// 获取鼠标X坐标
|
||||
static int getMouseX();
|
||||
// 获取鼠标Y坐标
|
||||
static int getMouseY();
|
||||
// 获取鼠标滚轮值
|
||||
static int getMouseWheel();
|
||||
// 鼠标移动消息
|
||||
static bool getMouseMovedMsg();
|
||||
// 左键双击消息
|
||||
static bool getLButtonDBClickedMsg();
|
||||
// 右键按下消息
|
||||
static bool getLButtonDownMsg();
|
||||
// 左键弹起消息
|
||||
static bool getLButtonUpMsg();
|
||||
// 右键双击消息
|
||||
static bool getRButtonDBClicked();
|
||||
// 右键按下消息
|
||||
static bool getRButtonDownMsg();
|
||||
// 右键弹起消息
|
||||
static bool getRButtonUpMsg();
|
||||
// 中键双击消息
|
||||
static bool getMButtonDBClicked();
|
||||
// 中键按下消息
|
||||
static bool getMButtonDownMsg();
|
||||
// 中键弹起消息
|
||||
static bool getMButtonUpMsg();
|
||||
// 鼠标滚轮拨动消息
|
||||
static bool getWheelMsg();
|
||||
// 清空鼠标消息
|
||||
static void resetMouseMsg();
|
||||
};
|
||||
|
||||
|
||||
class KeyMsg
|
||||
{
|
||||
friend class Application;
|
||||
|
||||
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, Decimal;
|
||||
// 控制键值
|
||||
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;
|
||||
|
||||
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 clearAllListener();
|
||||
// 判断键是否被按下,按下返回true
|
||||
static bool isKeyDown(VK_KEY key);
|
||||
};
|
||||
|
||||
|
||||
class FileUtils
|
||||
{
|
||||
public:
|
||||
// 得到文件扩展名(小写)
|
||||
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 = false);
|
||||
// 停止背景音乐
|
||||
static void stopBackgroundMusic(bool bReleaseData = false);
|
||||
// 暂停背景音乐
|
||||
static void pauseBackgroundMusic();
|
||||
// 继续播放背景音乐
|
||||
static void resumeBackgroundMusic();
|
||||
// 从头播放背景音乐
|
||||
static void rewindBackgroundMusic();
|
||||
// 背景音乐是否正在播放
|
||||
static bool isBackgroundMusicPlaying();
|
||||
|
||||
// 播放音效
|
||||
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);
|
||||
|
||||
// 暂停所有音乐
|
||||
static void pauseAllMusics();
|
||||
// 继续播放所有音乐
|
||||
static void resumeAllMusics();
|
||||
// 停止所有音乐
|
||||
static void stopAllMusics();
|
||||
// 停止所有音乐,并释放内存
|
||||
static void end();
|
||||
};
|
||||
|
||||
|
||||
class Timer
|
||||
{
|
||||
friend class Application;
|
||||
|
||||
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:
|
||||
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 deleteTimer(tstring name);
|
||||
// 删除所有定时器
|
||||
static void clearAllTimers();
|
||||
};
|
||||
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
class Object
|
||||
{
|
||||
friend class FreePool;
|
||||
|
||||
protected:
|
||||
int m_nRef;
|
||||
|
||||
public:
|
||||
Object();
|
||||
virtual ~Object();
|
||||
|
||||
void retain();
|
||||
void release();
|
||||
};
|
||||
|
||||
|
||||
class FontStyle :
|
||||
public virtual Object
|
||||
{
|
||||
friend class Text;
|
||||
|
||||
protected:
|
||||
LOGFONT m_font;
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
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 Node :
|
||||
public virtual Object
|
||||
{
|
||||
friend class Scene;
|
||||
friend class Layer;
|
||||
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:
|
||||
Node();
|
||||
Node(int x, int y);
|
||||
virtual ~Node();
|
||||
|
||||
// 获取节点横坐标
|
||||
const int getX() const;
|
||||
// 获取节点纵坐标
|
||||
const int getY() const;
|
||||
// 设置节点横坐标
|
||||
virtual void setX(int x);
|
||||
// 设置节点纵坐标
|
||||
virtual void setY(int y);
|
||||
// 设置节点横纵坐标
|
||||
virtual void setPos(int x, int y);
|
||||
// 移动节点
|
||||
virtual void move(int x, int y);
|
||||
// 节点是否显示
|
||||
bool display() const;
|
||||
// 设置节点是否显示
|
||||
void setDisplay(bool value);
|
||||
// 获取节点绘图顺序
|
||||
virtual int getZOrder() const;
|
||||
// 设置节点绘图顺序(0为最先绘制,显示在最底层)
|
||||
virtual void setZOrder(int z);
|
||||
// 获取节点所在场景
|
||||
Scene * getParentScene();
|
||||
};
|
||||
|
||||
|
||||
class BatchNode :
|
||||
public virtual Node
|
||||
{
|
||||
protected:
|
||||
std::vector<Node*> m_vChildren;
|
||||
|
||||
protected:
|
||||
virtual bool _exec(bool active) override;
|
||||
virtual void _onDraw() override;
|
||||
|
||||
public:
|
||||
BatchNode();
|
||||
virtual ~BatchNode();
|
||||
|
||||
// 添加子节点
|
||||
void add(Node *child, int z_Order = 0);
|
||||
// 删除子节点
|
||||
bool del(Node * child);
|
||||
// 清空所有子节点
|
||||
void clearAllChildren();
|
||||
};
|
||||
|
||||
|
||||
class Image :
|
||||
public virtual Node
|
||||
{
|
||||
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:
|
||||
Image();
|
||||
/**
|
||||
* 从图片文件获取图像(png/bmp/jpg/gif/emf/wmf/ico)
|
||||
* 参数:图片文件名,图片裁剪坐标,图片裁剪宽度和高度
|
||||
*/
|
||||
Image(LPCTSTR ImageFile, int x = 0, int y = 0, int width = 0, int height = 0);
|
||||
virtual ~Image();
|
||||
|
||||
// 获取图像宽度
|
||||
int getWidth() const;
|
||||
// 获取图像高度
|
||||
int getHeight() const;
|
||||
// 获取横向拉伸比例
|
||||
float getScaleX() const;
|
||||
// 获取纵向拉伸比例
|
||||
float getScaleY() const;
|
||||
|
||||
/**
|
||||
* 从图片文件获取图像(png/bmp/jpg/gif/emf/wmf/ico)
|
||||
* 参数:图片文件名,图片裁剪坐标,图片裁剪宽度和高度
|
||||
*/
|
||||
void 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);
|
||||
// 裁剪图片(裁剪后会恢复 stretch 拉伸)
|
||||
void crop(int x = 0, int y = 0, int width = 0, int height = 0);
|
||||
// 将图片拉伸到固定宽高
|
||||
void stretch(int width = 0, int height = 0);
|
||||
// 按比例拉伸图片(0 ~ 1.0f)
|
||||
void scale(float scaleX, float scaleY);
|
||||
// 设置图片位置
|
||||
void setPos(int x, int y) override;
|
||||
// 移动图片
|
||||
void move(int x, int y) override;
|
||||
// 设置图片横坐标
|
||||
void setX(int x) override;
|
||||
// 设置图片纵坐标
|
||||
void setY(int y) override;
|
||||
// 设置透明色
|
||||
void setTransparentColor(COLORREF value);
|
||||
// 保存到截图
|
||||
static void screenshot();
|
||||
};
|
||||
|
||||
|
||||
class Text :
|
||||
public virtual Node
|
||||
{
|
||||
friend class TextButton;
|
||||
|
||||
protected:
|
||||
tstring m_sText;
|
||||
COLORREF m_color;
|
||||
FontStyle * m_pFontStyle;
|
||||
|
||||
protected:
|
||||
virtual void _onDraw() override;
|
||||
|
||||
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();
|
||||
// 获取文字宽度
|
||||
int getWidth();
|
||||
// 获取文字高度
|
||||
int getHeight();
|
||||
// 文本是否为空
|
||||
bool isEmpty() const;
|
||||
|
||||
// 设置文字
|
||||
void setText(tstring text);
|
||||
// 设置文字颜色
|
||||
void setColor(COLORREF color);
|
||||
// 设置字体
|
||||
void setFontStyle(FontStyle * style);
|
||||
};
|
||||
|
||||
|
||||
class MouseNode :
|
||||
public virtual Node
|
||||
{
|
||||
private:
|
||||
bool m_bTarget;
|
||||
bool m_bBlock;
|
||||
enum { NORMAL, MOUSEIN, SELECTED } m_eStatus;
|
||||
CLICK_CALLBACK m_callback;
|
||||
|
||||
protected:
|
||||
virtual bool _exec(bool active) override;
|
||||
virtual void _onDraw() override;
|
||||
|
||||
void _setNormal();
|
||||
void _setMouseIn();
|
||||
void _setSelected();
|
||||
|
||||
// 重写该函数,实现鼠标位置的判定
|
||||
virtual void _judge() = 0;
|
||||
// 正常状态
|
||||
virtual void _onNormal() = 0;
|
||||
// 鼠标移入时
|
||||
virtual void _onMouseIn() = 0;
|
||||
// 鼠标选中时
|
||||
virtual void _onSelected() = 0;
|
||||
|
||||
public:
|
||||
MouseNode();
|
||||
virtual ~MouseNode();
|
||||
|
||||
// 鼠标点击时
|
||||
virtual void onClicked();
|
||||
// 鼠标是否移入
|
||||
virtual bool isMouseIn();
|
||||
// 鼠标是否选中
|
||||
virtual bool isSelected();
|
||||
// 设置回调函数
|
||||
virtual void setOnMouseClicked(const CLICK_CALLBACK & callback);
|
||||
// 重置状态
|
||||
virtual void reset();
|
||||
// 设置节点是否阻塞鼠标消息
|
||||
void setBlock(bool block);
|
||||
};
|
||||
|
||||
|
||||
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;
|
||||
virtual void _onSelected() = 0;
|
||||
virtual void _onDisable() = 0;
|
||||
|
||||
public:
|
||||
Button();
|
||||
virtual ~Button();
|
||||
|
||||
// 按钮是否启用
|
||||
virtual bool isEnable();
|
||||
// 设置是否启用
|
||||
virtual void setEnable(bool enable);
|
||||
};
|
||||
|
||||
|
||||
|
||||
class TextButton :
|
||||
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:
|
||||
TextButton();
|
||||
TextButton(Text * text);
|
||||
virtual ~TextButton();
|
||||
|
||||
// 设置按钮文字
|
||||
void setNormalText(Text * text);
|
||||
// 设置鼠标移入时的按钮文字
|
||||
void setMouseInText(Text * text);
|
||||
// 设置鼠标选中时的按钮文字
|
||||
void setSelectedText(Text * text);
|
||||
// 设置按钮禁用时的按钮文字
|
||||
void setUnableText(Text * text);
|
||||
|
||||
// 设置按钮横坐标
|
||||
virtual void setX(int x) override;
|
||||
// 设置按钮纵坐标
|
||||
virtual void setY(int y) override;
|
||||
// 设置按钮横纵坐标
|
||||
virtual void setPos(int x, int y) override;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class ImageButton :
|
||||
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:
|
||||
ImageButton();
|
||||
ImageButton(Image * image);
|
||||
virtual ~ImageButton();
|
||||
|
||||
// 设置按钮图片
|
||||
void setNormalImage(Image * image);
|
||||
// 设置鼠标移入时的按钮图片
|
||||
void setMouseInImage(Image * image);
|
||||
// 设置鼠标选中时的按钮图片
|
||||
void setSelectedImage(Image * image);
|
||||
// 设置按钮禁用时的按钮图片
|
||||
void setUnableImage(Image * image);
|
||||
|
||||
// 设置按钮横坐标
|
||||
virtual void setX(int x) override;
|
||||
// 设置按钮纵坐标
|
||||
virtual void setY(int y) override;
|
||||
// 设置按钮横纵坐标
|
||||
virtual void setPos(int x, int y) override;
|
||||
};
|
||||
|
||||
|
||||
class Shape :
|
||||
public virtual Node
|
||||
{
|
||||
protected:
|
||||
enum STYLE { round, solid, fill }; // 形状填充样式
|
||||
STYLE _style;
|
||||
COLORREF fillColor = 0;
|
||||
COLORREF lineColor = 0;
|
||||
|
||||
protected:
|
||||
virtual void _onDraw() override;
|
||||
virtual void solidShape() = 0;
|
||||
virtual void fillShape() = 0;
|
||||
virtual void roundShape() = 0;
|
||||
|
||||
public:
|
||||
Shape();
|
||||
virtual ~Shape();
|
||||
|
||||
// 获取形状的填充颜色
|
||||
COLORREF getFillColor() const;
|
||||
// 获取形状的线条颜色
|
||||
COLORREF getLineColor() const;
|
||||
// 设置填充颜色
|
||||
void setFillColor(COLORREF color);
|
||||
// 设置线条颜色
|
||||
void setLineColor(COLORREF color);
|
||||
};
|
||||
|
||||
|
||||
class Rect :
|
||||
public virtual Shape
|
||||
{
|
||||
protected:
|
||||
int m_nWidth;
|
||||
int m_nHeight;
|
||||
|
||||
protected:
|
||||
virtual void solidShape() override;
|
||||
virtual void fillShape() override;
|
||||
virtual void roundShape() override;
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
|
||||
class Circle :
|
||||
public virtual Shape
|
||||
{
|
||||
protected:
|
||||
int m_nRadius;
|
||||
|
||||
protected:
|
||||
virtual void solidShape() override;
|
||||
virtual void fillShape() override;
|
||||
virtual void roundShape() override;
|
||||
|
||||
public:
|
||||
Circle();
|
||||
Circle(int x, int y, int radius);
|
||||
virtual ~Circle();
|
||||
|
||||
// 获取圆形半径
|
||||
int getRadius() const;
|
||||
// 设置圆形半径
|
||||
void setRadius(int m_nRadius);
|
||||
};
|
||||
|
||||
} // End of easy2d namespace
|
||||
|
||||
|
||||
// 默认使用 easy2d 命名空间
|
||||
using namespace easy2d;
|
||||
Loading…
Reference in New Issue