BIGWORLD 客户端Tutorial

BIGWORLD_03–Tutorial

1.概述

本教程简要概述了从头开始制作一款基本游戏所需的最低步骤。第一次与BigWorld合作的游戏开发者和技术美工应该通过本教程了解如何将各种文件和目录组合在一起,从而制作出一款有效的游戏。

1.1常规

1.1.1 文件和目录

统一以/划分层级,例如 <res>/scripts/db.xml,而不是 <res>\scripts\db.xml。

1.1.2 提供的文件

本教程中使用的所有文件都在BigWorld包的教程目录中。

1.1.3 Debugging

在学习本教程时,由于脚本中的某些错误,客户端可能无法启动。为了发现错误的原因,使用诸如DebugView(可以在微软网站上找到)这样的程序,它捕获并显示调试输出。

2. 一个基本的仅限客户端的游戏

本章描述如何启动一个基本的客户机,并使用它自己的资源和脚本运行。这涉及到:

  • 创建一个新的BigWorld项目目录。
  • 创建定义单个客户端播放器实体所需的文件和目录。
  • 创造一个新的空间。
    在本部分教程的最后,我们将能够使用第一人称视角在客户端中行走。

2.1 创建新的项目

FantasyDemo项目位于C:\BigWorld的FantasyDemo目录中。按照这个约定,我们将在同一个目录中启动新的教程项目,方法是在C:\BigWorld中创建一个名为tutorial的新目录。所有特定于此项目的资源和脚本都将位于此目录中。

2.2 定义资源路径

2.3 创建资源目录

在tutorial中创建res目录,这个顶级资源目录将包含所有游戏特定的脚本、资产和配置文件。

2.4 创建第一个实体

实体是具有位置的游戏对象。实体的例子包括玩家、npc、聊天室、掉落物品等….

2.4.1 entities.xml

实例脚本必须位于res/scripts中,
在tutorial/res/scripts/entities.xml文件中写入:

1
2
3
4
5
6
7
<root>
<ClientServerEntities>
<Avatar/>
</ClientServerEntities>
<ServerOnlyEntities>
</ServerOnlyEntities>
</root>

2.4.2 定义Avatar实体类型

另一个必须存在的目录是res/scripts/entity_defs,其中包含.def文件包含每个实体的属性和方法的定义。

将这些定义文件想象成类似于C/C++头文件可能会有所帮助,因为它们指定了附加到实体的属性类型和方法调用。
在tutorial/res/scripts/entity_defs/Avatar.def文件中写入以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<root>
<Volatile>
<position/>
<yaw/>
</Volatile>
<Properties>
<playerName>
<Type> UNICODE_STRING </Type>
<Flags> ALL_CLIENTS </Flags>
</playerName>
</Properties>
<ClientMethods>
</ClientMethods>
<CellMethods>
</CellMethods>
<BaseMethods>
</BaseMethods>
</root>

这是一个非常基本的实体定义,它定义了实体的属性,但没有方法。注意,属性被分为两部分:volatile和非volatile。

2.4.2.1 Volatile properties

对于BigWorld实体,volatile属性是位置/方向属性。它们之所以被描述为不稳定的,是因为它们在不断地变化。volatile属性的当前值只被认为是重要的,而属性的历史变化则不那么重要。在带宽受限的环境中,只发送当前值。

2.4.2.2 Non-volatile properties

与volatile属性相比,常规属性的更改频率较低,因此对特定属性的所有更改都应该发送到客户机。每个属性都可以按照您的意愿命名,并且可以附加许多不同的设置。

2.4.3 实现Avatar实体类型

在 tutorial/res/scripts目录中创建base,cell,client文件夹,其中base和cell是控制服务端实体脚本文件夹,client是客户端实体脚本文件夹。

创建脚本tutorial/res/scripts/client/Avatar.py,并写入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    import BigWorld
# These are constants for identifying keypresses, mouse movement etc
import Keys
class Avatar( BigWorld.Entity ):
def onEnterWorld( self, prereqs ):
pass
class PlayerAvatar( Avatar ):
def onEnterWorld( self, prereqs ):
Avatar.onEnterWorld( self, prereqs )
# Set the position/movement filter to correspond to an player avatar
self.filter = BigWorld.PlayerAvatarFilter()
# Setup the physics for the Avatar
self.physics = BigWorld.STANDARD_PHYSICS
self.physics.velocityMouse = "Direction"
self.physics.collide = True
self.physics.fall = True
def handleKeyEvent( self, event ):
# Get the current velocity
v = self.physics.velocity
# Update the velocity depending on the key input
if event.key == Keys.KEY_W:
v.z = event.isKeyDown() * 5.0
elif event.key == Keys.KEY_S:
v.z = event.isKeyDown() * -5.0
elif event.key == Keys.KEY_A:
v.x = event.isKeyDown() * -5.0
elif event.key == Keys.KEY_D:
v.x = event.isKeyDown() * 5.0
self.physics.velocity = v
# Save back the new velocity

2.5 独立脚本(The personality script)

我们的基本客户端的下一个必需脚本是个性脚本。最简单的方法是把这个脚本看作BigWorld系统每个组件的引导脚本。
创建并保存以下脚本tutorial/res/scripts/client/BWPersonality.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# 这是BigWorld教程的客户端个性脚本。
# 可以将其视为客户机的引导脚本。它包含的函数
# 在各种输入事件的初始化、关闭和处理程序时调用。
import BigWorld
# ----------------------------------------------------------------------------
# 必需的回调
# ----------------------------------------------------------------------------
# init函数是作为BigWorld初始化过程的一部分调用的。
# 它接收BigWorld xml配置文件作为参数。
# 这是配置所有应用程序特定的BigWorld组件的最佳位置,比如初始相机视图等…
def init( scriptConfig, engineConfig, prefs ):
initOffline( scriptConfig )
#隐藏鼠标光标并将其限制在窗口的客户端区域。
GUI.mcursor().clipped = True
GUI.mcursor().visible = False
#init()结束后立即调用。
def start():
pass

# 当玩家从内部环境移动到外部环境时,
# BigWorld就会调用这一机制,反之亦然。
# 它应该被用来适应任何与个性相关的数据(例如,相机位置/性质等)。
def onChangeEnvironments( inside ):
pass

# 当出现系统生成的消息时,引擎将调用该函数。
def addChatMsg( msg ):
print "addChatMsg:", msg
# 键盘时间
def handleKeyEvent( event ):
return False
# 鼠标事件
def handleMouseEvent( event ):
return False
# 操纵杆事件
def handleAxisEvent( event ):
return False
# ----------------------------------------------------------------------------
# Section: Helper methods
# ----------------------------------------------------------------------------
def initOffline( scriptConfig ):
# Create a space for the client to inhabit
spaceID = BigWorld.createSpace()
# 加载script_config.xml中指定的空间
BigWorld.addSpaceGeometryMapping(spaceID, None, scriptConfig.readString( "space" ) )
# 使用script_config.xml中的位置创建玩家实体
playerID = BigWorld.createEntity(
scriptConfig.readString( "player/entityType" ),spaceID, 0,
scriptConfig.readVector3( "player/startPosition" ),
scriptConfig.readVector3( "player/startDirection" ),
{}
)
BigWorld.player( BigWorld.entities[ playerID ] )
# 使用第一人称模式,因为我们还没有使用模型。
BigWorld.camera().firstPerson = True

这个性脚本提供了一个initOffline方法,该方法包含足够的代码来运行一个基本的客户端,以及所有其他所需回调的存根实现。

下面的部分将描述如何设置这些文件,以便在启动时将它们传递给个性脚本。

2.6 XML configuration files(XML配置文件)

至少,BigWorld客户端希望在启动时向个性脚本传递三个XML配置文件:

  • <engine_config>.xml
  • <scripts_config>.xml
  • <preferences>.xml

xml文件用于在客户端引擎上设置各种可配置属性,包括游戏个性的名称。我们将通过复制FantasyDemo /res/engine_config.xml到tutorial/res/engine_config.xml.
打开复制的文件,并修改(名称与个性脚本名称一致):

1
2
3
4
<!-- 修改前 -->
<!-- <personality> FantasyDemo </personality> -->
<!-- 修改后 -->
<personality> BWPersonality </personality>

<scripts_config>.xml文件用于定义个性脚本所期望的设置—保存以下内容到tutorial/res/scripts_config.xml中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<scripts_config.xml>
<!-- 这个文件的内容被传递给个性脚本
作为init函数的第一个参数(作为数据部分)。它的
语法完全由个性脚本定义。 -->
<space> spaces/main </space>
<player>
<entityType> Avatar </entityType>
<!-- 这是将要创建的玩家的实体类型。你
必须实现一个Player<类>类型(例如PlayerAvatar)
来使用该类型作为客户端代理。以下选项 -->
<startPosition> 0.0 1.25 0.0 </startPosition>
<startDirection> 1.0 0.0 0.0 </startDirection>
<!-- 是由个性脚本提供的起始位置和
面对dir为玩家如果没有空间特定生成点.
-->
</player>
</scripts_config.xml>

脚本配置将字符串spaces/main作为创建客户端实体的空间传递到个性脚本中,因此接下来我们将创建一个基本的行走空间。

2.7 一个简单空间

在启动世界编辑器之前,您需要告诉它在哪里可以找到特定项目的资源。
为此,打开bigworld/tools/worldeditor/paths.xml,并将FantasyDemo的引用替换到你自己的项目中。例如,

1
2
3
4
5
6
<root>
<Paths>
<Path>../../../tutorial/res</Path>
<Path>../../../bigworld/res</Path>
</Paths>
</root>

要创建一个简单的可导航的空间,请遵循以下步骤:

  1. 启动世界编辑器(bigworld/tools/ worlddeditor /worldeditor.exe)
  2. 在打开空间对话框中,单击create按钮
  3. 在New Space对话框中:
    1. Set the Space Name field to main.
    2. Set the Space Dimensions group box’s Width and Height fields to 5.
    3. Set the Default Terrain Texture field to a texture of your choosing.
    4. Click the Create button

新的空间主体将被创建并显示在世界编辑器中,保存并关闭编辑器。

2.8 第一次运行客户端

执行完本教程前几节中的步骤后,现在可以运行客户机了。为此,请使用前面创建的(参考2.2 run.bat)。你应该拥有一个能够使用鼠标控制朝向和方向键控制在空间中行走的第一人称玩家。