前面的文章,我们已经创建完成了一个角色库,并能在场景编辑器STAGE中进行加载,但是还没有形成一个可以运行的程序,这节,我们先用Delta3d自带的GameStart.exe程序来启动我们的游戏
GameStart
GameStart是一个可独立运行的程序,在我们的角色库输出目录下,GameStart.exe文件。他可让我们在不编译自己的可执行程序的情况下通过查找游戏入口点来启动我们的应用或游戏。需要关注的三个函数:
- CreateApplication()
创建我们自己的App,可以传入配置文件的路径来配置游戏
- Initialize()
初始化函数,用于处理命令行参数,这里不能做任何游戏管理的事情。
- CreateGameManager()
创建我们自己的游戏管理器对象的地方(新版已删除此函数,因为一般不创建自己的GameManager,而是通过向GameManager添加组件的方式扩展功能)
- OnStartup()
在这里创建我们的游戏对象,加载场景地图及任何启动游戏前要做得事都在这里完成。
- OnShutdown()
游戏退出时,清理我们自己创建的资源。
创建并生成游戏入库点(dll)后,即可使用GameStart来启动:
GameStart.exe MyGame(不用添加扩展名,也不要添加debug标识)
创建GameEntryPoint
可以在我们之前创建的角色库中添加GameEntryPoint,也可以新建一个dll工程创建,我这里是在角色库工程中添加的。下面是我们创建的GameEntryPoint:
这里我们只需重载OnStartup函数,其他函数采用父类的默认实现。
// BlogTutorialGameEntryPoint.h
#ifndef BlogTutorialGameEntryPoint_h__
#define BlogTutorialGameEntryPoint_h__
#include "delta3d_export.h"
#include <dtGame/gameentrypoint.h>
class DELTA3D_EXPORT BlogTutorialGameEntryPoint : public dtGame::GameEntryPoint
{
public:
BlogTutorialGameEntryPoint();
~BlogTutorialGameEntryPoint();
virtual void OnStartup(dtABC::BaseABC& app, dtGame::GameManager& gamemanager) override;
};
#endif // BlogTutorialGameEntryPoint_h__
下面是实现文件:
// BlogTutorialGameEntryPoint.cpp
#include "BlogTutorialGameEntryPoint.h"
#include <dtGame/defaultmessageprocessor.h>
#include <dtGame/gamemanager.h>
#include <dtCore/flymotionmodel.h>
#include <dtCore/project.h>
#include <dtCore/scene.h>
#include <dtCore/transform.h>
#include <dtABC/baseabc.h>
// 以下两个函数是GameEntryPoint的关键函数,GameStart在启动时会查找这两个函数
extern "C" DELTA3D_EXPORT dtGame::GameEntryPoint *CreateGameEntryPoint()
{
return new BlogTutorialGameEntryPoint();
}
extern "C" DELTA3D_EXPORT void DestroyGameEntryPoint(dtGame::GameEntryPoint *gameEntryPoint)
{
delete gameEntryPoint;
}
BlogTutorialGameEntryPoint::BlogTutorialGameEntryPoint()
{
}
BlogTutorialGameEntryPoint::~BlogTutorialGameEntryPoint()
{
}
// 这里是进入游戏前要做得所有事情,如创建组件、事件处理器、设置工程路径等
void BlogTutorialGameEntryPoint::OnStartup(dtABC::BaseABC& app, dtGame::GameManager& gamemanager)
{
// 添加消息处理组件
dtGame::DefaultMessageProcessor *dmp = new dtGame::DefaultMessageProcessor("DefaultMessageProcessor");
// 添加到游戏管理器,并设置消息处理优先级
gamemanager.AddComponent(*dmp, dtGame::GameManager::ComponentPriority::HIGHEST);
// 加载场景地图
dtCore::Project::GetInstance().SetContext("data");
gamemanager.ChangeMap("Demo");
gamemanager.GetScene().UseSceneLight(true);
// 设置摄像相机
dtCore::FlyMotionModel *fm = new dtCore::FlyMotionModel(app.GetKeyboard(), app.GetMouse());
fm->SetTarget(app.GetCamera());
dtCore::Transform tx
(0, -40, 15, // 在yz平面上的
-50, -15, 0 // 看向xy平面(注:delta3d的坐标系为,x正向朝右,y正向朝屏幕里面,z正向朝上)
);
app.GetCamera()->SetTransform(tx); // 设置相机的位置和朝向
}
编译并生成dll文件后,在输入目录中打开cmd命令行窗口启动GameStart
这里有几个地方需注意,如果你在STAGE编辑器中,放入的Actor位置太远或太偏,则摄像头看不到Actor,需要调整坐标。因为我们在GameEntryPoint中设置的摄像头在(0, -40, 15)朝向(-50, -15,0)看去,因此我们需要将Actor的位置设置为(50, 15, 0),这样,程序一启动,我们就能看到Actor(图上黄色部分,是直接在编辑器里面拖拽了一个dtCore/Terrain/Infinite Terrain地形Actor自动生成的)