Reputation: 375
My Goal: To get an SKSpriteNode to move to another SKSpriteNodes position. (To create a magnet for my sprite kit game)
Hi, I am trying to get multiple SKSpriteNodes with the same name to move towards and collide with an sprite node that i’m going to be calling a magnet i just don’t understand where or how i would go about doing this, i have tried using this code but i’m left scratching my head on what to do:
func update(_ currentTime: TimeInterval) {
let node = childNode(withName: "specialObstacle")
let magnetLocation = magnet.position
let specialObjectLocation = node?.position
let x = node?.position.x - magnetLocation.x
let y = node?.position.y - magnetLocation.y
}
Note: My magnet’s location will be changing due to the fact the user will be moving the magnet around the screen and would like it to keep going towards the magnet but i just can’t figure out how to do this.
EDIT 1
I tried using the code you had whirlwind and it seems to work for the x-axis but it seems to not work for the y axis for some reason it looks like it tries to go down but fails and just vibrates in the one spot. i have added my code below and a image
HERE is the code i'm using:
let playerLocation:CGPoint = self.convert(thePlayer.position, from: worldNode)
let location = playerLocation
let nodeSpeed:CGFloat = 3.5
worldNode.enumerateChildNodes(withName: "levelUnit"){
node, stop in
let levelUnit:LevelUnit = node as! LevelUnit //cast as an actual LevelUnit class
levelUnit.enumerateChildNodes(withName: "specialObstacle"){
node, stop in
//Aim
let dx = location.x - (node.position.x)
let dy = location.y - (node.position.y)
let angle = atan2(dy, dx)
node.zRotation = angle
//Seek
let vx = cos(angle) * nodeSpeed
let vy = sin(angle) * nodeSpeed
node.position.x += vx
node.position.y += vy
}
}
Upvotes: 4
Views: 641
Reputation: 59516
First of all here's the code
import SpriteKit
class GameScene: SKScene {
let magnet = SKFieldNode.linearGravityField(withVector: vector_float3(0, 9.8 * 2, 0))
let circle = SKShapeNode(circleOfRadius: 30)
override func didMove(to view: SKView) {
circle.fillColor = .white
circle.position.x = 0
circle.position.y = frame.maxY
addChild(circle)
magnet.region = SKRegion(size: self.frame.size)
magnet.isEnabled = false
magnet.categoryBitMask = 0x1
circle.addChild(magnet)
self.physicsBody = SKPhysicsBody(edgeLoopFrom: frame)
for i in 0..<20 {
let ball = SKShapeNode(circleOfRadius: 30)
ball.fillColor = .yellow
ball.physicsBody = SKPhysicsBody(circleOfRadius: 30)
ball.position.x = CGFloat(i) * 10
ball.physicsBody!.fieldBitMask = 0x1
addChild(ball)
}
let ball = SKShapeNode(circleOfRadius: 30)
ball.fillColor = .green
ball.physicsBody = SKPhysicsBody(circleOfRadius: 30)
ball.position.y = 40
ball.physicsBody!.fieldBitMask = 0x2
addChild(ball)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
circle.fillColor = .red
magnet.isEnabled = true
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
circle.fillColor = .white
magnet.isEnabled = false
}
}
Here there are the core concepts
SKFieldNode
on top of the screen whose categoryBitMask is 0x1fieldBitMask = 0x1
(this will make the interact with the FieldNode)fieldBitMask = 0x2
(which makes it not affected by the SKFieldNode
)Finally I am simply turning on/off the SKFieldNode when you touch/untouch the screen.
Oh, and there's a red sprite exactly at the same position of the SKFieldNode but that's only for UI reasons.
Upvotes: 3