Orx官方教程: 08.物理特性(Physics)教程

本文译自 orx tutorials 的 physics tutorial ,六月的流光 译。最新版本见Orx 官方中文Wiki 。 本文转自六月的流光的博客 。原文链接在:http://yatusiter.blogbus.com/logs/68692886.html

Physics tutorial

物理特性教程

Summary

综述

See previous basic tutorials for more info about basic object creation , clock handling , frames hierarchy , animations , cameras & viewports , sounds & musics and FXs .

查看之前关于 basic object creation , clock handling , frames hierarchy , animations , cameras & viewports , sounds & musics and FXs .以获得更多的 信息。

This tutorial shows how to add physical properties to objects and handle collisions.

本 教程展示了如何为对象添加物理属性和处理碰撞。

As you can see, the physical properties are completely data-driven. Thus, creating an object with physical properties (ie. with a body) or without results in the exact same line of code.

如你所见,物理 属性完全是数据驱动的。因此,可以在完全相同的一行代码创建一个拥有物理属性(即通过一个body)或没有物理属性的对象。

Objects can be linked to a body which can be static or dynamic.

对象可以动态或 静态地链接到一个body(译注:body为Box2D中的一个概念,表示一个物理实体的概念)。

Each body can be made of up to 8 parts.

每一个body可以由8部分组成。

A body part is defined by:

一个body部分可以定义如下:

its shape (currently box, sphere and mesh (ie. convex polygon) are the only available)

information about the shape size (corners for the box, center and radius for the sphere, vertices for the mesh)

if no size data is specified, the shape will try to fill the complete body (using the object size and scale)

collision “self” flags that defines this part

collision “check” mask that defines with which other parts this one will collide 1) two parts in the same body will never collide

a flag (Solid) specifying if this shaped should only give information about collisions or if it should impact on the body physics simulation (bouncing, etc…)

various attributes such as restitution, friction, density, …

它的形状(目前可用的只有箱子( box,译注:长方体)、球体(sphere)和多边形(即 mesh,凸多边形))

关于形状大小的信息(箱子的拐角点,球体的球心和半径以及 凸多边形的顶点)

如果有没指定形状的大小数据,形状会尝试填满整个body(根据对象的大小和缩放)

“self”标记定义产生碰撞的部分

“check”掩码定义了与这部分产生碰撞的其他部分 (注释1 同一个物理的两个部分永远不会碰撞)

一个标记(Solid)指定了这个形状是否只给出碰撞的 信息还是应该影响body的模拟物理运动(弹跳等)

其他的各种属性如 弹性 (restitution) 、摩擦 (friction)、密度(density)……

In this tutorial we create static solid walls around our screen. We then spawn boxes in the middle.

The number of boxes created is tweakable through the config file and is 100 by default.

在 本教程中我们创建环绕我们屏幕的静态固体墙。然后我们在中间放置箱子。

要创建的箱子数目是可以通过配置文件调整的,默认为100。

The only interaction possible is using left and right mouse buttons (or left and right keys) to rotate the camera.

As we rotate it, we also update the gravity vector of our simulation.

Doing so, it gives the impression that the boxes will be always falling toward the bottom of our screen no matter how the camera is rotated.

唯一可能的交互操作是使用鼠标的左右键(或者键盘左右方向键)来旋转摄像头。

在旋转时也将会 更新我们的模拟的重力矢量。

如此,会让我们有无论摄像头怎么旋转那些箱子都一直往我们屏幕底部掉落的感觉。

We also register to the physics events to add a visual FXs on two colliding objects.

By default the FX is a fast color flash and is, as usual, tweakable in realtime (ie. reloading the config history will apply the new settings immediately as the FX isn't kept in cache by default).

我们也可以注册 物理事件来为两个碰撞的物体添加可视的特效(FXs)。

默认特效(FX)是一种快速的颜色闪烁,通常也是可以实时调整的(即,重新读取配置文 件会使新设置立即生效,因为特效默认是不保存在缓冲中的)。

Updating an object scale (including changing its scale with FXs) will update its physical properties (ie. its body).

Keep in mind that scaling an object with a physical body is more expensive as we have to delete the current shapes and recreate them at the correct size.

This is done this way as our current single physics plugin is based on Box2D which doesn't allow realtime rescaling of shapes.

更新一个对象的缩放比(包括通过FX改变它的缩放比)会更新它的物理属性(即 它的body)。

请注意改变一个 有物理特性的body对象代价是很高的,因为我们必须删除当前的形状并按正确的大小重建。

这么做是因为我 们目前唯一的物理引擎插件是基于Box2D的,它不支持实时重新缩放形状。

This tutorial does only show basic physics and collision control, but, for example, you can also be notified with events for object separating or keeping contact.

本教程只展示了 简单的物理特性和碰撞控制,但是,比如说,你也可以获取到对象碰撞和结束碰撞的事件。

Details

详细说明

As usual, we begin by loading our config file, creating a clock and registering our Update function to it.

Please refer to the previous tutorials for more details.

就像往常一样, 我们会以加载配置文件,创建一个时钟并注册我们的更新函数作为开始。

请参考前面的教程(LINK)以获得更多信息。

We also creates our walls. Actually we won't create them one by one, we'll group them in a ChildList of a parent object.

我们也创建了我 们的墙。实时上我们并不是一个一个的创建,我们把它们在父对象中的一个ChildList组合起来。

orxObject_CreateFromConfig("Walls");

This looks like we only create one object called Walls, but as we'll see in the config file, it's actually a container that will spawn a couple of walls.

这看起来我们只 是创建了一个叫做Walls的对象,但我们会在配置文件中看到,它实际上是一个会产生一堆墙的容器。

Lastly, we create our boxes.

接着,我们创建我们的箱子。

for(i = 0; i < orxConfig_GetU32("BoxNumber"); i++)

{

orxObject_CreateFromConfig("Box");

}

As you can see, we don't specify anything regarding the physics properties of our walls or boxes, this is entirely done in the config file and is fully data-driven.

如你所见,我们并没有指定任何关于墙或箱子的属性,这些都在配置文件中完成了并且完全是数据驱动的。

We then register to physics events.

然后我们注册到物理事件。

orxEvent_AddHandler(orxEVENT_TYPE_PHYSICS, EventHandler);

Nothing really new here, so let's have a look directly to our EventHandler callback.

这 里没有什么新东西,所以我们直接看下EventHandler回调函数。

if(_pstEvent->eID == orxPHYSICS_EVENT_CONTACT_ADD)

{

orxOBJECT *pstObject1, *pstObject2;

pstObject1 = orxOBJECT(_pstEvent->hRecipient);

pstObject2 = orxOBJECT(_pstEvent->hSender);

orxObject_AddFX(pstObject1, "Bump");

orxObject_AddFX(pstObject2, "Bump");

}

Basically we only handle the new contact event and we add a FX called Bump on both colliding objects. This FX will make them flash in a random color.

基本上我们只处 理了新的联系事件并且我们增加了一个叫做Bump的FX在两个碰撞的对象上。这个FX会使得它们闪烁一种随机的颜色。

Let's now see our Update function.

现在看看我们的Update函数。

void orxFASTCALL Update(const orxCLOCK_INFO *_pstClockInfo, void *_pstContext)

{

orxFLOAT fDeltaRotation = orxFLOAT_0;

if(orxInput_IsActive("RotateLeft"))

{

fDeltaRotation = orx2F(4.0f) * _pstClockInfo->fDT;

}

if(orxInput_IsActive("RotateRight"))

{

fDeltaRotation = orx2F(-4.0f) * _pstClockInfo->fDT;

}

if(fDeltaRotation != orxFLOAT_0)

{

orxVECTOR vGravity;

orxCamera_SetRotation(pstCamera, orxCamera_GetRotation(pstCamera) + fDeltaRotation);

if(orxPhysics_GetGravity(&vGravity))

{

orxVector_2DRotate(&vGravity, &vGravity, fDeltaRotation);

orxPhysics_SetGravity(&vGravity);

}

}

}

As you can see, we get the rotation update from the RotateLeft and RotateRight inputs.

If a rotation needs to be applied, we then update our camera with orxCamera_SetRotation() and we update our physics simulation gravity accordingly.

This way, our boxes will always look like they fall toward the bottom of our screen, whichever the camera rotation is.

Note the use of orxVector_2DRotate() so as to rotate the gravity vector.

如你所见,我们 从RotateLeft和RotateRight输入得到了旋转的更新。

如果需要旋转,那么我们就用orxCamera_SetRotation() 来更新摄像头并且我们更新相应的物理特性模拟的重力(矢量)。

这么做,无论摄像头怎么旋转,我们的箱子总会来看起来是向我们屏幕的底部运动。

注意使用 orxVector_2DRotate()以便旋转重力矢量。

NB: All rotations in orx's code are always expressed in radians!

注意:orx代码中的所有的旋转总是用弧度表示!

Let's now have a look at our config data. You can find more info on the config parameters in the body section of config settings .

First, we created implicitely many walls using the ChildList property. See below how it is done.

现在我们看一下 我们的配置数据。你可以在 body section of config settings (LINK 配置设置中的body 配置段)找到更多关于配置参数的信息。

首先,我们通过 ChildList属性隐式地((译者注:原文中的implicitely应为implicitly,应该是作者笔误))创建了许多墙。实现如下:

[Walls]

ChildList = Wall1 # Wall2 # Wall3 # Wall4; # Wall5 # Wall6

As we can see, our Walls object is empty, it will just create Wall1, Wall2, Wall3 and Wall4 (note the ';' ending the list there).You can remove this ';' to create 2 additional walls.

正如我们看到的,我们的墙对象为空,只是创建了Wall1、Wall2、Wall3 和Wall4 (注意 ‘;’ 在列表的结尾)。你可以移除这个 ‘;’ 新增两堵墙。

Let's now see how we define our walls and their physical properties.

Let's begin with the shape we'll use for both WallBody and BoxBody.

现在让我们看看怎么定义我们的墙和它们的物理属性。

让我们从我们将 要在WallBody和BoxBody中都用到的形状开始。

[FullBoxPart]

Type = box

Restitution = 0.0

Friction = 1.0

SelfFlags = 0x0001

CheckMask = 0xFFFF

Solid = true

Density = 1.0

Here we request a part that will use a box shape with no Restitution (ie. no bounciness) and some Friction.

We also define the SelfFlags and CheckMask for this wall.

The first ones defines the identity flags for this part, and the second ones define to which idendity(应 该是 identity) flags it'll be sensitive (ie. with who it'll collide).

Basically, if we have two objects: Object1 and Object2. They'll collide if the below expression is TRUE.

这里我们创造了 一个没有Restitution(弹性)和一点Friction(摩擦)的box (长方体)形状。

同样我们也为这 堵墙定义了 SelfFlags 和 CheckMask。

第一个(译注:SelfFlags)定义了标识标记,第二个定义了那些它会碰撞到的标 识标记

基 本上,如果我们有两个对象:Object1和Object2.如果以下条件为TRUE,它们就会发生碰撞。

(Object1.SeflFlags & Object2.CheckMask) && (Object1.CheckMask & Object2.SelfFlags)

NB: As we don't specify the TopLeft and BottomRight attributes for this FullBoxPart part, it will use the full size of the body/object that will reference it.

注意:我们没有 为这个FullBoxPart指定TopLeft 和 BottomRight 属性,所以它会使用所引用的body/object的完整尺寸。

Now we need to define our bodie

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值