【问题标题】:SpriteKit make two force on a body with jointSpriteKit 在有关节的身体上产生两个力
【发布时间】:2014-12-19 08:17:21
【问题描述】:

问题:我希望气球在空中升起。它们可以相互碰撞,也可以旋转。垂直方向的重力效果很好。

但现在我想将一个篮子连接到每个气球。这样做会导致篮子像气球一样“飞”起来。但在现实生活中,篮子应该比气球“重”,所以它总是向下指向地球。

我将如何实现这一目标?

【问题讨论】:

    标签: objective-c swift sprite-kit skphysicsbody


    【解决方案1】:

    模拟带有篮子的气球的一种方法是将重力设置为向下方向,以将篮子拉向场景底部并向气球施加浮力以产生升力。以下是如何做到这一点的示例:

    定义常量

    #define kRandMax        0x7fffffff
    #define kNumBalloons    5
    

    制作气球和篮子

    self.physicsWorld.gravity = CGVectorMake(0, -3);
    
    for (int i=0;i<kNumBalloons;i++) {
    
        // Create a balloon near the bottom of the scene with a random x position
        SKShapeNode *balloon = [SKShapeNode shapeNodeWithCircleOfRadius:16];
        balloon.fillColor = [SKColor redColor];
                balloon.name = @"balloon";
        balloon.physicsBody.allowsRotation = NO;
        CGFloat rand1 = arc4random_uniform(kRandMax) / (double)kRandMax;
        // A value in (-view.frame.size.width/2, view.frame.size.width/2)
        CGFloat xOffset = (rand1 - 0.5) *  view.frame.size.width / 2;
        balloon.position = CGPointMake (CGRectGetMidX(view.frame)+xOffset,
                                        CGRectGetMinY(view.frame)+50);
        balloon.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:16];
        [self addChild:balloon];
    
        // Create the basket        
        SKSpriteNode *basket = [SKSpriteNode spriteNodeWithColor:[SKColor brownColor] size:CGSizeMake(8, 8)];
        basket.position = CGPointMake(balloon.position.x, balloon.position.y-24);
        basket.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:basket.size.width/2];
        [self addChild:basket];
    
        // Connect the balloon and basket with an SKPhysicsJointPin
        SKPhysicsJointPin *joint = [SKPhysicsJointPin jointWithBodyA:balloon.physicsBody
                                    bodyB:basket.physicsBody anchor:balloon.position];
        [self.physicsWorld addJoint:joint];
    }
    

    在更新方法中,对每个气球施加一个力以创建升力

    -(void)update:(CFTimeInterval)currentTime {
        // Apply buoyant force to all balloons in the scene
        [self enumerateChildNodesWithName:@"//balloon" usingBlock:^(SKNode *node, BOOL *stop){
            // Adjust force as needed
            [node.physicsBody applyForce:CGVectorMake(0, 17.2)];
        }];
    }
    

    【讨论】:

      【解决方案2】:

      查看SKPhysicsBody 文档(可以找到here)。

      查看Defining a Body’s Physical Properties 部分。
      每个物理体都有您想要使用的属性(例如质量),以获得更“真实”的行为。

      如果您想要一个不太笼统的答案,
      发布一些代码示例。

      祝你好运。

      【讨论】:

        【解决方案3】:

        我现在有这样的解决方案:

        我创建了一个向上的力场

        func createForceField(strength:Float) {
            // add force field
            for i in 1...9 {
                let field = SKFieldNode.electricField()
                field.physicsBody?.categoryBitMask = PhysikcsCategory.ForceField
                field.position = CGPointMake(frame.size.width*0.1*CGFloat(i), -1000)
                field.strength = strength
                addChild(field)
            }
        }
        

        在开始游戏之前我打开重力和力场

        override init(size: CGSize) {
        
            super.init(size: size)
        
            // Set-Up forcefield
            createForceField(0.1)
            self.physicsWorld.gravity = CGVectorMake(0, -0.09)
        
            startGame()
        
        }
        

        这里我用绳子和标签创建气球,气球被充电所以它会对力场做出反应

        func createBalloon(vokabel:Vokabel) {

            let x = self.frame.width*0.2
            let y = self.frame.height*0.2
        
            // Balloon
            var balloon = BalloonNode()
            balloon.size =  CGSizeMake(balloon.size.width*0.7, balloon.size.height*0.7)
            balloon.position = CGPointMake(x-6,y)
            balloon.name = "SPRITE"
            balloon.vokabel = vokabel
            balloon.score = 50
            balloonLayer.addChild(balloon)
        
            // Special Start
            var specialStar = SKSpriteNode(imageNamed: "Star")
            specialStar.size =  CGSizeMake(balloon.size.width*0.7, balloon.size.height*0.7)
            specialStar.hidden = true
            specialStar.name = "STAR"  
            balloon.addChild(specialStar)
        
        
            // Rope
            let rope = SKSpriteNode(color: UIColor.blackColor(), size: CGSize(width: 2, height: 15))
            rope.position = CGPointMake(x, y-balloon.size.height/2-rope.size.height/2)
            rope.alpha = 0.2
            balloonLayer.addChild(rope)
        
            // Tag
            var labelText = getLabelText(vokabel)
            let tag = createTagWithText(labelText)
            tag.position = CGPointMake(x, y-balloon.size.height/2-rope.size.height)
            balloonLayer.addChild(tag)
        
            self.physicsWorld.gravity=CGVectorMake(0.0, -0.3)
        
            // physical bodies
        
            balloon.physicsBody = SKPhysicsBody(rectangleOfSize: balloon.size)  
            rope.physicsBody = SKPhysicsBody(rectangleOfSize: rope.size)
            tag.physicsBody = SKPhysicsBody(rectangleOfSize: tag.size)
        
            // physical forces
            balloon.physicsBody?.allowsRotation = false
            balloon.physicsBody?.charge = 0.5
            tag.physicsBody?.allowsRotation = false
            tag.physicsBody?.linearDamping = 1.0
            rope.physicsBody?.linearDamping = 1.0
        
            // anchor Points
            let anchorBalloonRope = CGPointMake(x, y-balloon.size.height/2)
            let anchorRopeTag = CGPointMake(x, y-balloon.size.height/2-rope.size.height)
        
            // create joints
            let joint = SKPhysicsJointPin.jointWithBodyA(balloon.physicsBody, bodyB: rope.physicsBody, anchor: anchorBalloonRope)
            let joint_rope_tag = SKPhysicsJointPin.jointWithBodyA(rope.physicsBody, bodyB: tag.physicsBody, anchor: anchorRopeTag)
        
            // add joints to physic
            self.physicsWorld.addJoint(joint)
            self.physicsWorld.addJoint(joint_rope_tag)
        
            // give it a horizontal push
            balloon.physicsBody?.applyImpulse(CGVectorMake(10.0, 0.0))
        
        
        
            // BalloonNode ( is just a layer, has no special position so it is the same coordinate system as the gamelayer)
            let node = BalloonNode()
            node.vokabel = vokabel
            node.score = SCORE_STANDARD
            node.name = "BALLOON"
            node.rope = rope
            node.tag = tag
        
        
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-04-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-03-26
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多