首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SpriteKit对具有关节的实体施加两个力

问SpriteKit对具有关节的实体施加两个力
EN

Stack Overflow用户
提问于 2014-12-19 16:17:22
回答 3查看 242关注 0票数 0

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

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

我该如何做到这一点?

EN

回答 3

Stack Overflow用户

发布于 2014-12-20 06:18:30

使用篮子模拟气球的一种方法是将重力设置为向下方向,以将篮子拉向场景的底部,并对气球应用浮力以创建升力。下面是一个如何做到这一点的示例:

定义常量

代码语言:javascript
复制
#define kRandMax        0x7fffffff
#define kNumBalloons    5

创建气球和篮子

代码语言:javascript
复制
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];
}

在update方法中,对每个气球应用一个力以创建升力。

代码语言:javascript
复制
-(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)];
    }];
}
票数 1
EN

Stack Overflow用户

发布于 2014-12-19 16:56:05

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

查看Defining a Body’s Physical Properties部分。

每个物理体都有你想要的属性(比如质量),以便获得更“真实”的行为。

如果你想要一个不太通用的答案,

发布一些代码示例。

祝你好运,伙计。

票数 0
EN

Stack Overflow用户

发布于 2014-12-23 13:34:33

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

我创建了一个向上的力场

代码语言:javascript
复制
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)
    }
}

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

代码语言:javascript
复制
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) {

代码语言:javascript
复制
    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


}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27562083

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档