Swift 移动平台顶部的移动节点
我有一个移动的平台,但当节点位于平台上方时,它不会随着平台水平移动 在本文中,问题被解释为:移动平台地狱 在注释中,有Box2D的解决方案:运动学体 但是SpriteKit呢 更新 我正在使用移动平台Swift 移动平台顶部的移动节点,swift,sprite-kit,physics,Swift,Sprite Kit,Physics,我有一个移动的平台,但当节点位于平台上方时,它不会随着平台水平移动 在本文中,问题被解释为:移动平台地狱 在注释中,有Box2D的解决方案:运动学体 但是SpriteKit呢 更新 我正在使用移动平台 let moveHPart1 = SKAction.moveByX(origW, y: 0, duration: moveDuration); let moveHPart2 = SKAction.moveByX(-origW, y: 0, duration: moveDuration); pl
let moveHPart1 = SKAction.moveByX(origW, y: 0, duration: moveDuration);
let moveHPart2 = SKAction.moveByX(-origW, y: 0, duration: moveDuration);
platform(SKAction.repeatActionForever(SKAction.sequence([moveHPart1, moveHPart2])));
就我个人而言,我反对将物理学用于移动平台,因为移动平台的物理体必须是动态的 静态平台 对于静态平台,将Physical body
dynamic
属性设置为false是完美的解决方案。这就是它的本意。静态实体不受力的影响,但仍会提供碰撞响应。这样,问题就解决了
但你们不能用力来改变静态物理体的位置。您可以通过使用操作或手动设置其位置来完成此操作。但是,然后你将从物理模拟中移除一个平台
为了完成所有的物理任务,你必须让平台保持动态。但这可能导致其他问题。例如,当玩家降落在平台上时,他会将平台向下推,因为玩家有一个质量。
即使平台的质量很大,它也会随着时间的推移而下降。记住,我们不能仅仅手动更新平台x位置,因为这会给物理模拟带来混乱
“移动平台地狱”如《学习的美好》中所述,可能是使用物理完成此任务时可能发生的最好描述:-)
移动平台示例
为了向您展示一些可能性,我举了一个简单的例子,说明如何通过对平台施加力来移动平台,并使角色停留在平台上。为了实现这一点,我做了一些事情:
- 改变了大量的平台。当玩家从下方撞击平台时,这将阻止平台移动
- 制作了一个基于边缘的物理体,以防止玩家在平台上着陆时平台坠落
- 使用诸如允许旋转和摩擦的特性来获得所需的效果
import SpriteKit
class GameScene: SKScene,SKPhysicsContactDelegate
{
let BodyCategory : UInt32 = 0x1 << 1
let PlatformCategory : UInt32 = 0x1 << 2
let WallCategory : UInt32 = 0x1 << 3
let EdgeCategory : UInt32 = 0x1 << 4 // This will prevent a platforom from falling down
let PlayerCategory : UInt32 = 0x1 << 5
let platformSpeed: CGFloat = 40.0
let body = SKShapeNode(circleOfRadius: 20.0)
let player = SKShapeNode(circleOfRadius: 20.0)
let platform = SKSpriteNode(color: SKColor.greenColor(), size: CGSize(width:100, height:20))
let notDynamicPlatform = SKSpriteNode(color: SKColor.greenColor(), size: CGSize(width:100, height:20))
override func didMoveToView(view: SKView)
{
//Setup contact delegate so we can use didBeginContact and didEndContact methods
physicsWorld.contactDelegate = self
//Setup borders
self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
self.physicsBody?.categoryBitMask = WallCategory
self.physicsBody?.collisionBitMask = BodyCategory | PlayerCategory
//Setup some physics body object
body.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
body.fillColor = SKColor.greenColor()
body.physicsBody = SKPhysicsBody(circleOfRadius: 20)
body.physicsBody?.categoryBitMask = BodyCategory
body.physicsBody?.contactTestBitMask = PlatformCategory
body.physicsBody?.collisionBitMask = PlatformCategory | WallCategory
body.physicsBody?.allowsRotation = false
body.physicsBody?.dynamic = true
self.addChild(body)
//Setup player
player.position = CGPoint(x: CGRectGetMidX(self.frame), y:30)
player.fillColor = SKColor.greenColor()
player.physicsBody = SKPhysicsBody(circleOfRadius: 20)
player.physicsBody?.categoryBitMask = PlayerCategory
player.physicsBody?.contactTestBitMask = PlatformCategory
player.physicsBody?.collisionBitMask = PlatformCategory | WallCategory | BodyCategory
player.physicsBody?.allowsRotation = false
player.physicsBody?.friction = 1
player.physicsBody?.dynamic = true
self.addChild(player)
//Setup platform
platform.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame) - 100)
platform.physicsBody = SKPhysicsBody(rectangleOfSize: platform.size)
platform.physicsBody?.categoryBitMask = PlatformCategory
platform.physicsBody?.contactTestBitMask = BodyCategory
platform.physicsBody?.collisionBitMask = BodyCategory | EdgeCategory | PlayerCategory
platform.physicsBody?.allowsRotation = false
platform.physicsBody?.affectedByGravity = false
platform.physicsBody?.dynamic = true
platform.physicsBody?.friction = 1.0
platform.physicsBody?.restitution = 0.0
platform.physicsBody?.mass = 20
//Setup edge
let edge = SKNode()
edge.physicsBody = SKPhysicsBody(edgeFromPoint: CGPoint(x: 0, y:-platform.size.height/2), toPoint: CGPoint(x: self.frame.size.width, y:-platform.size.height/2))
edge.position = CGPoint(x:0, y: CGRectGetMidY(self.frame) - 100)
edge.physicsBody?.categoryBitMask = EdgeCategory
edge.physicsBody?.collisionBitMask = PlatformCategory
self.addChild(edge)
self.addChild(platform)
}
override func update(currentTime: NSTimeInterval) {
if(platform.position.x <= platform.size.width/2.0 + 20.0 && platform.physicsBody?.velocity.dx < 0.0 ){
platform.physicsBody?.velocity = CGVectorMake(platformSpeed, 0.0)
}else if((platform.position.x >= self.frame.size.width - platform.size.width/2.0 - 20.0) && platform.physicsBody?.velocity.dx >= 0.0){
platform.physicsBody?.velocity = CGVectorMake(-platformSpeed, 0.0)
}else if(platform.physicsBody?.velocity.dx > 0.0){
platform.physicsBody?.velocity = CGVectorMake(platformSpeed, 0.0)
}else{
platform.physicsBody?.velocity = CGVectorMake(-platformSpeed, 0.0)
}
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
let touch: AnyObject? = touches.anyObject()
let location = touch?.locationInNode(self)
if(location?.x > 187.5){
player.physicsBody?.applyImpulse(CGVector(dx: 3, dy: 50))
}else{
player.physicsBody?.applyImpulse(CGVector(dx: -3, dy: 50))
}
}
}
导入SpriteKit
类游戏场景:SKScene,SKPhysicContactDelegate
{
让BodyCategory:UInt32=0x1@grape1首先,你应该用相关代码更新你的问题。如果你正在使用动作移动平台,那么你就是在物理模拟中将其拉出。因此,要将身体和平台一起移动,你应该对平台施力,并设置一些属性,如平台和平台的摩擦力身体…@Whirlwind我用的是SKAction.moveByX,但如何施加力向左和向后移动?不确定,但看看这是否有帮助是的,这是一个很好的解决方案,但由于平台使用SKAction移动,其速度为0。有什么想法如何移动到给定的x位置吗?@EpicByte您使用什么技术来保持移动平台的y位置不变(在某些碰撞之后)?我猜你们的平台是动态的,不受重力的影响,对吗?或者,我错了,你们使用的是带有静态物理体的平台,唯一改变的是当检测到成功降落在平台上时玩家的速度?有趣的解决方案,干得好!但是,如果平台垂直移动,在spritekit关于平台游戏的课程当平台向下移动,英雄在上面时,有很小的弹跳性…而且课程非常昂贵!我使用SKPhysicsJointFixed.jointWithBodyA让英雄粘在平台上,但我不知道删除该关节,当英雄向右或向左移动时,如果你想尝试,请将其放在di中dBeginContact:let contactPoint:CGPoint=contact.contactPoint let joint=SKPhysicsJointFixed.jointWithBodyA(contact.bodyA,bodyB:contact.bodyB,anchor:CGPointMake(contactPoint.x,contactPoint.y))self.physicsWorld.addJoint(joint),如果您知道以后点击时如何删除(将英雄向右移动)让我知道我认为您在发布的代码中缺少了contactDelegate方法。@我没有缺少它们,因为我在本例中没有使用它们;-)(它们不仅仅用于碰撞模拟)@Whirlwind噢,糟糕,我看到你的场景符合SKPhysicContactDelegate,所以我想也许你有一些代码忘了包括在内。