gra*_*pe1 5 physics sprite-kit swift
我有一个移动平台,但当节点在平台上方时,它不会随平台水平移动
在本文中,解释了问题:移动平台地狱
http://www.learn-cocos2d.com/2013/08/physics-engine-platformer-terrible-idea/
在评论中有Box2D的解决方案:运动体
但是SpriteKit怎么样?
更新
我正在使用平台
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])));
Run Code Online (Sandbox Code Playgroud)
我个人反对使用物理学来移动平台,因为移动平台物理主体必须是动态的.
静态平台
对于静态平台,将物理体dynamic属性设置为false是完美的解决方案.这就是它的意义.静态物体不受力的影响,但仍然会给你一个碰撞响应.所以,问题就解决了.
但是你无法通过使用力来改变静态物理体的位置.您可以使用操作或手动设置其位置来执行此操作.但是,那么你正在从物理模拟中移除一个平台.
为了完成所有物理学,你必须保持平台的动态.但这可能导致其他问题.例如,当玩家登陆平台时,他会将平台向下推,因为玩家有一个质量.即使平台质量很大,它也会随着时间的流逝而下降.请记住,我们不能手动更新平台x位置,因为这可能会使物理模拟变得混乱.
学习LearnCocos2d的好文章中所说的"移动平台地狱" 可能是使用物理学完成此任务时可能发生的最佳描述:-)
移动平台示例
为了向您展示一些可能性,我做了一个简单的例子,说明如何通过对其施加力来移动平台,并使角色留在它上面.为了使其工作,我做了很少的事情:
改变了大量的平台.当玩家从下面碰到平台时,这将阻止平台移动.
制作一个基于边缘的物理机构,以防止玩家落地时平台掉落.
使用诸如允许旋转和摩擦等属性来获得所需效果.
这是代码:
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))
}
}
}
Run Code Online (Sandbox Code Playgroud)
结果如下:
| 归档时间: |
|
| 查看次数: |
1146 次 |
| 最近记录: |