├── Sounds
├── Chomp.wav
├── Drip.wav
├── Error.wav
├── Ka-Ching.wav
├── Scrape.wav
├── Grid.atlas
│ ├── Tile_1.png
│ ├── Tile_10.png
│ ├── Tile_11.png
│ ├── Tile_12.png
│ ├── Tile_13.png
│ ├── Tile_14.png
│ ├── Tile_15.png
│ ├── Tile_2.png
│ ├── Tile_3.png
│ ├── Tile_4.png
│ ├── Tile_5.png
│ ├── Tile_7.png
│ ├── Tile_8.png
│ ├── MaskTile.png
│ ├── Tile_1@2x.png
│ ├── Tile_1@3x.png
│ ├── Tile_2@2x.png
│ ├── Tile_2@3x.png
│ ├── Tile_3@2x.png
│ ├── Tile_3@3x.png
│ ├── Tile_4@2x.png
│ ├── Tile_4@3x.png
│ ├── Tile_5@2x.png
│ ├── Tile_5@3x.png
│ ├── Tile_7@2x.png
│ ├── Tile_7@3x.png
│ ├── Tile_8@2x.png
│ ├── Tile_8@3x.png
│ ├── MaskTile@2x.png
│ ├── MaskTile@3x.png
│ ├── Tile_10@2x.png
│ ├── Tile_10@3x.png
│ ├── Tile_11@2x.png
│ ├── Tile_11@3x.png
│ ├── Tile_12@2x.png
│ ├── Tile_12@3x.png
│ ├── Tile_13@2x.png
│ ├── Tile_13@3x.png
│ ├── Tile_14@2x.png
│ ├── Tile_14@3x.png
│ ├── Tile_15@2x.png
│ └── Tile_15@3x.png
└── Mining by Moonlight.mp3
├── Sprites.atlas
├── Danish.png
├── Donut.png
├── Tile.png
├── Cupcake.png
├── Donut@2x.png
├── Donut@3x.png
├── Macaroon.png
├── Tile@2x.png
├── Tile@3x.png
├── Croissant.png
├── Cupcake@2x.png
├── Cupcake@3x.png
├── Danish@2x.png
├── Danish@3x.png
├── Macaroon@2x.png
├── Macaroon@3x.png
├── SugarCookie.png
├── Croissant@2x.png
├── Croissant@3x.png
├── SugarCookie@2x.png
├── SugarCookie@3x.png
├── Danish-Highlighted.png
├── Donut-Highlighted.png
├── Croissant-Highlighted.png
├── Cupcake-Highlighted.png
├── Danish-Highlighted@2x.png
├── Danish-Highlighted@3x.png
├── Donut-Highlighted@2x.png
├── Donut-Highlighted@3x.png
├── Macaroon-Highlighted.png
├── Cupcake-Highlighted@2x.png
├── Cupcake-Highlighted@3x.png
├── Macaroon-Highlighted@2x.png
├── Macaroon-Highlighted@3x.png
├── SugarCookie-Highlighted.png
├── Croissant-Highlighted@2x.png
├── Croissant-Highlighted@3x.png
├── SugarCookie-Highlighted@2x.png
└── SugarCookie-Highlighted@3x.png
├── CookieCrunch
├── Assets.xcassets
│ ├── Contents.json
│ ├── Button.imageset
│ │ ├── Button@3x.png
│ │ └── Contents.json
│ ├── AppIcon.appiconset
│ │ ├── Icon-40@2x-2.png
│ │ ├── Icon-40@2x.png
│ │ ├── Icon-60@2x.png
│ │ ├── Icon-60@3x.png
│ │ ├── Icon-Small@2x.png
│ │ ├── Icon-Small@3x.png
│ │ └── Contents.json
│ ├── GameOver.imageset
│ │ ├── GameOver@3x.png
│ │ └── Contents.json
│ ├── Background.imageset
│ │ ├── Background@3x.png
│ │ └── Contents.json
│ └── LevelComplete.imageset
│ │ ├── LevelComplete@3x.png
│ │ └── Contents.json
├── Tile.swift
├── Array2D.swift
├── Swap.swift
├── Info.plist
├── Extensions.swift
├── Chain.swift
├── Cookie.swift
├── Base.lproj
│ ├── Main.storyboard
│ ├── LaunchScreen.storyboard
│ └── Main2.storyboard
├── AppDelegate.swift
├── GameViewController.swift
├── Level.swift
└── GameScene.swift
├── README.md
├── Cookie Crunch Adventure.xcodeproj
├── xcuserdata
│ └── nilsbernhardt.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── CookieCrunch.xcscheme
├── project.xcworkspace
│ ├── xcuserdata
│ │ └── nilsbernhardt.xcuserdatad
│ │ │ └── UserInterfaceState.xcuserstate
│ └── contents.xcworkspacedata
└── project.pbxproj
├── Levels
├── Level_0.json
├── Level_1.json
├── Level_2.json
├── Level_3.json
└── Level_4.json
└── CookieCrunchTests
├── Info.plist
└── CookieCrunchTests.swift
/Sounds/Chomp.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Chomp.wav
--------------------------------------------------------------------------------
/Sounds/Drip.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Drip.wav
--------------------------------------------------------------------------------
/Sounds/Error.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Error.wav
--------------------------------------------------------------------------------
/Sounds/Ka-Ching.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Ka-Ching.wav
--------------------------------------------------------------------------------
/Sounds/Scrape.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Scrape.wav
--------------------------------------------------------------------------------
/Sprites.atlas/Danish.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Danish.png
--------------------------------------------------------------------------------
/Sprites.atlas/Donut.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Donut.png
--------------------------------------------------------------------------------
/Sprites.atlas/Tile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Tile.png
--------------------------------------------------------------------------------
/Sprites.atlas/Cupcake.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Cupcake.png
--------------------------------------------------------------------------------
/Sprites.atlas/Donut@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Donut@2x.png
--------------------------------------------------------------------------------
/Sprites.atlas/Donut@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Donut@3x.png
--------------------------------------------------------------------------------
/Sprites.atlas/Macaroon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Macaroon.png
--------------------------------------------------------------------------------
/Sprites.atlas/Tile@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Tile@2x.png
--------------------------------------------------------------------------------
/Sprites.atlas/Tile@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Tile@3x.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_1.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_10.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_11.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_12.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_13.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_14.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_15.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_2.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_3.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_4.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_5.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_7.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_8.png
--------------------------------------------------------------------------------
/Sprites.atlas/Croissant.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Croissant.png
--------------------------------------------------------------------------------
/Sprites.atlas/Cupcake@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Cupcake@2x.png
--------------------------------------------------------------------------------
/Sprites.atlas/Cupcake@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Cupcake@3x.png
--------------------------------------------------------------------------------
/Sprites.atlas/Danish@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Danish@2x.png
--------------------------------------------------------------------------------
/Sprites.atlas/Danish@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Danish@3x.png
--------------------------------------------------------------------------------
/Sprites.atlas/Macaroon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Macaroon@2x.png
--------------------------------------------------------------------------------
/Sprites.atlas/Macaroon@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Macaroon@3x.png
--------------------------------------------------------------------------------
/Sprites.atlas/SugarCookie.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/SugarCookie.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/MaskTile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/MaskTile.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_1@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_1@2x.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_1@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_1@3x.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_2@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_2@2x.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_2@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_2@3x.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_3@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_3@2x.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_3@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_3@3x.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_4@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_4@2x.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_4@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_4@3x.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_5@2x.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_5@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_5@3x.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_7@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_7@2x.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_7@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_7@3x.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_8@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_8@2x.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_8@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_8@3x.png
--------------------------------------------------------------------------------
/Sounds/Mining by Moonlight.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Mining by Moonlight.mp3
--------------------------------------------------------------------------------
/Sprites.atlas/Croissant@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Croissant@2x.png
--------------------------------------------------------------------------------
/Sprites.atlas/Croissant@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Croissant@3x.png
--------------------------------------------------------------------------------
/CookieCrunch/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/MaskTile@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/MaskTile@2x.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/MaskTile@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/MaskTile@3x.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_10@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_10@2x.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_10@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_10@3x.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_11@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_11@2x.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_11@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_11@3x.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_12@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_12@2x.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_12@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_12@3x.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_13@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_13@2x.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_13@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_13@3x.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_14@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_14@2x.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_14@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_14@3x.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_15@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_15@2x.png
--------------------------------------------------------------------------------
/Sounds/Grid.atlas/Tile_15@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sounds/Grid.atlas/Tile_15@3x.png
--------------------------------------------------------------------------------
/Sprites.atlas/SugarCookie@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/SugarCookie@2x.png
--------------------------------------------------------------------------------
/Sprites.atlas/SugarCookie@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/SugarCookie@3x.png
--------------------------------------------------------------------------------
/Sprites.atlas/Danish-Highlighted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Danish-Highlighted.png
--------------------------------------------------------------------------------
/Sprites.atlas/Donut-Highlighted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Donut-Highlighted.png
--------------------------------------------------------------------------------
/Sprites.atlas/Croissant-Highlighted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Croissant-Highlighted.png
--------------------------------------------------------------------------------
/Sprites.atlas/Cupcake-Highlighted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Cupcake-Highlighted.png
--------------------------------------------------------------------------------
/Sprites.atlas/Danish-Highlighted@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Danish-Highlighted@2x.png
--------------------------------------------------------------------------------
/Sprites.atlas/Danish-Highlighted@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Danish-Highlighted@3x.png
--------------------------------------------------------------------------------
/Sprites.atlas/Donut-Highlighted@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Donut-Highlighted@2x.png
--------------------------------------------------------------------------------
/Sprites.atlas/Donut-Highlighted@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Donut-Highlighted@3x.png
--------------------------------------------------------------------------------
/Sprites.atlas/Macaroon-Highlighted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Macaroon-Highlighted.png
--------------------------------------------------------------------------------
/Sprites.atlas/Cupcake-Highlighted@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Cupcake-Highlighted@2x.png
--------------------------------------------------------------------------------
/Sprites.atlas/Cupcake-Highlighted@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Cupcake-Highlighted@3x.png
--------------------------------------------------------------------------------
/Sprites.atlas/Macaroon-Highlighted@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Macaroon-Highlighted@2x.png
--------------------------------------------------------------------------------
/Sprites.atlas/Macaroon-Highlighted@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Macaroon-Highlighted@3x.png
--------------------------------------------------------------------------------
/Sprites.atlas/SugarCookie-Highlighted.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/SugarCookie-Highlighted.png
--------------------------------------------------------------------------------
/Sprites.atlas/Croissant-Highlighted@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Croissant-Highlighted@2x.png
--------------------------------------------------------------------------------
/Sprites.atlas/Croissant-Highlighted@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/Croissant-Highlighted@3x.png
--------------------------------------------------------------------------------
/Sprites.atlas/SugarCookie-Highlighted@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/SugarCookie-Highlighted@2x.png
--------------------------------------------------------------------------------
/Sprites.atlas/SugarCookie-Highlighted@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Sprites.atlas/SugarCookie-Highlighted@3x.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CookieCrunch
2 | Tutorial-Project while learning Swift
3 |
4 | https://www.raywenderlich.com/125311/make-game-like-candy-crush-spritekit-swift-part-1
5 |
--------------------------------------------------------------------------------
/CookieCrunch/Assets.xcassets/Button.imageset/Button@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/CookieCrunch/Assets.xcassets/Button.imageset/Button@3x.png
--------------------------------------------------------------------------------
/CookieCrunch/Assets.xcassets/AppIcon.appiconset/Icon-40@2x-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/CookieCrunch/Assets.xcassets/AppIcon.appiconset/Icon-40@2x-2.png
--------------------------------------------------------------------------------
/CookieCrunch/Assets.xcassets/AppIcon.appiconset/Icon-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/CookieCrunch/Assets.xcassets/AppIcon.appiconset/Icon-40@2x.png
--------------------------------------------------------------------------------
/CookieCrunch/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/CookieCrunch/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png
--------------------------------------------------------------------------------
/CookieCrunch/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/CookieCrunch/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png
--------------------------------------------------------------------------------
/CookieCrunch/Assets.xcassets/GameOver.imageset/GameOver@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/CookieCrunch/Assets.xcassets/GameOver.imageset/GameOver@3x.png
--------------------------------------------------------------------------------
/CookieCrunch/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/CookieCrunch/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png
--------------------------------------------------------------------------------
/CookieCrunch/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/CookieCrunch/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png
--------------------------------------------------------------------------------
/CookieCrunch/Assets.xcassets/Background.imageset/Background@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/CookieCrunch/Assets.xcassets/Background.imageset/Background@3x.png
--------------------------------------------------------------------------------
/CookieCrunch/Assets.xcassets/LevelComplete.imageset/LevelComplete@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/CookieCrunch/Assets.xcassets/LevelComplete.imageset/LevelComplete@3x.png
--------------------------------------------------------------------------------
/Cookie Crunch Adventure.xcodeproj/xcuserdata/nilsbernhardt.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/CookieCrunch/Tile.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Tile.swift
3 | // CookieCrunch
4 | //
5 | // Created by Nils Bernhardt on 17.06.16.
6 | // Copyright © 2016 Nils Bernhardt. All rights reserved.
7 | //
8 |
9 | class Tile {
10 |
11 | }
--------------------------------------------------------------------------------
/Cookie Crunch Adventure.xcodeproj/project.xcworkspace/xcuserdata/nilsbernhardt.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bombcheck/CookieCrunch/master/Cookie Crunch Adventure.xcodeproj/project.xcworkspace/xcuserdata/nilsbernhardt.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/Cookie Crunch Adventure.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/CookieCrunch/Assets.xcassets/Button.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "Button@3x.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/CookieCrunch/Assets.xcassets/Background.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "Background@3x.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/CookieCrunch/Assets.xcassets/GameOver.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "GameOver@3x.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/CookieCrunch/Assets.xcassets/LevelComplete.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "scale" : "2x"
10 | },
11 | {
12 | "idiom" : "universal",
13 | "filename" : "LevelComplete@3x.png",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/Levels/Level_0.json:
--------------------------------------------------------------------------------
1 | {
2 | "tiles" : [ [1, 1, 1, 1, 1, 1, 1, 1, 1 ],
3 | [1, 1, 1, 1, 1, 1, 1, 1, 1 ],
4 | [1, 1, 1, 1, 1, 1, 1, 1, 1 ],
5 | [1, 1, 1, 1, 1, 1, 1, 1, 1 ],
6 | [1, 1, 1, 1, 1, 1, 1, 1, 1 ],
7 | [1, 1, 1, 1, 1, 1, 1, 1, 1 ],
8 | [1, 1, 1, 1, 1, 1, 1, 1, 1 ],
9 | [1, 1, 1, 1, 1, 1, 1, 1, 1 ],
10 | [1, 1, 1, 1, 1, 1, 1, 1, 1 ] ],
11 |
12 | "targetScore" : 2000,
13 | "moves" : 15,
14 | }
15 |
--------------------------------------------------------------------------------
/Levels/Level_1.json:
--------------------------------------------------------------------------------
1 | {
2 | "tiles" : [ [0, 1, 1, 0, 0, 0, 1, 1, 0 ],
3 | [1, 1, 1, 1, 1, 1, 1, 1, 1 ],
4 | [1, 1, 1, 1, 1, 1, 1, 1, 1 ],
5 | [1, 1, 1, 1, 1, 1, 1, 1, 1 ],
6 | [0, 0, 1, 1, 1, 1, 1, 0, 0 ],
7 | [1, 1, 1, 1, 1, 1, 1, 1, 1 ],
8 | [1, 1, 1, 1, 1, 1, 1, 1, 1 ],
9 | [1, 1, 1, 1, 1, 1, 1, 1, 1 ],
10 | [0, 1, 1, 0, 0, 0, 1, 1, 0 ] ],
11 |
12 | "targetScore" : 1500,
13 | "moves" : 15,
14 | }
15 |
--------------------------------------------------------------------------------
/Levels/Level_2.json:
--------------------------------------------------------------------------------
1 | {
2 | "tiles" : [ [1, 1, 0, 0, 1, 0, 0, 1, 1 ],
3 | [1, 0, 0, 1, 1, 1, 0, 0, 1 ],
4 | [0, 0, 1, 1, 1, 1, 1, 0, 0 ],
5 | [0, 1, 1, 1, 0, 1, 1, 1, 0 ],
6 | [1, 1, 1, 0, 0, 0, 1, 1, 1 ],
7 | [0, 1, 1, 1, 0, 1, 1, 1, 0 ],
8 | [0, 0, 1, 1, 1, 1, 1, 0, 0 ],
9 | [1, 0, 0, 1, 1, 1, 0, 0, 1 ],
10 | [1, 1, 0, 0, 1, 0, 0, 1, 1 ] ],
11 |
12 | "targetScore" : 1500,
13 | "moves" : 15,
14 | }
15 |
--------------------------------------------------------------------------------
/Levels/Level_3.json:
--------------------------------------------------------------------------------
1 | {
2 | "tiles" : [ [0, 0, 1, 0, 0, 0, 1, 0, 0 ],
3 | [0, 1, 1, 1, 1, 1, 1, 1, 0 ],
4 | [1, 1, 0, 1, 1, 1, 0, 1, 1 ],
5 | [1, 1, 1, 1, 1, 1, 1, 1, 1 ],
6 | [0, 1, 1, 1, 1, 1, 1, 1, 0 ],
7 | [1, 1, 1, 1, 1, 1, 1, 1, 1 ],
8 | [1, 0, 1, 1, 1, 1, 1, 0, 1 ],
9 | [1, 0, 1, 1, 1, 1, 1, 0, 1 ],
10 | [0, 0, 1, 0, 0, 0, 1, 0, 0 ] ],
11 |
12 | "targetScore" : 1000,
13 | "moves" : 10,
14 | }
15 |
--------------------------------------------------------------------------------
/Levels/Level_4.json:
--------------------------------------------------------------------------------
1 | {
2 | "tiles" : [ [0, 0, 0, 0, 0, 0, 0, 0, 0 ],
3 | [0, 0, 0, 0, 0, 0, 0, 0, 0 ],
4 | [0, 0, 0, 0, 0, 0, 0, 0, 0 ],
5 | [0, 0, 0, 1, 1, 1, 0, 0, 0 ],
6 | [0, 0, 0, 1, 1, 1, 0, 0, 0 ],
7 | [0, 0, 0, 1, 1, 1, 0, 0, 0 ],
8 | [0, 0, 0, 0, 0, 0, 0, 0, 0 ],
9 | [0, 0, 0, 0, 0, 0, 0, 0, 0 ],
10 | [0, 0, 0, 0, 0, 0, 0, 0, 0 ] ],
11 |
12 | "targetScore" : 500,
13 | "moves" : 20,
14 | }
15 |
--------------------------------------------------------------------------------
/CookieCrunch/Array2D.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Array2D.swift
3 | // CookieCrunch
4 | //
5 | // Created by Nils Bernhardt on 17.06.16.
6 | // Copyright © 2016 Nils Bernhardt. All rights reserved.
7 | //
8 |
9 | struct Array2D {
10 | let columns: Int
11 | let rows: Int
12 | private var array: Array
13 |
14 | init (columns: Int, rows: Int) {
15 | self.columns = columns
16 | self.rows = rows
17 | array = Array(count: rows*columns, repeatedValue: nil)
18 | }
19 |
20 | subscript(colum: Int, row: Int) -> T? {
21 | get {
22 | return array[row*columns + colum]
23 | }
24 | set {
25 | array [row*columns + colum] = newValue
26 | }
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/Cookie Crunch Adventure.xcodeproj/xcuserdata/nilsbernhardt.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | CookieCrunch.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | EE9E10FA1D12EB46009B1A02
16 |
17 | primary
18 |
19 |
20 | EE9E11121D12EB47009B1A02
21 |
22 | primary
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/CookieCrunchTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/CookieCrunch/Swap.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Swap.swift
3 | // CookieCrunch
4 | //
5 | // Created by Nils Bernhardt on 17.06.16.
6 | // Copyright © 2016 Nils Bernhardt. All rights reserved.
7 | //
8 |
9 | struct Swap: CustomStringConvertible, Hashable {
10 | let cookieA: Cookie
11 | let cookieB: Cookie
12 |
13 | init(cookieA: Cookie, cookieB: Cookie) {
14 | self.cookieA = cookieA
15 | self.cookieB = cookieB
16 | }
17 |
18 | var description: String {
19 | return "swap \(cookieA) with \(cookieB)"
20 | }
21 |
22 | var hashValue: Int {
23 | return cookieA.hashValue ^ cookieB.hashValue
24 | }
25 | }
26 |
27 | func ==(lhs: Swap, rhs: Swap) -> Bool {
28 | return (lhs.cookieA == rhs.cookieA && lhs.cookieB == rhs.cookieB) ||
29 | (lhs.cookieB == rhs.cookieA && lhs.cookieA == rhs.cookieB)
30 | }
--------------------------------------------------------------------------------
/CookieCrunch/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "29x29",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-Small@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "29x29",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-Small@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "40x40",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-40@2x.png",
19 | "scale" : "2x"
20 | },
21 | {
22 | "size" : "40x40",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-40@2x-2.png",
25 | "scale" : "3x"
26 | },
27 | {
28 | "size" : "60x60",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-60@2x.png",
31 | "scale" : "2x"
32 | },
33 | {
34 | "size" : "60x60",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-60@3x.png",
37 | "scale" : "3x"
38 | }
39 | ],
40 | "info" : {
41 | "version" : 1,
42 | "author" : "xcode"
43 | }
44 | }
--------------------------------------------------------------------------------
/CookieCrunchTests/CookieCrunchTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CookieCrunchTests.swift
3 | // CookieCrunchTests
4 | //
5 | // Created by Nils Bernhardt on 16.06.16.
6 | // Copyright © 2016 Nils Bernhardt. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import CookieCrunch
11 |
12 | class CookieCrunchTests: XCTestCase {
13 |
14 | override func setUp() {
15 | super.setUp()
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 | }
18 |
19 | override func tearDown() {
20 | // Put teardown code here. This method is called after the invocation of each test method in the class.
21 | super.tearDown()
22 | }
23 |
24 | func testExample() {
25 | // This is an example of a functional test case.
26 | // Use XCTAssert and related functions to verify your tests produce the correct results.
27 | }
28 |
29 | func testPerformanceExample() {
30 | // This is an example of a performance test case.
31 | self.measureBlock {
32 | // Put the code you want to measure the time of here.
33 | }
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/CookieCrunch/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main2
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UIStatusBarHidden
34 |
35 | UISupportedInterfaceOrientations
36 |
37 | UIInterfaceOrientationPortrait
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/CookieCrunch/Extensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Extensions.swift
3 | // CookieCrunch
4 | //
5 | // Created by Nils Bernhardt on 17.06.16.
6 | // Copyright © 2016 Nils Bernhardt. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | // JSON-Handling
12 | extension Dictionary {
13 | static func loadJSONFromBundle(filename: String) -> Dictionary ? {
14 | var dataOK: NSData
15 | var dictionaryOK: NSDictionary = NSDictionary()
16 |
17 | if let path = NSBundle.mainBundle().pathForResource(filename, ofType: "json") {
18 | let _: NSError?
19 | do {
20 | let data = try NSData(contentsOfFile: path, options: NSDataReadingOptions()) as NSData!
21 | dataOK = data
22 | }
23 | catch {
24 | print("Could not load file: \(filename), error: \(error)")
25 | return nil
26 | }
27 |
28 | do {
29 | let dictionary = try NSJSONSerialization.JSONObjectWithData(dataOK, options: NSJSONReadingOptions()) as AnyObject!
30 | dictionaryOK = (dictionary as! NSDictionary as? Dictionary )!
31 | }
32 | catch {
33 | print("file '\(filename)' is not valid JSON: \(error)")
34 | return nil
35 | }
36 | }
37 |
38 | return dictionaryOK as? Dictionary
39 | }
40 | }
--------------------------------------------------------------------------------
/CookieCrunch/Chain.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Chain.swift
3 | // CookieCrunch
4 | //
5 | // Created by Nils Bernhardt on 17.06.16.
6 | // Copyright © 2016 Nils Bernhardt. All rights reserved.
7 | //
8 |
9 | class Chain: Hashable, CustomStringConvertible {
10 | var cookies = [Cookie]()
11 | var chainType: ChainType
12 | var score = 0
13 |
14 | enum ChainType: CustomStringConvertible {
15 | case Horizontal
16 | case Vertical
17 |
18 | var description: String {
19 | switch self {
20 | case .Horizontal: return "Horizontal"
21 | case .Vertical: return "Vertical"
22 | }
23 | }
24 | }
25 |
26 | // Initializer
27 | init(chainType: ChainType) {
28 | self.chainType = chainType
29 | }
30 |
31 |
32 | // Methods
33 | // *******
34 | func addCookie(cookie: Cookie) {
35 | cookies.append(cookie)
36 | }
37 |
38 | func firstCookie() -> Cookie {
39 | return cookies[0]
40 | }
41 |
42 | func lastCookie() -> Cookie {
43 | return cookies[cookies.count - 1]
44 | }
45 |
46 | var length: Int {
47 | return cookies.count
48 | }
49 |
50 | var description: String {
51 | return "type:\(chainType) cookies:\(cookies)"
52 | }
53 |
54 | var hashValue: Int {
55 | return cookies.reduce (0) { $0.hashValue ^ $1.hashValue }
56 | }
57 | // ********
58 | }
59 |
60 | func ==(lhs: Chain, rhs: Chain) -> Bool {
61 | return lhs.cookies == rhs.cookies
62 | }
63 |
--------------------------------------------------------------------------------
/CookieCrunch/Cookie.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Cookie.swift
3 | // CookieCrunch
4 | //
5 | // Created by Nils Bernhardt on 16.06.16.
6 | // Copyright © 2016 Nils Bernhardt. All rights reserved.
7 | //
8 |
9 | import SpriteKit
10 |
11 | enum CookieType: Int, CustomStringConvertible {
12 | case Unknown = 0, Croissant, Cupcake, Danish, Donut, Macaroon, SugarCookie
13 |
14 | var spriteName: String {
15 | let spriteNames = [
16 | "Croissant",
17 | "Cupcake",
18 | "Danish",
19 | "Donut",
20 | "Macaroon",
21 | "SugarCookie"]
22 |
23 | return spriteNames[rawValue - 1]
24 | }
25 |
26 | var highlightedSpriteName: String {
27 | return spriteName + "-Highlighted"
28 | }
29 |
30 | static func random() -> CookieType {
31 | return CookieType(rawValue: Int(arc4random_uniform(6)) + 1)!
32 | }
33 |
34 | var description: String {
35 | return spriteName
36 | }
37 | }
38 |
39 | class Cookie: CustomStringConvertible, Hashable {
40 | var column: Int
41 | var row: Int
42 | let cookieType: CookieType
43 | var sprite: SKSpriteNode?
44 |
45 | init(column: Int, row: Int, cookieType: CookieType) {
46 | self.column = column
47 | self.row = row
48 | self.cookieType = cookieType
49 | }
50 |
51 | var description: String {
52 | return "type:\(cookieType) square:(\(column),\(row))"
53 | }
54 |
55 | var hashValue: Int {
56 | return row*10 + column
57 | }
58 | }
59 |
60 | func ==(lhs: Cookie, rhs: Cookie) -> Bool {
61 | return lhs.column == rhs.column && lhs.row == rhs.row
62 | }
63 |
--------------------------------------------------------------------------------
/CookieCrunch/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/CookieCrunch/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // CookieCrunch
4 | //
5 | // Created by Nils Bernhardt on 16.06.16.
6 | // Copyright © 2016 Nils Bernhardt. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(application: UIApplication) {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/Cookie Crunch Adventure.xcodeproj/xcuserdata/nilsbernhardt.xcuserdatad/xcschemes/CookieCrunch.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
53 |
54 |
64 |
66 |
72 |
73 |
74 |
75 |
76 |
77 |
83 |
85 |
91 |
92 |
93 |
94 |
96 |
97 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/CookieCrunch/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
30 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/CookieCrunch/GameViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GameViewController.swift
3 | // CookieCrunch
4 | //
5 | // Created by Nils Bernhardt on 16.06.16.
6 | // Copyright (c) 2016 Nils Bernhardt. All rights reserved.
7 | // Based upon tutorial:
8 | // https://www.raywenderlich.com/125311/make-game-like-candy-crush-spritekit-swift-part-1
9 | //
10 |
11 | import UIKit
12 | import SpriteKit
13 | import AVFoundation
14 |
15 | class GameViewController: UIViewController {
16 | var scene: GameScene!
17 | var level: Level!
18 | var movesLeft = 0
19 | var score = 0
20 | var currentLevelNum = 0
21 |
22 | @IBOutlet weak var targetLabel: UILabel!
23 | @IBOutlet weak var movesLabel: UILabel!
24 | @IBOutlet weak var scoreLabel: UILabel!
25 |
26 | @IBOutlet weak var gameOverPanel: UIImageView!
27 | var tapGestureRecognizer: UITapGestureRecognizer!
28 |
29 | @IBOutlet weak var shuffleButton: UIButton!
30 | @IBAction func shuffleButtonPressed(_: AnyObject) {
31 | shuffle()
32 | decrementMoves()
33 | }
34 |
35 | func beginGame() {
36 | movesLeft = level.maximumMoves
37 | score = 0
38 | updateLabels()
39 | level.resetComboMultiplier()
40 | scene.animateBeginGame() {
41 | self.shuffleButton.hidden = false
42 | }
43 | shuffle()
44 | }
45 |
46 | func shuffle() {
47 | scene.removeAllCookieSprites()
48 | let newCookies = level.shuffle()
49 | scene.addSpritesForCookies(newCookies)
50 | }
51 |
52 | override func prefersStatusBarHidden() -> Bool {
53 | return true
54 | }
55 |
56 | override func shouldAutorotate() -> Bool {
57 | return true
58 | }
59 |
60 | override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask {
61 | return [UIInterfaceOrientationMask.Portrait, UIInterfaceOrientationMask.PortraitUpsideDown]
62 | }
63 |
64 | override func viewDidLoad() {
65 | super.viewDidLoad()
66 |
67 | // Setup view with level 1
68 | setupLevel(currentLevelNum)
69 |
70 | // Start the background music.
71 | backgroundMusic?.play()
72 | }
73 |
74 | func setupLevel(levelNum: Int) {
75 | let skView = view as! SKView
76 | skView.multipleTouchEnabled = false
77 |
78 | // Create and configure the scene.
79 | scene = GameScene(size: skView.bounds.size)
80 | scene.scaleMode = .AspectFill
81 |
82 | // Setup the level.
83 | level = Level(filename: "Level_\(levelNum)")
84 | scene.level = level
85 |
86 | scene.addTiles()
87 | scene.swipeHandler = handleSwipe
88 |
89 | gameOverPanel.hidden = true
90 | shuffleButton.hidden = true
91 |
92 | // Present the scene.
93 | skView.presentScene(scene)
94 |
95 | // Start the game.
96 | beginGame()
97 | }
98 |
99 | func handleSwipe(swap: Swap) {
100 | view.userInteractionEnabled = false
101 |
102 | if level.isPossibleSwap(swap) {
103 | level.performSwap(swap)
104 | scene.animateSwap(swap) {
105 | self.handleMatches()
106 | self.view.userInteractionEnabled = true
107 | }
108 | } else {
109 | scene.animateInvalidSwap(swap) {
110 | self.view.userInteractionEnabled = true
111 | }
112 | }
113 | }
114 |
115 | func beginNextTurn() {
116 | level.resetComboMultiplier()
117 | level.detectPossibleSwaps()
118 | view.userInteractionEnabled = true
119 | decrementMoves()
120 | }
121 |
122 | func handleMatches() {
123 | let chains = level.removeMatches()
124 |
125 | if chains.count == 0 {
126 | beginNextTurn()
127 | return
128 | }
129 |
130 | scene.animateMatchedCookies(chains) {
131 | for chain in chains {
132 | self.score += chain.score
133 | }
134 | self.updateLabels()
135 |
136 | let columns = self.level.fillHoles()
137 | self.scene.animateFallingCookies(columns) {
138 | let columns = self.level.topUpCookies()
139 | self.scene.animateNewCookies(columns) {
140 | self.handleMatches()
141 | }
142 | }
143 | }
144 | }
145 |
146 | func updateLabels() {
147 | targetLabel.text = String(format: "%ld", level.targetScore)
148 | movesLabel.text = String(format: "%ld", movesLeft)
149 | scoreLabel.text = String(format: "%ld", score)
150 | }
151 |
152 | func decrementMoves() {
153 | movesLeft -= 1
154 | updateLabels()
155 |
156 | if score >= level.targetScore {
157 | gameOverPanel.image = UIImage(named: "LevelComplete")
158 | currentLevelNum = currentLevelNum < NumLevels ? currentLevelNum+1 : 1
159 | showGameOver()
160 | } else if movesLeft == 0 {
161 | gameOverPanel.image = UIImage(named: "GameOver")
162 | showGameOver()
163 | }
164 | }
165 |
166 | func showGameOver() {
167 | gameOverPanel.hidden = false
168 | scene.userInteractionEnabled = false
169 | shuffleButton.hidden = true
170 |
171 | scene.animateGameOver() {
172 | self.tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.hideGameOver))
173 | self.view.addGestureRecognizer(self.tapGestureRecognizer)
174 | }
175 | }
176 |
177 | func hideGameOver() {
178 | view.removeGestureRecognizer(tapGestureRecognizer)
179 | tapGestureRecognizer = nil
180 |
181 | gameOverPanel.hidden = true
182 | scene.userInteractionEnabled = true
183 |
184 | setupLevel(currentLevelNum)
185 | }
186 |
187 | lazy var backgroundMusic: AVAudioPlayer? = {
188 | guard let url = NSBundle.mainBundle().URLForResource("Mining by Moonlight", withExtension: "mp3") else {
189 | return nil
190 | }
191 | do {
192 | let player = try AVAudioPlayer(contentsOfURL: url)
193 | player.numberOfLoops = -1
194 | return player
195 | } catch {
196 | return nil
197 | }
198 | }()
199 |
200 | }
--------------------------------------------------------------------------------
/CookieCrunch/Base.lproj/Main2.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
35 |
43 |
44 |
45 |
46 |
47 |
48 |
56 |
64 |
65 |
66 |
67 |
68 |
69 |
77 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
--------------------------------------------------------------------------------
/CookieCrunch/Level.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Level.swift
3 | // CookieCrunch
4 | //
5 | // Created by Nils Bernhardt on 17.06.16.
6 | // Copyright © 2016 Nils Bernhardt. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | let NumColumns = 9
12 | let NumRows = 9
13 | let NumLevels = 5
14 |
15 | class Level {
16 | private var cookies = Array2D(columns: NumColumns, rows: NumRows)
17 | private var tiles = Array2D(columns: NumColumns, rows: NumRows)
18 | private var possibleSwaps = Set()
19 |
20 | var targetScore = 0
21 | var maximumMoves = 0
22 | private var comboMultiplier = 0
23 |
24 |
25 | private func createInitialCookies() -> Set {
26 | var set = Set()
27 |
28 | // 1: Loop through rows and columns of 2D Array
29 | for row in 0..= 2 &&
38 | cookies[column - 1, row]?.cookieType == cookieType &&
39 | cookies[column - 2, row]?.cookieType == cookieType)
40 | || (row >= 2 &&
41 | cookies[column, row - 1]?.cookieType == cookieType &&
42 | cookies[column, row - 2]?.cookieType == cookieType)
43 |
44 | // 3: Create new cookie object and add to array
45 | let cookie = Cookie(column: column, row: row, cookieType: cookieType)
46 | cookies[column, row] = cookie
47 |
48 | // 4: Add new cookie object to Set
49 | set.insert(cookie)
50 | }
51 | }
52 | }
53 | return set
54 | }
55 |
56 | private func hasChainAtColumn(column: Int, row: Int) -> Bool {
57 | let cookieType = cookies[column, row]!.cookieType
58 |
59 | // Horizontal chain check
60 | var horzLength = 1
61 |
62 | // Left
63 | var i = column - 1
64 | while i >= 0 && cookies[i, row]?.cookieType == cookieType {
65 | i -= 1
66 | horzLength += 1
67 | }
68 |
69 | // Right
70 | i = column + 1
71 | while i < NumColumns && cookies[i, row]?.cookieType == cookieType {
72 | i += 1
73 | horzLength += 1
74 | }
75 | if horzLength >= 3 { return true }
76 |
77 | // Vertical chain check
78 | var vertLenght = 1
79 |
80 | // Down
81 | i = row - 1
82 | while i >= 0 && cookies[column, i]?.cookieType == cookieType {
83 | i -= 1
84 | vertLenght += 1
85 | }
86 |
87 | // Up
88 | i = row + 1
89 | while i < NumRows && cookies[column, i]?.cookieType == cookieType {
90 | i += 1
91 | vertLenght += 1
92 | }
93 | return vertLenght >= 3
94 | }
95 |
96 | private func detectHorizontalMatches() -> Set {
97 | // 1: Create new set to hold horizontal chains
98 | var set = Set()
99 |
100 | // 2: Loop through rows and columns
101 | for row in 0.. Set {
130 | // 1
131 | var set = Set()
132 |
133 | // 2
134 | for column in 0..) {
162 | for chain in chains {
163 | for cookie in chain.cookies {
164 | cookies[cookie.column, cookie.row] = nil
165 | }
166 | }
167 | }
168 |
169 | private func calculateScores(chains: Set) {
170 | // 3-chain is 60 pts, 4-chain is 120, 5-chain is 180, and so on
171 | for chain in chains {
172 | chain.score = 60 * (chain.length - 2) * comboMultiplier
173 | comboMultiplier += 1
174 | }
175 | }
176 |
177 | init(filename: String) {
178 | // 1: Load the named file into Dictionary
179 | guard let dictionary = Dictionary.loadJSONFromBundle(filename) else {
180 | print("Error loading JSON")
181 | return
182 | }
183 | // 2: Get Tiles-Description from JSON
184 | guard let tilesArray = dictionary["tiles"] as? [[Int]] else {
185 | print("Error parsing tiles-array in json-file")
186 | return
187 | }
188 | // 3:
189 | for (row, rowArray) in tilesArray.enumerate() {
190 | // 4
191 | let tileRow = NumRows - row - 1
192 |
193 | for (column, value) in rowArray.enumerate() {
194 | if value == 1 {
195 | tiles[column, tileRow] = Tile()
196 | }
197 | }
198 | }
199 |
200 | targetScore = dictionary["targetScore"] as! Int
201 | maximumMoves = dictionary["moves"] as! Int
202 | }
203 |
204 | func tileAtColumn(column: Int, row: Int) -> Tile? {
205 | assert(column >= 0 && column < NumColumns)
206 | assert(row >= 0 && row < NumRows)
207 | return tiles[column, row]
208 | }
209 |
210 | func cookieAtColumn(column: Int, row: Int) -> Cookie? {
211 | assert(column >= 0 && column < NumColumns)
212 | assert(row >= 0 && row < NumRows)
213 | return cookies[column, row]
214 | }
215 |
216 | func shuffle() -> Set {
217 | //return createInitialCookies()
218 | var set: Set
219 | repeat {
220 | set = createInitialCookies()
221 | detectPossibleSwaps()
222 | print("possible swaps: \(possibleSwaps)")
223 | } while possibleSwaps.count == 0
224 |
225 | return set
226 | }
227 |
228 | func performSwap(swap: Swap) {
229 | let columnA = swap.cookieA.column
230 | let rowA = swap.cookieA.row
231 | let columnB = swap.cookieB.column
232 | let rowB = swap.cookieB.row
233 |
234 | cookies[columnA, rowA] = swap.cookieB
235 | swap.cookieB.column = columnA
236 | swap.cookieB.row = rowA
237 |
238 | cookies[columnB, rowB] = swap.cookieA
239 | swap.cookieA.column = columnB
240 | swap.cookieA.row = rowB
241 | }
242 |
243 | func detectPossibleSwaps() {
244 | var set = Set()
245 |
246 | for row in 0.. Bool {
293 | return possibleSwaps.contains(swap)
294 | }
295 |
296 | func removeMatches() -> Set {
297 | let horizontalChains = detectHorizontalMatches()
298 | let verticalChains = detectVerticalMatches()
299 |
300 | removeCookie(horizontalChains)
301 | removeCookie(verticalChains
302 | )
303 |
304 | calculateScores(horizontalChains)
305 | calculateScores(verticalChains)
306 |
307 | return horizontalChains.union(verticalChains)
308 | }
309 |
310 | func fillHoles() -> [[Cookie]] {
311 | var columns = [[Cookie]]()
312 |
313 | // 1: Loop through rows from bottom to top
314 | for column in 0.. [[Cookie]] {
346 | var columns = [[Cookie]]()
347 | var cookieType: CookieType = .Unknown
348 |
349 | for column in 0..= 0 && cookies[column, row] == nil {
355 | // 2: Ignore gaps: They do not need to be filled with new cookies.
356 | if tiles[column, row] != nil {
357 | // 3: Randomly create new cookies, but not of the type the previous one was of.
358 | var newCookieType: CookieType
359 | repeat {
360 | newCookieType = CookieType.random()
361 | } while newCookieType == cookieType
362 | cookieType = newCookieType
363 | // 4: Create new cookie object and add it to array
364 | let cookie = Cookie(column: column, row: row, cookieType: cookieType)
365 | cookies[column, row] = cookie
366 | array.append(cookie)
367 | }
368 |
369 | row -= 1
370 | }
371 | // 5: If column did not have any holes, do not add to final array
372 | if !array.isEmpty {
373 | columns.append(array)
374 | }
375 | }
376 | return columns
377 | }
378 |
379 | func resetComboMultiplier() {
380 | comboMultiplier = 1
381 | }
382 |
383 |
384 | }
--------------------------------------------------------------------------------
/CookieCrunch/GameScene.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GameScene.swift
3 | // CookieCrunch
4 | //
5 | // Created by Nils Bernhardt on 16.06.16.
6 | // Copyright (c) 2016 Nils Bernhardt. All rights reserved.
7 | //
8 |
9 | import SpriteKit
10 |
11 | class GameScene: SKScene {
12 | var level: Level!
13 | var swipeFromColumn: Int?
14 | var swipeFromRow: Int?
15 | var swipeHandler: ((Swap) -> ())?
16 | var selectionSprite = SKSpriteNode()
17 | let cropLayer = SKCropNode()
18 | let maskLayer = SKNode()
19 |
20 | // Sounds
21 | let swapSound = SKAction.playSoundFileNamed("Chomp.wav", waitForCompletion: false)
22 | let invalidSwapSound = SKAction.playSoundFileNamed("Error.wav", waitForCompletion: false)
23 | let matchSound = SKAction.playSoundFileNamed("Ka-Ching.wav", waitForCompletion: false)
24 | let fallingCookieSound = SKAction.playSoundFileNamed("Scrape.wav", waitForCompletion: false)
25 | let addCookieSound = SKAction.playSoundFileNamed("Drip.wav", waitForCompletion: false)
26 |
27 | let TileWidth: CGFloat = 32.0
28 | let TileHeight: CGFloat = 36.0
29 |
30 | // Game-Layers
31 | let gameLayer = SKNode()
32 | let tilesLayer = SKNode()
33 | let cookiesLayer = SKNode()
34 |
35 | required init?(coder aDecoder: NSCoder) {
36 | fatalError("init(coder) is not used in this app")
37 | }
38 |
39 | // Initializer
40 | override init(size: CGSize) {
41 | super.init(size: size)
42 |
43 | anchorPoint = CGPoint(x: 0.5, y: 0.5)
44 |
45 | let background = SKSpriteNode(imageNamed: "Background")
46 | background.size = size
47 |
48 | // Add Background to Scene
49 | addChild(background)
50 |
51 | // Add Gamelayer to Scene
52 | addChild(gameLayer)
53 | gameLayer.hidden = true
54 |
55 | let layerPosition = CGPoint(
56 | x: -TileWidth * CGFloat(NumColumns) / 2,
57 | y: -TileHeight * CGFloat(NumRows) / 2)
58 |
59 | // Add Tiles-Layer to Scene
60 | tilesLayer.position = layerPosition
61 | gameLayer.addChild(tilesLayer)
62 |
63 | // Add Crop-Layer to Scene
64 | gameLayer.addChild(cropLayer)
65 | maskLayer.position = layerPosition
66 | cropLayer.maskNode = maskLayer
67 |
68 | // Add Cookies-Layer to Scene
69 | cookiesLayer.position = layerPosition
70 | cropLayer.addChild(cookiesLayer)
71 |
72 | // Initialize Swipe: No Swipe-Action running
73 | swipeFromRow = nil
74 | swipeFromColumn = nil
75 |
76 | let _ = SKLabelNode(fontNamed: "GillSans-BoldItalic")
77 | }
78 |
79 | override func touchesBegan(touches: Set, withEvent event: UIEvent?) {
80 | // 1: Convert touch location relative to cookie layer
81 | guard let touch = touches.first else { return }
82 | let location = touch.locationInNode(cookiesLayer)
83 |
84 | // 2: Check if touch is within the 9x9 game grid
85 | let (success, column, row) = convertPoint(location)
86 | if success {
87 | // 3: Check if touch is on a cookie rather then on an empty square
88 | if let cookie = level.cookieAtColumn(column, row: row) {
89 | // 4: Record column & row where the swipe started
90 | showSelectionIndicatorForCookie(cookie)
91 | swipeFromColumn = column
92 | swipeFromRow = row
93 | }
94 | }
95 | }
96 |
97 | override func touchesMoved(touches: Set, withEvent event: UIEvent?) {
98 | // 1: Check if it is a valid swipe
99 | guard swipeFromColumn != nil else { return }
100 |
101 | // 2: Calc Row / Col under players finger
102 | guard let touch = touches.first else { return }
103 | let location = touch.locationInNode(cookiesLayer)
104 |
105 | let (success, column, row) = convertPoint(location)
106 | if (success) {
107 | // 3: Figure out the direction of the swipe
108 | var horzDelta = 0, vertDelta = 0
109 | if column < swipeFromColumn! {
110 | horzDelta = -1
111 | } else if column > swipeFromColumn! {
112 | horzDelta = 1
113 | } else if row < swipeFromRow! {
114 | vertDelta = -1
115 | } else if row > swipeFromRow! {
116 | vertDelta = 1
117 | }
118 |
119 | // 4: Only swap if player swiped out of old square
120 | if horzDelta != 0 || vertDelta != 0 {
121 | trySwapHorizontal(horzDelta, vertical: vertDelta)
122 | hideSelectionIndicator()
123 |
124 | // 5: Ignore rest of the motion
125 | swipeFromColumn = nil
126 | }
127 | }
128 | }
129 |
130 | override func touchesEnded(touches: Set, withEvent event: UIEvent?) {
131 | if selectionSprite.parent != nil && swipeFromColumn != nil {
132 | hideSelectionIndicator()
133 | }
134 |
135 | swipeFromRow = nil
136 | swipeFromColumn = nil
137 | }
138 |
139 | override func touchesCancelled(touches: Set?, withEvent event: UIEvent?) {
140 | if let touches = touches {
141 | touchesEnded(touches, withEvent: event)
142 | }
143 | }
144 |
145 |
146 | // Methods
147 | // *******
148 | func trySwapHorizontal(horzDelta: Int, vertical vertDelta: Int) {
149 | // 1: Calculate the column and row numbers of the cookie to swap with
150 | let toColumn = swipeFromColumn! + horzDelta
151 | let toRow = swipeFromRow! + vertDelta
152 |
153 | // 2: It is possible that the toColumn or toRow is outside the 9×9 grid. Ignore these swipes.
154 | guard toColumn >= 0 && toColumn < NumColumns else { return }
155 | guard toRow >= 0 && toRow < NumRows else { return }
156 |
157 | // 3: Check to make sure that there is actually a cookie at the new position.
158 | if let toCookie = level.cookieAtColumn(toColumn, row: toRow) {
159 | let fromCookie = level.cookieAtColumn(swipeFromColumn!, row: swipeFromRow!)
160 |
161 | // 4: Got until here? OK, it is a valid swap! Do it!
162 | //print("*** swapping \(fromCookie) with \(toCookie)")
163 | if let handler = swipeHandler {
164 | let swap = Swap(cookieA: fromCookie!, cookieB: toCookie)
165 | handler(swap)
166 | }
167 | }
168 | }
169 |
170 | func animateSwap(swap: Swap, completion: () -> ()) {
171 | let spriteA = swap.cookieA.sprite!
172 | let spriteB = swap.cookieB.sprite!
173 |
174 | spriteA.zPosition = 100
175 | spriteB.zPosition = 90
176 |
177 | let Duration: NSTimeInterval = 0.3
178 |
179 | let moveA = SKAction.moveTo(spriteB.position, duration: Duration)
180 | moveA.timingMode = .EaseOut
181 | spriteA.runAction(moveA, completion: completion)
182 |
183 | let moveB = SKAction.moveTo(spriteA.position, duration: Duration)
184 | moveB.timingMode = .EaseOut
185 | spriteB.runAction(moveB)
186 |
187 | runAction(swapSound)
188 | }
189 |
190 | func animateInvalidSwap(swap: Swap, completion: () -> ()) {
191 | let spriteA = swap.cookieA.sprite!
192 | let spriteB = swap.cookieB.sprite!
193 |
194 | spriteA.zPosition = 100
195 | spriteB.zPosition = 90
196 |
197 | let Duration: NSTimeInterval = 0.2
198 |
199 | let moveA = SKAction.moveTo(spriteB.position, duration: Duration)
200 | moveA.timingMode = .EaseOut
201 |
202 | let moveB = SKAction.moveTo(spriteA.position, duration: Duration)
203 | moveB.timingMode = .EaseOut
204 |
205 | spriteA.runAction(SKAction.sequence([moveA, moveB]), completion: completion)
206 | spriteB.runAction(SKAction.sequence([moveB, moveA]))
207 |
208 | runAction(invalidSwapSound)
209 | }
210 |
211 | func animateMatchedCookies(chains: Set, completion: () -> ()) {
212 | for chain in chains {
213 | animateScoreForChain(chain)
214 |
215 | for cookie in chain.cookies {
216 | if let sprite = cookie.sprite {
217 | if sprite.actionForKey("removing") == nil {
218 | let scaleAction = SKAction.scaleTo(0.1, duration: 0.3)
219 | scaleAction.timingMode = .EaseOut
220 | sprite.runAction(SKAction.sequence([scaleAction, SKAction.removeFromParent()]), withKey: "removing")
221 | }
222 | }
223 | }
224 | }
225 | runAction(matchSound)
226 | runAction(SKAction.waitForDuration(0.3), completion: completion)
227 | }
228 |
229 | func animateFallingCookies(columns: [[Cookie]], completion: () -> ()) {
230 | // 1
231 | var longestDuration: NSTimeInterval = 0
232 | for array in columns {
233 | for (idx, cookie) in array.enumerate() {
234 | let newPosition = pointForColumn(cookie.column, row: cookie.row)
235 | // 2
236 | let delay = 0.05 + 0.15*NSTimeInterval(idx)
237 | // 3
238 | let sprite = cookie.sprite!
239 | let duration = NSTimeInterval(((sprite.position.y - newPosition.y) / TileHeight) * 0.1)
240 | // 4
241 | longestDuration = max(longestDuration, duration + delay)
242 | // 5
243 | let moveAction = SKAction.moveTo(newPosition, duration: duration)
244 | moveAction.timingMode = .EaseOut
245 | sprite.runAction(
246 | SKAction.sequence([
247 | SKAction.waitForDuration(delay),
248 | SKAction.group([moveAction, fallingCookieSound])]))
249 | }
250 | }
251 | // 6
252 | runAction(SKAction.waitForDuration(longestDuration), completion: completion)
253 | }
254 |
255 | func animateNewCookies(columns: [[Cookie]], completion: () -> ()) {
256 | // 1
257 | var longestDuration: NSTimeInterval = 0
258 |
259 | for array in columns {
260 | // 2
261 | let startRow = array[0].row + 1
262 |
263 | for (idx, cookie) in array.enumerate() {
264 | // 3
265 | let sprite = SKSpriteNode(imageNamed: cookie.cookieType.spriteName)
266 | sprite.size = CGSize(width: TileWidth, height: TileHeight)
267 | sprite.position = pointForColumn(cookie.column, row: startRow)
268 | cookiesLayer.addChild(sprite)
269 | cookie.sprite = sprite
270 | // 4
271 | let delay = 0.1 + 0.2 * NSTimeInterval(array.count - idx - 1)
272 | // 5
273 | let duration = NSTimeInterval(startRow - cookie.row) * 0.1
274 | longestDuration = max(longestDuration, duration + delay)
275 | // 6
276 | let newPosition = pointForColumn(cookie.column, row: cookie.row)
277 | let moveAction = SKAction.moveTo(newPosition, duration: duration)
278 | moveAction.timingMode = .EaseOut
279 | sprite.alpha = 0
280 | sprite.runAction(
281 | SKAction.sequence([
282 | SKAction.waitForDuration(delay),
283 | SKAction.group([
284 | SKAction.fadeInWithDuration(0.05),
285 | moveAction,
286 | addCookieSound])
287 | ]))
288 | }
289 | }
290 | // 7
291 | runAction(SKAction.waitForDuration(longestDuration), completion: completion)
292 | }
293 |
294 | func animateScoreForChain(chain: Chain) {
295 | // Figure out what the midpoint of the chain is.
296 | let firstSprite = chain.firstCookie().sprite!
297 | let lastSprite = chain.lastCookie().sprite!
298 | let centerPosition = CGPoint(
299 | x: (firstSprite.position.x + lastSprite.position.x)/2,
300 | y: (firstSprite.position.y + lastSprite.position.y)/2 - 8)
301 |
302 | // Add a label for the score that slowly floats up.
303 | let scoreLabel = SKLabelNode(fontNamed: "GillSans-BoldItalic")
304 | scoreLabel.fontSize = 16
305 | scoreLabel.text = String(format: "%ld", chain.score)
306 | scoreLabel.position = centerPosition
307 | scoreLabel.zPosition = 300
308 | cookiesLayer.addChild(scoreLabel)
309 |
310 | let moveAction = SKAction.moveBy(CGVector(dx: 0, dy: 3), duration: 0.7)
311 | moveAction.timingMode = .EaseOut
312 | scoreLabel.runAction(SKAction.sequence([moveAction, SKAction.removeFromParent()]))
313 | }
314 |
315 | func animateGameOver(completion: () -> ()) {
316 | let action = SKAction.moveBy(CGVector(dx: 0, dy: -size.height), duration: 0.3)
317 | action.timingMode = .EaseIn
318 | gameLayer.runAction(action, completion: completion)
319 | }
320 |
321 | func animateBeginGame(completion: () -> ()) {
322 | gameLayer.hidden = false
323 | gameLayer.position = CGPoint(x: 0, y: size.height)
324 | let action = SKAction.moveBy(CGVector(dx: 0, dy: -size.height), duration: 0.3)
325 | action.timingMode = .EaseOut
326 | gameLayer.runAction(action, completion: completion)
327 | }
328 |
329 | func showSelectionIndicatorForCookie(cookie: Cookie) {
330 | if selectionSprite.parent != nil {
331 | selectionSprite.removeFromParent()
332 | }
333 |
334 | if let sprite = cookie.sprite {
335 | let texture = SKTexture(imageNamed: cookie.cookieType.highlightedSpriteName)
336 | selectionSprite.size = CGSize(width: TileWidth, height: TileHeight)
337 | selectionSprite.runAction(SKAction.setTexture(texture))
338 |
339 | sprite.addChild(selectionSprite)
340 | selectionSprite.alpha = 1.0
341 | }
342 | }
343 |
344 | func hideSelectionIndicator() {
345 | selectionSprite.runAction(SKAction.sequence([
346 | SKAction.fadeOutWithDuration(0.3),
347 | SKAction.removeFromParent()]))
348 | }
349 |
350 | func addSpritesForCookies(cookies: Set) {
351 | for cookie in cookies {
352 | let sprite = SKSpriteNode(imageNamed: cookie.cookieType.spriteName)
353 | sprite.size = CGSize(width: TileWidth, height: TileHeight)
354 | sprite.position = pointForColumn(cookie.column, row: cookie.row)
355 | cookiesLayer.addChild(sprite)
356 | cookie.sprite = sprite
357 |
358 | // Give each cookie sprite a small, random delay. Then fade them in.
359 | sprite.alpha = 0
360 | sprite.xScale = 0.5
361 | sprite.yScale = 0.5
362 |
363 | sprite.runAction(
364 | SKAction.sequence([
365 | SKAction.waitForDuration(0.25, withRange: 0.5),
366 | SKAction.group([
367 | SKAction.fadeInWithDuration(0.25),
368 | SKAction.scaleTo(1.0, duration: 0.25)
369 | ])
370 | ]))
371 | }
372 | }
373 |
374 | func pointForColumn(column: Int, row: Int) -> CGPoint {
375 | return CGPoint(
376 | x: CGFloat(column)*TileWidth + TileWidth/2,
377 | y: CGFloat(row)*TileHeight + TileHeight/2)
378 | }
379 |
380 | func convertPoint(point: CGPoint) -> (success: Bool, column: Int, row: Int) {
381 | if point.x >= 0 && point.x < CGFloat(NumColumns)*TileWidth &&
382 | point.y >= 0 && point.y < CGFloat(NumRows)*TileHeight {
383 | return (true, Int(point.x / TileWidth), Int(point.y / TileHeight))
384 | }
385 | else {
386 | return (false, 0, 0) // Invalid location
387 | }
388 | }
389 |
390 | func addTiles() {
391 | for row in 0.. 0) && (row < NumRows)
405 | && level.tileAtColumn(column - 1, row: row) != nil
406 | let bottomLeft = (column > 0) && (row > 0)
407 | && level.tileAtColumn(column - 1, row: row - 1) != nil
408 | let topRight = (column < NumColumns) && (row < NumRows)
409 | && level.tileAtColumn(column, row: row) != nil
410 | let bottomRight = (column < NumColumns) && (row > 0)
411 | && level.tileAtColumn(column, row: row - 1) != nil
412 |
413 | // The tiles are named from 0 to 15, according to the bitmask that is
414 | // made by combining these four values.
415 | let value = Int(topLeft) | Int(topRight) << 1 | Int(bottomLeft) << 2 | Int(bottomRight) << 3
416 |
417 | // Values 0 (no tiles), 6 and 9 (two opposite tiles) are not drawn.
418 | if value != 0 && value != 6 && value != 9 {
419 | let name = String(format: "Tile_%ld", value)
420 | let tileNode = SKSpriteNode(imageNamed: name)
421 | tileNode.size = CGSize(width: TileWidth, height: TileHeight)
422 | var point = pointForColumn(column, row: row)
423 | point.x -= TileWidth/2
424 | point.y -= TileHeight/2
425 | tileNode.position = point
426 | tilesLayer.addChild(tileNode)
427 | }
428 | }
429 | }
430 | }
431 |
432 | func removeAllCookieSprites() {
433 | cookiesLayer.removeAllChildren()
434 | }
435 | // ***************
436 | }
437 |
--------------------------------------------------------------------------------
/Cookie Crunch Adventure.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | EE88D8341D13F5690079D8C5 /* Level.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE88D8331D13F5690079D8C5 /* Level.swift */; };
11 | EE88D8381D14016A0079D8C5 /* Tile.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE88D8371D14016A0079D8C5 /* Tile.swift */; };
12 | EE88D83A1D1402420079D8C5 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE88D8391D1402420079D8C5 /* Extensions.swift */; };
13 | EE88D8411D14115B0079D8C5 /* Level_0.json in Resources */ = {isa = PBXBuildFile; fileRef = EE88D83C1D14115B0079D8C5 /* Level_0.json */; };
14 | EE88D8421D14115B0079D8C5 /* Level_1.json in Resources */ = {isa = PBXBuildFile; fileRef = EE88D83D1D14115B0079D8C5 /* Level_1.json */; };
15 | EE88D8431D14115B0079D8C5 /* Level_2.json in Resources */ = {isa = PBXBuildFile; fileRef = EE88D83E1D14115B0079D8C5 /* Level_2.json */; };
16 | EE88D8441D14115B0079D8C5 /* Level_3.json in Resources */ = {isa = PBXBuildFile; fileRef = EE88D83F1D14115B0079D8C5 /* Level_3.json */; };
17 | EE88D8451D14115B0079D8C5 /* Level_4.json in Resources */ = {isa = PBXBuildFile; fileRef = EE88D8401D14115B0079D8C5 /* Level_4.json */; };
18 | EE88D8471D141FFE0079D8C5 /* Swap.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE88D8461D141FFE0079D8C5 /* Swap.swift */; };
19 | EE88D84F1D1435C20079D8C5 /* Chomp.wav in Resources */ = {isa = PBXBuildFile; fileRef = EE88D8491D1435C20079D8C5 /* Chomp.wav */; };
20 | EE88D8501D1435C20079D8C5 /* Drip.wav in Resources */ = {isa = PBXBuildFile; fileRef = EE88D84A1D1435C20079D8C5 /* Drip.wav */; };
21 | EE88D8511D1435C20079D8C5 /* Error.wav in Resources */ = {isa = PBXBuildFile; fileRef = EE88D84B1D1435C20079D8C5 /* Error.wav */; };
22 | EE88D8521D1435C20079D8C5 /* Ka-Ching.wav in Resources */ = {isa = PBXBuildFile; fileRef = EE88D84C1D1435C20079D8C5 /* Ka-Ching.wav */; };
23 | EE88D8531D1435C20079D8C5 /* Mining by Moonlight.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = EE88D84D1D1435C20079D8C5 /* Mining by Moonlight.mp3 */; };
24 | EE88D8541D1435C20079D8C5 /* Scrape.wav in Resources */ = {isa = PBXBuildFile; fileRef = EE88D84E1D1435C20079D8C5 /* Scrape.wav */; };
25 | EE9E10FF1D12EB46009B1A02 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE9E10FE1D12EB46009B1A02 /* AppDelegate.swift */; };
26 | EE9E11031D12EB46009B1A02 /* GameScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE9E11021D12EB46009B1A02 /* GameScene.swift */; };
27 | EE9E11051D12EB46009B1A02 /* GameViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE9E11041D12EB46009B1A02 /* GameViewController.swift */; };
28 | EE9E110A1D12EB46009B1A02 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EE9E11091D12EB46009B1A02 /* Assets.xcassets */; };
29 | EE9E11181D12EB47009B1A02 /* CookieCrunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE9E11171D12EB47009B1A02 /* CookieCrunchTests.swift */; };
30 | EE9E11231D12EBA8009B1A02 /* Sprites.atlas in Resources */ = {isa = PBXBuildFile; fileRef = EE9E11221D12EBA8009B1A02 /* Sprites.atlas */; };
31 | EE9E11251D12EF03009B1A02 /* Cookie.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE9E11241D12EF03009B1A02 /* Cookie.swift */; };
32 | EEAD2DE81D13E33C009C9F63 /* Array2D.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEAD2DE71D13E33C009C9F63 /* Array2D.swift */; };
33 | EEB72BF01D149B0400E9FD39 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EEB72BEE1D149B0400E9FD39 /* LaunchScreen.storyboard */; };
34 | EEB72BFF1D1568EE00E9FD39 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EEB72BFD1D1568EE00E9FD39 /* Main.storyboard */; };
35 | EEB72C021D1568F500E9FD39 /* Main2.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EEB72C001D1568F500E9FD39 /* Main2.storyboard */; };
36 | EEB72C041D15708000E9FD39 /* Grid.atlas in Resources */ = {isa = PBXBuildFile; fileRef = EEB72C031D15708000E9FD39 /* Grid.atlas */; };
37 | EEDEFDC61D1442E400A14F59 /* Chain.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEDEFDC51D1442E400A14F59 /* Chain.swift */; };
38 | /* End PBXBuildFile section */
39 |
40 | /* Begin PBXContainerItemProxy section */
41 | EE9E11141D12EB47009B1A02 /* PBXContainerItemProxy */ = {
42 | isa = PBXContainerItemProxy;
43 | containerPortal = EE9E10F31D12EB46009B1A02 /* Project object */;
44 | proxyType = 1;
45 | remoteGlobalIDString = EE9E10FA1D12EB46009B1A02;
46 | remoteInfo = CookieCrunch;
47 | };
48 | /* End PBXContainerItemProxy section */
49 |
50 | /* Begin PBXFileReference section */
51 | EE88D8331D13F5690079D8C5 /* Level.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Level.swift; sourceTree = ""; };
52 | EE88D8371D14016A0079D8C5 /* Tile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Tile.swift; sourceTree = ""; };
53 | EE88D8391D1402420079D8C5 /* Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; };
54 | EE88D83C1D14115B0079D8C5 /* Level_0.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = Level_0.json; sourceTree = ""; };
55 | EE88D83D1D14115B0079D8C5 /* Level_1.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = Level_1.json; sourceTree = ""; };
56 | EE88D83E1D14115B0079D8C5 /* Level_2.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = Level_2.json; sourceTree = ""; };
57 | EE88D83F1D14115B0079D8C5 /* Level_3.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = Level_3.json; sourceTree = ""; };
58 | EE88D8401D14115B0079D8C5 /* Level_4.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = Level_4.json; sourceTree = ""; };
59 | EE88D8461D141FFE0079D8C5 /* Swap.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Swap.swift; sourceTree = ""; };
60 | EE88D8491D1435C20079D8C5 /* Chomp.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = Chomp.wav; sourceTree = ""; };
61 | EE88D84A1D1435C20079D8C5 /* Drip.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = Drip.wav; sourceTree = ""; };
62 | EE88D84B1D1435C20079D8C5 /* Error.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = Error.wav; sourceTree = ""; };
63 | EE88D84C1D1435C20079D8C5 /* Ka-Ching.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = "Ka-Ching.wav"; sourceTree = ""; };
64 | EE88D84D1D1435C20079D8C5 /* Mining by Moonlight.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = "Mining by Moonlight.mp3"; sourceTree = ""; };
65 | EE88D84E1D1435C20079D8C5 /* Scrape.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = Scrape.wav; sourceTree = ""; };
66 | EE9E10FB1D12EB46009B1A02 /* Cookie Crunch Adventure.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Cookie Crunch Adventure.app"; sourceTree = BUILT_PRODUCTS_DIR; };
67 | EE9E10FE1D12EB46009B1A02 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
68 | EE9E11021D12EB46009B1A02 /* GameScene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameScene.swift; sourceTree = ""; };
69 | EE9E11041D12EB46009B1A02 /* GameViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameViewController.swift; sourceTree = ""; };
70 | EE9E11091D12EB46009B1A02 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
71 | EE9E110E1D12EB46009B1A02 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
72 | EE9E11131D12EB47009B1A02 /* Cookie Crunch Adventure.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Cookie Crunch Adventure.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
73 | EE9E11171D12EB47009B1A02 /* CookieCrunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CookieCrunchTests.swift; sourceTree = ""; };
74 | EE9E11191D12EB47009B1A02 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
75 | EE9E11221D12EBA8009B1A02 /* Sprites.atlas */ = {isa = PBXFileReference; lastKnownFileType = folder.skatlas; path = Sprites.atlas; sourceTree = ""; };
76 | EE9E11241D12EF03009B1A02 /* Cookie.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Cookie.swift; sourceTree = ""; };
77 | EEAD2DE71D13E33C009C9F63 /* Array2D.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Array2D.swift; sourceTree = ""; };
78 | EEB72BEF1D149B0400E9FD39 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = CookieCrunch/Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
79 | EEB72BFE1D1568EE00E9FD39 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
80 | EEB72C011D1568F500E9FD39 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main2.storyboard; sourceTree = ""; };
81 | EEB72C031D15708000E9FD39 /* Grid.atlas */ = {isa = PBXFileReference; lastKnownFileType = folder.skatlas; name = Grid.atlas; path = Sounds/Grid.atlas; sourceTree = ""; };
82 | EEDEFDC51D1442E400A14F59 /* Chain.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Chain.swift; sourceTree = ""; };
83 | /* End PBXFileReference section */
84 |
85 | /* Begin PBXFrameworksBuildPhase section */
86 | EE9E10F81D12EB46009B1A02 /* Frameworks */ = {
87 | isa = PBXFrameworksBuildPhase;
88 | buildActionMask = 2147483647;
89 | files = (
90 | );
91 | runOnlyForDeploymentPostprocessing = 0;
92 | };
93 | EE9E11101D12EB47009B1A02 /* Frameworks */ = {
94 | isa = PBXFrameworksBuildPhase;
95 | buildActionMask = 2147483647;
96 | files = (
97 | );
98 | runOnlyForDeploymentPostprocessing = 0;
99 | };
100 | /* End PBXFrameworksBuildPhase section */
101 |
102 | /* Begin PBXGroup section */
103 | EE88D83B1D14115B0079D8C5 /* Levels */ = {
104 | isa = PBXGroup;
105 | children = (
106 | EE88D83C1D14115B0079D8C5 /* Level_0.json */,
107 | EE88D83D1D14115B0079D8C5 /* Level_1.json */,
108 | EE88D83E1D14115B0079D8C5 /* Level_2.json */,
109 | EE88D83F1D14115B0079D8C5 /* Level_3.json */,
110 | EE88D8401D14115B0079D8C5 /* Level_4.json */,
111 | );
112 | path = Levels;
113 | sourceTree = "";
114 | };
115 | EE88D8481D1435C20079D8C5 /* Sounds */ = {
116 | isa = PBXGroup;
117 | children = (
118 | EE88D8491D1435C20079D8C5 /* Chomp.wav */,
119 | EE88D84A1D1435C20079D8C5 /* Drip.wav */,
120 | EE88D84B1D1435C20079D8C5 /* Error.wav */,
121 | EE88D84C1D1435C20079D8C5 /* Ka-Ching.wav */,
122 | EE88D84D1D1435C20079D8C5 /* Mining by Moonlight.mp3 */,
123 | EE88D84E1D1435C20079D8C5 /* Scrape.wav */,
124 | );
125 | path = Sounds;
126 | sourceTree = "";
127 | };
128 | EE9E10F21D12EB46009B1A02 = {
129 | isa = PBXGroup;
130 | children = (
131 | EE9E10FD1D12EB46009B1A02 /* Cookie Crunch Adventure */,
132 | EE9E11161D12EB47009B1A02 /* CookieCrunchTests */,
133 | EE9E10FC1D12EB46009B1A02 /* Products */,
134 | EE88D8481D1435C20079D8C5 /* Sounds */,
135 | EE88D83B1D14115B0079D8C5 /* Levels */,
136 | EEB72C031D15708000E9FD39 /* Grid.atlas */,
137 | EE9E11221D12EBA8009B1A02 /* Sprites.atlas */,
138 | );
139 | sourceTree = "";
140 | };
141 | EE9E10FC1D12EB46009B1A02 /* Products */ = {
142 | isa = PBXGroup;
143 | children = (
144 | EE9E10FB1D12EB46009B1A02 /* Cookie Crunch Adventure.app */,
145 | EE9E11131D12EB47009B1A02 /* Cookie Crunch Adventure.xctest */,
146 | );
147 | name = Products;
148 | sourceTree = "";
149 | };
150 | EE9E10FD1D12EB46009B1A02 /* Cookie Crunch Adventure */ = {
151 | isa = PBXGroup;
152 | children = (
153 | EE9E110E1D12EB46009B1A02 /* Info.plist */,
154 | EE9E10FE1D12EB46009B1A02 /* AppDelegate.swift */,
155 | EEAD2DE71D13E33C009C9F63 /* Array2D.swift */,
156 | EEDEFDC51D1442E400A14F59 /* Chain.swift */,
157 | EE9E11241D12EF03009B1A02 /* Cookie.swift */,
158 | EE88D8391D1402420079D8C5 /* Extensions.swift */,
159 | EE9E11021D12EB46009B1A02 /* GameScene.swift */,
160 | EE9E11041D12EB46009B1A02 /* GameViewController.swift */,
161 | EE88D8331D13F5690079D8C5 /* Level.swift */,
162 | EE88D8461D141FFE0079D8C5 /* Swap.swift */,
163 | EE88D8371D14016A0079D8C5 /* Tile.swift */,
164 | EE9E11091D12EB46009B1A02 /* Assets.xcassets */,
165 | EEB72BEE1D149B0400E9FD39 /* LaunchScreen.storyboard */,
166 | EEB72BFD1D1568EE00E9FD39 /* Main.storyboard */,
167 | EEB72C001D1568F500E9FD39 /* Main2.storyboard */,
168 | );
169 | name = "Cookie Crunch Adventure";
170 | path = CookieCrunch;
171 | sourceTree = "";
172 | };
173 | EE9E11161D12EB47009B1A02 /* CookieCrunchTests */ = {
174 | isa = PBXGroup;
175 | children = (
176 | EE9E11171D12EB47009B1A02 /* CookieCrunchTests.swift */,
177 | EE9E11191D12EB47009B1A02 /* Info.plist */,
178 | );
179 | path = CookieCrunchTests;
180 | sourceTree = "";
181 | };
182 | /* End PBXGroup section */
183 |
184 | /* Begin PBXNativeTarget section */
185 | EE9E10FA1D12EB46009B1A02 /* Cookie Crunch Adventure */ = {
186 | isa = PBXNativeTarget;
187 | buildConfigurationList = EE9E111C1D12EB47009B1A02 /* Build configuration list for PBXNativeTarget "Cookie Crunch Adventure" */;
188 | buildPhases = (
189 | EE9E10F71D12EB46009B1A02 /* Sources */,
190 | EE9E10F81D12EB46009B1A02 /* Frameworks */,
191 | EE9E10F91D12EB46009B1A02 /* Resources */,
192 | );
193 | buildRules = (
194 | );
195 | dependencies = (
196 | );
197 | name = "Cookie Crunch Adventure";
198 | productName = CookieCrunch;
199 | productReference = EE9E10FB1D12EB46009B1A02 /* Cookie Crunch Adventure.app */;
200 | productType = "com.apple.product-type.application";
201 | };
202 | EE9E11121D12EB47009B1A02 /* Cookie Crunch AdventureTests */ = {
203 | isa = PBXNativeTarget;
204 | buildConfigurationList = EE9E111F1D12EB47009B1A02 /* Build configuration list for PBXNativeTarget "Cookie Crunch AdventureTests" */;
205 | buildPhases = (
206 | EE9E110F1D12EB47009B1A02 /* Sources */,
207 | EE9E11101D12EB47009B1A02 /* Frameworks */,
208 | EE9E11111D12EB47009B1A02 /* Resources */,
209 | );
210 | buildRules = (
211 | );
212 | dependencies = (
213 | EE9E11151D12EB47009B1A02 /* PBXTargetDependency */,
214 | );
215 | name = "Cookie Crunch AdventureTests";
216 | productName = CookieCrunchTests;
217 | productReference = EE9E11131D12EB47009B1A02 /* Cookie Crunch Adventure.xctest */;
218 | productType = "com.apple.product-type.bundle.unit-test";
219 | };
220 | /* End PBXNativeTarget section */
221 |
222 | /* Begin PBXProject section */
223 | EE9E10F31D12EB46009B1A02 /* Project object */ = {
224 | isa = PBXProject;
225 | attributes = {
226 | LastSwiftUpdateCheck = 0730;
227 | LastUpgradeCheck = 0730;
228 | ORGANIZATIONNAME = "Nils Bernhardt";
229 | TargetAttributes = {
230 | EE9E10FA1D12EB46009B1A02 = {
231 | CreatedOnToolsVersion = 7.3.1;
232 | DevelopmentTeam = ZABJ92MWNL;
233 | };
234 | EE9E11121D12EB47009B1A02 = {
235 | CreatedOnToolsVersion = 7.3.1;
236 | TestTargetID = EE9E10FA1D12EB46009B1A02;
237 | };
238 | };
239 | };
240 | buildConfigurationList = EE9E10F61D12EB46009B1A02 /* Build configuration list for PBXProject "Cookie Crunch Adventure" */;
241 | compatibilityVersion = "Xcode 3.2";
242 | developmentRegion = English;
243 | hasScannedForEncodings = 0;
244 | knownRegions = (
245 | en,
246 | Base,
247 | );
248 | mainGroup = EE9E10F21D12EB46009B1A02;
249 | productRefGroup = EE9E10FC1D12EB46009B1A02 /* Products */;
250 | projectDirPath = "";
251 | projectRoot = "";
252 | targets = (
253 | EE9E10FA1D12EB46009B1A02 /* Cookie Crunch Adventure */,
254 | EE9E11121D12EB47009B1A02 /* Cookie Crunch AdventureTests */,
255 | );
256 | };
257 | /* End PBXProject section */
258 |
259 | /* Begin PBXResourcesBuildPhase section */
260 | EE9E10F91D12EB46009B1A02 /* Resources */ = {
261 | isa = PBXResourcesBuildPhase;
262 | buildActionMask = 2147483647;
263 | files = (
264 | EE88D8501D1435C20079D8C5 /* Drip.wav in Resources */,
265 | EE88D8451D14115B0079D8C5 /* Level_4.json in Resources */,
266 | EEB72C041D15708000E9FD39 /* Grid.atlas in Resources */,
267 | EE88D8511D1435C20079D8C5 /* Error.wav in Resources */,
268 | EEB72BF01D149B0400E9FD39 /* LaunchScreen.storyboard in Resources */,
269 | EE88D8431D14115B0079D8C5 /* Level_2.json in Resources */,
270 | EE88D8541D1435C20079D8C5 /* Scrape.wav in Resources */,
271 | EEB72BFF1D1568EE00E9FD39 /* Main.storyboard in Resources */,
272 | EE88D8411D14115B0079D8C5 /* Level_0.json in Resources */,
273 | EE88D84F1D1435C20079D8C5 /* Chomp.wav in Resources */,
274 | EE88D8531D1435C20079D8C5 /* Mining by Moonlight.mp3 in Resources */,
275 | EE9E110A1D12EB46009B1A02 /* Assets.xcassets in Resources */,
276 | EE88D8521D1435C20079D8C5 /* Ka-Ching.wav in Resources */,
277 | EE88D8421D14115B0079D8C5 /* Level_1.json in Resources */,
278 | EE88D8441D14115B0079D8C5 /* Level_3.json in Resources */,
279 | EEB72C021D1568F500E9FD39 /* Main2.storyboard in Resources */,
280 | EE9E11231D12EBA8009B1A02 /* Sprites.atlas in Resources */,
281 | );
282 | runOnlyForDeploymentPostprocessing = 0;
283 | };
284 | EE9E11111D12EB47009B1A02 /* Resources */ = {
285 | isa = PBXResourcesBuildPhase;
286 | buildActionMask = 2147483647;
287 | files = (
288 | );
289 | runOnlyForDeploymentPostprocessing = 0;
290 | };
291 | /* End PBXResourcesBuildPhase section */
292 |
293 | /* Begin PBXSourcesBuildPhase section */
294 | EE9E10F71D12EB46009B1A02 /* Sources */ = {
295 | isa = PBXSourcesBuildPhase;
296 | buildActionMask = 2147483647;
297 | files = (
298 | EE88D8341D13F5690079D8C5 /* Level.swift in Sources */,
299 | EE9E11031D12EB46009B1A02 /* GameScene.swift in Sources */,
300 | EE9E11251D12EF03009B1A02 /* Cookie.swift in Sources */,
301 | EE88D83A1D1402420079D8C5 /* Extensions.swift in Sources */,
302 | EE88D8381D14016A0079D8C5 /* Tile.swift in Sources */,
303 | EEDEFDC61D1442E400A14F59 /* Chain.swift in Sources */,
304 | EE9E11051D12EB46009B1A02 /* GameViewController.swift in Sources */,
305 | EE9E10FF1D12EB46009B1A02 /* AppDelegate.swift in Sources */,
306 | EEAD2DE81D13E33C009C9F63 /* Array2D.swift in Sources */,
307 | EE88D8471D141FFE0079D8C5 /* Swap.swift in Sources */,
308 | );
309 | runOnlyForDeploymentPostprocessing = 0;
310 | };
311 | EE9E110F1D12EB47009B1A02 /* Sources */ = {
312 | isa = PBXSourcesBuildPhase;
313 | buildActionMask = 2147483647;
314 | files = (
315 | EE9E11181D12EB47009B1A02 /* CookieCrunchTests.swift in Sources */,
316 | );
317 | runOnlyForDeploymentPostprocessing = 0;
318 | };
319 | /* End PBXSourcesBuildPhase section */
320 |
321 | /* Begin PBXTargetDependency section */
322 | EE9E11151D12EB47009B1A02 /* PBXTargetDependency */ = {
323 | isa = PBXTargetDependency;
324 | target = EE9E10FA1D12EB46009B1A02 /* Cookie Crunch Adventure */;
325 | targetProxy = EE9E11141D12EB47009B1A02 /* PBXContainerItemProxy */;
326 | };
327 | /* End PBXTargetDependency section */
328 |
329 | /* Begin PBXVariantGroup section */
330 | EEB72BEE1D149B0400E9FD39 /* LaunchScreen.storyboard */ = {
331 | isa = PBXVariantGroup;
332 | children = (
333 | EEB72BEF1D149B0400E9FD39 /* Base */,
334 | );
335 | name = LaunchScreen.storyboard;
336 | path = ..;
337 | sourceTree = "";
338 | };
339 | EEB72BFD1D1568EE00E9FD39 /* Main.storyboard */ = {
340 | isa = PBXVariantGroup;
341 | children = (
342 | EEB72BFE1D1568EE00E9FD39 /* Base */,
343 | );
344 | name = Main.storyboard;
345 | sourceTree = "";
346 | };
347 | EEB72C001D1568F500E9FD39 /* Main2.storyboard */ = {
348 | isa = PBXVariantGroup;
349 | children = (
350 | EEB72C011D1568F500E9FD39 /* Base */,
351 | );
352 | name = Main2.storyboard;
353 | sourceTree = "";
354 | };
355 | /* End PBXVariantGroup section */
356 |
357 | /* Begin XCBuildConfiguration section */
358 | EE9E111A1D12EB47009B1A02 /* Debug */ = {
359 | isa = XCBuildConfiguration;
360 | buildSettings = {
361 | ALWAYS_SEARCH_USER_PATHS = NO;
362 | CLANG_ANALYZER_NONNULL = YES;
363 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
364 | CLANG_CXX_LIBRARY = "libc++";
365 | CLANG_ENABLE_MODULES = YES;
366 | CLANG_ENABLE_OBJC_ARC = YES;
367 | CLANG_WARN_BOOL_CONVERSION = YES;
368 | CLANG_WARN_CONSTANT_CONVERSION = YES;
369 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
370 | CLANG_WARN_EMPTY_BODY = YES;
371 | CLANG_WARN_ENUM_CONVERSION = YES;
372 | CLANG_WARN_INT_CONVERSION = YES;
373 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
374 | CLANG_WARN_UNREACHABLE_CODE = YES;
375 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
376 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
377 | COPY_PHASE_STRIP = NO;
378 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
379 | ENABLE_STRICT_OBJC_MSGSEND = YES;
380 | ENABLE_TESTABILITY = YES;
381 | GCC_C_LANGUAGE_STANDARD = gnu99;
382 | GCC_DYNAMIC_NO_PIC = NO;
383 | GCC_NO_COMMON_BLOCKS = YES;
384 | GCC_OPTIMIZATION_LEVEL = 0;
385 | GCC_PREPROCESSOR_DEFINITIONS = (
386 | "DEBUG=1",
387 | "$(inherited)",
388 | );
389 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
390 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
391 | GCC_WARN_UNDECLARED_SELECTOR = YES;
392 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
393 | GCC_WARN_UNUSED_FUNCTION = YES;
394 | GCC_WARN_UNUSED_VARIABLE = YES;
395 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
396 | MTL_ENABLE_DEBUG_INFO = YES;
397 | ONLY_ACTIVE_ARCH = YES;
398 | SDKROOT = iphoneos;
399 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
400 | };
401 | name = Debug;
402 | };
403 | EE9E111B1D12EB47009B1A02 /* Release */ = {
404 | isa = XCBuildConfiguration;
405 | buildSettings = {
406 | ALWAYS_SEARCH_USER_PATHS = NO;
407 | CLANG_ANALYZER_NONNULL = YES;
408 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
409 | CLANG_CXX_LIBRARY = "libc++";
410 | CLANG_ENABLE_MODULES = YES;
411 | CLANG_ENABLE_OBJC_ARC = YES;
412 | CLANG_WARN_BOOL_CONVERSION = YES;
413 | CLANG_WARN_CONSTANT_CONVERSION = YES;
414 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
415 | CLANG_WARN_EMPTY_BODY = YES;
416 | CLANG_WARN_ENUM_CONVERSION = YES;
417 | CLANG_WARN_INT_CONVERSION = YES;
418 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
419 | CLANG_WARN_UNREACHABLE_CODE = YES;
420 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
421 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
422 | COPY_PHASE_STRIP = NO;
423 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
424 | ENABLE_NS_ASSERTIONS = NO;
425 | ENABLE_STRICT_OBJC_MSGSEND = YES;
426 | GCC_C_LANGUAGE_STANDARD = gnu99;
427 | GCC_NO_COMMON_BLOCKS = YES;
428 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
429 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
430 | GCC_WARN_UNDECLARED_SELECTOR = YES;
431 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
432 | GCC_WARN_UNUSED_FUNCTION = YES;
433 | GCC_WARN_UNUSED_VARIABLE = YES;
434 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
435 | MTL_ENABLE_DEBUG_INFO = NO;
436 | SDKROOT = iphoneos;
437 | VALIDATE_PRODUCT = YES;
438 | };
439 | name = Release;
440 | };
441 | EE9E111D1D12EB47009B1A02 /* Debug */ = {
442 | isa = XCBuildConfiguration;
443 | buildSettings = {
444 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
445 | CODE_SIGN_IDENTITY = "iPhone Developer";
446 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
447 | INFOPLIST_FILE = CookieCrunch/Info.plist;
448 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
449 | PRODUCT_BUNDLE_IDENTIFIER = com.example.CookieCrunchAdventure;
450 | PRODUCT_NAME = "Cookie Crunch Adventure";
451 | PROVISIONING_PROFILE = "";
452 | SWIFT_VERSION = 2.3;
453 | };
454 | name = Debug;
455 | };
456 | EE9E111E1D12EB47009B1A02 /* Release */ = {
457 | isa = XCBuildConfiguration;
458 | buildSettings = {
459 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
460 | CODE_SIGN_IDENTITY = "iPhone Developer";
461 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
462 | INFOPLIST_FILE = CookieCrunch/Info.plist;
463 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
464 | PRODUCT_BUNDLE_IDENTIFIER = com.example.CookieCrunchAdventure;
465 | PRODUCT_NAME = "Cookie Crunch Adventure";
466 | PROVISIONING_PROFILE = "";
467 | SWIFT_VERSION = 2.3;
468 | };
469 | name = Release;
470 | };
471 | EE9E11201D12EB47009B1A02 /* Debug */ = {
472 | isa = XCBuildConfiguration;
473 | buildSettings = {
474 | BUNDLE_LOADER = "$(TEST_HOST)";
475 | DEBUG_INFORMATION_FORMAT = dwarf;
476 | INFOPLIST_FILE = CookieCrunchTests/Info.plist;
477 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
478 | PRODUCT_BUNDLE_IDENTIFIER = com.example.CookieCrunchTests;
479 | PRODUCT_NAME = "Cookie Crunch Adventure";
480 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Cookie Crunch Adventure.app/Cookie Crunch Adventure";
481 | };
482 | name = Debug;
483 | };
484 | EE9E11211D12EB47009B1A02 /* Release */ = {
485 | isa = XCBuildConfiguration;
486 | buildSettings = {
487 | BUNDLE_LOADER = "$(TEST_HOST)";
488 | INFOPLIST_FILE = CookieCrunchTests/Info.plist;
489 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
490 | PRODUCT_BUNDLE_IDENTIFIER = com.example.CookieCrunchTests;
491 | PRODUCT_NAME = "Cookie Crunch Adventure";
492 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Cookie Crunch Adventure.app/Cookie Crunch Adventure";
493 | };
494 | name = Release;
495 | };
496 | /* End XCBuildConfiguration section */
497 |
498 | /* Begin XCConfigurationList section */
499 | EE9E10F61D12EB46009B1A02 /* Build configuration list for PBXProject "Cookie Crunch Adventure" */ = {
500 | isa = XCConfigurationList;
501 | buildConfigurations = (
502 | EE9E111A1D12EB47009B1A02 /* Debug */,
503 | EE9E111B1D12EB47009B1A02 /* Release */,
504 | );
505 | defaultConfigurationIsVisible = 0;
506 | defaultConfigurationName = Release;
507 | };
508 | EE9E111C1D12EB47009B1A02 /* Build configuration list for PBXNativeTarget "Cookie Crunch Adventure" */ = {
509 | isa = XCConfigurationList;
510 | buildConfigurations = (
511 | EE9E111D1D12EB47009B1A02 /* Debug */,
512 | EE9E111E1D12EB47009B1A02 /* Release */,
513 | );
514 | defaultConfigurationIsVisible = 0;
515 | defaultConfigurationName = Release;
516 | };
517 | EE9E111F1D12EB47009B1A02 /* Build configuration list for PBXNativeTarget "Cookie Crunch AdventureTests" */ = {
518 | isa = XCConfigurationList;
519 | buildConfigurations = (
520 | EE9E11201D12EB47009B1A02 /* Debug */,
521 | EE9E11211D12EB47009B1A02 /* Release */,
522 | );
523 | defaultConfigurationIsVisible = 0;
524 | defaultConfigurationName = Release;
525 | };
526 | /* End XCConfigurationList section */
527 | };
528 | rootObject = EE9E10F31D12EB46009B1A02 /* Project object */;
529 | }
530 |
--------------------------------------------------------------------------------