Swift Sprite 套件相机运动
Swift Sprite Kit Camera Movement
我在 Sprite Kit 中制作了一个专注于 SKSpriteNode 的相机。
Apple 有一个很棒的文档:Apple Document
但是,现在的camera是直接跟随SKSpriteNode的,而我想留一点余地。
例如触摸后SKSpriteNode上下移动,相机从原点开始缓慢跟随SKSpriteNode,最大距离Height为SKSpriteNode是半屏,当SKSpriteNode静止时,相机和SKSpriteNode移动回到原点。
另外 节点的 PhysicBody 行为异常,远离其实际图像。我该如何解决?
这是我的代码:
class GameScene: SKScene, SKPhysicsContactDelegate {
var Player: SKSpriteNode!
var Platform0: SKSpriteNode!
var Platform1: SKSpriteNode!
var Platform2: SKSpriteNode!
var Platform3: SKSpriteNode!
var Platform4: SKSpriteNode!
var Platform5: SKSpriteNode!
var World: SKNode!
var Camera: SKNode!
override func didMoveToView(view: SKView) {
/* Setup your scene here */
self.physicsWorld.contactDelegate = self
self.anchorPoint = CGPoint(x: 0.5, y: 0.1)
self.World = SKNode()
self.World.name = "World"
addChild(self.World)
self.Camera = SKNode()
self.Camera.name = "Camera"
self.World.addChild(self.Camera)
SpawnPlatforms()
SpawnPlayer()
}
func SpawnPlatforms() {
Platform0 = SKSpriteNode (color: SKColor.greenColor(), size: CGSize(width: self.frame.size.width , height: 25))
Platform0.position = CGPoint(x: self.frame.size.width / 2, y: 40)
Platform0.zPosition = 1
Platform0.physicsBody = SKPhysicsBody(rectangleOfSize:Platform0.size)
Platform0.physicsBody?.dynamic = false
Platform0.physicsBody?.allowsRotation = false
Platform0.physicsBody?.restitution = 0
Platform0.physicsBody?.usesPreciseCollisionDetection = true
Platform0.physicsBody?.categoryBitMask = Platform0Category
Platform0.physicsBody?.collisionBitMask = PlayerCategory
Platform0.physicsBody?.contactTestBitMask = PlayerCategory
World.addChild(Platform0)
/// All other Platforms declared as the same above
}
func SpawnPlayer(){
var Player1:SKTexture!
var Player2:SKTexture!
var Animation:SKAction!
var AnimationRepeat:SKAction!
Player1 = SKTexture(imageNamed: "Image.png")
Player1.filteringMode = .Nearest
Player2 = SKTexture(imageNamed: "Image2.png")
Player2.filteringMode = .Nearest
Animation = SKAction.animateWithTextures([Player1,Player2], timePerFrame: 0.5)
AnimationRepeat = SKAction.repeatActionForever(Animation)
Player = SKSpriteNode (imageNamed: "Image.png")
Player.size = CGSize(width: 64, height: 64)
Player.position = CGPoint(x: self.frame.size.width / 2, y: 80)
Player.zPosition = 2
Player.physicsBody = SKPhysicsBody(rectangleOfSize:CGSize(width: 35, height: 50))
Player.physicsBody?.dynamic = true
Player.physicsBody?.allowsRotation = false
Player.physicsBody?.restitution = 0
Player.physicsBody?.usesPreciseCollisionDetection = true
Player.physicsBody?.velocity = CGVector(dx: 0, dy: -0.1)
Player.physicsBody?.categoryBitMask = PlayerCategory
Player.physicsBody?.collisionBitMask = Platform0Category
Player.physicsBody?.contactTestBitMask = Platform0Category | Platform1Category | Platform2Category | Platform3Category | Platform4Category | Platform5Category
Player.runAction(AnimationRepeat)
World.addChild(Player)
}
override func didFinishUpdate() {
Camera.position = CGPoint(x: Player.position.x, y: Player.position.y)
self.centerOnNode(Camera)
}
func centerOnNode(node: SKNode) {
let cameraPositionInScene: CGPoint = node.scene!.convertPoint(node.position, fromNode: World)
node.parent!.position = CGPoint(x:node.parent!.position.x - cameraPositionInScene.x, y:node.parent!.position.y - cameraPositionInScene.y)
}
不要直接在centeronnode中声明位置,而是使用SKAction moveTo。
它有持续时间值。
将旧的 centerOnNode 函数替换为:
func centerOnNode(node: SKNode) {
let cameraPositionInScene: CGPoint = node.scene!.convertPoint(node.position, fromNode: World)
node.parent!..runAction(SKAction.moveTo(CGPoint(x:node.parent!.position.x - cameraPositionInScene.x, y:node.parent!.position.y - cameraPositionInScene.y), duration: 1))
}
应该可以,但抱歉,我还没有测试过。
更新 Swift 3
func centerOnNode(node: SKNode) {
let cameraPositionInScene: CGPoint = node.scene!.convert(node.position, from: World)
node.parent!.run(SKAction.move(to: CGPoint(x:node.parent!.position.x - cameraPositionInScene.x, y:node.parent!.position.y - cameraPositionInScene.y), duration: 1))
}
我在 Sprite Kit 中制作了一个专注于 SKSpriteNode 的相机。
Apple 有一个很棒的文档:Apple Document
但是,现在的camera是直接跟随SKSpriteNode的,而我想留一点余地。
例如触摸后SKSpriteNode上下移动,相机从原点开始缓慢跟随SKSpriteNode,最大距离Height为SKSpriteNode是半屏,当SKSpriteNode静止时,相机和SKSpriteNode移动回到原点。
另外 节点的 PhysicBody 行为异常,远离其实际图像。我该如何解决?
这是我的代码:
class GameScene: SKScene, SKPhysicsContactDelegate {
var Player: SKSpriteNode!
var Platform0: SKSpriteNode!
var Platform1: SKSpriteNode!
var Platform2: SKSpriteNode!
var Platform3: SKSpriteNode!
var Platform4: SKSpriteNode!
var Platform5: SKSpriteNode!
var World: SKNode!
var Camera: SKNode!
override func didMoveToView(view: SKView) {
/* Setup your scene here */
self.physicsWorld.contactDelegate = self
self.anchorPoint = CGPoint(x: 0.5, y: 0.1)
self.World = SKNode()
self.World.name = "World"
addChild(self.World)
self.Camera = SKNode()
self.Camera.name = "Camera"
self.World.addChild(self.Camera)
SpawnPlatforms()
SpawnPlayer()
}
func SpawnPlatforms() {
Platform0 = SKSpriteNode (color: SKColor.greenColor(), size: CGSize(width: self.frame.size.width , height: 25))
Platform0.position = CGPoint(x: self.frame.size.width / 2, y: 40)
Platform0.zPosition = 1
Platform0.physicsBody = SKPhysicsBody(rectangleOfSize:Platform0.size)
Platform0.physicsBody?.dynamic = false
Platform0.physicsBody?.allowsRotation = false
Platform0.physicsBody?.restitution = 0
Platform0.physicsBody?.usesPreciseCollisionDetection = true
Platform0.physicsBody?.categoryBitMask = Platform0Category
Platform0.physicsBody?.collisionBitMask = PlayerCategory
Platform0.physicsBody?.contactTestBitMask = PlayerCategory
World.addChild(Platform0)
/// All other Platforms declared as the same above
}
func SpawnPlayer(){
var Player1:SKTexture!
var Player2:SKTexture!
var Animation:SKAction!
var AnimationRepeat:SKAction!
Player1 = SKTexture(imageNamed: "Image.png")
Player1.filteringMode = .Nearest
Player2 = SKTexture(imageNamed: "Image2.png")
Player2.filteringMode = .Nearest
Animation = SKAction.animateWithTextures([Player1,Player2], timePerFrame: 0.5)
AnimationRepeat = SKAction.repeatActionForever(Animation)
Player = SKSpriteNode (imageNamed: "Image.png")
Player.size = CGSize(width: 64, height: 64)
Player.position = CGPoint(x: self.frame.size.width / 2, y: 80)
Player.zPosition = 2
Player.physicsBody = SKPhysicsBody(rectangleOfSize:CGSize(width: 35, height: 50))
Player.physicsBody?.dynamic = true
Player.physicsBody?.allowsRotation = false
Player.physicsBody?.restitution = 0
Player.physicsBody?.usesPreciseCollisionDetection = true
Player.physicsBody?.velocity = CGVector(dx: 0, dy: -0.1)
Player.physicsBody?.categoryBitMask = PlayerCategory
Player.physicsBody?.collisionBitMask = Platform0Category
Player.physicsBody?.contactTestBitMask = Platform0Category | Platform1Category | Platform2Category | Platform3Category | Platform4Category | Platform5Category
Player.runAction(AnimationRepeat)
World.addChild(Player)
}
override func didFinishUpdate() {
Camera.position = CGPoint(x: Player.position.x, y: Player.position.y)
self.centerOnNode(Camera)
}
func centerOnNode(node: SKNode) {
let cameraPositionInScene: CGPoint = node.scene!.convertPoint(node.position, fromNode: World)
node.parent!.position = CGPoint(x:node.parent!.position.x - cameraPositionInScene.x, y:node.parent!.position.y - cameraPositionInScene.y)
}
不要直接在centeronnode中声明位置,而是使用SKAction moveTo。
它有持续时间值。
将旧的 centerOnNode 函数替换为:
func centerOnNode(node: SKNode) {
let cameraPositionInScene: CGPoint = node.scene!.convertPoint(node.position, fromNode: World)
node.parent!..runAction(SKAction.moveTo(CGPoint(x:node.parent!.position.x - cameraPositionInScene.x, y:node.parent!.position.y - cameraPositionInScene.y), duration: 1))
}
应该可以,但抱歉,我还没有测试过。
更新 Swift 3
func centerOnNode(node: SKNode) {
let cameraPositionInScene: CGPoint = node.scene!.convert(node.position, from: World)
node.parent!.run(SKAction.move(to: CGPoint(x:node.parent!.position.x - cameraPositionInScene.x, y:node.parent!.position.y - cameraPositionInScene.y), duration: 1))
}