首先要下载SexyAppFramework先到其
老家注册一用户名并下载到SexyAppFramework引擎.解压到本地目录,注意从1.3版本开始不支持VC6的编译了.当然如果非要在VC6的环境下开发也是可以的,不过要修改较多的设置和某些语法.1.3版本推荐VS2005当然VC++8已经集成了最新的PlatformSDK,我们现在还需要 DirectX SDK,理论上Engine最低支持DirectX7.0但是我们还是最好去Microsoft下载最新的DirectX SDK.我的是aug2007版本.当然在IDE中设置好各个include path和Lib path就不废话了.下面定位到osframework/source/SexyAppFramework目录下打开你喜欢的工程,我这里选择的是 SexyAppBase VS2005.vcproj在编译之前先找到EditWidget.cpp文件定位到266行(unsigned int)(L'?))由于代码页的原因导致'被"吃掉"所以编译会失败.在?后加上'.慢着,还不能编译,为了您今后更好的使用该引擎请打开 Project Options,由于我们现在准备编译Debug和Release库各一个,所以先选择Debug,在C/C++编译->优化->全程序优化,我们选择否.然后在Release中选择/GL(链接时优化).这样我们就不必在Debug模式下调试程序时每次Link都要进行漫长的等待了. ok,编译吧.在编译期间简单介绍下该引擎的1.3版本.首先是支持了Vista系统,其实就是在读写注册表和写一些log时对vista做了一些特殊处理使之能正常工作.该引擎图像渲染使用DirectX的Graphics,声音音效使用Bass.dll.最低支持DirectX6,所以可以运行在一些较老的机器上.该引擎把DirectX中的Surface概念包装成了Widget,可以说一个游戏就是若干个Widget组成.每个Widget由自己的渲染过程来绘制各自的实现.系统统一管理各个Widget来协调运作.这个是大概的介绍.以后会再详细说明.现在Debug的lib编译好了.建议命名为SexyAppFrameworkD.lib然后再编译Release版本.该引擎提供了一些辅助工具来方便你进行工作,如字体生成工具 FontBuilder,资源打包工具PopPak,资源管理代码生成工具ResourceGen等等.好了大概介绍完毕我们开始第一个Hello World之旅吧.
新建一Win32工程并选择产生空工程类型.先新建一个头文件MyWidget.h,然后看代码说话:
程序代码
接着MyWidget.cpp
程序代码
#include "GameApp.h"
#include "MyWidget.h"
#include <Graphics.h>
#include <Color.h>
#include <HyperlinkWidget.h>
#include <WidgetManager.h>
using namespace Sexy;
MyWidget::MyWidget(GameApp *theApp)
{
//保存指针
anApp=theApp;
//设置Widget的大小(也就是重绘的区域)
Resize(0,0,anApp->mWidth,anApp->mHeight);
}
MyWidget::~MyWidget()
{
//删除控件
if(mLink)
delete mLink;
}
void MyWidget::AddedToManager(Sexy::WidgetManager *theWidgetManager)
{
Widget::AddedToManager(theWidgetManager);
//Override时我们乘势加入我们Widget的组件
mLink=new HyperlinkWidget(1,this);//资源ID为1
mLink->Resize(anApp->mWidth / 2-80,anApp->mHeight / 2-10,150,20);//设置大小和显示位置
mLink->mLabel=_S("Hello World");//显示内容
mLink->mColor=Color(80,160,58);//颜色1
mLink->mOverColor=Color(0,255,0);//颜色2
theWidgetManager->AddWidget(mLink);//加入
}
void MyWidget::RemovedFromManager(Sexy::WidgetManager *theWidgetManager)
{
Widget::RemovedFromManager(theWidgetManager);
theWidgetManager->RemoveWidget(mLink);//踢掉
}
void MyWidget::Update()
{
Widget::Update();
MarkDirty();//计算脏区,这样可以大大加快重绘速度
}
void MyWidget::Draw(Sexy::Graphics *g)
{
//g就是锁定的surface,哦这是Sexy引擎应该叫做锁定的Widget显示表面,对g进行操作就可以在Widget上进行各种数据操作.如画图写字等.
g->SetColor(Color::Black);//先设置颜色为黑
g->FillRect(0,0,mWidth,mHeight);//全部填充颜色为黑
g->SetFont(mLink->mFont);//我们使用mLink的字体偷一下懒(因为mLink不载入字体时会有默认字体但g不会.载入资源以后详细说明)
g->SetColor(Color::White);//我们使用白色
//写出
g->DrawString(_S("Click hyperlink open my blog:/" http://www.RainCoding.com/blog/""),55,300);
}
void MyWidget::ButtonDepress(int theId)
{
//如果单击的是HyperLink就打开链接
if(1==theId)
{
ShellExecute(0,"open"," http://www.raincoding.com/blog",NULL,NULL,SW_NORMAL);
}
}
然后GameApp.h
程序代码
#include <SexyAppBase.h>
namespace Sexy
{
class MyWidget;
class GameApp:public SexyAppBase
{
private:
//声明我们要使用的Widget
MyWidget* mywidget;
public:
GameApp();
virtual ~GameApp();
//初始化,需要在main.c中显示调用(在载入进度时必须先初始化的资源.比如载入进度条图片等放在这里初始化)
virtual void Init();
//Init()完成后自动调用(这里一般就是Widget的初始化和做载入进度条的地方)
virtual void LoadingThreadProc();
//LodingThreadProc()完成后自动调用
virtual void LoadingThreadCompleted();
};
}
然后GameApp.cpp
程序代码
#include "GameApp.h"
#include "MyWidget.h"
#include "WidgetManager.h"
using namespace Sexy;
GameApp::GameApp()
{
mWidth=480;//主窗口宽
mHeight=320;//高
mTitle=_S("MyFirstSexy");//标题,所有的Sexy用到的字符串需要_S()宏或者SexyStringToXXX等系列函数
mywidget=NULL;
}
GameApp::~GameApp()
{
//删除管理
mWidgetManager->RemoveWidget(mywidget);
//释放Widget
delete mywidget;
mywidget=NULL;
}
void GameApp::Init()
{
SexyAppBase::Init();
//没事可做
}
void GameApp::LoadingThreadProc()
{
//创建我们的Widget
mywidget=new MyWidget(this);
}
void GameApp::LoadingThreadCompleted()
{
SexyAppBase::LoadingThreadCompleted();
//加入资源管理
mWidgetManager->AddWidget(mywidget);
}
最后入口main.cpp
程序代码
#include "GameApp.h"
using namespace Sexy;
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
//几乎所有的Sexy都是这样
GameApp* app=new GameApp;
//Init
app->Init();
//开始循环,返回也就意味着游戏退出.
app->Start();
delete app;
return 0;
}
编译之前注意几点,以上源码是设置了SexyAppFramework的include head file path和lib path,否则请include 相对路径或绝对路径.编译时请加入Lib(其他工程如有加入可排除重复)SexyAppFramework.lib //Debug请加入对应的版本
winmm.lib
wsock32.lib
gdi32.lib
advapi32.lib
shell32.lib
代码生成请选择调式或非调试静态多线程(MT/MTd)而不要选择动态多线程Dll,否则会link error重复的定义错误.
ok,有问题或意见可以留言.下回见.
本章源码
=============================================
补充一下,引擎提供的hyperlink,button,edit等等UI都是Widget,不过是帮你实现好的Widget,言下之意就是实现了Draw(Graphics* g)的函数实现,所以可以直接AddedToManager就可显示等操作.
运行截图:
新建一Win32工程并选择产生空工程类型.先新建一个头文件MyWidget.h,然后看代码说话:

#include <Widget.h>
#include <ButtonListener.h>
namespace Sexy
{
class Graphics;
class WidgetManager;
class HyperlinkWidget;
class MyWidget:public Widget,public ButtonListener
{
private:
//一个HyperLink widget,是引擎给我们封装好的一个widget,可以直接使用
HyperlinkWidget *mLink;
//引用主GameApp
GameApp *anApp;
public:
//创建,根据引进的GameApp就可以在Widget的各个地方使用GameApp的资源.
MyWidget(GameApp *theApp);
virtual ~MyWidget();
// 当GameApp->mWidgetManager->AddWidget()时会检查载入的Widget是否有override该 AddedToManager,有则调用.参数theWidgetManager就是引用的Game->mWidgetManager
virtual void AddedToManager(WidgetManager *theWidgetManager);
//同上,发生在GameApp->mWidgetManager->RemoveWidget()时调用.这就起到了GameApp中的mWidgetManager能够统一管理所有Widget的目的.
virtual void RemovedFromManager(WidgetManager *theWidgetManager);
//根据指定的FPS间隔调用,一般放逻辑运算,状态变化处理等.
virtual void Update();
//根据显卡的运行速度全速调用,一般是根据Update()处理后的数据进行数据图像的更新重绘等处理
virtual void Draw(Graphics* g);
//Widget被鼠标点击时调用,参数为点击Owner的ID号.
virtual void ButtonDepress(int theId);
};
}
#include <ButtonListener.h>
namespace Sexy
{
class Graphics;
class WidgetManager;
class HyperlinkWidget;
class MyWidget:public Widget,public ButtonListener
{
private:
//一个HyperLink widget,是引擎给我们封装好的一个widget,可以直接使用
HyperlinkWidget *mLink;
//引用主GameApp
GameApp *anApp;
public:
//创建,根据引进的GameApp就可以在Widget的各个地方使用GameApp的资源.
MyWidget(GameApp *theApp);
virtual ~MyWidget();
// 当GameApp->mWidgetManager->AddWidget()时会检查载入的Widget是否有override该 AddedToManager,有则调用.参数theWidgetManager就是引用的Game->mWidgetManager
virtual void AddedToManager(WidgetManager *theWidgetManager);
//同上,发生在GameApp->mWidgetManager->RemoveWidget()时调用.这就起到了GameApp中的mWidgetManager能够统一管理所有Widget的目的.
virtual void RemovedFromManager(WidgetManager *theWidgetManager);
//根据指定的FPS间隔调用,一般放逻辑运算,状态变化处理等.
virtual void Update();
//根据显卡的运行速度全速调用,一般是根据Update()处理后的数据进行数据图像的更新重绘等处理
virtual void Draw(Graphics* g);
//Widget被鼠标点击时调用,参数为点击Owner的ID号.
virtual void ButtonDepress(int theId);
};
}
接着MyWidget.cpp

#include "GameApp.h"
#include "MyWidget.h"
#include <Graphics.h>
#include <Color.h>
#include <HyperlinkWidget.h>
#include <WidgetManager.h>
using namespace Sexy;
MyWidget::MyWidget(GameApp *theApp)
{
//保存指针
anApp=theApp;
//设置Widget的大小(也就是重绘的区域)
Resize(0,0,anApp->mWidth,anApp->mHeight);
}
MyWidget::~MyWidget()
{
//删除控件
if(mLink)
delete mLink;
}
void MyWidget::AddedToManager(Sexy::WidgetManager *theWidgetManager)
{
Widget::AddedToManager(theWidgetManager);
//Override时我们乘势加入我们Widget的组件
mLink=new HyperlinkWidget(1,this);//资源ID为1
mLink->Resize(anApp->mWidth / 2-80,anApp->mHeight / 2-10,150,20);//设置大小和显示位置
mLink->mLabel=_S("Hello World");//显示内容
mLink->mColor=Color(80,160,58);//颜色1
mLink->mOverColor=Color(0,255,0);//颜色2
theWidgetManager->AddWidget(mLink);//加入
}
void MyWidget::RemovedFromManager(Sexy::WidgetManager *theWidgetManager)
{
Widget::RemovedFromManager(theWidgetManager);
theWidgetManager->RemoveWidget(mLink);//踢掉
}
void MyWidget::Update()
{
Widget::Update();
MarkDirty();//计算脏区,这样可以大大加快重绘速度
}
void MyWidget::Draw(Sexy::Graphics *g)
{
//g就是锁定的surface,哦这是Sexy引擎应该叫做锁定的Widget显示表面,对g进行操作就可以在Widget上进行各种数据操作.如画图写字等.
g->SetColor(Color::Black);//先设置颜色为黑
g->FillRect(0,0,mWidth,mHeight);//全部填充颜色为黑
g->SetFont(mLink->mFont);//我们使用mLink的字体偷一下懒(因为mLink不载入字体时会有默认字体但g不会.载入资源以后详细说明)
g->SetColor(Color::White);//我们使用白色
//写出
g->DrawString(_S("Click hyperlink open my blog:/" http://www.RainCoding.com/blog/""),55,300);
}
void MyWidget::ButtonDepress(int theId)
{
//如果单击的是HyperLink就打开链接
if(1==theId)
{
ShellExecute(0,"open"," http://www.raincoding.com/blog",NULL,NULL,SW_NORMAL);
}
}
然后GameApp.h

#include <SexyAppBase.h>
namespace Sexy
{
class MyWidget;
class GameApp:public SexyAppBase
{
private:
//声明我们要使用的Widget
MyWidget* mywidget;
public:
GameApp();
virtual ~GameApp();
//初始化,需要在main.c中显示调用(在载入进度时必须先初始化的资源.比如载入进度条图片等放在这里初始化)
virtual void Init();
//Init()完成后自动调用(这里一般就是Widget的初始化和做载入进度条的地方)
virtual void LoadingThreadProc();
//LodingThreadProc()完成后自动调用
virtual void LoadingThreadCompleted();
};
}
然后GameApp.cpp

#include "GameApp.h"
#include "MyWidget.h"
#include "WidgetManager.h"
using namespace Sexy;
GameApp::GameApp()
{
mWidth=480;//主窗口宽
mHeight=320;//高
mTitle=_S("MyFirstSexy");//标题,所有的Sexy用到的字符串需要_S()宏或者SexyStringToXXX等系列函数
mywidget=NULL;
}
GameApp::~GameApp()
{
//删除管理
mWidgetManager->RemoveWidget(mywidget);
//释放Widget
delete mywidget;
mywidget=NULL;
}
void GameApp::Init()
{
SexyAppBase::Init();
//没事可做
}
void GameApp::LoadingThreadProc()
{
//创建我们的Widget
mywidget=new MyWidget(this);
}
void GameApp::LoadingThreadCompleted()
{
SexyAppBase::LoadingThreadCompleted();
//加入资源管理
mWidgetManager->AddWidget(mywidget);
}
最后入口main.cpp

#include "GameApp.h"
using namespace Sexy;
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int)
{
//几乎所有的Sexy都是这样
GameApp* app=new GameApp;
//Init
app->Init();
//开始循环,返回也就意味着游戏退出.
app->Start();
delete app;
return 0;
}
编译之前注意几点,以上源码是设置了SexyAppFramework的include head file path和lib path,否则请include 相对路径或绝对路径.编译时请加入Lib(其他工程如有加入可排除重复)SexyAppFramework.lib //Debug请加入对应的版本
winmm.lib
wsock32.lib
gdi32.lib
advapi32.lib
shell32.lib
代码生成请选择调式或非调试静态多线程(MT/MTd)而不要选择动态多线程Dll,否则会link error重复的定义错误.
ok,有问题或意见可以留言.下回见.
本章源码
=============================================
补充一下,引擎提供的hyperlink,button,edit等等UI都是Widget,不过是帮你实现好的Widget,言下之意就是实现了Draw(Graphics* g)的函数实现,所以可以直接AddedToManager就可显示等操作.
运行截图: