Swift 如何使精灵在对象内反弹?

Swift 如何使精灵在对象内反弹?,swift,sprite-kit,Swift,Sprite Kit,我试着让球在一个圆内反弹,这样它就不能跳出圆的圆周。现在球在自我框架中反弹。如何使球在圆圈内反弹 let sceneBody = SKPhysicsBody(edgeLoopFromRect: self.frame) sceneBody.friction = 0 self.physicsBody = sceneBody var ball = SKShapeNode(circleOfRadius: 9) ball.fillColor = SKColor.white

我试着让球在一个圆内反弹,这样它就不能跳出圆的圆周。现在球在自我框架中反弹。如何使球在圆圈内反弹

let sceneBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
    sceneBody.friction = 0
    self.physicsBody = sceneBody

    var ball = SKShapeNode(circleOfRadius: 9)
    ball.fillColor = SKColor.whiteColor()
    ball.position = view.center
    ball.physicsBody = SKPhysicsBody(circleOfRadius: 9)
    ball.physicsBody?.affectedByGravity = true
    ball.physicsBody?.restitution = 1
    ball.physicsBody?.linearDamping = 0
    ball.zPosition = 3
    self.addChild(ball)

    circulo = SKSpriteNode(imageNamed: "circuloFondo2")
    //Circle that I want the ball bounce within
    circulo.size = CGSize(width:view.frame.size.width - padding , height: view.frame.size.width - padding)
    circulo.color = UIColor(red: 0.15, green: 0.15, blue: 0.15, alpha: 1)
    circulo.colorBlendFactor = 1
    circulo.alpha = 0.35
    circulo.position = view.center
    self.addChild(circulo)
    circulo.zPosition = 1

我准备了一个简单的测试项目来解释如何做:

import UIKit
import SpriteKit

class GameScene: SKScene, SKPhysicsContactDelegate {

    enum CollisionTypes: UInt32 {
        case Circle = 1
        case Ball = 2
        //case Enemy1 = 4
        //case Enemy2 = 8
        //case Enemy3 = 16
        //case EnemyBoss = 32
    }

    var circulo: SKSpriteNode!
    var padding: CGFloat = 40.0
    var center: CGPoint!

    override func didMoveToView(view: SKView) {

        self.physicsWorld.gravity = CGVectorMake(0, -6)
        self.physicsWorld.contactDelegate = self
        self.center = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMidY(self.frame))

        // Prepare circle
        circulo = SKSpriteNode(imageNamed: "circuloFondo2.png")
        //Circle that I want the ball bounce within
        circulo.size = CGSize(width:view.frame.size.width - padding , height: view.frame.size.width - padding)
        let circlePath = UIBezierPath(arcCenter: self.center, radius: (view.frame.size.width - padding*2)/2, startAngle: CGFloat(0), endAngle:CGFloat(M_PI * 2), clockwise: true)
        circulo.color = UIColor(red: 0.15, green: 0.15, blue: 0.15, alpha: 1)
        circulo.colorBlendFactor = 1
        circulo.alpha = 1
        circulo.position = self.center
        circulo.zPosition = 1

        // Set physics
        let circuloBody = SKPhysicsBody.init(edgeLoopFromPath: circlePath.CGPath)
        self.physicsBody = circuloBody
        self.physicsBody!.affectedByGravity = false
        self.physicsBody!.usesPreciseCollisionDetection = true
        self.physicsBody!.dynamic = true
        self.physicsBody!.mass = 0
        self.physicsBody!.friction = 0
        self.physicsBody!.linearDamping = 0
        self.physicsBody!.angularDamping = 0
        self.physicsBody!.restitution = 1
        self.physicsBody!.categoryBitMask = CollisionTypes.Circle.rawValue
        self.physicsBody!.contactTestBitMask = CollisionTypes.Ball.rawValue
        //self.circulo.physicsBody!.collisionBitMask = 0

        self.addChild(circulo)


        //Prepare ball
        let ball = SKShapeNode(circleOfRadius: 9)
        ball.fillColor = SKColor.whiteColor()
        ball.position = self.center
        ball.zPosition = 1

        // Set physics
        ball.physicsBody = SKPhysicsBody(circleOfRadius: 9)
        ball.physicsBody!.affectedByGravity = true
        ball.physicsBody!.restitution = 0.8
        ball.physicsBody!.linearDamping = 0
        ball.physicsBody!.friction = 0.3
        ball.physicsBody?.dynamic = true
        ball.physicsBody!.mass = 0.5
        ball.physicsBody!.allowsRotation = true
        ball.physicsBody!.categoryBitMask = CollisionTypes.Ball.rawValue
        ball.physicsBody!.contactTestBitMask = CollisionTypes.Circle.rawValue
        //ball.physicsBody!.collisionBitMask = 0

        self.addChild(ball)

    }

    func didBeginContact(contact: SKPhysicsContact) {
        // elements
        if (contact.bodyA.categoryBitMask == CollisionTypes.Circle.rawValue &&
            contact.bodyB.categoryBitMask == CollisionTypes.Ball.rawValue) {
            print("contact between circle and ball")
        }
    }
circuloFondo2图像:

项目演示


在这个答案中,你可以看到所有的代码,但是如果你愿意,你可以下载这个项目

非常感谢Alessandro,就像往常一样,但是如果我想让这个球跳得更高,我的意思是,当它弹起时,球总是碰到它弹起的另一侧,我也会问你。球受到重力的作用,因此您可以仅关闭球的重力(InfectedByGravity=false),球将永远停止(就像在重力为0的宇宙飞船中)。要移动它,您可以应用冲量(让冲量=CGVectorMake(0.0150.0)ball.physicsBody!.applyImpulse(冲量)),您可以看到球在完全没有重力的情况下从一侧跳到另一侧。您可以通过更改ball physics参数来执行任何操作致命错误:在展开可选值时意外发现零它告诉我ball.physicsBody!中没有任何原因!。applyImpulse(冲动)谢谢alessandro!我们需要更多像你这样的人