Xamarin.iOS 中的 SpriteKit
SpriteKit 是 Apple 的 2D 图形框架,在 iOS 8 和 OS X Yosemite 中具有一些有趣的新功能。 其中包括与 SceneKit 的集成、着色器支持、照明、阴影、约束、法线贴图生成和物理增强。 具体而言,新的物理功能使向游戏添加逼真效果变得非常容易。
物理体
SpriteKit 包含 2D 刚体物理 API。 每个子画面都有一个关联的物理体 (SKPhysicsBody
) 来定义物理属性,如质量与摩擦,以及物理世界中物理体的几何图形。
通过纹理创建物理体
SpriteKit 现在支持通过纹理派生子画面的物理体。 这样可以轻松实现效果更自然的碰撞。
例如,请注意在下面的碰撞中,香蕉和猴子在每个图像的表面几乎都要发生碰撞:
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 阈值的效果会微调之前的碰撞,这样猴子在与香蕉碰撞时就会摔倒:
物理场
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);
}
这使得香蕉像弹簧一样在场节点周围振荡:
径向重力场
添加其他场的操作与此类似。 例如,以下代码创建了径向重力场:
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;
这会导致不同的力场,其中香蕉在场周围呈放射状拉伸: