├── 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 | --------------------------------------------------------------------------------