当前位置: 首页 > 工具软件 > Starling 2D > 使用案例 >

Urho2D和 Physics2D

冀啸
2023-12-01

为了在Urho3D中制作2D游戏,提供了Urho2D和Physics2D子库。

典型的2D游戏设置包括以下内容:

  • 创建正交摄影机
  • 创建一些精灵
  • 使用物理和约束与场景交互

正交照相机

为了使用Urho2D,我们需要先将相机设置为正交模式;可以用以下代码完成:

C++:

Node* cameraNode = scene_->CreateChild("Camera"); // Create camera node
Camera* camera = cameraNode->CreateComponent<Camera>(); // Create camera
camera->SetOrthographic(true); // Set camera orthographic
camera->SetOrthoSize((float)graphics->GetHeight() * PIXEL_SIZE); // Set camera ortho size (the value of PIXEL_SIZE is 0.01)

AngelScript:

Node@ cameraNode = scene_.CreateChild("Camera"); // Create camera node
Camera@ camera = cameraNode.CreateComponent("Camera"); // Create camera
camera.orthographic = true; // Set camera orthographic
camera.orthoSize = graphics.height * PIXEL_SIZE; // Set camera ortho size (the value of PIXEL_SIZE is 0.01)

Lua:

cameraNode = scene_:CreateChild("Camera") -- Create camera node
local camera = cameraNode:CreateComponent("Camera") -- Create camera
camera.orthographic = true -- Set camera orthographic
camera.orthoSize = graphics.height * PIXEL_SIZE -- Set camera ortho size (the value of PIXEL_SIZE is 0.01)

要放大/缩小,请使用SetZoom()。

精灵

Urho2D提供了一些类来加载/绘制游戏所需的精灵。可以从动画小精灵、2D粒子发射器和静态小精灵中进行选择。

动画精灵

     在Urho2D中创建动画精灵的工作流依赖于精灵(c)。Spriter是用于创建2D动画的跨平台工具。它既有几乎功能齐全的免费版,也有更高级的“专业版”。免费版本可在http://www.brashmonkey.com/spriter.htm.首先,可以在Spriter中加载bin/Data/Urho2D文件夹中的scml文件。请注意,虽然当前Spriter不支持spritesheets/纹理图谱,但Urho2D支持:您只需为scml文件和spritesheet的xml文件使用相同的名称(有关如何生成此文件的详细信息,请参阅下面的静态sprites)。示例33_Urho2DSpriterAnimation很好地演示了这一特性(scml文件和xml spritesheet都被命名为“imp”,以指示Urho2D使用图集而不是单个文件)。您可以删除“imp”文件夹中的所有图像文件,只需保留“imp_all.png”即可进行测试。但是,如果您想稍后在Spriter中编辑scml项目,请保留您的单个图像文件,因为它们仍然是必需的。

     使用AnimationSet2D类(资源)加载*.scml文件,并使用AnimatedSprite2D类(可绘制组件)渲染:

    AnimationSet2D:Spriter*.scml文件,包括一个或多个动画。可以通过其索引和名称(使用GetAnimation())访问AnimationSet2D中包含的每个Spriter动画(Animation2D)。

    AnimatedSprite2D:用于从AnimationSet2D显示Spriter动画(Animation2D)的组件。相当于3D动画模型。使用SetAnimation()通过名称(字符串)访问AnimationSet2D中的Animation2D动画。可以使用SetSpeed()控制播放动画的速度。可以使用SetLoopMode()控制循环模式。您可以使用Spriter(LM_default)中设置的默认值,也可以使动画重复(LM_FORCE_LOOPED)或钳制(LM_FFORCE_CCLAMPED)。一个有趣的功能是使用SetFlip()、SetFlipX()或SetFlipY()在两个轴上翻转/镜像动画。翻转后,动画将保持该状态,直到布尔状态恢复为false。如果希望轻松翻转其动画并避免对位置和碰撞形状使用偏移,建议在“精灵”中构建居中的精灵。

    Animation2D(RefCounted):来自AnimationSet2D的精灵动画。它允许只读访问给定scml的动画名称(GetName())、长度(GetLength())和循环状态(IsLooped())。

    有关演示,请查看示例33_Urho2DSpriterAnimation和24_Urho2DSprite。

    命名文件的提示:

  • 如果xml文件与同一存储库中的图像文件同名,则假定它是纹理参数文件
  • 如果xml文件与同一存储库中的Spriter scml文件同名,则假定它是spritesheet文件。因此,为了防止冲突,scml和图像文件不应具有完全相同的名称。

粒子发射器

2D粒子发射器由*.pex文件(许多2D引擎使用的格式)构建。使用ParticleEffect2D类(资源)加载*.pex文件,并使用ParticleEmitter2D类(可绘制组件)渲染:

  • ParticleEffect2D:定义2D粒子(ParticleEmitter2D)的行为和纹理的*.pex文件。有关示例,请参见bin/Data/Urho2D/greenspiral.pex
  • ParticleEmitter2D:用于显示ParticleEffect2D。相当于3D ParticleEmitter。

有关演示,请查看示例25_Urho2DParticle。

“ParticleEditor2D”工具(https://github.com/aster2013/ParticleEditor2D)可以用于轻松创建pex文件。为了让你开始,许多精心制作的pex样本都可以在网上获得,它们都是在Github上获得的,主要是在Github上(查看ParticlePanda、Citrus Engine、Particle Designer、Flambe、Starling、CBL…)

静态精灵

静态子画面是从单个图像文件或子画面/纹理图集构建的。使用Sprite2D类(资源)加载单个图像文件,使用SpriteSheet2D类(资源。两者都使用StaticSprite2D类(可绘制组件)渲染:

  • Sprite2D:由纹理、纹理矩形和热点定义的图像。
  • SpriteSheet2D:纹理图集图像(包含多个Sprite2D图像)。
  • StaticSprite2D:用于显示Sprite2D。相当于3D静态模型。Spritesheets可以使用ShoeBox等工具创建(http://renderhjs.net/shoebox/),darkFunction编辑器(http://darkfunction.com/editor/),精灵助手(http://www.gamedevhelper.com/spriteHelper2Info.php),TexturePacker(https://www.codeandweb.com/texturepacker), ... 这些工具将为每个单独的图像生成一个图像文件和一个映射坐标和大小的xml文件。注意,Urho2D使用与Sparrow/Starling引擎相同的xml文件格式。

    通过创建一个名为图像并位于同一文件夹中的xml参数文件,可以将材质指定给图像。例如,要使长方体精灵(bin/Data/Urho2D/box.png)最接近过滤,请在其旁边创建一个文件box.xml,内容如下:    

<texture>
    <filter mode="nearest" />
</texture>

此处记录了纹理参数的完整列表。

若要控制子画面不透明度,请使用SetAlpha()(也可以使用SetColor()调整颜色alpha)。)

默认情况下,精灵热点位于中心,但如果需要,您可以选择另一个热点:使用SetUseHotSpot()和SetHotSpot()。

背景和图层

   要设置场景的背景色,请使用GetDefaultZone()和SetFogColor()。

   可以使用不同的层来模拟透视。在这种情况下,您可以使用SetLayer()和SetOrderInLayer()。

   最后,请注意,您可以轻松地混合2D和3D资源。3D资源的位置需要在Z轴上稍微偏移(Z=1就足够了),相机的位置需要从3D资源的最大周长稍微偏移(在Z轴),并且需要灯光。

物理2D

要设置场景的背景色,请使用GetDefaultZone()和SetFogColor()。

可以使用不同的层来模拟透视。在这种情况下,您可以使用SetLayer()和SetOrderInLayer()。

最后,请注意,您可以轻松地混合2D和3D资源。3D资源的位置需要在Z轴上稍微偏移(Z=1就足够了),相机的位置需要从3D资源的最大周长稍微偏移(在Z轴),并且需要灯光。

刚体组件

RigidBody2D是2D物理对象实例的基类。

可用的刚体(BodyType2D)包括:

  • BT_STATIC:静态物体在模拟下不会移动,其行为就像它有无限大的质量一样。在内部,Box2D为质量和反质量存储零。用户可以手动移动静态物体。静止物体的速度为零。静态实体不会与其他静态或运动实体碰撞。
  • BT_DYNAMIC:完全模拟动态体。它可以由用户手动移动,但通常根据力移动。动态实体可以与所有实体类型碰撞。动态物体总是具有有限的非零质量。如果你试图将动态物体的质量设置为零,它将自动获得一千克的质量。
  • BT_KINEMATIC:运动体根据其速度在模拟下移动。运动体不响应力。它们可以由用户手动移动,但通常通过设置其速度来移动运动体。运动体的行为就像它有无限大的质量一样,然而,Box2D将质量和反质量存储为零。运动体不会与其他静态或运动体碰撞。

    您应该在创建时使用SetBodyType()建立主体类型,因为稍后更改主体类型代价高昂。

    通过施加力和脉冲可以移动/旋转刚体:

  •  线性力(渐进/渐进):
  • 应用力()
  • ApplyForceToCenter()(与ApplyForce相同,施加力的世界点设置为质心,这会阻止身体旋转/旋转)
  • 线性或角脉冲(野蛮/立即):
  • 应用线性脉冲()
  • 应用角度脉冲()
  • 扭矩(角力)
  • 应用扭矩()

ApplyForce()和ApplyLinearImpulse()采用两个参数:力的方向和施加力的位置。请注意,为了提高性能,可以通过将“唤醒”参数设置为false来请求身体睡眠。

您还可以使用SetLinearVelocity()或SetAngularVelociity()直接设置身体的线速度或角速度。您可以使用GetLinearVelocity()或GetAngularVelocity()获取当前速度。

要“手动”移动或旋转实体,只需平移或旋转其所属的节点。

碰撞形状组件

请参阅2D手册-第4章碰撞模块和第7章夹具,以获取完整参考。

形状

  • CollisionBox2D:定义2D物理碰撞盒。长方体形状具有可选的位置偏移(SetCenter())、宽度和高度大小(SetSize())以及以度表示的旋转角度(SetAngle())。长方体是实心的,因此如果需要空心长方体形状,请从CollisionChain2D形状创建一个。
  • 圆形<=>CollisionCircle2D:定义2D物理碰撞圆。圆形具有可选的位置偏移(SetCenter())和半径(SetRadius())。圆是实心的,不能使用圆形形状创建空心圆。
  • 多边形形状<=>CollisionPolygon2D:定义2D物理碰撞多边形。多边形形状是实心凸多边形。当连接内部两点的所有线段不与多边形的任何边相交时,多边形是凸的。多边形必须有3个或更多顶点(SetVertices())。多边形顶点缠绕无关紧要。
  • 边形状<=>CollisionEdge2D:定义2D物理碰撞边。边形状是由2个顶点(SetVertex1()和SetVertex2()或全局SetVertices())定义的线段。提供它们是为了帮助为您的游戏创建自由形式的静态环境。边缘形状的一个主要限制是它们可以与圆和多边形碰撞,但不能与自身碰撞。Box2D使用的碰撞算法要求两个碰撞形状中至少有一个具有体积。边缘形状没有体积,因此不可能发生边缘碰撞。
  • 链形状<=>CollisionChain2D:定义二维物理碰撞链。链形提供了一种将多条边连接在一起的有效方法(SetVertices()),以构建静态游戏世界。可以使用重影顶点将链连接在一起。不支持链形状的自相交。

    同一节点中可能存在多个碰撞形状以创建复合形状。这可以方便地近似复杂或凹形形状。

     重要提示:碰撞形状必须与纹理匹配才能准确。可以使用平铺的对象创建形状(请参见平铺贴图对象)。或者你可以使用像Physics Body Editor这样的工具(https://code.google.com/p/box2d-editor/),鲁比(https://www.iforce2d.net/rube/),级别助手(http://www.gamedevhelper.com/levelhelper/),PhysicsEditor(https://www.codeandweb.com/physicseditor), ... 帮助您。其他有趣的工具是BisonKick(https://bisonkick.com/app/518195d06927101d38a83b66/).

    将SetDrawShape()与DrawDebugGeometry()结合使用以切换形状可见性。

固定设施

    Box2D夹具通过用于2D物理碰撞形状的CollisionShape2D基类实现。每个碰撞形状共享的常见参数包括:

  • 密度:设置密度()和获取密度()
  • 摩擦力:SetFriction()和GetFriction()
  • 恢复(弹性):SetRestituon()和GetRestituon()

CollisionShape2D类还提供对这些财产的只读访问:

  • 质量:获取质量()
  • 惯性:GetInertia()
  • 质心:GetMassCenter()

碰撞过滤

    Box2D支持使用类别和组进行碰撞过滤(限制要碰撞的其他对象):

  • 碰撞类别:

         首先使用SetCategoryBits()将碰撞形状指定给类别。有16个类别可用。

         然后,可以使用SetMaskBits()指定给定碰撞形状可以碰撞的其他类别。

  • 碰撞组:使用SetGroupIndex()指定的正负索引。同一组索引中的所有碰撞形状总是碰撞(正索引)或从不碰撞(负索引)。

注意:

  • 碰撞组的优先级高于碰撞类别
  • 静态物体上的碰撞形状只能与动态物体碰撞
  • 运动体上的碰撞形状只能与动态体碰撞
  • 同一物体上的碰撞形状不会彼此碰撞

剩下的后面有空翻译

 类似资料: