Group Group Group Group Group Group Group Group Group Forums

How to Make a Game Like Candy Crush with SpriteKit and Swift: Part 1

In this epic tutorial you'll learn how to make a tasty match-3 game like Candy Crush with SpriteKit and Swift. Now updated for Xcode 7.3 and Swift 2.2.

This is a companion discussion topic for the original entry at

Great tutorial so far. I am definitely a newbie, I am running into two issues:

  1. The tiles show up at the very top instead of the center EDIT: The IOS Simulator was too large, the tiles were in the center. Zooming out to 50% showed a better picture. I’m an idiot, but I’m going to leave this here for others.
  2. If I add the if tiles[column, row] != nil { in createInitialCookies then no cookies are shown. EDIT: The Levels folder was not able to be read, removing it and re-added it with the option Added folders set to “Create groups” worked.

Does anybody have any ideas why I am running into this? (I’ll update this post once I figure it out.)

A great tutorial. This is chock-full of gems! And there are 3 more tutorials in the series! Yay!

I think there is a typo about two thirds of the way down. Where it says “Remember that earlier you set the anchorPoint of the scene to (0, 0)…”, I think it should be (0.5, 0.5), instead.

Hey @jonaldomo. Glad you’re enjoying the tutorial and that you figured out the problems for yourself – have fun with the rest of the tutorial series :]

Hey @kgs. You’re absolutely right – I’ve corrected the mistake. Thanks :]

Hey @mfaarkrog Thanks for the tutorial.
I have a doubt. In Level class, in function cookieAtColumn why is the return type Cookie? Shouldn’t it be Array2D? Also what is purpose of using ‘?’ ?

Hey @dimplepatel. Good questions :] The return type is Cookie? because you’re getting an item inside the cookies property which is a Array2D consisting of Cookies. Also, we’re using an optional (?) because we cannot guarantee that the row and column given are actually pointing to a valid index in the 2D array.

Hope this clears it up for you :]

1 Like


i am new to ios-development.
In GameScene (View) you make a direct connection to Level (Model) with var level : Level! Later you use … level.tileAtColumn(…) in GameScene.

I have learned, that in MVC should never be a direct contact between the view and the model. What is the reason or did i missunderstand something?


Hi :] You’re right; referring to a Model from within a View is not really pure MVC. However, sometimes you may still do it for convenience. You could refactor it if you wanted to be more strict about it, though :]

Great tutorial, the explanations of concepts are great.

Did we need tot put the cookieAtColumn func and the shuffle and createInitialCookies functions in the level class, instead of just the file? Otherwise i just get an error :confused:


Great tutorial!

I have finished part 1 now but the tiles and cookies never apear on the screen.
The first thing I did was to look through the tutorial again to see if I missed something, after that I downloaded the sampleCode and started copying methods that I thought could have errors.

I ended up copying the whole classes and I still don’t get the tiles and cookies to load.

What could be the error?


This is a fantastic project and the tutorial is very well done. Though, I don’t think I understand why we write a 2DArray class when it is possible to use a native 2D array to start? Thoughts?

Excellent tutorial! Thanks a lot

1 Like

Excellent tutorial! yet I got a crash while the simulator is running trying to print the grid of cookies with that errors : “SKUtil.m: MGGetBoolAnswer is not available in the simulator.” I tried hard to get it fixed but in vain! Can somebody in there help me please because I have no idea how to solve it! It comes from the array2D structure with the subscript methods get and set. Thank you !

Hi everybody, for those of you who are stucked in the same position as I were, I fixed mine just by changing the path of the file “Level_1” in the line : level = Level(filename: “Level_1”) in the GameViewController.swift. Just put the right path, so to me it was : level = Level(filename: “Levels/Level_1”).

Hello, i hope that this is the right place for asking. I’m interested in if it is possible to make zombocalypse game on ios System. You can look the game at this site

Loving the tutorial. One snag.

When I build to show the the full grid of cookies for the first time. (just before “Loading Levels from JSON”) – I’m getting the following error on the “scene.level = level” line in the viewDidLoad section of the GameViewController:

fatal error: unexpectedly found nil while unwrapping an Optional value

I’ve poured through the code and cant find what’s wrong.

Hey @robsauna
I had the same problem and I fixed it by deleting the “Levels” folder with the .json documents inside. Then I reimported them without the folder. Only the .json documents! By drag and drop.

I don`t know exactly why, but Xcode is not able to find the .json documents inside the blue folder. If you make a yellow one inside Xcode it should work… :]

I know that I reply to a comment that’s a few month old but I think it can help other people who are scanning through the comments seeking for help. ;]

By the way, a very great and easy to understand tutorial! It helped me a lot.

It looks like the Swift syntax changed slightly when declaring an array

from: (in context)

 init(columns: Int, rows: Int) {
    self.columns = columns
    self.rows = rows
    array = Array<T?>(count: rows*columns, repeatedValue: nil)


init(columns: Int, rows: Int) {
    self.columns = columns
    self.rows = rows
    array = Array<T?>(repeating: nil, count: rows*columns)

I face the same your problem and my solution to solve this problem is replace the default code of swift as follow:

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    if UIDevice.current.userInterfaceIdiom == .phone {
        return .allButUpsideDown
    } else {
        return .all

by this:

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return [.portrait, .portraitUpsideDown]

Hope it work.