在移动平台之上的移动节点 [英] Moving Node on top of a moving platform

查看:92
本文介绍了在移动平台之上的移动节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个移动的平台,但是当节点在平台上方时,它不会随平台水平移动

I have a moving platform, but when the node is above the platform it doesnt move with the platform horizontally

在本文中,对问题进行了解释:移动平台地狱

In this article, the problem is explained: Moving Platform Hell

http://www.learn-cocos2d .com/2013/08/physics-engine-platformer-terrible-idea/

在评论中,有针对Box2D的解决方案:运动身体

And in comment there is solutions for Box2D: Kinematic body

但是SpriteKit呢?

But what about 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])));

推荐答案

我个人反对在移动平台上使用物理,因为移动平台物理主体必须是动态的.

Personally I am against of using physics for moving platforms because moving platform physics body has to be dynamic.

静态平台

对于静态平台,将物理实体dynamic属性设置为false是完美的解决方案.这就是它的本意.静态物体不受力的影响,但仍会产生碰撞响应.这样,问题就解决了.

For static platforms setting physics body dynamic property to false is perfect solution. And this is how it is meant to be. Static bodies are not affected by forces but still give you a collision response. So, the problem is solved.

但是您不能通过使用力来改变静态物理物体的位置.您可以通过使用操作或手动设置其位置来执行此操作.但是,那么您将要从物理模拟中删除一个平台.

But you can't change position of static physics bodies by using forces. You can do this by using actions or manually setting its position. But, then you are removing a platform out of physics simulation.

为了处理所有物理问题,您必须保持平台动态.但这可能导致其他问题.例如,当玩家降落在平台上时,他会向下推平台,因为玩家有重物. 即使平台的质量很大,它也会随着时间的流逝而下降.请记住,我们不能只手动更新平台x位置,因为这可能会干扰物理模拟.

In order to do all with physics, you have to keep the platform dynamic. But this can lead in other problems. For example when player lands on platform, he will push the platform down, because player has a mass. Even if platform has big mass it will go down as time passing. Remember, we cant just update platforms x position manually, because this can make a mess with physics simulation.

移动平台地狱",如该文章的文章所述LearnCocos2d可能是最好的描述,当使用物理学完成这项任务时会发生什么:-)

"Moving platform hell" as stated in that nice article of LearnCocos2d is probably the best description what can happen when using physics for this task :-)

移动平台示例

为向您展示一些可能性,我举了一个简单的示例,说明如何在施加力的情况下移动平台并使角色保持在平台上.工作:

To show you some possibilities I made an simple example on how you can move a platform with applying a force to it, and make a character to stay on it.There are few things I've done in order to make this to work:

  • 更改了大量平台.当玩家从下方撞击平台时,这将防止平台移动.

  • Changed a mass of platform. This will prevent platform from moving when player bumps in it from below.

制作一个基于边缘的物理物体,以防止玩家落在平台上时平台掉落.

Made an edge based physics body to prevent platform falling when player lands on it.

发挥了诸如允许旋转和摩擦之类的特性.

Played with properties like allows rotation and friction to get desired effect.

这是代码:

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))
        }
    }

}

这是结果:

这篇关于在移动平台之上的移动节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆