I am wanting my sprite "Character" to move and rotate "follow" my finger as I move it around. I had it working fine but somehow have managed to screw it up. I'm not sure what I've done but can't for the life of me figure it out.
Any help would be greatly appreciated. Im sure its something stupid that I'm just overlooking. Thanks in advance.
Mark
GameScene.swift
import SpriteKit
import GameplayKit
//MARK: ---------------Global Variables Section
var nodeType: String = String()
var characterNode = Character()
let characterImage: String = String("default_pose")
var characterTexture:SKTexture = SKTexture()
let characterSize: CGSize = CGSize(width: 64, height: 64)
let characterPosition: CGPoint = CGPoint(x: 0, y: 0)
var enemyNode = Enemy()
let enemyImage: String = String("blob1")
var enemyTexture = SKTexture()
let enemySize: CGSize = CGSize(width: 50, height: 50)
let enemyPosition: CGPoint = CGPoint(x: 150, y: 150)
class GameScene: SKScene, SKPhysicsContactDelegate {
//MARK: --------------------Class Variables Section
var affectedByGravity: Bool = false
var dynamic: Bool = true
var rotation: Bool = false
var lastUpdateTime: CFTimeInterval = 0
//MARK: --------------------DidMove to View Section
override func didMove(to view: SKView) {
var node = SKSpriteNode()
node = addNode(NodeType: "Character")
applyPhysics(physicsNode: node, nodeImage: characterImage, nodeSize: characterSize, nodeName: node.name!)
node.zPosition = 10
addChild(node)
node = addNode(NodeType: "Enemy")
applyPhysics(physicsNode: node, nodeImage: enemyImage, nodeSize: enemySize, nodeName: node.name!)
node.zPosition = 9
addChild(node)
}
//MARK: -----------------------Add Node Section
func addNode(NodeType: String) -> SKSpriteNode {
var node = SKSpriteNode()
switch NodeType {
case "Enemy":
node = enemyNode.setupNode(nodeName: "Enemy", nodeImage: "blob1", nodeSize: enemySize, nodePosition: enemyPosition)
default:
node = characterNode.setupNode(nodeName: "Player", nodeImage: "default_pose", nodeSize: characterSize, nodePosition: characterPosition)
}
return node
}
//MARK: ------------------------Physics Section
func applyPhysics(physicsNode: SKSpriteNode, nodeImage: String, nodeSize: CGSize, nodeName: String) {
let nodeTexture: SKTexture = SKTexture(imageNamed: nodeImage)
physicsNode.physicsBody = SKPhysicsBody(texture: nodeTexture, size: nodeSize)
physicsNode.physicsBody?.isDynamic = dynamic
physicsNode.physicsBody?.affectedByGravity = affectedByGravity
physicsNode.physicsBody?.allowsRotation = rotation
physicsNode.physicsBody?.categoryBitMask = 1
physicsNode.physicsBody?.contactTestBitMask = 1
physicsNode.physicsBody?.collisionBitMask = 1
}
//MARK: ------------------------Movement and Rotation Section
func moveAndRotate(sprite: Character, toPosition position: CGPoint) {
let angle = atan2(position.y - sprite.position.y, position.x - sprite.position.x)
let rotateAction = SKAction.rotate(toAngle: angle - .pi / 2, duration: 0.05, shortestUnitArc:true)
sprite.run(rotateAction)
let offsetX = position.x - (sprite.position.x)
let offsetY = position.y - (sprite.position.y)
let normal = simd_normalize(simd_double2(x: Double(offsetX), y:Double(offsetY)))
characterNode.velocity = CGVector(dx: CGFloat(normal.x) * sprite.movePointsPerSecond, dy: CGFloat(normal.y) * sprite.movePointsPerSecond)
}
//MARK: ----------------------Touches Section
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
let touchLocation = touch.location(in: self)
characterNode.isMoving = true
moveAndRotate(sprite: characterNode, toPosition: touchLocation)
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
let touchLocation = touch.location(in: self)
moveAndRotate(sprite: characterNode, toPosition: touchLocation)
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
characterNode.isMoving = false
}
//MARK: ------------------Update Section
override func update(_ currentTime: TimeInterval) {
let deltaTime = max(1.0/30, currentTime - lastUpdateTime)
lastUpdateTime = currentTime
update(character: characterNode, dt: deltaTime)
}
func update(character: Character, dt: CFTimeInterval) {
if characterNode.isMoving == true {
let newX = character.position.x + character.velocity.dx * CGFloat(dt)
let newY = character.position.y + character.velocity.dy * CGFloat(dt)
character.position = CGPoint(x: newX, y: newY)
}
}
}
Character.swift
import SpriteKit
import GameplayKit
class Character: SKSpriteNode {
let movePointsPerSecond: CGFloat = 150.0
var velocity = CGVector(dx: 0.0, dy: 0.0)
var isMoving = false
var node: SKSpriteNode = SKSpriteNode()
func setupNode(nodeName: String, nodeImage: String, nodeSize: CGSize, nodePosition: CGPoint) -> SKSpriteNode {
node = SKSpriteNode(imageNamed: nodeImage)
node.name = nodeName
node.position = nodePosition
return node
}
}
Your node does not move because you never assign characterNode to the node on your screen