Xamarin.iOS 中的 SpriteKit

SpriteKit 是 Apple 的 2D 图形框架,在 iOS 8 和 OS X Yosemite 中具有一些有趣的新功能。 其中包括与 SceneKit 的集成、着色器支持、照明、阴影、约束、法线贴图生成和物理增强。 具体而言,新的物理功能使向游戏添加逼真效果变得非常容易。

物理体

SpriteKit 包含 2D 刚体物理 API。 每个子画面都有一个关联的物理体 (SKPhysicsBody) 来定义物理属性,如质量与摩擦,以及物理世界中物理体的几何图形。

通过纹理创建物理体

SpriteKit 现在支持通过纹理派生子画面的物理体。 这样可以轻松实现效果更自然的碰撞。

例如,请注意在下面的碰撞中,香蕉和猴子在每个图像的表面几乎都要发生碰撞:

The banana and monkey collide nearly at the surface of each image

SpriteKit 使用一行代码即可创建一个这样的物理体。 只需使用纹理和大小调用 SKPhysicsBody.Create:sprite.PhysicsBody = SKPhysicsBody.Create (sprite.Texture, sprite.Size);

Alpha 阈值

除了直接将 PhysicsBody 属性设置为派生自纹理的几何之外,应用程序还可以设置 alpha 阈值来控制几何的派生方式。

alpha 阈值定义像素必须包含在生成的物理体中的最小 alpha 值。 例如,以下代码会生成一个略有不同的物理体:

sprite.PhysicsBody = SKPhysicsBody.Create (sprite.Texture, 0.7f, sprite.Size);

像这样调整 alpha 阈值的效果会微调之前的碰撞,这样猴子在与香蕉碰撞时就会摔倒:

The monkey falls over when colliding with the banana

物理场

SpriteKit 的另一个很好的补充是支持新的物理场。 该功能可用于添加漩涡场、径向重力场和弹簧场等。

物理场是使用 SKFieldNode 类创建的,该类添加到场景中的方式与任何其他 SKNode 一样。 SKFieldNode 上有各种工厂方法来创建不同的物理场。 可以通过调用 SKFieldNode.CreateSpringField() 来创建弹簧场,通过调用 SKFieldNode.CreateRadialGravityField() 来创建径向重力场,等等。

SKFieldNode 还具有用于控制场特性的属性,如场强、场区和场力的衰减。

弹簧场

例如,以下代码创建了一个弹簧场并将其添加到场景中:

SKFieldNode fieldNode = SKFieldNode.CreateSpringField ();
fieldNode.Enabled = true;
fieldNode.Position = new PointF (Size.Width / 2, Size.Height / 2);
fieldNode.Strength = 0.5f;
fieldNode.Region = new SKRegion(Frame.Size);
AddChild (fieldNode);

然后,可以添加子画面并设置其 PhysicsBody 属性,以便物理场会作用于子画面。例如,下面的代码将在用户触摸屏幕时发挥作用:

public override void TouchesBegan (NSSet touches, UIEvent evt)
{
    var touch = touches.AnyObject as UITouch;
    var pt = touch.LocationInNode (this);
    var node = SKSpriteNode.FromImageNamed ("TinyBanana");
    node.PhysicsBody = SKPhysicsBody.Create (node.Texture, node.Size);
    node.PhysicsBody.AffectedByGravity = false;
    node.PhysicsBody.AllowsRotation = true;
    node.PhysicsBody.Mass = 0.03f;
    node.Position = pt;
    AddChild (node);
}

这使得香蕉像弹簧一样在场节点周围振荡:

The bananas oscillate like a spring around the field node

径向重力场

添加其他场的操作与此类似。 例如,以下代码创建了径向重力场:

SKFieldNode fieldNode = SKFieldNode.CreateRadialGravityField ();
fieldNode.Enabled = true;
fieldNode.Position = new PointF (Size.Width / 2, Size.Height / 2);
fieldNode.Strength = 10.0f;
fieldNode.Falloff = 1.0f;

这会导致不同的力场,其中香蕉在场周围呈放射状拉伸:

The bananas are pulled radially around the field