边界效应
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<UITouch>, 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 针连接 允许两个主体独立的绕锚点旋转,就像钉在一起那样.
抽象图
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<UITouch>, 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
}
}
连接
物体间连接.gif
参考博文 :
[SpriteKit] 通过检测掩码进行物理识别