我正在使用Sprite Kit编写一个基于物理的游戏。我能够处理主角和电源之间的联系。从屏幕上移除加电,我的模型更新并播放声音,正如预期的那样。但是,角色在接通电源时会改变方向。这是不希望的。我想让角色在通电时通过,并且不会因为碰撞而改变它。以下是我的一些代码,如果您需要更多帮助,请告诉我。
所有这些都是用C#中的Xamarin.iOS编写的。但是代码几乎与它的Objective-C计数器部分完全相同。如果我需要进一步解释,请告诉我。并提前感谢您的帮助!
编辑:此外,这是参考我在这个问题中讨论的游戏:
Sprite Kit - Create arch path for SKSpriteNode given a swipe gesture
**代码! **
我的碰撞位枚举:
public enum COLLISION_BITS : uint
{
Character = 1 << 0,
Background = 1 << 1,
Ground = 1 << 2,
BadGuy = 1 << 3,
PowerUp = 1 << 4,
Fan = 1 << 5
}
我的角色对象设置:
public Character (SizeF size, PointF position) : base("character")
{
this.Name = CHARACTER_NAME;
this.Size = size;
this.Position = position;
this.PhysicsBody = SKPhysicsBody.BodyWithRectangleOfSize (this.Size);
this.PhysicsBody.Dynamic = true;
this.PhysicsBody.AffectedByGravity = true;
this.PhysicsBody.AllowsRotation = false;
this.PhysicsBody.Mass = 1.0f;
this.PhysicsBody.SetCategoryBitMask (COLLISION_BITS.Character);
this.PhysicsBody.SetContactTestBitMask (COLLISION_BITS.Ground);
this.PhysicsBody.SetContactTestBitMask (COLLISION_BITS.BadGuy, false);
this.PhysicsBody.SetContactTestBitMask (COLLISION_BITS.PowerUp, false);
this.PhysicsBody.SetContactTestBitMask (COLLISION_BITS.Fan, false);
}
我的PowerUp对象设置:
private void SetupPowerUp(SizeF size, PointF position)
{
this.Size = size;
this.Position = position;
this.PhysicsBody = SKPhysicsBody.BodyWithRectangleOfSize (this.Size);
this.PhysicsBody.Dynamic = false;
this.PhysicsBody.AffectedByGravity = false;
this.PhysicsBody.AllowsRotation = false;
this.PhysicsBody.Mass = 0f;
this.PhysicsBody.SetCategoryBitMask (COLLISION_BITS.PowerUp);
}
我将位处理放在的扩展方法:
public static void SetContactTestBitMask(this SKPhysicsBody body, COLLISION_BITS bits, bool overwrite = true)
{
if (body == null) return;
if (overwrite) {
body.ContactTestBitMask = (uint)bits;
} else {
body.ContactTestBitMask |= (uint)bits;
}
}
public static void SetCategoryBitMask(this SKPhysicsBody body, COLLISION_BITS bits, bool overwrite = true)
{
if (body == null) return;
if (overwrite) {
body.CategoryBitMask = (uint)bits;
} else {
body.CategoryBitMask |= (uint)bits;
}
}
public static bool IsOfCategory(this SKPhysicsBody body, COLLISION_BITS bits, bool matchAll = false)
{
if (body == null) return false;
if (matchAll) {
return (body.CategoryBitMask & (uint)bits) == (uint)bits;
} else {
return (body.CategoryBitMask & (uint)bits) > 0;
}
}
最后,我的DidBeginContact方法:
public void HandleDidBeginContact(object sender, EventArgs args)
{
var contact = (SKPhysicsContact)sender;
SKPhysicsBody firstBody, secondBody;
if (contact.BodyA.CategoryBitMask < contact.BodyB.CategoryBitMask) {
firstBody = contact.BodyA;
secondBody = contact.BodyB;
} else {
firstBody = contact.BodyB;
secondBody = contact.BodyA;
}
// collected power up
if (firstBody.IsOfCategory(COLLISION_BITS. Character) && secondBody.IsOfCategory(COLLISION_BITS.PowerUp)) {
secondBody.Node.RemoveFromParent ();
GameModel.GatheredPowerUp ();
PowerUpCollisionSoundPlayer.Play ();
}
// other collision stuff for the other objects in the screen...
// ...
}
答案 0 :(得分:2)
您正在设置类别并联系回调位掩码,但您似乎没有设置collisionBitMask
- 它保持默认值,因此您的角色设置为与任何东西发生碰撞并改变方向联系。
尝试明确设置玩家的碰撞位掩码(可能是Xamarin中的this.PhysicsBody.setCollisionBitMask
?),说明此玩家应该与之进行物理碰撞的所有类别,并省略它应该通过的类别(PowerUp)。
答案 1 :(得分:1)
SKPhysicsBody
有 3个属性。
categoryBitMask
property
collisionBitMask
属性
contactTestBitMask
属性
在您的情况下,您需要逻辑碰撞 而不是物理碰撞。
因此,与您一样,您需要设置contactTestBitMask
,但您还需要将collisionBitMask
设置为对象的categoryBitMask
,并将SKPhysicsBody
设置为动态({{ 1}}但它是默认值,所以你可以忽略它。)
我给你写了简单的构造代码(它更容易理解),但你可以将它改编为你的结构(使用内部/外部方法)。
碰撞位枚举:
this.PhysicsBody.Dynamic = true;
角色对象设置:
public enum COLLISION_BITS : uint
{
Character = 1 << 0,
Background = 1 << 1,
Ground = 1 << 2,
BadGuy = 1 << 3,
PowerUp = 1 << 4,
Fan = 1 << 5
}
PowerUp对象设置:
public Character (SizeF size, PointF position) : base("character")
{
this.Name = CHARACTER_NAME;
this.Size = size;
this.Position = position;
this.PhysicsBody = SKPhysicsBody.BodyWithRectangleOfSize (this.Size);
this.PhysicsBody.AffectedByGravity = true;
this.PhysicsBody.AllowsRotation = false;
this.PhysicsBody.Mass = 1.0f;
this.PhysicsBody.CategoryBitMask = COLLISION_BITS.Character;
this.PhysicsBody.CollisionBitMask = COLLISION_BITS.Character;
this.PhysicsBody.ContactTestBitMask = COLLISION_BITS.PowerUp;
}