第一天:准备出发
出自Ogre3D开放资源地带
目录 |
前言
1978年TAITO的西角友宏制作了一款叫做《太空侵略者》的街机游戏,这款游戏的灵感来自西角友宏一个奇怪的梦,在他的梦里一群小孩在圣诞节前等待圣诞老人的降临,却迎来了一批外太空不速之客,于是他们用自制的激光炮左右移动的反击这些外星人。轰动一时的《太空侵略者》就这样诞生了。这款游戏在七十年代末风靡一时,甚至因此引发了全日本范围100日元硬币的短缺现象。游戏为TAITO创造了5亿美元的收入,也为日本街机市场的兴盛做出了卓越贡献。
正文
今天我们站在了巨人的肩上,不仅伟大的游戏设计师给我们留下宝贵的创意,无私的开源社区也给我们提供了游戏开发的基础工具以及程序库。正如我们所熟悉的Ogre3D。
包括Ogre3D(图形)或者Fmod(音频)以及OIS(输入)等,这些程序库提供了对某个专业功能的实现和封装;就如Ogre所说,他们承担了一个View(视图)的功能。而我们这里提供的Orz程序库,着重于把诸多功能库整合梳理,提供良好的开发以及运行流程,承担了一个Controller(控制器)的工作。
基于这些程序库和工具,今天我们并不需要从头一砖一瓦从头来实现一个完整的游戏,只要把游戏的逻辑、数据以及资源提供给整个系统,就可以很快的开发出我们所希望的东西。换句话说,我们需要完成的,可能仅仅只有Model(模型)。(参考MVC设计模式)
在展开我们七天神奇的游戏开发之旅的起点,请到我们的首页http://orz.ogre3d.cn/下载相应的代码和工程依赖项目。
你可能需要先编译Orz项目,我们会在之后的稳定版本提供Orz的SDK安装文件。
按照使用CMake从最新的代码中编译中的方法,直到生成OrzTutorial.sln解决方案文件并打开,在解决方案管理器中我们可以看到不同的课程,在第一课程的项目中我们可以看到5个文件。
Tutorial.def
LIBRARY "Tutorial" EXPORTS dllStartPlugin dllStopPlugin
这个文件提供了dll导出信息,让我们的Orz框架可以调用dllStartPlugin以及dllStopPlugin两个函数来作为载入插件的接口。
TutorialConfig.h
#ifndef __Orz_Tutorial_TutorialConfig_h__ #define __Orz_Tutorial_TutorialConfig_h__ #include <orz/Tookit_Base/Global.h> #include <orz/View_OGRE3D/OgreGraphicsManager.h> #pragma warning(push) #pragma warning(disable:4819) #include <Ogre/Ogre.h> #pragma warning(pop) #endif
这里我们提供了一些基础包含文件,我们在之后也可以在其中添加一些其他的公共设置。
Tutorial.cpp
#include "TutorialConfig.h"
#include "TutorialDirector.h"
#include <orz/Framework_Base/Logic.h>
///new 一个TutorialDirector的工厂。并委托给智能指针管理其生命期。
Orz::DirectorFactoryPtr director = Orz::DirectorFactoryPtr(new Orz::TutorialDirectorFactory());
extern "C" void dllStartPlugin(void)
{
using namespace Orz;
//注册工厂
GameFactories::getInstance().addDirectorFactory(director.get());
}
extern "C" void dllStopPlugin(void)
{
using namespace Orz;
//注销工厂
GameFactories::getInstance().removeDirectorFactory(director.get());
}
这个文件是本工程作为插件的接口,其中创建了一个Director(导演)工厂实例,并交给智能指针管理,智能指针可以帮助我们在插件释放的时候删除工厂对象。这里使用了设计模式中的工厂方法模式。
我们已经列出了三个最基本的文件,这些文件作为基础在之后也不会进行修改(本教程内)。
TutorialDirector.h
在讲解TutorialDirector对象之前,我们先要说明一下在Orz框架中Director(导演)的概念,我们认为在一个运行的游戏实例中有一个负责协调统一的对象,即导演Director(导演)类实例,它负责在构造的时候创建所需游戏组件(主要是其他对象实例);在初始化时候安置游戏组件;在卸载的时候关闭组件;在析构的时候释放游戏组件。这四个功能分别放置在如下四个函数内:
//这个类继承与框架提供的Director(导演),其作用是调控整个游戏
class TutorialDirector : public Director
{
public:
//下面构造函数中提供的name参数提供给IDManager工具使用
TutorialDirector(const std::string & name = IDManager::BLANK);//创建
virtual ~TutorialDirector(void);//释放
bool doEnable(void);//安置
void doDisable(void);//关闭
};
如上面我们所看到,这是一个极其简单的接口。在后面我们会看到相应的实现。 为了提供给我们的框架使用,我们也遵守工厂模式提供了一个用于生产导演的工厂类:
//同时为了配合插件体系,我们提供了相应的导演工厂类。用于系统来“生产”相应导演。
class TutorialDirectorFactory: public IFactory<Director>
{
public:
virtual const std::string & getTypeName() const;
virtual pointer_type createInstance(
const std::string& instanceName = IDManager::BLANK,
parameter_type parameter = NULL);
};
不错,标准的工厂模式。
TutorialDirector.cpp
来看看我们元宵夜最后一道大餐。里面提供了上面文件的相关实现。
//这个函数会在初始化调用
bool TutorialDirector::doEnable(void)
{
using namespace Ogre;
//从系统中得到Ogre的场景管理器
SceneManager * sm =
OgreGraphicsManager::getSingleton().getSceneManager();
//把其场景清空
sm->clearScene();
//设置环境光
sm->setAmbientLight(ColourValue(0.5, 0.5, 0.5));
//创建天空盒
sm->setSkyBox(true, "Examples/SpaceSkyBox", 50 );
// 创建一个光源
Light* l = sm->createLight("MainLight");
//设置光源位置
l->setPosition(20,80,50);
return true;//这个返回值告诉调用者:我成功了/失败了。
}
另外还有三个空的函数体。哦,没错,这些都是最基本的Ogre图形引擎使用方法。我们对不同的View采用了不同的方法来结合。对于Ogre3D这种需要复杂接口的View库我们采用了适配——即框架负责基本的元素创建和销毁,用户直接调用其原始接口——的方式。而对于音频和输入,我们采用了封装,即——规定了新的简化的接口——方式,我们之后的课程中会见到相关的代码。这两种结合的方法都不是绝对的,我们可以按需采用。框架本身是极其容易扩展的。
当然,如果有对上面Ogre3D代码有什么不理解,可以去我们的网站Ogre3d.cn上面看看,或者直接学习其Demo。不过最好的办法还是到我们的论坛http://bbs.ogre3d.cn来找我,我和很多社区内的热心人会很乐意为您解答与交流。
最后是两个朴实的工厂方法的函数:
const std::string & TutorialDirectorFactory::getTypeName() const
{
static const std::string typeName("TutorialDirector");
return typeName;
}
TutorialDirectorFactory::pointer_type
TutorialDirectorFactory::createInstance (
const std::string& instanceName,
parameter_type parameter)
{
return pointer_type(new TutorialDirector(instanceName));
}
好了,我们看了上面五个文件。编译运行,会生在./bin/debug(或者./bin/release根据不同的编译模式)下面看到Tutorial.dll这个新生成的文件,这就是我们今天的成果。运行Controller_Base.exe文件,在配置完成显示系统以及一大串log信息之后,我们会看到一个类似宇宙的场景,那便是我们布置的SkyBox(天空盒)。
今天没什么大不了的,但是很重要,因为这是我们的第一步。
课程结语
叮咚,已经下课了。
怎么样,今天是觉得吃力呢还是有点意犹未尽(当然,我相信也有许多朋友觉得乏味,但估计不会有几个有耐心看到这里的了)。
在今天的课程中,我们简单的布置了一些基础的代码。除了简单的C++语言之外,还涉及到boost的智能指针以及Ogre的一些操作,我们使用了工厂方法设计模式,并大致的接触了MVC模式。
如果有什么不清楚的或者对这个教程有什么意见,欢迎到http://bbs.ogre3d.cn论坛来提出。
透露一下明天的课程:比今天有趣一点。
