SpriteKit(10) - 物理引擎

边界效应

import SpriteKit
import GameplayKit

class GameScene: SKScene {
    override func didMove(to view: SKView) {
        self.size = UIScreen.main.bounds.size
        self.physicsBody = SKPhysicsBody(edgeLoopFrom: self.frame)
        addStaticShapeNode()
       
    }
    
    override func touchesBegan(_ touches: Set, with event: UIEvent?) {
        for touch in touches {
            let node = SKSpriteNode()
            node.position = touch.location(in: self)
            node.size = CGSize(width: 40, height: 40)
            node.color = UIColor.randomColor
            node.physicsBody = SKPhysicsBody(rectangleOf: node.frame.size)
            self.addChild(node)
        }
    }
    
    //创建一个不规则的静态物体
    func addStaticShapeNode() {
        let shapeNode = SKShapeNode()
        shapeNode.position = CGPoint.zero
        let path = CGMutablePath()
        let point_1 = CGPoint(x: self.frame.midX - 59, y: 0)
        let point_2 = CGPoint(x: point_1.x + 59, y: point_1.y + 59)
        let point_3 = CGPoint(x: point_1.x + 100, y: point_1.y )
        let point_4 = CGPoint(x: point_1.x + 59, y: point_1.y - 59)
        let point_5 = point_1
        path.move(to: point_1)
        path.addLine(to: point_2)
        path.addLine(to: point_3)
        path.addLine(to: point_4)
        path.addLine(to: point_5)
        shapeNode.path = path
        shapeNode.strokeColor = UIColor.white       //填充颜色
        shapeNode.fillColor = UIColor.red           //线颜色
        shapeNode.lineWidth = 1                     //线宽
        shapeNode.glowWidth = 4                     //光晕
        shapeNode.lineJoin = .round                 //线连接方式
        shapeNode.physicsBody = SKPhysicsBody(polygonFrom: path)//设置物理引擎
        shapeNode.physicsBody?.isDynamic = false  //设置为静态物体
        self.addChild(shapeNode)
    }
    
}

extension UIColor {
    //返回随机颜色
    class var randomColor:UIColor{
        get{
            let red = CGFloat(arc4random()%256)/255.0
            let green = CGFloat(arc4random()%256)/255.0
            let blue = CGFloat(arc4random()%256)/255.0
            return UIColor(red: red, green: green, blue: blue, alpha: 1.0)
        }
    }
}
物理引擎

理解

  • 物体有三种 : 动态的(往下落的小方块),静态的(中间不规则图形),边(底部地板)
  • 每个节点都有对应的物理引擎. SKPhysicsBody.也就是每一个节点都需要对它进行设定.(从代码中简单体会就好了.),各种各样的设置可以直接看SKPhysicsBody有什么可以设置的属性.比较容易理解.

物体间连接

//物体连接 :
//SKPHysicsJointFix           固定连接  在某个参考点混合两个主体在一起.固定联合用于创建以后可以打散的复杂形状
//SKPHysicsJointSliding       滑动连接  允许两个主体的锚点眼选定的滑动轴
//SKPHysicsJointSpring        弹簧连接  就像弹簧那样,它的长度是两个主体之间的初始距离
//SKPHysicsJointLimit         限制连接  限定了两个主体之间的最大距离,就像他们用绳子连接那样
//SKPHysicsJointPin           针连接    允许两个主体独立的绕锚点旋转,就像钉在一起那样.
SpriteKit(10) - 物理引擎_第1张图片
抽象图
import SpriteKit
class GameMix: SKScene {
 
    override func didMove(to view: SKView) {
        self.size = UIScreen.main.bounds.size
        self.physicsBody = SKPhysicsBody(edgeLoopFrom: self.frame)
        setupContext()
    }
    
    //设置场景内容
    func setupContext() {
        //创建一个地板
        let ground = SKSpriteNode()
        ground.size = CGSize(width: self.frame.width, height: 10)
        ground.color = UIColor.red
        ground.position = CGPoint(x: self.frame.midX, y: 30)
        ground.physicsBody = SKPhysicsBody(rectangleOf: ground.size)
        ground.physicsBody!.isDynamic = false
        self.addChild(ground)
        print(ground.frame)
        
        //创建中心圆节点
        let centerNode = SKShapeNode()
        centerNode.path = UIBezierPath(ovalIn: CGRect(x: -10, y: -10, width: 20, height: 20)).cgPath
        centerNode.position = CGPoint(x: self.frame.midX, y: self.frame.midY)
        centerNode.physicsBody = SKPhysicsBody(circleOfRadius: 10)
        centerNode.fillColor = UIColor.red
        centerNode.name = "center"
        self.addChild(centerNode)
        
        let angle = CGFloat.pi/10.0
        var first : SKNode?
        var previous : SKNode?
        
        for i in 0...20 {
            //计算外围圆球的x,y
            let a = Double(angle) * Double(i)
            let x = 100 * cos(a) + Double(centerNode.position.x)
            let y = 100 * sin(a) + Double(centerNode.position.y)
            
            let n = SKShapeNode()
            n.path = UIBezierPath(ovalIn: CGRect(x: -10, y: -10, width: 20, height: 20)).cgPath
            n.position = CGPoint(x: x, y: y)
            n.physicsBody = SKPhysicsBody(circleOfRadius: 10)
            n.physicsBody?.friction = 1.0
            n.physicsBody?.restitution = 1.0
            self.addChild(n)
            
            //弹簧 : 与中心圆连接
            let joint = SKPhysicsJointSpring.joint(withBodyA: centerNode.physicsBody!,
                                                   bodyB: n.physicsBody!,
                                                   anchorA: centerNode.position,
                                                   anchorB: n.position)
            joint.damping = 0.2
            joint.frequency = 10.0
            self.physicsWorld.add(joint)
            
            //限定外围两个球之间的距离
            if previous != nil {
                let limit = SKPhysicsJointLimit.joint(withBodyA: previous!.physicsBody!,
                                                      bodyB: n.physicsBody!,
                                                      anchorA: previous!.position,
                                                      anchorB: n.position)
                limit.maxLength = 30
                self.physicsWorld.add(limit)
            }else {
                first = n
            }
            previous = n
        }
        //给最后外围两个球之间限定距离
        let limit = SKPhysicsJointLimit.joint(withBodyA: previous!.physicsBody!,
                                              bodyB: first!.physicsBody!,
                                              anchorA: previous!.position,
                                              anchorB: first!.position)
        limit.maxLength = 30
        self.physicsWorld.add(limit)
    }
    
    
    
    
    override func touchesBegan(_ touches: Set, with event: UIEvent?) {
        let node = self.childNode(withName: "center")
        node?.physicsBody?.applyImpulse(CGVector(dx: 100, dy: 200))
        node?.physicsBody?.restitution = 1.0
        node?.physicsBody?.friction = 1.0

    }
}
SpriteKit(10) - 物理引擎_第2张图片
连接
物体间连接.gif

参考博文 :
[SpriteKit] 通过检测掩码进行物理识别

你可能感兴趣的:(SpriteKit(10) - 物理引擎)