+ Create animation with texture atlases
+ Change the direction the bear faces based on the moving location
+ Make the ninja move to the touch location
+ Knight will stand and move
# Create the Swift Project
To start the tutorial, you need to create a Swift Project.
Start up you Xcode, select File\New\Project… (if there is no project), choose the iOS/Game Template and click on Next Button.
Game Project with Sprite Kit |
Enter LapKanAnimationKnight for the Product Name.
Choose Swift for Language (Important)
Sprite Kit for Game Technology.
Next to create Project.
=> We have a ready project to start.
# Download the asset: Link
These images from Tokegameart, they are really good for RPG Games, so if you see this is good assets, buy from them, they are royal free.
Dark Knight Atlas |
# Texture Atlases:
Copy these asset to Project.
Drag and drop these file to the project.
# Make simple animation first:
Create the variable for code:
private var knight = SKSpriteNode()
private var knightWalkingFrames: [SKTexture] = []
private var knightIdleFrames: [SKTexture] = []
# Setting up the Texture Atlas:
Now, we write the code to set the texture for each action
Action for walking from 0 -> 23.
Action for standing from 0 -> 17.
If you have more actions, you need to write more code for each action.
func buildKnight() {
let knightAnimatedAtlas = SKTextureAtlas(named: "DarkKnight")
// Walking Frames
var walkingFrames: [SKTexture] = []
for i in 0...23 {
let knightTextureName = String(format: "Walking_%03d", arguments: [i])
walkingFrames.append(knightAnimatedAtlas.textureNamed(knightTextureName))
}
knightWalkingFrames = walkingFrames
// Idle Frames
var idleFrames: [SKTexture] = []
for i in 0...17 {
let knightTextureName = String(format: "Idle_%03d", arguments: [i])
idleFrames.append(knightAnimatedAtlas.textureNamed(knightTextureName))
}
knightIdleFrames = idleFrames
}
So we have the function buildNinja, now the only thing we need to create a ninja is use
func animatedKnight() {
knight.run(SKAction.repeatForever(SKAction.animate(with: knightWalkingFrames, timePerFrame: 0.03, resize: false, restore: true)), withKey: "walkingInPlaceKnight")
}
# Make Stand Frames:
After the knight go to the goal point, we remove all action and set the action for standing.
func knightStand() {
knight.removeAllActions()
knight.run(SKAction.repeatForever(SKAction.animate(with: knightIdleFrames, timePerFrame: 0.03, resize: false, restore: true)), withKey: "idleInPlaceKnight")
}
# Change Animation Facing Direction
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
for t in touches { self.touchUp(atPoint: t.location(in: self)) }
let touch = touches.first!
let location = touch.location(in: self)
moveKnight(location: location)
}
# Make Knight Moving:
func moveKnight(location: CGPoint) {
if knight.action(forKey: "idleInPlaceKnight") != nil {
knight.removeAction(forKey: "idleInPlaceKnight")
}
var multiplierForDirection: CGFloat
let knightSpeed = frame.size.width / 3.0
let moveDifference = CGPoint(x: location.x - knight.position.x, y: location.y - knight.position.y)
let distanceToMove = sqrt(moveDifference.x * moveDifference.x + moveDifference.y * moveDifference.y)
let moveDuration = distanceToMove / knightSpeed
if moveDifference.x < 0 {
multiplierForDirection = -1.0
} else {
multiplierForDirection = 1.0
}
knight.xScale = abs(knight.xScale) * multiplierForDirection
if knight.action(forKey: "walkingInPlaceKnight") == nil {
animatedKnight()
}
let moveAction = SKAction.move(to: location, duration: (TimeInterval(moveDuration)))
let doneAction = SKAction.run( {
[weak self] in self?.knightStand()
})
let moveActionWithDone = SKAction.sequence([moveAction, doneAction])
knight.run(moveActionWithDone, withKey: "knightMoving")
}
Full Code Done: Link