Thanks for the great tutorial Ray! It works well and did a good job breaking the ice with my first time using SpriteKit with Swift. Iām new to iOS development, I just started to dabble in it about a month ago, and I found this tutorial explained very well even for a noob like me.
I have a couple of questions.
Why does the background audio playback stop after the game scene is loaded, just after the transition animation. This only happens after finishing the first round and starting the next (after the first time the game scene loads, after the first transition animation). Note I can hear the audio for the duration of the transition animation then it stops.
When I played this on my actual iPhone (5S), the audio is only heard if I have my headphones plugged in. For some unknown reason the audio doesnāt play over the speakers.
I want to bring up a possible issue with this tutorial. It may be changed since Swift 2.2 revision went out but when I use code such as:
let actualY = random(min: monster.size.height/2, max: size.height - monster.size.height/2)
I get an error of āUse of unresolved identifier āsizeāā
I tried to append the statement with an identifier, such as monster.size.height but that saw the code as an argument and gave me another error. I also tried adding SKScene.size.height which cleared the errors, but I donāt think I want to be setting the monsterās position based on the sceneās size and height do I?ā
Anyway, Iāll keep playing around with it, but I donāt wan to set a parameter thatās going to make it work the way it wasnāt intended to for this tutorial.
Just one note. I think firstBody and secondBody need to be switched in the following line: projectileDidCollideWithMonster(firstBody.node as! SKSpriteNode, monster: secondBody.node as! SKSpriteNode)
The projectile node is supposed to be passed in first, then the monster node. But the bit-wise check just above this line assigns the monster node to firstBody and the projectile to secondBody. So, as it stands now, the monster node is passed in first, followed by the projectile node.
The outcome happens to be exactly the same in this particular tutorial because both monster and the projectile are removed from the scene at the same time. But inside projectileDidCollideWithMonster(), āprojectileā is monster, and āmonsterā is projectile.
I love RW tutorials. They are not only insightful, but also simple to understand and fun to code. Thanks for the great work!
Regarding the comment that āsizeā is undefined, I think addMonster should be defined inside SKScene:
import SpriteKit
class GameScene: SKScene {
// 1
let player = SKSpriteNode(imageNamed: "player")
override func didMoveToView(view: SKView) {
// 2
backgroundColor = SKColor.whiteColor()
// 3
player.position = CGPoint(x: size.width * 0.1, y: size.height * 0.5)
// 4
addChild(player)
self.addMonster()
}
func addMonster() {
// Create sprite
let monster = SKSpriteNode(imageNamed: "monster")
// Determine where to spawn the monster along the Y axis
let actualY = random(min: monster.size.height/2, max: self.size.height - monster.size.height/2)
// Position the monster slightly off-screen along the right edge,
// and along a random position along the Y axis as calculated above
monster.position = CGPoint(x: self.size.width + monster.size.width/2, y: actualY)
// Add the monster to the scene
addChild(monster)
// Determine speed of the monster
let actualDuration = random(min: CGFloat(2.0), max: CGFloat(4.0))
// Create the actions
let actionMove = SKAction.moveTo(CGPoint(x: -monster.size.width/2, y: actualY), duration: NSTimeInterval(actualDuration))
let actionMoveDone = SKAction.removeFromParent()
monster.runAction(SKAction.sequence([actionMove, actionMoveDone]))
}
I was wondering if this tutorial would still work if when I first created the project, I set the devices to Universal. I was also wondering if there is a way to change that without having to restart all the coding. Thank you.
Iām able to get the game to crash consistently when running inside the simulator. The crash occurs when I rapid fire more than one projectile at a monster and the first projectile hits the monster.
Iāve confirmed itās not a mistake on my part in entering the code by running the downloadable full source thatās provided and reproducing the crash.
The error message in the console window at the bottom is āfatal error: unexpectedly found nil while unwrapping an Optional valueā. In the GameScene.swift file, Xcode has highlighted in red the call to projectileDidCollideWithMonster inside the didBeginContact method. The following message is given below the highlighted text:āThread 1:EXC_BAD_INSTRUCTIONā¦ā
Iām still relatively new to programming on the Mac, so Iām hoping that wiser and more experienced minds can diagnose and solve this problem.
If a projectile hits two monsters at the same time, you will get the error because projectile gets destroyed after colliding with first monster and then when it comes time to evaluate and remove projectile for second monster, the projectile does not exist.
The easiest way to handle this is to check if projectile is ānilāā¦if nil then dont remove it. Another modification would be to not remove projectile and let it continue to destroy monsters even after the first one.
if (secondBody.node != nil){
secondBody.node!.removeFromParent()
}
firstBody.node!.removeFromParent()
I canāt seem to make my projectiles destroy the monster and themselves upon impact. I believe that I have put everything where it needs to go and typed it all up correctly. I can send the code over to you if necessary.
If you collisions are not working, and if you are using Xcode8/Swift 3 with the Swift 2 version of this tutorial, note that the SKPhysicsContactDelegate method signatures have changed from this:
func didBeginContact(contact: SKPhysicsContact) {
to this:
func didBegin(_ contact: SKPhysicsContact) {
If you are using the old version of this contact method, it will never be called, and you wonāt get any kind of warning or error from Xcode that your code is wrong (because the SKPhysicsContactDelegate methods are optional)
Thanks Ray for the great tutorial! I am inspired to write a game. It involves striking a small oblong stick on the ground with a long stick to make the wedge jump and then with same long stick hit the small stick it like you a baseballā¦The striking is collision and then there is gravity to introduce. Is there a tutorial to include force against gravity?