├── .DS_Store ├── ColorByNumber ├── .DS_Store ├── Assets.xcassets │ ├── Contents.json │ ├── category │ │ ├── Contents.json │ │ ├── category1.imageset │ │ │ ├── category1.png │ │ │ ├── category1-1.png │ │ │ └── Contents.json │ │ ├── category2.imageset │ │ │ ├── category2.png │ │ │ ├── category2-1.png │ │ │ └── Contents.json │ │ └── category3.imageset │ │ │ ├── category3.png │ │ │ ├── category3-1.png │ │ │ └── Contents.json │ ├── completion │ │ ├── Contents.json │ │ ├── Box.imageset │ │ │ ├── Box.png │ │ │ ├── Box@2x.png │ │ │ ├── Box@3x.png │ │ │ └── Contents.json │ │ ├── Circle.imageset │ │ │ ├── Circle.png │ │ │ ├── Circle@2x.png │ │ │ ├── Circle@3x.png │ │ │ └── Contents.json │ │ ├── Spiral.imageset │ │ │ ├── Spiral.png │ │ │ ├── Spiral@2x.png │ │ │ ├── Spiral@3x.png │ │ │ └── Contents.json │ │ └── Triangle.imageset │ │ │ ├── Triangle.png │ │ │ ├── Triangle@2x.png │ │ │ ├── Triangle@3x.png │ │ │ └── Contents.json │ ├── back.imageset │ │ ├── back.png │ │ ├── back-1.png │ │ ├── back-2.png │ │ └── Contents.json │ ├── fill.imageset │ │ ├── fill.png │ │ ├── fill-1.png │ │ ├── fill-2.png │ │ └── Contents.json │ ├── tick.imageset │ │ ├── tick.png │ │ └── Contents.json │ ├── fill_empty.imageset │ │ ├── fill_empty.png │ │ ├── fill_empty-1.png │ │ ├── fill_empty-2.png │ │ └── Contents.json │ ├── fill_selected.imageset │ │ ├── fill_selected-1.png │ │ ├── fill_selected-2.png │ │ ├── fill_selected.png │ │ └── Contents.json │ └── AppIcon.appiconset │ │ └── Contents.json ├── resources │ ├── fonts │ │ ├── Disposable.ttf │ │ └── Disposable_bold.ttf │ └── levelJsons │ │ └── dogs │ │ └── dog1.json ├── Views │ ├── Horizontal tableView │ │ ├── DoneTickTableViewCell.swift │ │ ├── Table.swift │ │ ├── ColorBoxForCell │ │ │ └── ColorBox.swift │ │ ├── Helpers.swift │ │ ├── CollectionView.swift │ │ ├── ColorBoxesCollectionViewCell.swift │ │ ├── TableViewCell.swift │ │ ├── DoneTickTableViewCell.xib │ │ └── ColorBoxesCollectionViewCell.xib │ ├── CategoryNode.swift │ ├── GameScene+ParticleExtension.swift │ ├── LevelScreen.swift │ ├── LevelNode.swift │ ├── DemoCamera.swift │ └── GameScene.swift ├── modal │ ├── ColorObjects │ │ ├── Colors.swift │ │ ├── AllColors.swift │ │ └── ColorPixel.swift │ ├── Array2D.swift │ ├── Category.swift │ ├── Utility │ │ └── Utilily.swift │ └── Level.swift ├── Tile.swift ├── Info.plist ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── AppDelegate.swift └── GameViewController.swift ├── ColorByNumber.xcodeproj ├── project.xcworkspace │ ├── xcuserdata │ │ └── Araib.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── xcuserdata │ ├── gallonallen.xcuserdatad │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ └── Araib.xcuserdatad │ │ ├── xcschemes │ │ └── xcschememanagement.plist │ │ └── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist ├── xcshareddata │ └── xcschemes │ │ └── ColorByNumber.xcscheme └── project.pbxproj └── README.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/.DS_Store -------------------------------------------------------------------------------- /ColorByNumber/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/.DS_Store -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/category/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/completion/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /ColorByNumber/resources/fonts/Disposable.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/resources/fonts/Disposable.ttf -------------------------------------------------------------------------------- /ColorByNumber/resources/fonts/Disposable_bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/resources/fonts/Disposable_bold.ttf -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/back.imageset/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/back.imageset/back.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/fill.imageset/fill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/fill.imageset/fill.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/tick.imageset/tick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/tick.imageset/tick.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/back.imageset/back-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/back.imageset/back-1.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/back.imageset/back-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/back.imageset/back-2.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/fill.imageset/fill-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/fill.imageset/fill-1.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/fill.imageset/fill-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/fill.imageset/fill-2.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/completion/Box.imageset/Box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/completion/Box.imageset/Box.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/completion/Box.imageset/Box@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/completion/Box.imageset/Box@2x.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/completion/Box.imageset/Box@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/completion/Box.imageset/Box@3x.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/fill_empty.imageset/fill_empty.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/fill_empty.imageset/fill_empty.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/completion/Circle.imageset/Circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/completion/Circle.imageset/Circle.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/completion/Spiral.imageset/Spiral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/completion/Spiral.imageset/Spiral.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/fill_empty.imageset/fill_empty-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/fill_empty.imageset/fill_empty-1.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/fill_empty.imageset/fill_empty-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/fill_empty.imageset/fill_empty-2.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/category/category1.imageset/category1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/category/category1.imageset/category1.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/category/category2.imageset/category2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/category/category2.imageset/category2.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/category/category3.imageset/category3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/category/category3.imageset/category3.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/completion/Circle.imageset/Circle@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/completion/Circle.imageset/Circle@2x.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/completion/Circle.imageset/Circle@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/completion/Circle.imageset/Circle@3x.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/completion/Spiral.imageset/Spiral@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/completion/Spiral.imageset/Spiral@2x.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/completion/Spiral.imageset/Spiral@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/completion/Spiral.imageset/Spiral@3x.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/completion/Triangle.imageset/Triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/completion/Triangle.imageset/Triangle.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/fill_selected.imageset/fill_selected-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/fill_selected.imageset/fill_selected-1.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/fill_selected.imageset/fill_selected-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/fill_selected.imageset/fill_selected-2.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/fill_selected.imageset/fill_selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/fill_selected.imageset/fill_selected.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/category/category1.imageset/category1-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/category/category1.imageset/category1-1.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/category/category2.imageset/category2-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/category/category2.imageset/category2-1.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/category/category3.imageset/category3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/category/category3.imageset/category3-1.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/completion/Triangle.imageset/Triangle@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/completion/Triangle.imageset/Triangle@2x.png -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/completion/Triangle.imageset/Triangle@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber/Assets.xcassets/completion/Triangle.imageset/Triangle@3x.png -------------------------------------------------------------------------------- /ColorByNumber.xcodeproj/project.xcworkspace/xcuserdata/Araib.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AraibKarim/ColorByNumber-iOS/HEAD/ColorByNumber.xcodeproj/project.xcworkspace/xcuserdata/Araib.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /ColorByNumber.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ColorByNumber.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/tick.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" : "tick.png", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /ColorByNumber/Views/Horizontal tableView/DoneTickTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DoneTickTableViewCell.swift 3 | // SKCamera Demo 4 | // 5 | // Created by Araib on 6/6/18. 6 | // Copyright © 2018 WoodyApps. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class DoneTickTableViewCell: UICollectionViewCell { 12 | 13 | override func awakeFromNib() { 14 | super.awakeFromNib() 15 | // Initialization code 16 | } 17 | 18 | 19 | 20 | } 21 | -------------------------------------------------------------------------------- /ColorByNumber.xcodeproj/xcuserdata/gallonallen.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SKCamera Demo.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/category/category1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "category1-1.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "category1.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/category/category2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "category2-1.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "category2.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/category/category3.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "category3-1.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "filename" : "category3.png", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/back.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "back-2.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "back-1.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "back.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/fill.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "fill-2.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "fill-1.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "fill.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/completion/Box.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Box.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Box@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Box@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/completion/Circle.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Circle.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Circle@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Circle@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/completion/Spiral.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Spiral.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Spiral@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Spiral@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/fill_empty.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "fill_empty-2.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "fill_empty-1.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "fill_empty.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/completion/Triangle.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Triangle.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Triangle@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Triangle@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/fill_selected.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "fill_selected-2.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "fill_selected-1.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "fill_selected.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /ColorByNumber/Views/Horizontal tableView/Table.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Table.swift 3 | // SKCamera Demo 4 | // 5 | // Created by Araib on 6/6/18. 6 | // Copyright © 2018 WoodyApps. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | class Table: UITableView { 12 | var gameViewController : GameViewController! 13 | 14 | override func touchesBegan(_ touches: Set, with event: UIEvent?) { 15 | super.touchesBegan(touches, with: event) 16 | let touch: UITouch = touches.first! 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ColorByNumber/Views/Horizontal tableView/ColorBoxForCell/ColorBox.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ColorBox.swift 3 | // SKCamera Demo 4 | // 5 | // Created by Araib on 6/6/18. 6 | // Copyright © 2018 WoodyApps. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import SpriteKit 11 | 12 | public class ColorBox { 13 | var middleShadow: UIColor! 14 | var lowerBox: UIColor! 15 | var lowestShadow: UIColor! 16 | var upperShadow: UIColor! 17 | var middleBox: UIColor! 18 | 19 | var color: Colors! 20 | var index = 0 21 | var isSelected = false 22 | var isTouchAble = true 23 | 24 | 25 | } 26 | -------------------------------------------------------------------------------- /ColorByNumber/modal/ColorObjects/Colors.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Colors.swift 3 | // SKCamera Demo 4 | // 5 | // Created by Araib on 6/6/18. 6 | // Copyright © 2018 WoodyApps. All rights reserved. 7 | // 8 | import Foundation 9 | import SpriteKit 10 | 11 | public class Colors { 12 | var mainColor = UIColor () 13 | var grayColor = UIColor () 14 | var mainHex = String () 15 | var number = 0 16 | 17 | init(hex: String, mainColor : UIColor, grayColor : UIColor, number : Int ) 18 | { 19 | self.mainHex = hex 20 | self.mainColor = mainColor 21 | self.grayColor = grayColor 22 | self.number = number 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /ColorByNumber/Tile.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Tile.swift 3 | // SKCamera Demo 4 | // 5 | // Created by Araib on 6/6/18. 6 | // Copyright © 2018 WoodyApps. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import SpriteKit 11 | 12 | class Tile: SKNode { 13 | var row = 0; 14 | var column = 0 15 | var mainColor = String () 16 | var background : SKSpriteNode! 17 | var backgroundStroke : SKSpriteNode! 18 | var text : SKLabelNode! 19 | 20 | var shape : SKShapeNode! 21 | 22 | 23 | func hideNumber (){ 24 | 25 | text.isHidden = true 26 | } 27 | func showNumber (){ 28 | text.isHidden = false 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /ColorByNumber/modal/Array2D.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Array2D.swift 3 | // CookieCrunch 4 | // 5 | // Created by Razeware on 13/04/16. 6 | // Copyright © 2018 WoodyApps. All rights reserved. 7 | // 8 | struct Array2D { 9 | 10 | let columns: Int 11 | let rows: Int 12 | fileprivate var array: Array 13 | 14 | init(columns: Int, rows: Int) { 15 | self.columns = columns 16 | self.rows = rows 17 | array = Array(repeating: nil, count: rows*columns) 18 | } 19 | 20 | subscript(column: Int, row: Int) -> T? { 21 | get { 22 | return array[row*columns + column] 23 | } 24 | set { 25 | array[row*columns + column] = newValue 26 | } 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /ColorByNumber/Views/Horizontal tableView/Helpers.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | func generateRandomData() -> [[UIColor]] { 4 | let numberOfRows = 20 5 | let numberOfItemsPerRow = 15 6 | 7 | return (0.. UIColor { 15 | 16 | let hue = CGFloat(arc4random() % 100) / 100 17 | let saturation = CGFloat(arc4random() % 100) / 100 18 | let brightness = CGFloat(arc4random() % 100) / 100 19 | 20 | return UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1.0) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ColorByNumber.xcodeproj/xcuserdata/Araib.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | ColorByNumber.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 1 11 | 12 | SKCamera Demo.xcscheme 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | B2441BB7206DACC10060E453 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /ColorByNumber/modal/ColorObjects/AllColors.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AllColors.swift 3 | // SKCamera Demo 4 | // 5 | // Created by Araib on 6/11/18. 6 | // Copyright © 2018 WoodyApps. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | public class AllColors { 11 | //For keep track of count only. 12 | var index = 0; 13 | var name = String () 14 | var count = 0; 15 | 16 | init(index : Int, name : String) { 17 | self.index = index 18 | self.name = name 19 | } 20 | 21 | func updateCount (addition : Int){ 22 | count = count + addition 23 | } 24 | func subtractToCount() -> Bool { 25 | if (self.count == 0){ 26 | return true 27 | }else { 28 | self.count = self.count - 1 29 | print("Counting","Index ", self.index, " count ", self.count) 30 | if (count == 0){ 31 | return true 32 | }else { 33 | return false 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ColorByNumber/modal/Category.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Category.swift 3 | // SKCamera Demo 4 | // 5 | // Created by Araib on 7/22/18. 6 | // Copyright © 2018 WoodyApps. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | public class Category{ 11 | 12 | var categoryID = 0 13 | var categoryName = ""; 14 | var image = "" 15 | var levels = [Level] () 16 | 17 | init(categoryID : Int, categoryName : String, image : String) { 18 | 19 | self.categoryID = categoryID 20 | self.categoryName = categoryName 21 | self.image = image 22 | 23 | buildLevels(categoryID: categoryID) 24 | 25 | } 26 | 27 | func buildLevels (categoryID : Int){ 28 | switch categoryID { 29 | case 1: 30 | levels.append(Level(id : 1,size: 32, levelName : "",categoryID : categoryID, categoryName: self.categoryName, isLocked: false, fileName : "dog1")) 31 | 32 | break 33 | default: 34 | break 35 | } 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /ColorByNumber/Views/Horizontal tableView/CollectionView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CollectionView.swift 3 | // SKCamera Demo 4 | // 5 | // Created by Araib on 6/6/18. 6 | // Copyright © 2018 WoodyApps. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | class CollectionView: UICollectionView { 12 | var gameViewController : GameViewController! 13 | 14 | override func touchesBegan(_ touches: Set, with event: UIEvent?) { 15 | super.touchesBegan(touches, with: event) 16 | let _: UITouch = touches.first! 17 | gameViewController.move = false 18 | } 19 | 20 | override func touchesMoved(_ touches: Set, with event: UIEvent?) { 21 | super.touchesMoved(touches, with: event) 22 | let touch: UITouch = touches.first! 23 | gameViewController.move = false 24 | } 25 | 26 | override func touchesEnded(_ touches: Set, with event: UIEvent?) { 27 | super.touchesEnded(touches, with: event) 28 | let touch: UITouch = touches.first! 29 | gameViewController.move = true 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ColorByNumber/modal/Utility/Utilily.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Utilily.swift 3 | // SKCamera Demo 4 | // 5 | // Created by Araib on 6/6/18. 6 | // Copyright © 2018 WoodyApps. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import SpriteKit 11 | 12 | public class Utility { 13 | 14 | static func hexStringToUIColor (hex:String) -> UIColor { 15 | var cString:String = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased() 16 | 17 | if (cString.hasPrefix("#")) { 18 | cString.remove(at: cString.startIndex) 19 | } 20 | 21 | if ((cString.count) != 6) { 22 | print("weird",hex); 23 | return UIColor.cyan 24 | } 25 | 26 | var rgbValue:UInt32 = 0 27 | Scanner(string: cString).scanHexInt32(&rgbValue) 28 | 29 | return UIColor( 30 | red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0, 31 | green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0, 32 | blue: CGFloat(rgbValue & 0x0000FF) / 255.0, 33 | alpha: CGFloat(1.0) 34 | ) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ColorByNumber/Views/Horizontal tableView/ColorBoxesCollectionViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ColorBoxesCollectionViewCell.swift 3 | // SKCamera Demo 4 | // 5 | // Created by Araib on 6/6/18. 6 | // Copyright © 2018 WoodyApps. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ColorBoxesCollectionViewCell: UICollectionViewCell { 12 | 13 | @IBOutlet weak var middleShadow: UIView! 14 | @IBOutlet weak var lowerBox: UIView! 15 | @IBOutlet weak var lowestShadow: UIView! 16 | @IBOutlet weak var upperShadow: UIView! 17 | @IBOutlet weak var middleBox: UIView! 18 | 19 | @IBOutlet weak var black_Top: UIView! 20 | @IBOutlet weak var blackTop_left: UIView! 21 | 22 | @IBOutlet weak var blackTop_right: UIView! 23 | 24 | @IBOutlet weak var black_middle: UIView! 25 | @IBOutlet weak var blackLower1: UIView! 26 | 27 | @IBOutlet weak var blackLower2: UIView! 28 | @IBOutlet weak var blackLower3: UIView! 29 | 30 | @IBOutlet weak var numberText: UILabel! 31 | 32 | var index = 0 33 | override func awakeFromNib() { 34 | super.awakeFromNib() 35 | // Initialization code 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /ColorByNumber/modal/Level.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Level.swift 3 | // SKCamera Demo 4 | // 5 | // Created by Araib on 8/26/18. 6 | // Copyright © 2018 WoodyApps. All rights reserved. 7 | // 8 | import Foundation 9 | 10 | public class Level{ 11 | var id = 0 12 | var categoryID = 0 13 | var categoryName = "" 14 | var levelName = ""; 15 | var isSolved = false 16 | var isLocked = false 17 | var fileName = "" 18 | var size = 0 19 | var zoom = 0 20 | 21 | init(id : Int, size : Int, levelName : String,categoryID : Int,categoryName : String, isLocked: Bool, fileName : String) { 22 | self.id = id 23 | self.categoryName = categoryName 24 | self.categoryID = categoryID 25 | self.levelName = levelName 26 | self.isLocked = isLocked 27 | self.fileName = fileName 28 | self.isSolved = isLevelSolved () 29 | self.size = size 30 | 31 | if(size > 55){ 32 | zoom = 20 33 | }else { 34 | zoom = 13 35 | } 36 | } 37 | 38 | 39 | fileprivate func isLevelSolved () -> Bool { 40 | var isSolved = false 41 | let pref = ColorPixel_Constants.isLevelSolved + "_\(id)" 42 | isSolved = UserDefaults.standard.bool(forKey: pref) 43 | 44 | return isSolved 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /ColorByNumber/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 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 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIAppFonts 24 | 25 | Disposable_bold.ttf 26 | Disposable.ttf 27 | 28 | UILaunchStoryboardName 29 | LaunchScreen 30 | UIMainStoryboardFile 31 | Main 32 | UIRequiredDeviceCapabilities 33 | 34 | armv7 35 | 36 | UIStatusBarHidden 37 | 38 | UISupportedInterfaceOrientations 39 | 40 | UIInterfaceOrientationPortrait 41 | 42 | UISupportedInterfaceOrientations~ipad 43 | 44 | UIInterfaceOrientationPortrait 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ColorByNumber-iOS 2 | Color by Number: a pixel coloring game on iOS. 3 | 4 | One of the most popular game on iOS in the last 2 years. I wrote the code about 1 year ago and decided to open source it. 5 | 6 | ## Screenshots 7 | 8 | ![alt text](https://i.imgur.com/WkheoG2.png) 9 | 10 | ## Example: 11 | https://apps.apple.com/us/app/color-by-number-coloring-game/id1317978215 12 | 13 | 14 | ## Tools & Programming Language 15 | Spritekit and Swift 4.2 16 | 17 | ## How does it work? 18 | 19 | 1. The Pixel Image & its colors are stored in a JSON File [Sample in the code]. \ 20 | The JSON file contains an array of String. The String corresponds to the colors of the pixel character. The sample contains a 2-d array with total 32 objects. \ 21 | "0x000000" -> represents on no color or empty area. \ 22 | Use https://www.piskelapp.com/ to create your pixel objects. It also allows you convert the pixel objects into a JSON array. Use 'Export to C file'. 23 | 2. The game uses SKCameraNode to move around the scene. You can pan and zoom into the scene. You need to adjust the zoom according to the size of the JSON array. 24 | 3. JSON file array is convert into tiles on the scene which you can color with touch. 25 | 4. Progress of current colored art is also saved in Preferences. 26 | 27 | ## Run the Project? 28 | 29 | Just download the project and run it in Xcode. 30 | 31 | ## Compatibility 32 | 33 | iOS 11.0 and above. 34 | 35 | ## How to create a JSON file after drawing with Piskel 36 | 37 | Follow the wiki: https://github.com/AraibKarim/ColorByNumber-iOS/wiki/How-to-convert-Piskel-files-(.c-files)-into-json-for-usage-in-the-source-code%3F 38 | 39 | ## Issues & Questions 40 | 41 | Please let me know if there are some issues. 42 | Contact me at: http://www.syedaraib.com 43 | -------------------------------------------------------------------------------- /ColorByNumber/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 | 25 | 26 | -------------------------------------------------------------------------------- /ColorByNumber/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /ColorByNumber/Views/CategoryNode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CategoryNode.swift 3 | // SKCamera Demo 4 | // 5 | // Created by Araib on 6/6/18. 6 | // Copyright © 2018 WoodyApps. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import SpriteKit 11 | public class CategoryNode : SKNode { 12 | 13 | var width = Float(); 14 | var height = Float(); 15 | var categoryData : Category! 16 | 17 | func addCategoryView (categoryData: Category, width : Float, height : Float, image : String, text : String){ 18 | self.width = width 19 | self.height = height 20 | self.categoryData = categoryData 21 | var node = SKSpriteNode () 22 | node = SKSpriteNode(color: UIColor.init(hexString: "#f3f3f3") ,size: CGSize(width: Int(width), height: Int(height))) 23 | 24 | 25 | 26 | 27 | 28 | 29 | let cropNode = SKCropNode() 30 | // cropNode.zPosition = 2 31 | cropNode.name = "crop node" 32 | let mask = SKShapeNode(rect: CGRect(x: -Int(width)/2, y: -Int(height)/2, width: Int(width), height: Int(height)), cornerRadius: 15) 33 | mask.fillColor = SKColor.white 34 | // mask.zPosition = 2 35 | mask.name = "mask node" 36 | cropNode.maskNode = mask 37 | // self.addChild(cropNode) 38 | node.position = CGPoint(x: 0, y: 0 ) 39 | node.name = "categoryNode" 40 | self.addChild(node) 41 | // cropNode.addChild(node) 42 | 43 | let categoryImage = SKSpriteNode.init(imageNamed: image) 44 | categoryImage.position = CGPoint(x: Int(width * 0.25), y: 0 ) 45 | self.addChild(categoryImage) 46 | categoryImage.name = "categoryNode" 47 | 48 | let label = SKLabelNode.init(fontNamed: "DisposableDroidBB") 49 | label.text = text 50 | label.fontSize = 30 51 | label.fontColor = SKColor.black 52 | label.position = CGPoint(x: 0 - CGFloat (width/2.2) + label.frame.width/2, y: CGFloat(height/2 * 0.5)) 53 | self.addChild(label) 54 | label.name = "categoryNode" 55 | } 56 | 57 | 58 | } 59 | -------------------------------------------------------------------------------- /ColorByNumber/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SKCamera Demo 4 | // 5 | // Created by Araib on 8/26/18. 6 | // Copyright © 2018 WoodyApps. 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: [UIApplicationLaunchOptionsKey: Any]?) -> 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 invalidate graphics rendering callbacks. 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 active 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 | 47 | -------------------------------------------------------------------------------- /ColorByNumber/Views/Horizontal tableView/TableViewCell.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | 3 | class TableViewCell: UITableViewCell { 4 | 5 | /* 6 | override func touchesBegan(_ touches: Set, with event: UIEvent?) { 7 | super.touchesBegan(touches, with: event) 8 | // gameViewController.touchesBegan(touches, with: event) 9 | let touch: UITouch = touches.first as! UITouch 10 | print ("cell",touch.view?.tag) 11 | } 12 | 13 | override func touchesMoved(_ touches: Set, with event: UIEvent?) { 14 | super.touchesMoved(touches, with: event) 15 | // gameViewController.touchesBegan(touches, with: event) 16 | let touch: UITouch = touches.first as! UITouch 17 | print ("cell",touch.view?.tag) 18 | } 19 | 20 | override func touchesEnded(_ touches: Set, with event: UIEvent?) { 21 | super.touchesEnded(touches, with: event) 22 | // gameViewController.touchesBegan(touches, with: event) 23 | let touch: UITouch = touches.first as! UITouch 24 | print ("cell",touch.view?.tag) 25 | } 26 | */ 27 | @IBOutlet weak var collectionView: CollectionView! 28 | 29 | 30 | } 31 | 32 | extension TableViewCell { 33 | 34 | func setCollectionViewDataSourceDelegate(_ dataSourceDelegate: D, forRow row: Int) { 35 | 36 | collectionView.delegate = dataSourceDelegate 37 | collectionView.dataSource = dataSourceDelegate 38 | collectionView.tag = row 39 | collectionView.setContentOffset(collectionView.contentOffset, animated:false) // Stops collection view if it was scrolling. 40 | collectionView.reloadData() 41 | } 42 | 43 | 44 | var collectionViewOffset: CGFloat { 45 | set { collectionView.contentOffset.x = newValue } 46 | get { return collectionView.contentOffset.x } 47 | } 48 | func setGameViewControllerToCollectionView (gameViewController : GameViewController){ 49 | self.collectionView.tag = 2 50 | self.collectionView.gameViewController = gameViewController 51 | self.collectionView.register(UINib(nibName: "ColorBoxesCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "ColorBoxesCollectionViewCell") 52 | self.collectionView.register(UINib(nibName: "DoneTickTableViewCell", bundle: nil), forCellWithReuseIdentifier: "DoneTickTableViewCell") 53 | self.collectionView.reloadData() 54 | 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ColorByNumber/Views/GameScene+ParticleExtension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GameScene+ParticleExtension.swift 3 | // SKCamera Demo 4 | // 5 | // Created by Araib on 6/6/18. 6 | // Copyright © 2018 WoodyApps. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | import SpriteKit 12 | 13 | extension GameScene { 14 | 15 | 16 | func addParticleEffect (){ 17 | self.emitter.emitterPosition = CGPoint(x: (self.view?.frame.size.width)! / 2, y: -10) 18 | self.emitter.emitterShape = kCAEmitterLayerLine 19 | self.emitter.emitterSize = CGSize(width: (self.view?.frame.size.width)!, height: 2.0) 20 | self.emitter.emitterCells = generateEmitterCells() 21 | self.emitter.beginTime = CACurrentMediaTime(); 22 | self.view?.layer.addSublayer(self.emitter) 23 | 24 | let wait = SKAction.wait(forDuration: 5) 25 | 26 | 27 | self.run(wait, completion:{ 28 | self.stopParticleEffect() 29 | }) 30 | } 31 | func stopParticleEffect (){ 32 | self.emitter.birthRate = 0 33 | // self.emitter.removeFromSuperlayer() 34 | } 35 | func removeParticleEffect (){ 36 | self.emitter.birthRate = 0 37 | self.emitter.removeFromSuperlayer() 38 | } 39 | private func generateEmitterCells() -> [CAEmitterCell] { 40 | var cells:[CAEmitterCell] = [CAEmitterCell]() 41 | for index in 0..<16 { 42 | 43 | let cell = CAEmitterCell() 44 | 45 | cell.birthRate = 4.0 46 | cell.lifetime = 14.0 47 | cell.lifetimeRange = 0 48 | cell.velocity = CGFloat(getRandomVelocity()) 49 | cell.velocityRange = 0 50 | cell.emissionLongitude = CGFloat(Double.pi) 51 | cell.emissionRange = 0.5 52 | cell.spin = 3.5 53 | cell.spinRange = 0 54 | cell.color = getNextColor(i: index) 55 | cell.contents = getNextImage(i: index) 56 | cell.scaleRange = 0.25 57 | cell.scale = 0.1 58 | 59 | cells.append(cell) 60 | 61 | } 62 | 63 | return cells 64 | 65 | } 66 | 67 | private func getRandomVelocity() -> Int { 68 | return velocities[getRandomNumber()] 69 | } 70 | 71 | private func getRandomNumber() -> Int { 72 | return Int(arc4random_uniform(4)) 73 | } 74 | 75 | private func getNextColor(i:Int) -> CGColor { 76 | if i <= 4 { 77 | return colors[0].cgColor 78 | } else if i <= 8 { 79 | return colors[1].cgColor 80 | } else if i <= 12 { 81 | return colors[2].cgColor 82 | } else { 83 | return colors[3].cgColor 84 | } 85 | } 86 | 87 | private func getNextImage(i:Int) -> CGImage { 88 | return images[i % 4].cgImage! 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /ColorByNumber/Views/Horizontal tableView/DoneTickTableViewCell.xib: -------------------------------------------------------------------------------- 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 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /ColorByNumber.xcodeproj/xcshareddata/xcschemes/ColorByNumber.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /ColorByNumber/modal/ColorObjects/ColorPixel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ColorPixel.swift 3 | // SKCamera Demo 4 | // 5 | // Created by Araib on 6/6/18. 6 | // Copyright © 2018 WoodyApps. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import SpriteKit 11 | public class ColorPixel { 12 | 13 | var strokeColor = UIColor.black 14 | var currentState = 0 15 | var currentColor = UIColor () 16 | var hex : Colors! 17 | var row = 0 18 | var col = 0 19 | 20 | var node : Tile! 21 | 22 | var isNOT_Touchable = false 23 | var isWhiteArea = false 24 | 25 | init(col: Int, row : Int, hex : Colors ) 26 | { 27 | // print("colored " + "\(col)" + " " + "\(row)") 28 | self.col = col 29 | self.row = row 30 | self.hex = Colors (hex: hex.mainHex, mainColor: hex.mainColor, grayColor: hex.grayColor, number: hex.number) 31 | currentColor = hex.grayColor 32 | strokeColor = Utility.hexStringToUIColor(hex: "8c8c8c") 33 | 34 | } 35 | 36 | init (col: Int, row : Int){ 37 | // print("white " + "\(col)" + " " + "\(row)") 38 | self.hex = Colors (hex: "ffffff", mainColor:UIColor.white, grayColor:UIColor.white, number: 0) 39 | self.col = col; 40 | self.row = row; 41 | self.isNOT_Touchable = true 42 | self.isWhiteArea = true 43 | 44 | } 45 | 46 | func getColor () -> UIColor{ 47 | if(currentState == ColorPixel_Constants.STATE_DRAWN_CorrectColor){ 48 | return self.hex.mainColor; 49 | }else if (currentState == ColorPixel_Constants.STATE_DRAWN_IncorrectCOLOR){ 50 | return self.currentColor; 51 | }else { 52 | return self.hex.grayColor; 53 | } 54 | } 55 | 56 | func getStrokeColor () -> UIColor{ 57 | if(currentState == ColorPixel_Constants.STATE_DRAWN_CorrectColor){ 58 | return self.hex.mainColor; 59 | }else if (currentState == ColorPixel_Constants.STATE_DRAWN_IncorrectCOLOR){ 60 | return self.strokeColor; 61 | }else{ 62 | return self.strokeColor; 63 | } 64 | } 65 | 66 | func getNumber () -> String { 67 | if(currentState == ColorPixel_Constants.STATE_DRAWN_CorrectColor){ 68 | return ""; 69 | }else if (currentState == ColorPixel_Constants.STATE_DRAWN_IncorrectCOLOR){ 70 | return "\(self.hex.number)"; 71 | }else{ 72 | return "\(self.hex.number)"; 73 | } 74 | } 75 | 76 | func setColor (color: Colors){ 77 | if(color.number == self.hex.number){ 78 | print("index","Match") 79 | print("index",self.hex.number) 80 | self.currentState = ColorPixel_Constants.STATE_DRAWN_CorrectColor; 81 | isNOT_Touchable = true; 82 | currentColor = hex.mainColor; 83 | }else{ 84 | print("index","didn't match") 85 | print("index",self.hex.number) 86 | currentColor = color.mainColor; 87 | self.currentState = ColorPixel_Constants.STATE_DRAWN_IncorrectCOLOR; 88 | 89 | } 90 | } 91 | 92 | 93 | } 94 | 95 | 96 | struct ColorPixel_Constants { 97 | static let STATE_NOT_DRAWN = 0; 98 | static let STATE_DRAWN_CorrectColor = 1; 99 | static let STATE_DRAWN_IncorrectCOLOR = 2; 100 | static let SAVINGLEVEL = "SavingLevel" 101 | static let isLevelSolved = "LevelIsSolved" 102 | } 103 | struct ColorPixel_NumbersConstant { 104 | static let Show_Number = 0; 105 | static let Hide_Number = 1; 106 | } 107 | -------------------------------------------------------------------------------- /ColorByNumber/Views/LevelScreen.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LevelScreen.swift 3 | // SKCamera Demo 4 | // 5 | // Created by Araib on 6/6/18. 6 | // Copyright © 2018 WoodyApps. All rights reserved. 7 | // 8 | 9 | import SpriteKit 10 | import GameplayKit 11 | 12 | class LevelScreen : SKScene { 13 | var levelNumber = 0 14 | var allLevels = [Level]() 15 | var gameViewController : GameViewController! 16 | var moveableArea = SKNode () 17 | var startY = Float () 18 | var lastY = Float () 19 | var bottamOFMoveableArea = Float () 20 | var runOnce = false 21 | var categoryData : Category! 22 | var tapGesture : UITapGestureRecognizer! 23 | 24 | override init(size: CGSize) { 25 | super.init(size: size) 26 | } 27 | required init?(coder aDecoder: NSCoder) { 28 | fatalError("Coder not used in this app") 29 | } 30 | override func didMove(to view: SKView) { 31 | self.backgroundColor = UIColor.init(hexString: "#f3f3f3") 32 | 33 | gameViewController.belowView.isHidden = true 34 | tapGesture = UITapGestureRecognizer.init(target: self, action:#selector(self.tapped(_:))) 35 | tapGesture.numberOfTapsRequired = 1 36 | self.view?.addGestureRecognizer(self.tapGesture) 37 | 38 | 39 | //gameViewController.belowView.isHidden = true 40 | initListView() 41 | 42 | } 43 | 44 | func initListView (){ 45 | moveableArea = SKNode () 46 | moveableArea.position = CGPoint(x: 0, y: 0) 47 | self.addChild(moveableArea) 48 | var startingY = self.frame.height * 0.8 - 50; 49 | let width = 150.0 50 | let height = 150.0 51 | var index = 0 52 | for _ in 0...categoryData.levels.count - 1 { 53 | for column in 0...1 54 | { 55 | if(index < categoryData.levels.count){ 56 | if(column == 0){ 57 | let node = LevelNode () 58 | node.index = index 59 | node.addLevelView(id: index,width: Float(width), height: Float(height), level: categoryData.levels[index]) 60 | node.position = CGPoint(x: self.frame.midX - CGFloat (node.width/2) - 10, y: startingY) 61 | 62 | moveableArea.addChild(node) 63 | index = index + 1 64 | 65 | }else{ 66 | let node = LevelNode () 67 | node.addLevelView(id: index,width: Float(width), height: Float(height), level: categoryData.levels[index]) 68 | node.position = CGPoint(x: self.frame.midX + CGFloat (node.width/2) + 10, y: startingY) 69 | node.index = index 70 | moveableArea.addChild(node) 71 | index = index + 1 72 | } 73 | } 74 | } 75 | startingY = startingY - CGFloat (height) * 1.12 76 | bottamOFMoveableArea = Float(startingY) 77 | } 78 | bottamOFMoveableArea = bottamOFMoveableArea - Float (height*2) 79 | print(bottamOFMoveableArea) 80 | let upperView = SKSpriteNode(color: UIColor.init(hexString: "#ffffff") ,size: CGSize(width: self.frame.width, height: self.frame.height * 0.2)) 81 | upperView.position = CGPoint(x: self.frame.midX, y: self.frame.height - upperView.size.height/2 + 50) 82 | upperView.zPosition = 10000 83 | self.addChild(upperView) 84 | 85 | let label = SKLabelNode.init(fontNamed: "DisposableDroidBB") 86 | label.text = categoryData.categoryName 87 | label.fontSize = 37 88 | label.fontColor = SKColor.black 89 | label.position = CGPoint(x: self.frame.midX - CGFloat (width) + label.frame.width/2, y: self.frame.height * 0.9) 90 | self.addChild(label) 91 | label.zPosition = 10001 92 | 93 | 94 | 95 | } 96 | 97 | @objc func tapped(_ sender: UITapGestureRecognizer) { 98 | 99 | if(sender.state == UIGestureRecognizerState.ended){ 100 | print ("tap") 101 | let touchLocation = sender.location(in: self.view) 102 | let pointFromView = self.convertPoint(toView: touchLocation) 103 | let node = self.nodes(at: pointFromView) 104 | if node.count == 0 { 105 | 106 | print("you very like tapped 'nowhere'") 107 | return 108 | } 109 | /*print(node.count) 110 | if node.count != 1 { 111 | 112 | // in almost all games or physics scenes, 113 | // it is not possible this would happen 114 | print("something odd happened - overlapping nodes?") 115 | return 116 | } 117 | */ 118 | if let categoryNode = node.first! as? SKNode, categoryNode.name == "levelNode" { 119 | print("levelNodeTouched") 120 | if node.first! is SKSpriteNode { 121 | //var parentNode = categoryNode.parent as! LevelNode 122 | 123 | if let parentNode = categoryNode.parent as? LevelNode{ 124 | moveToGamePlayScreen (level: parentNode.level, index: parentNode.index) 125 | return 126 | }else if let parentNode = categoryNode.parent as? Tile { 127 | 128 | if let node = parentNode.parent as? LevelNode{ 129 | print("tile") 130 | moveToGamePlayScreen (level: node.level, index: node.index) 131 | return 132 | } 133 | } 134 | 135 | 136 | } 137 | 138 | } 139 | 140 | 141 | } 142 | } 143 | 144 | func removeGestures(){ 145 | for gesture in (self.view?.gestureRecognizers)!{ 146 | self.view?.removeGestureRecognizer(gesture) 147 | } 148 | } 149 | func moveToGamePlayScreen (level : Level, index : Int){ 150 | removeGestures() 151 | let levelScreen = GameScene(size: (self.view?.bounds.size)!) 152 | levelScreen.scaleMode = .resizeFill 153 | levelScreen.gameViewController = self.gameViewController 154 | levelScreen.currentLeveL = level 155 | levelScreen.categoryData = self.categoryData 156 | let skView = self.view 157 | skView?.presentScene(levelScreen) 158 | } 159 | 160 | 161 | } 162 | extension UIColor { 163 | convenience init(hexString: String) { 164 | let hex = hexString.trimmingCharacters(in: CharacterSet.alphanumerics.inverted) 165 | var int = UInt32() 166 | Scanner(string: hex).scanHexInt32(&int) 167 | let a, r, g, b: UInt32 168 | switch hex.count { 169 | case 3: // RGB (12-bit) 170 | (a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17) 171 | case 6: // RGB (24-bit) 172 | (a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF) 173 | case 8: // ARGB (32-bit) 174 | (a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF) 175 | default: 176 | (a, r, g, b) = (255, 0, 0, 0) 177 | } 178 | self.init(red: CGFloat(r) / 255, green: CGFloat(g) / 255, blue: CGFloat(b) / 255, alpha: CGFloat(a) / 255) 179 | } 180 | 181 | } 182 | -------------------------------------------------------------------------------- /ColorByNumber/Views/LevelNode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LevelNode.swift 3 | // SKCamera Demo 4 | // 5 | // Created by Araib on 7/29/18. 6 | // Copyright © 2018 WoodyApps. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import SpriteKit 11 | public class LevelNode : SKNode { 12 | 13 | var width = Float(); 14 | var height = Float(); 15 | var gridSize = 0 16 | var index = 0 17 | var level : Level! 18 | 19 | let PREFS_ColoredPixel = "ColoredPixel" 20 | fileprivate var grid = Array2D(columns: NumColumns, rows: NumRows) 21 | func addLevelView (id: Int, width : Float, height : Float, level : Level){ 22 | self.level = level 23 | self.width = width 24 | self.height = height 25 | var node = SKSpriteNode () 26 | node = SKSpriteNode(color: UIColor.init(hexString: "#ffffff") ,size: CGSize(width: Int(width), height: Int(height))) 27 | node.position = CGPoint(x: 0, y: 0 ) 28 | self.addChild(node) 29 | node.name = "levelNode" 30 | self.gridSize = level.size 31 | grid = Array2D(columns: gridSize, rows: gridSize) 32 | let columns = level.size 33 | let rows = level.size 34 | var i = 0 35 | readJSON (fileName: level.fileName) 36 | let sizeForEachItem = width / Float (level.size) 37 | var trackX = width/2 * -1 38 | var trackY = width/2 * -1 39 | let previouslyPlayedData = getColorPixelForEachLevel() 40 | 41 | for column in 0...columns - 1 { 42 | for row in 0...rows - 1 { 43 | print(column,row) 44 | let colorPixel = gridAT(column: column, row: row) 45 | if(colorPixel?.isWhiteArea)!{ 46 | 47 | } else{ 48 | let node = Tile() 49 | let isSolved = previouslyPlayedData [i] 50 | if(isSolved){ 51 | node.background = SKSpriteNode(color: (colorPixel?.hex.mainColor)!,size: CGSize(width: CGFloat(sizeForEachItem), height: CGFloat(sizeForEachItem))) 52 | }else{ 53 | node.background = SKSpriteNode(color: (colorPixel?.hex.grayColor)!,size: CGSize(width: CGFloat(sizeForEachItem), height: CGFloat(sizeForEachItem))) 54 | } 55 | node.background.position = CGPoint(x: 0, y: 0) 56 | node.column = column 57 | node.row = row 58 | node.background.name = "levelNode" 59 | node.addChild (node.background) 60 | 61 | node.position = CGPoint(x: CGFloat(trackX), y: CGFloat(trackY)) 62 | self.addChild(node) 63 | node.name = "levelNode" 64 | 65 | 66 | 67 | 68 | } 69 | trackY = trackY + sizeForEachItem 70 | 71 | i = i + 1 72 | } 73 | trackY = width/2 * -1 74 | trackX = trackX + sizeForEachItem 75 | 76 | } 77 | 78 | } 79 | func gridAT(column: Int, row: Int) -> ColorPixel? { 80 | assert(column >= 0 && column < gridSize) 81 | assert(row >= 0 && row < gridSize) 82 | return grid[column, row] 83 | } 84 | func readJSON (fileName : String){ 85 | let path = Bundle.main.path(forResource: fileName, ofType: "json") 86 | let jsonData = try? NSData(contentsOfFile: path!, options: NSData.ReadingOptions.mappedIfSafe) 87 | if jsonData != nil { 88 | do { 89 | // Set the map style by passing a valid JSON string. 90 | let datastring = NSString(data: jsonData! as Data, encoding: String.Encoding.utf8.rawValue) 91 | // print(datastring as! String) 92 | let dict = convertToArray(text : datastring! as String) 93 | // print(dict) 94 | 95 | let allPointColors = dict as! [String] 96 | var allHex = [String] () 97 | var index = 1 98 | var uniqueColorsForCheck = [String]() 99 | var allColors = [Colors]() 100 | var grayColor = Utility.hexStringToUIColor(hex: "#f7f7f7"); 101 | for img in allPointColors { 102 | //print(img) 103 | var colorString = img.dropFirst(2) 104 | 105 | if (colorString == "000000"){ 106 | colorString = "ffffff" 107 | } 108 | allHex.append(String(colorString)) 109 | if(uniqueColorsForCheck.contains(String(colorString))){ 110 | 111 | }else{ 112 | 113 | uniqueColorsForCheck.append(String(colorString)) 114 | 115 | if( colorString != "ffffff"){ 116 | 117 | 118 | 119 | grayColor = grayColor.darker(by: 5)! 120 | let uniqueColorObject = Colors (hex: String(colorString), mainColor: Utility.hexStringToUIColor(hex: String(colorString)), grayColor: grayColor, number: index) 121 | allColors.append(uniqueColorObject) 122 | index = index + 1 123 | } 124 | 125 | } 126 | } 127 | 128 | setGameColors(allHexColors: allHex, uniqueColors: allColors) 129 | 130 | } 131 | } 132 | } 133 | private func setGameColors (allHexColors : [String], uniqueColors : [Colors]){ 134 | 135 | // for () 136 | print(allHexColors) 137 | print(uniqueColors) 138 | let columns = self.gridSize 139 | let rows = self.gridSize 140 | var i = 0 141 | var row = rows - 1 142 | while row > -1 { 143 | for column in 0...columns - 1 { 144 | let colorString = allHexColors[i] 145 | 146 | if(colorString != "ffffff"){ 147 | 148 | for colortype in uniqueColors{ 149 | if(colortype.mainHex == colorString){ 150 | let color = ColorPixel(col: column, row : row, hex : colortype ) 151 | grid [column,row] = color 152 | break; 153 | 154 | } else{ 155 | 156 | } 157 | } 158 | }else{ 159 | let color = ColorPixel (col: column, row : row) 160 | grid [column,row] = color 161 | } 162 | i=i+1 163 | } 164 | row -= 1 165 | } 166 | 167 | 168 | } 169 | func convertToArray(text: String) -> Any? { 170 | 171 | if let data = text.data(using: .utf8) { 172 | 173 | do { 174 | return try JSONSerialization.jsonObject(with: data, options: []) as? [String] 175 | } catch { 176 | print(error.localizedDescription) 177 | } 178 | 179 | } 180 | 181 | return nil 182 | 183 | } 184 | 185 | func getPrefsString () -> String { 186 | let prefs = PREFS_ColoredPixel + "_" + "\(self.level.categoryID)" + "_" + "\(self.level.id)" 187 | return prefs 188 | } 189 | func getColorPixelForEachLevel() -> [Bool]{ 190 | var data = [Bool] () 191 | if let tempData = UserDefaults.standard.array(forKey: getPrefsString ()) as? [Bool] { 192 | 193 | data = tempData 194 | 195 | }else{ 196 | 197 | let columns = gridSize 198 | let rows = gridSize 199 | for _ in 0...columns - 1 { 200 | for _ in 0...rows - 1 { 201 | data.append(false) 202 | } 203 | 204 | } 205 | } 206 | 207 | return data 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /ColorByNumber/resources/levelJsons/dogs/dog1.json: -------------------------------------------------------------------------------- 1 | ["0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", 2 | "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", 3 | "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", 4 | "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", 5 | "0x000000", "0x000000", "0x4d2828", "0xca8f58", "0xca8f58", "0xe7c79d", "0xca8f58", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x2b1313", "0x2b1313", "0x2b1313", "0x2b1313", "0x4d2828", "0x4d2828", "0x4d2828", "0x4d2828", "0x4d2828", "0x4d2828", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", 6 | "0x000000", "0x4d2828", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xca8f58", "0xe7c79d", "0xca8f58", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x2b1313", "0x4d2828", "0x4d2828", "0x4d2828", "0x2b1313", "0xca8f58", "0xe7c79d", "0xca8f58", "0xca8f58", "0xca8f58", "0xca8f58", "0x4d2828", "0x4d2828", "0x000000", "0x000000", "0x000000", 7 | "0x4d2828", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xca8f58", "0xe7c79d", "0xca8f58", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x2b1313", "0x4d2828", "0x4d2828", "0x4d2828", "0x4d2828", "0x2b1313", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xca8f58", "0xca8f58", "0xe7c79d", "0xe7c79d", "0x713232", "0x4d2828", "0x000000", "0x000000", 8 | "0x2b1313", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xca8f58", "0xe7c79d", "0xca8f58", "0x000000", "0x000000", "0x000000", "0x4d2828", "0x4d2828", "0x4d2828", "0x4d2828", "0x2b1313", "0x4d2828", "0x4d2828", "0x4d2828", "0x2b1313", "0xe7c79d", "0xe7c79d", "0x9d583d", "0x9d583d", "0xca8f58", "0xca8f58", "0xe7c79d", "0x9d583d", "0x9d583d", "0x4d2828", "0x000000", "0x000000", 9 | "0x2b1313", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0x2b1313", "0x2b1313", "0x4d2828", "0x4d2828", "0x4d2828", "0x4d2828", "0x4d2828", "0x9d583d", "0x9d583d", "0x9d583d", "0x2b1313", "0x4d2828", "0x4d2828", "0x4d2828", "0x4d2828", "0x2b1313", "0xe7c79d", "0x4d2828", "0x713232", "0x713232", "0xca8f58", "0x9d583d", "0x713232", "0x713232", "0x713232", "0x2b1313", "0x4d2828", "0x000000", 10 | "0x2b1313", "0xca8f58", "0x2b1313", "0xca8f58", "0x2b1313", "0x9d583d", "0xca8f58", "0xca8f58", "0xe7c79d", "0x9d583d", "0xe7c79d", "0x9d583d", "0xe7c79d", "0xca8f58", "0x2b1313", "0x4d2828", "0x4d2828", "0x4d2828", "0x4d2828", "0x2b1313", "0xe7c79d", "0x4d2828", "0x343434", "0x713232", "0xca8f58", "0x9d583d", "0x9d583d", "0x713232", "0x343434", "0x2b1313", "0x4d2828", "0x000000", 11 | "0x000000", "0x2b1313", "0x4d2828", "0xca8f58", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xca8f58", "0xe7c79d", "0xca8f58", "0xe7c79d", "0xe7c79d", "0x9d583d", "0x2b1313", "0x2b1313", "0x2b1313", "0x2b1313", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0x4d2828", "0x4d2828", "0x9d583d", "0x4d2828", "0x4d2828", "0x9d583d", "0x713232", "0x2b1313", "0x4d2828", "0x000000", 12 | "0x000000", "0x000000", "0x2b1313", "0xca8f58", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xca8f58", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xca8f58", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0x9d583d", "0xe7c79d", "0xe7c79d", "0xca8f58", "0x4d2828", "0x9d583d", "0x4d2828", "0x4d2828", "0x4d2828", "0x4d2828", "0x9d583d", "0x000000", "0x000000", "0x000000", 13 | "0x000000", "0x000000", "0x2b1313", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xca8f58", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0x9d583d", "0x9d583d", "0xe7c79d", "0x9d583d", "0xe7c79d", "0xe7c79d", "0x2b1313", "0x4d2828", "0x9d583d", "0x2b1313", "0x2b1313", "0x2b1313", "0x4d2828", "0x9d583d", "0x000000", "0x000000", "0x000000", 14 | "0x000000", "0x2b1313", "0x9d583d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xca8f58", "0xca8f58", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xca8f58", "0xca8f58", "0xe7c79d", "0xe7c79d", "0x2b1313", "0x4d2828", "0x2b1313", "0xd139a6", "0xd139a6", "0xd139a6", "0x2b1313", "0x2b1313", "0x000000", "0x000000", "0x000000", 15 | "0x000000", "0x2b1313", "0x9d583d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xca8f58", "0xca8f58", "0xe7c79d", "0xe7c79d", "0x2b1313", "0xac1c51", "0xd139a6", "0xd139a6", "0xd139a6", "0xac1c51", "0x000000", "0x000000", "0x000000", "0x000000", 16 | "0x000000", "0x2b1313", "0xca8f58", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xca8f58", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0x9d583d", "0xe7c79d", "0x9d583d", "0x9d583d", "0xac1c51", "0xd139a6", "0xd139a6", "0xd139a6", "0xac1c51", "0x000000", "0x000000", "0x000000", "0x000000", 17 | "0x000000", "0x2b1313", "0xca8f58", "0xca8f58", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xca8f58", "0xca8f58", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xca8f58", "0x9d583d", "0xe7c79d", "0xe7c79d", "0x713232", "0x713232", "0x713232", "0x713232", "0xac1c51", "0xac1c51", "0xac1c51", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", 18 | "0x000000", "0x000000", "0x2b1313", "0xca8f58", "0xca8f58", "0xe7c79d", "0xe7c79d", "0x9d583d", "0xca8f58", "0xca8f58", "0xca8f58", "0x9d583d", "0xca8f58", "0xca8f58", "0xca8f58", "0xca8f58", "0xca8f58", "0x9d583d", "0xca8f58", "0x713232", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xe7c79d", "0xca8f58", "0x4d2828", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", 19 | "0x000000", "0x000000", "0x000000", "0x2b1313", "0xca8f58", "0xca8f58", "0xe7c79d", "0xe7c79d", "0x2b1313", "0x2b1313", "0x2b1313", "0x2b1313", "0x2b1313", "0x2b1313", "0x2b1313", "0x2b1313", "0x4d2828", "0x4d2828", "0xca8f58", "0x713232", "0xe7c79d", "0xca8f58", "0xe7c79d", "0xe7c79d", "0x4d2828", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", 20 | "0x000000", "0x000000", "0x2b1313", "0x9d583d", "0x9d583d", "0xca8f58", "0xe7c79d", "0xe7c79d", "0x2b1313", "0x4d2828", "0x2b1313", "0x2b1313", "0x2b1313", "0x000000", "0x000000", "0x000000", "0x000000", "0x4d2828", "0xca8f58", "0x713232", "0xe7c79d", "0xca8f58", "0xe7c79d", "0xca8f58", "0x4d2828", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", 21 | "0x000000", "0x000000", "0x2b1313", "0x9d583d", "0x9d583d", "0x2b1313", "0xca8f58", "0xe7c79d", "0xca8f58", "0x2b1313", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x4d2828", "0xca8f58", "0x713232", "0xe7c79d", "0xca8f58", "0xe7c79d", "0x4d2828", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", 22 | "0x000000", "0x000000", "0x000000", "0x2b1313", "0x2b1313", "0x2b1313", "0xca8f58", "0xca8f58", "0xca8f58", "0x2b1313", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x4d2828", "0x9d583d", "0xe7c79d", "0x9d583d", "0xe7c79d", "0xca8f58", "0x4d2828", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", 23 | "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x2b1313", "0xca8f58", "0xe7c79d", "0x2b1313", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x4d2828", "0x9d583d", "0xca8f58", "0xca8f58", "0x4d2828", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", 24 | "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x2b1313", "0x2b1313", "0x2b1313", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x4d2828", "0x4d2828", "0x4d2828", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", 25 | "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", 26 | "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", 27 | "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", 28 | "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", 29 | "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", 30 | "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", 31 | "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", 32 | "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000", "0x000000" 33 | ] 34 | -------------------------------------------------------------------------------- /ColorByNumber/Views/DemoCamera.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DemoCamera.swift 3 | // SKCamera Demo 4 | // 5 | // Created by Araib on 8/26/18. 6 | // Copyright © 2018 WoodyApps. All rights reserved. 7 | // 8 | import SpriteKit 9 | import os.log 10 | 11 | 12 | protocol DemoCameraOnChange { 13 | func onChange(x: CGFloat,y: CGFloat,size: CGFloat) 14 | } 15 | class DemoCamera: SKCameraNode { 16 | 17 | var delegate: DemoCameraOnChange? 18 | 19 | var area = 1000 20 | var saveVelocity : (x: CGFloat, y: CGFloat, z: CGFloat) = (0, 0, 0) 21 | // var saveVelocity : (x: CGFloat, y: CGFloat, z: CGFloat) = (0, 0, 0) 22 | // MARK: Properties 23 | 24 | // velocity is the value that the camera should move each frame in the x, y and z direction. 25 | // x and y are position values and will adjust the pixel location of the camera in the scene. 26 | // z is a scale value and will adjust the scale of the camera's viewport. 27 | private var velocity: (x: CGFloat, y: CGFloat, z: CGFloat) = (0, 0, 0) 28 | 29 | // friction is a used to decrease the velocity of the camera after user interaction has 30 | // ended to cause the camera to gradually slow to a stop. 31 | private var friction: CGFloat = 0.95 32 | 33 | // attraction is a value derived from the distance the camera's position is outside of the 34 | // camera's range. It is used along with the attractive force to provide a 'soft' edge to 35 | // the camera's range, allowing it to cross its min and max slightly and bounce back. 36 | private var attraction: (x: CGFloat, y: CGFloat, z: CGFloat) = (0, 0, 0) 37 | 38 | // attractiveForce sets the 'softness' of the edge of the camera's range. 39 | // A value of 1.0 will be a hard edge where the camera stops at it min and max ranges with no give or bounce. 40 | // Smaller values will allow the camera to travel farther past its range and bounce back. 41 | // A value of 0.0 will allow the camera to completely ignore its defined range. 42 | private let attractiveForce: CGFloat = 0.25 43 | 44 | // The cameras position and scale range 45 | var range: (x: (min: CGFloat, max: CGFloat), 46 | y: (min: CGFloat, max: CGFloat), 47 | z: (min: CGFloat, max: CGFloat)) = ((-1000, 1000), (-1000, 1000),(1, 12)) 48 | 49 | // A boolean value that indicates whether the camera displays a position indicator. 50 | private var showsPosition = false 51 | 52 | // A boolean value that indicates whether the camera displays a scale indicator. 53 | private var showsScale = false 54 | 55 | // A boolean value that indicates whether the camera displays a viewport indicator. 56 | private var showsViewport = false 57 | 58 | // Position indicator that demonstrates adding game controls to the camera and aids in debugging 59 | private let positionLabel = SKLabelNode(fontNamed: "AppleSDGothicNeo-SemiBold") 60 | 61 | // Scale indicator that demonstrates adding game controls to the camera and aids in debugging 62 | private let scaleLabel = SKLabelNode(fontNamed: "AppleSDGothicNeo-SemiBold") 63 | 64 | // Viewport indicator that demonstrates adding game controls to the camera and aids in debugging 65 | private let viewportLabel = SKLabelNode(fontNamed: "AppleSDGothicNeo-SemiBold") 66 | 67 | 68 | // MARK: Initializers 69 | 70 | // Creates a camera node 71 | override init() { 72 | super.init() 73 | } 74 | 75 | // Sks files are not used in this demo. 76 | required init?(coder aDecoder: NSCoder) { 77 | fatalError("Coder not used in this app") 78 | } 79 | 80 | func setZoomRange (zoom : CGFloat){ 81 | range = ((-1500, 1500), (-1500, 1500),(1, zoom)) 82 | } 83 | 84 | // MARK: Public Functions 85 | 86 | // set all forces that act upon the camera to 0, stoping the camera's motion 87 | func stop() { 88 | velocity = (0.0, 0.0, 0.0) 89 | attraction = (0.0, 0.0, 0.0) 90 | } 91 | 92 | // Update tells the camera to update itself 93 | func update() { 94 | updatePosition() 95 | updateScale() 96 | updateHUD() 97 | } 98 | 99 | // Display the position indicator 100 | func showPosition() { 101 | if (!showsPosition) { 102 | showsPosition = true 103 | positionLabel.fontSize = 8 104 | positionLabel.fontColor = .black 105 | addChild(positionLabel) 106 | } 107 | } 108 | 109 | // Display the scale indicator 110 | func showScale() { 111 | if (!showsScale) { 112 | showsScale = true 113 | scaleLabel.fontSize = 8 114 | scaleLabel.fontColor = .black 115 | scaleLabel.position = CGPoint(x:0.0, y: -15.0) 116 | addChild(scaleLabel) 117 | } 118 | } 119 | 120 | func showViewport() { 121 | if (!showsViewport) { 122 | showsViewport = true 123 | viewportLabel.fontSize = 8 124 | viewportLabel.fontColor = .white 125 | viewportLabel.position = CGPoint(x:0.0, y: -30.0) 126 | addChild(viewportLabel) 127 | } 128 | } 129 | 130 | // Set the velocity of the camera position and scale 131 | func setCameraVelocity(x: CGFloat!, y: CGFloat!, z: CGFloat!) { 132 | setCameraPositionVelocity(x: x, y: y) 133 | if (z != nil) { 134 | setCameraScaleVelocity(z: z) 135 | } 136 | } 137 | 138 | // Set the camera's position velocity 139 | // We multiply the velocity by scale so that panning appears to happen at the same rate at every zoom level. 140 | func setCameraPositionVelocity(x: CGFloat!, y: CGFloat!) { 141 | if (x != nil) { 142 | velocity.x = x * xScale 143 | } 144 | 145 | if (y != nil) { 146 | velocity.y = y * yScale 147 | } 148 | } 149 | 150 | // Set the camsera's scale velocity 151 | // We multiply the velocity by scale so that zooming appears to happen at the same rate at every zoom level. 152 | func setCameraScaleVelocity(z: CGFloat) { 153 | velocity.z = z * xScale 154 | } 155 | 156 | // Set the camera's friction force 157 | func setCameraFriction(force: CGFloat) { 158 | if (force <= 0 || force >= 1.0) { 159 | os_log("Friction should be a number between 0 and 1", type: .error) 160 | } 161 | friction = force 162 | } 163 | 164 | // Set the camera's attractive force 165 | func setCameraAttractiveForce(force: CGFloat) { 166 | if (force <= 0 || force >= 1.0) { 167 | os_log("Attractive force should be a number between 0 and 1", type: .error) 168 | } 169 | } 170 | 171 | // MARK: Private Functions 172 | 173 | // Apply's forces to the camera's velocity and then upadtes its position 174 | private func updatePosition() { 175 | 176 | // Update attraction x 177 | if (position.x < range.x.min) { 178 | attraction.x = position.x - range.x.min 179 | attraction.x *= attractiveForce 180 | } else if (position.x > range.x.max) { 181 | // Attraction is a positive number 182 | attraction.x = position.x - range.x.max 183 | attraction.x *= attractiveForce 184 | } else { 185 | attraction.x = 0.0 186 | } 187 | 188 | // Update attraction y 189 | if (position.y < range.y.min) { 190 | attraction.y = position.y - range.y.min 191 | attraction.y *= attractiveForce 192 | } else if (position.y > range.y.max) { 193 | attraction.y = position.y - range.y.max 194 | attraction.y *= attractiveForce 195 | } else { 196 | attraction.y = 0.0 197 | } 198 | 199 | // Apply friction 200 | 201 | velocity.x *= friction 202 | velocity.y *= friction 203 | 204 | // And finally update the position 205 | var x = position.x 206 | var y = position.y 207 | x -= velocity.x + attraction.x 208 | y += velocity.y - attraction.y 209 | if x.isNaN { 210 | // print("infinite") 211 | } 212 | if y.isNaN || x.isNaN { 213 | // print("infinite") 214 | }else{ 215 | // print ("finitePosition",x) 216 | // print ("finitePosition",y) 217 | position.x -= velocity.x + attraction.x 218 | position.y += velocity.y - attraction.y 219 | } 220 | 221 | 222 | // print("infinite",x) 223 | 224 | 225 | } 226 | 227 | // Applies forces to the camera's scale velocity and then updates the scale 228 | private func updateScale() { 229 | 230 | // x and y should always be scaling equally in this camera, 231 | // but just incase something happens to throw them out of whack... set them equal 232 | yScale = xScale 233 | 234 | // Test if xScale is outside its range and set an attraction to the bound it has exceded 235 | // so that the attraction can be applied when updating the camera's position 236 | if (xScale < range.z.min) { 237 | attraction.z = range.z.min - xScale 238 | attraction.z *= attractiveForce 239 | } else if (xScale > range.z.max) { 240 | attraction.z = range.z.max - xScale 241 | attraction.z *= attractiveForce 242 | } else { 243 | attraction.z = 0 244 | } 245 | 246 | // Apply friction to velocity so the camera slows to a stop when user interaction ends. 247 | 248 | var z = velocity.z 249 | z *= friction 250 | if(z.isNaN){ 251 | // print("velocity","infinite") 252 | velocity = self.saveVelocity 253 | }else{ 254 | velocity.z *= friction 255 | self.saveVelocity = velocity 256 | 257 | // Update the camera's scale 258 | // print("velocityFinite",velocity.z) 259 | 260 | setScale(xScale - velocity.z + attraction.z) 261 | } 262 | 263 | 264 | } 265 | 266 | /** 267 | Update the camera's SKLabelNode children. 268 | 269 | - Author: 270 | Sean Allen 271 | 272 | - Important: 273 | This function is called by the update() method. 274 | 275 | - Version: 276 | 0.1 277 | 278 | The updateHUD() funcition is called by the update() method so that when the scale and position debug labels are enabled they 279 | will accurately display the current camera orientation. This HUD serves to provide information about the camera state and 280 | serves as an example of how to implement a HUD by adding nodes as children of the camera. 281 | */ 282 | private func updateHUD() { 283 | let x = position.x.rounded(FloatingPointRoundingRule.toNearestOrEven) 284 | let y = position.y.rounded(FloatingPointRoundingRule.toNearestOrEven) 285 | let scale = round(100 * xScale) / 100.0 286 | 287 | if (showsPosition) { 288 | 289 | let x = position.x.rounded(FloatingPointRoundingRule.toNearestOrEven) 290 | let y = position.y.rounded(FloatingPointRoundingRule.toNearestOrEven) 291 | 292 | positionLabel.text = "position: (\(x), \(y))" 293 | 294 | positionLabel.position = CGPoint(x:parent!.frame.size.width / 2 - 50, y: -parent!.frame.size.height/2 + 130) 295 | } 296 | 297 | if (showsScale) { 298 | let scale = round(100 * xScale) / 100.0 299 | scaleLabel.text = "Scale: \(scale)" 300 | scaleLabel.position = CGPoint(x:parent!.frame.size.width / 2 - 50, y: -parent!.frame.size.height/2 + 40) 301 | } 302 | 303 | if (showsViewport) { 304 | viewportLabel.text = "Viewport: (\(parent!.frame.size.width), \(parent!.frame.size.height))" 305 | viewportLabel.position = CGPoint(x:parent!.frame.size.width / 2 - 50, y: -parent!.frame.size.height/2 + 20) 306 | } 307 | 308 | delegate?.onChange(x: x, y: y, size: scale) 309 | } 310 | } 311 | 312 | -------------------------------------------------------------------------------- /ColorByNumber.xcodeproj/xcuserdata/Araib.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 9 | 22 | 23 | 24 | 26 | 39 | 40 | 41 | 43 | 56 | 57 | 58 | 60 | 73 | 74 | 75 | 77 | 90 | 91 | 92 | 94 | 107 | 108 | 109 | 111 | 124 | 125 | 126 | 128 | 141 | 142 | 143 | 145 | 158 | 159 | 160 | 162 | 175 | 176 | 177 | 179 | 192 | 193 | 194 | 196 | 209 | 210 | 211 | 213 | 225 | 226 | 227 | 229 | 241 | 242 | 243 | 245 | 257 | 258 | 259 | 261 | 273 | 274 | 275 | 277 | 289 | 290 | 291 | 293 | 305 | 306 | 307 | 309 | 321 | 322 | 323 | 324 | 325 | -------------------------------------------------------------------------------- /ColorByNumber/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | DisposableDroidBB-Bold 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /ColorByNumber/GameViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GameViewController.swift 3 | // SKCamera Demo 4 | // 5 | // This demo application implements the gesture recognizers which manipulate the demo camera in the view controller. 6 | // The purpose is for compatibility in universal applications. Universal apps can share a single scene and will have 7 | // a separate view controller for each target platform. 8 | // 9 | // Created by Araib on 8/26/18. 10 | // Copyright © 2018 WoodyApps. All rights reserved. 11 | // 12 | 13 | import UIKit 14 | import SpriteKit 15 | import GameplayKit 16 | 17 | class GameViewController: UIViewController, UIGestureRecognizerDelegate, UITableViewDelegate, UITableViewDataSource { 18 | 19 | @IBOutlet weak var belowView: UIView! 20 | 21 | // MARK: Properties 22 | let prefs_Fills = "ColorPixel_Fills" 23 | var numberOfFills = 0; 24 | var isFillButton_Selected = false 25 | var storedOffsets = [Int: CGFloat]() 26 | 27 | var colorBoxArray = [ColorBox] () 28 | 29 | @IBOutlet weak var tableView: Table! 30 | 31 | var currentColorIndex = 0; 32 | var demoScene: GameScene! 33 | var isFill_Selected = false 34 | @IBOutlet weak var numberOfFill_Label: UILabel! 35 | 36 | 37 | var levelScreen : LevelScreen! 38 | var panGesture = UIPanGestureRecognizer() 39 | var pinchGesture = UIPinchGestureRecognizer() 40 | var move = true 41 | var isScrolling = false 42 | 43 | @IBOutlet weak var backButton: UIButton! 44 | 45 | 46 | @IBOutlet weak var fillButton: UIButton! 47 | // MARK: Fill Button functions 48 | @IBAction func fillButtonClicked(_ sender: Any) { 49 | unSelectAllColorBoxes () 50 | if(numberOfFills == 0){ 51 | //no more fills remain 52 | }else { 53 | isFillButton_Selected = true 54 | isFill_Selected = true 55 | fillButton.setBackgroundImage(UIImage.init(named: "fill_selected"), for: UIControlState.normal) 56 | } 57 | 58 | } 59 | 60 | 61 | func UseFill () -> Bool{ 62 | if(numberOfFills == 0){ 63 | return false 64 | }else{ 65 | numberOfFills = numberOfFills - 1 66 | numberOfFill_Label.text = "\(numberOfFills)" 67 | setNumberOfFills() 68 | fillButton.setBackgroundImage(UIImage.init(named: "fill"), for: UIControlState.normal) 69 | 70 | if(numberOfFills == 0){ 71 | fillButton.setBackgroundImage(UIImage.init(named: "fill_empty"), for: UIControlState.normal) 72 | } 73 | 74 | return true 75 | } 76 | } 77 | func hideFillButton (){ 78 | fillButton.isEnabled = false 79 | fillButton.isHidden = true 80 | } 81 | func showFillButton(){ 82 | fillButton.isEnabled = true 83 | fillButton.isHidden = false 84 | 85 | } 86 | func getNumberOfFills (){ 87 | self.numberOfFills = UserDefaults.standard.integer(forKey: prefs_Fills) 88 | } 89 | func setNumberOfFills (){ 90 | UserDefaults.standard.set(numberOfFills, forKey: prefs_Fills) 91 | } 92 | // MARK: Back Button 93 | @IBAction func backButtonClicked(_ sender: Any) { 94 | hideBackButton () 95 | tableView.isHidden = true 96 | belowView.isHidden = true 97 | tableView.delegate = nil 98 | tableView.dataSource = nil 99 | 100 | demoScene.moveBackToLevelScreen() 101 | } 102 | 103 | func hideBackButton (){ 104 | backButton.isEnabled = false 105 | backButton.isHidden = true 106 | } 107 | func showBackButton(){ 108 | backButton.isEnabled = true 109 | backButton.isHidden = false 110 | 111 | } 112 | // MARK: ViewdidLoad 113 | override func viewDidLoad() { 114 | super.viewDidLoad() 115 | 116 | let isFirstTime = UserDefaults.standard.bool(forKey: "firstTime") 117 | 118 | if(isFirstTime){ 119 | 120 | }else{ 121 | UserDefaults.standard.set(true, forKey: "firstTime") 122 | UserDefaults.standard.set(5, forKey: self.prefs_Fills) 123 | numberOfFills = 5 124 | } 125 | 126 | 127 | 128 | 129 | // Configure the view. 130 | let skView = self.view as! SKView 131 | skView.ignoresSiblingOrder = true 132 | skView.showsFPS = true 133 | skView.showsNodeCount = true 134 | 135 | // Configure the scene. 136 | demoScene = GameScene(size: skView.bounds.size) 137 | demoScene.scaleMode = .resizeFill 138 | 139 | // Configure the pan gesture recognizer 140 | // panGesture.addTarget(self, action: #selector(handlePanGesture(recognizer:))) 141 | // panGesture.delegate = self 142 | // self.view.addGestureRecognizer(panGesture) 143 | 144 | // Configure the pinch gesture recognizer 145 | // pinchGesture.addTarget(self, action: #selector(handlePinchGesture(recognizer:))) 146 | // self.view.addGestureRecognizer(pinchGesture) 147 | 148 | // Present the scene. 149 | demoScene.gameViewController = self 150 | // skView.presentScene(demoScene) 151 | tableView.gameViewController = self 152 | // tableView.delegate = self 153 | // tableView.dataSource = self 154 | tableView.tableFooterView = UIView() 155 | tableView.separatorStyle = .none 156 | 157 | hideFillButton () 158 | levelScreen = LevelScreen(size: skView.bounds.size) 159 | levelScreen.scaleMode = .resizeFill 160 | levelScreen.gameViewController = self 161 | levelScreen.categoryData = Category (categoryID: 1, categoryName: "Dogs", image: "category1") 162 | skView.presentScene(levelScreen) 163 | } 164 | func initCollectionView (gameScene : GameScene){ 165 | demoScene = gameScene 166 | panGesture = UIPanGestureRecognizer() 167 | pinchGesture = UIPinchGestureRecognizer() 168 | panGesture.addTarget(self, action: #selector(handlePanGesture(recognizer:))) 169 | panGesture.delegate = self 170 | self.view.addGestureRecognizer(panGesture) 171 | pinchGesture.delegate = self 172 | pinchGesture.addTarget(self, action: #selector(handlePinchGesture(recognizer:))) 173 | self.view.addGestureRecognizer(pinchGesture) 174 | tableView.delegate = self 175 | tableView.dataSource = self 176 | tableView.isHidden = false 177 | belowView.isHidden = false 178 | getNumberOfFills () 179 | numberOfFill_Label.text = "\(numberOfFills)" 180 | showFillButton () 181 | print("PinPanTable") 182 | } 183 | 184 | // MARK: Touch-based event handling 185 | 186 | /* override func touchesBegan(_ touches: Set, with event: UIEvent?) { 187 | // use stop to give the effect of pinning the camera under your finger when touching the screen. 188 | let touch: UITouch = touches.first as! UITouch 189 | print ("ttoch",touch.view?.tag) 190 | //print (touch.view) 191 | if(touch.view?.tag == 2){ 192 | // print ("tag 2 touch",touch.view?.tag) 193 | move = false; 194 | }else{ 195 | // print ("tag 2 not touch",touch.view?.tag) 196 | move = true; 197 | } 198 | demoScene.demoCamera.stop() 199 | } 200 | override func touchesMoved(_ touches: Set, with event: UIEvent?) { 201 | let touch: UITouch = touches.first as! UITouch 202 | // print (touch.view) 203 | print ("ttoch",touch.view?.tag) 204 | if(touch.view?.tag == 2){ 205 | move = false; 206 | }else{ 207 | move = true; 208 | } 209 | } 210 | */ 211 | // MARK: Touch functions 212 | override func touchesEnded(_ touches: Set, with event: UIEvent?) { 213 | move = true 214 | isScrolling = false 215 | print("scroll","off") 216 | } 217 | // MARK: Gestures 218 | @objc func handlePanGesture(recognizer: UIPanGestureRecognizer) { 219 | // print(recognizer.view) 220 | // Update the camera's position velocity based on user interaction. 221 | // The velocity of the recognizer is much larger than what feels comfortable to the user, so it is reduced by a factor of 100. 222 | // If your game needs a faster or slower camera feel reduce or increase the number that velocity is being divided by. 223 | if(move){ 224 | let panVelocity = (recognizer.velocity(in: demoScene.view)) 225 | demoScene.demoCamera.setCameraPositionVelocity(x: panVelocity.x / 100, y: panVelocity.y / 100) 226 | isScrolling = true 227 | // print("scroll","true") 228 | } 229 | 230 | if(recognizer.state == .ended) 231 | { 232 | // isScrolling = false 233 | // print("scroll","off") 234 | //All fingers are lifted. 235 | } 236 | } 237 | 238 | @objc func handlePinchGesture(recognizer: UIPinchGestureRecognizer) { 239 | // Update the camera's scale velocity based on user interaction. 240 | // Recognizer velocity is reduced to provide a more pleasant user experience. 241 | // Increase or decrease the divisor to create a faster or slower camera. 242 | if(move){ 243 | let pinchVelocity = recognizer.velocity 244 | demoScene.demoCamera.setCameraScaleVelocity(z: pinchVelocity / 100) 245 | isScrolling = true 246 | // print("scroll","true") 247 | } 248 | if(recognizer.state == .ended) 249 | { 250 | // isScrolling = false 251 | // print("scroll","off") 252 | //All fingers are lifted. 253 | } 254 | } 255 | 256 | // MARK: Gesture Recognizer Delegate 257 | 258 | func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, 259 | shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { 260 | // Since this demo only configures two gesture recognizers and we want them to work simultaneously we only need to return true. 261 | // If additional gesture recognizers are added there could be a need to add aditional logic here to setup which specific 262 | // recognizers should be working together. 263 | return true; 264 | } 265 | 266 | // MARK: View Controller Configuration 267 | 268 | override var shouldAutorotate: Bool { 269 | return true 270 | } 271 | 272 | override var supportedInterfaceOrientations: UIInterfaceOrientationMask { 273 | if UIDevice.current.userInterfaceIdiom == .phone { 274 | return .allButUpsideDown 275 | } else { 276 | return .all 277 | } 278 | } 279 | 280 | override var prefersStatusBarHidden: Bool { 281 | return true 282 | } 283 | 284 | // MARK: Memory Management 285 | 286 | override func didReceiveMemoryWarning() { 287 | super.didReceiveMemoryWarning() 288 | // Release any cached data, images, etc that aren't in use. 289 | } 290 | 291 | // MARK: Table Delegate 292 | func tableView(_ tableView:UITableView, numberOfRowsInSection section:Int) -> Int 293 | { 294 | return 1 295 | } 296 | 297 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 298 | { 299 | let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 300 | 301 | return cell 302 | } 303 | 304 | func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { 305 | 306 | guard let tableViewCell = cell as? TableViewCell else { return } 307 | 308 | tableViewCell.setCollectionViewDataSourceDelegate(self, forRow: indexPath.row) 309 | tableViewCell.collectionViewOffset = storedOffsets[indexPath.row] ?? 0 310 | tableViewCell.setGameViewControllerToCollectionView (gameViewController: self) 311 | 312 | 313 | } 314 | 315 | func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) { 316 | 317 | guard let tableViewCell = cell as? TableViewCell else { return } 318 | 319 | storedOffsets[indexPath.row] = tableViewCell.collectionViewOffset 320 | } 321 | 322 | // MARK: Refresg Selected Logic 323 | 324 | func unSelectAllColorBoxes (){ 325 | currentColorIndex = 0 326 | for colorBox in colorBoxArray { 327 | colorBox.isSelected = false 328 | } 329 | self.tableView.reloadData() 330 | 331 | } 332 | 333 | 334 | } 335 | // MARK: CollectionView Extension 336 | 337 | extension GameViewController: UICollectionViewDelegate, UICollectionViewDataSource { 338 | func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 339 | return colorBoxArray.count 340 | } 341 | 342 | func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 343 | 344 | let colorBoxObject = colorBoxArray[indexPath.row] 345 | 346 | if(colorBoxObject.isTouchAble){ 347 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ColorBoxesCollectionViewCell", for: indexPath) as! ColorBoxesCollectionViewCell 348 | 349 | 350 | cell.middleBox.backgroundColor = colorBoxArray[indexPath.row].middleBox 351 | cell.lowerBox.backgroundColor = colorBoxArray[indexPath.row].lowerBox 352 | cell.upperShadow.backgroundColor = colorBoxArray[indexPath.row].upperShadow 353 | cell.upperShadow.alpha = 0.5 354 | cell.lowestShadow.backgroundColor = colorBoxArray[indexPath.row].lowestShadow 355 | cell.middleShadow.backgroundColor = colorBoxArray[indexPath.row].middleShadow 356 | cell.index = colorBoxArray[indexPath.row].index 357 | cell.isSelected = colorBoxArray[indexPath.row].isSelected 358 | let num = indexPath.row + 1 359 | cell.numberText.text = "\(num)" 360 | if(cell.isSelected){ 361 | cell.black_Top.isHidden = false 362 | cell.blackTop_left.isHidden = false 363 | cell.blackTop_right.isHidden = false 364 | 365 | cell.black_middle.isHidden = false 366 | cell.blackLower1.isHidden = false 367 | cell.blackLower2.isHidden = false 368 | cell.blackLower3.isHidden = false 369 | print("showBlackBorder",indexPath.row) 370 | }else{ 371 | cell.black_Top.isHidden = true 372 | cell.blackTop_left.isHidden = true 373 | cell.blackTop_right.isHidden = true 374 | cell.black_middle.isHidden = true 375 | cell.blackLower1.isHidden = true 376 | cell.blackLower2.isHidden = true 377 | cell.blackLower3.isHidden = true 378 | print("dontShowBlackBorder",indexPath.row) 379 | } 380 | return cell 381 | }else{ 382 | let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "DoneTickTableViewCell", for: indexPath) as! DoneTickTableViewCell 383 | 384 | return cell 385 | } 386 | } 387 | 388 | func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 389 | print("Collection view at row \(collectionView.tag) selected index path \(indexPath)") 390 | 391 | let selectedColorBox = colorBoxArray [indexPath.row] 392 | if(selectedColorBox.isTouchAble){ 393 | currentColorIndex = selectedColorBox.index 394 | for colorBox in colorBoxArray { 395 | if(colorBox.index == selectedColorBox.index){ 396 | colorBox.isSelected = true 397 | isFillButton_Selected = false 398 | fillButton.setBackgroundImage(UIImage.init(named: "fill"), for: UIControlState.normal) 399 | }else{ 400 | colorBox.isSelected = false 401 | } 402 | } 403 | collectionView.reloadData() 404 | } 405 | 406 | } 407 | 408 | 409 | 410 | func scrollViewWillBeginDragging(_ scrollView: UIScrollView) { 411 | move = false 412 | } 413 | func scrollViewDidScroll(_ scrollView: UIScrollView) { 414 | move = false 415 | } 416 | func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { 417 | move = true 418 | 419 | } 420 | 421 | func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { 422 | move = false 423 | } 424 | 425 | func reloadDataAfterColorCountCompletion (){ 426 | 427 | tableView.reloadData() 428 | } 429 | } 430 | -------------------------------------------------------------------------------- /ColorByNumber/Views/Horizontal tableView/ColorBoxesCollectionViewCell.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | DisposableDroidBB 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 37 | 45 | 53 | 61 | 69 | 77 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 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 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | -------------------------------------------------------------------------------- /ColorByNumber.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 36226C9420C7AD0F002F44A7 /* ColorPixel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36226C9320C7AD0F002F44A7 /* ColorPixel.swift */; }; 11 | 36226C9620C7B329002F44A7 /* Colors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36226C9520C7B329002F44A7 /* Colors.swift */; }; 12 | 36226C9920C7B63F002F44A7 /* Utilily.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36226C9820C7B63F002F44A7 /* Utilily.swift */; }; 13 | 36226C9B20C7E81B002F44A7 /* Array2D.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36226C9A20C7E81B002F44A7 /* Array2D.swift */; }; 14 | 36226C9D20CE9465002F44A7 /* AllColors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36226C9C20CE9464002F44A7 /* AllColors.swift */; }; 15 | 36226CA020CF9B3D002F44A7 /* TableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36226C9F20CF9B3D002F44A7 /* TableViewCell.swift */; }; 16 | 36226CA220CF9B47002F44A7 /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36226CA120CF9B47002F44A7 /* Helpers.swift */; }; 17 | 362865EC20D0F10800BD9103 /* ColorBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 362865EB20D0F10800BD9103 /* ColorBox.swift */; }; 18 | 3633A86520D063E10099D139 /* Table.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3633A86420D063E10099D139 /* Table.swift */; }; 19 | 3633A86720D0654C0099D139 /* CollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3633A86620D0654C0099D139 /* CollectionView.swift */; }; 20 | 3633A86A20D077AE0099D139 /* ColorBoxesCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3633A86820D077AE0099D139 /* ColorBoxesCollectionViewCell.swift */; }; 21 | 3633A86B20D077AE0099D139 /* ColorBoxesCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3633A86920D077AE0099D139 /* ColorBoxesCollectionViewCell.xib */; }; 22 | 3651FC9621127B44002E0B9C /* dog1.json in Resources */ = {isa = PBXBuildFile; fileRef = 3651FC9021127B44002E0B9C /* dog1.json */; }; 23 | 3657303B2132F38A0050984D /* GameScene+ParticleExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3657303A2132F38A0050984D /* GameScene+ParticleExtension.swift */; }; 24 | 3668B53C2103E4AE00BD1AB4 /* DoneTickTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3668B53A2103E4AE00BD1AB4 /* DoneTickTableViewCell.swift */; }; 25 | 3668B53D2103E4AE00BD1AB4 /* DoneTickTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 3668B53B2103E4AE00BD1AB4 /* DoneTickTableViewCell.xib */; }; 26 | 3668B5432104D7A400BD1AB4 /* Level.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3668B5422104D7A400BD1AB4 /* Level.swift */; }; 27 | 3668B5452104DD5600BD1AB4 /* Category.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3668B5442104DD5600BD1AB4 /* Category.swift */; }; 28 | 3668B54A210CA2D900BD1AB4 /* CategoryNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3668B549210CA2D900BD1AB4 /* CategoryNode.swift */; }; 29 | 3668B54D210CD16800BD1AB4 /* Disposable_bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 3668B54B210CD16800BD1AB4 /* Disposable_bold.ttf */; }; 30 | 3668B54E210CD16800BD1AB4 /* Disposable.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 3668B54C210CD16800BD1AB4 /* Disposable.ttf */; }; 31 | 3668B552210CF3CA00BD1AB4 /* LevelScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3668B551210CF3CA00BD1AB4 /* LevelScreen.swift */; }; 32 | 36921955210D231700E778CA /* LevelNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36921954210D231700E778CA /* LevelNode.swift */; }; 33 | 36E8EF3120BE7FA7002FEC8F /* Tile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36E8EF3020BE7FA7002FEC8F /* Tile.swift */; }; 34 | B2441BBC206DACC10060E453 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2441BBB206DACC10060E453 /* AppDelegate.swift */; }; 35 | B2441BC2206DACC10060E453 /* GameScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2441BC1206DACC10060E453 /* GameScene.swift */; }; 36 | B2441BC4206DACC10060E453 /* GameViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2441BC3206DACC10060E453 /* GameViewController.swift */; }; 37 | B2441BC7206DACC10060E453 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B2441BC5206DACC10060E453 /* Main.storyboard */; }; 38 | B2441BC9206DACC10060E453 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B2441BC8206DACC10060E453 /* Assets.xcassets */; }; 39 | B2441BCC206DACC10060E453 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B2441BCA206DACC10060E453 /* LaunchScreen.storyboard */; }; 40 | B2441BD4206F24380060E453 /* DemoCamera.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2441BD3206F24380060E453 /* DemoCamera.swift */; }; 41 | /* End PBXBuildFile section */ 42 | 43 | /* Begin PBXFileReference section */ 44 | 36226C9320C7AD0F002F44A7 /* ColorPixel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorPixel.swift; sourceTree = ""; }; 45 | 36226C9520C7B329002F44A7 /* Colors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Colors.swift; sourceTree = ""; }; 46 | 36226C9820C7B63F002F44A7 /* Utilily.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utilily.swift; sourceTree = ""; }; 47 | 36226C9A20C7E81B002F44A7 /* Array2D.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Array2D.swift; sourceTree = ""; }; 48 | 36226C9C20CE9464002F44A7 /* AllColors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllColors.swift; sourceTree = ""; }; 49 | 36226C9F20CF9B3D002F44A7 /* TableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TableViewCell.swift; sourceTree = ""; }; 50 | 36226CA120CF9B47002F44A7 /* Helpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Helpers.swift; sourceTree = ""; }; 51 | 362865EB20D0F10800BD9103 /* ColorBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorBox.swift; sourceTree = ""; }; 52 | 3633A86420D063E10099D139 /* Table.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Table.swift; sourceTree = ""; }; 53 | 3633A86620D0654C0099D139 /* CollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionView.swift; sourceTree = ""; }; 54 | 3633A86820D077AE0099D139 /* ColorBoxesCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorBoxesCollectionViewCell.swift; sourceTree = ""; }; 55 | 3633A86920D077AE0099D139 /* ColorBoxesCollectionViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ColorBoxesCollectionViewCell.xib; sourceTree = ""; }; 56 | 3651FC9021127B44002E0B9C /* dog1.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = dog1.json; sourceTree = ""; }; 57 | 3657303A2132F38A0050984D /* GameScene+ParticleExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GameScene+ParticleExtension.swift"; sourceTree = ""; }; 58 | 3668B53A2103E4AE00BD1AB4 /* DoneTickTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DoneTickTableViewCell.swift; sourceTree = ""; }; 59 | 3668B53B2103E4AE00BD1AB4 /* DoneTickTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DoneTickTableViewCell.xib; sourceTree = ""; }; 60 | 3668B5422104D7A400BD1AB4 /* Level.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Level.swift; sourceTree = ""; }; 61 | 3668B5442104DD5600BD1AB4 /* Category.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Category.swift; sourceTree = ""; }; 62 | 3668B549210CA2D900BD1AB4 /* CategoryNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CategoryNode.swift; sourceTree = ""; }; 63 | 3668B54B210CD16800BD1AB4 /* Disposable_bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = Disposable_bold.ttf; sourceTree = ""; }; 64 | 3668B54C210CD16800BD1AB4 /* Disposable.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = Disposable.ttf; sourceTree = ""; }; 65 | 3668B551210CF3CA00BD1AB4 /* LevelScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LevelScreen.swift; sourceTree = ""; }; 66 | 36921954210D231700E778CA /* LevelNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LevelNode.swift; sourceTree = ""; }; 67 | 36E8EF3020BE7FA7002FEC8F /* Tile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tile.swift; sourceTree = ""; }; 68 | B2441BB8206DACC10060E453 /* ColorByNumber.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ColorByNumber.app; sourceTree = BUILT_PRODUCTS_DIR; }; 69 | B2441BBB206DACC10060E453 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 70 | B2441BC1206DACC10060E453 /* GameScene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameScene.swift; sourceTree = ""; }; 71 | B2441BC3206DACC10060E453 /* GameViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameViewController.swift; sourceTree = ""; }; 72 | B2441BC6206DACC10060E453 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 73 | B2441BC8206DACC10060E453 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 74 | B2441BCB206DACC10060E453 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 75 | B2441BCD206DACC10060E453 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 76 | B2441BD3206F24380060E453 /* DemoCamera.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoCamera.swift; sourceTree = ""; }; 77 | /* End PBXFileReference section */ 78 | 79 | /* Begin PBXFrameworksBuildPhase section */ 80 | B2441BB5206DACC10060E453 /* Frameworks */ = { 81 | isa = PBXFrameworksBuildPhase; 82 | buildActionMask = 2147483647; 83 | files = ( 84 | ); 85 | runOnlyForDeploymentPostprocessing = 0; 86 | }; 87 | /* End PBXFrameworksBuildPhase section */ 88 | 89 | /* Begin PBXGroup section */ 90 | 36226C9220C7ACEF002F44A7 /* ColorObjects */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | 36226C9320C7AD0F002F44A7 /* ColorPixel.swift */, 94 | 36226C9520C7B329002F44A7 /* Colors.swift */, 95 | 36226C9C20CE9464002F44A7 /* AllColors.swift */, 96 | ); 97 | path = ColorObjects; 98 | sourceTree = ""; 99 | }; 100 | 36226C9720C7B62B002F44A7 /* Utility */ = { 101 | isa = PBXGroup; 102 | children = ( 103 | 36226C9820C7B63F002F44A7 /* Utilily.swift */, 104 | ); 105 | path = Utility; 106 | sourceTree = ""; 107 | }; 108 | 36226C9E20CF9B23002F44A7 /* Horizontal tableView */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | 362865EA20D0F0F400BD9103 /* ColorBoxForCell */, 112 | 3633A86420D063E10099D139 /* Table.swift */, 113 | 36226CA120CF9B47002F44A7 /* Helpers.swift */, 114 | 36226C9F20CF9B3D002F44A7 /* TableViewCell.swift */, 115 | 3633A86620D0654C0099D139 /* CollectionView.swift */, 116 | 3633A86820D077AE0099D139 /* ColorBoxesCollectionViewCell.swift */, 117 | 3633A86920D077AE0099D139 /* ColorBoxesCollectionViewCell.xib */, 118 | 3668B53A2103E4AE00BD1AB4 /* DoneTickTableViewCell.swift */, 119 | 3668B53B2103E4AE00BD1AB4 /* DoneTickTableViewCell.xib */, 120 | ); 121 | path = "Horizontal tableView"; 122 | sourceTree = ""; 123 | }; 124 | 362865EA20D0F0F400BD9103 /* ColorBoxForCell */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | 362865EB20D0F10800BD9103 /* ColorBox.swift */, 128 | ); 129 | path = ColorBoxForCell; 130 | sourceTree = ""; 131 | }; 132 | 36346B272376BCDD000537E9 /* resources */ = { 133 | isa = PBXGroup; 134 | children = ( 135 | 3668B54F210CD16C00BD1AB4 /* fonts */, 136 | 36921956210E25D500E778CA /* levelJsons */, 137 | ); 138 | path = resources; 139 | sourceTree = ""; 140 | }; 141 | 36346B282376BCFC000537E9 /* Views */ = { 142 | isa = PBXGroup; 143 | children = ( 144 | B2441BD3206F24380060E453 /* DemoCamera.swift */, 145 | 36226C9E20CF9B23002F44A7 /* Horizontal tableView */, 146 | 3668B549210CA2D900BD1AB4 /* CategoryNode.swift */, 147 | 36921954210D231700E778CA /* LevelNode.swift */, 148 | B2441BC1206DACC10060E453 /* GameScene.swift */, 149 | 3657303A2132F38A0050984D /* GameScene+ParticleExtension.swift */, 150 | 3668B551210CF3CA00BD1AB4 /* LevelScreen.swift */, 151 | ); 152 | path = Views; 153 | sourceTree = ""; 154 | }; 155 | 36346B292376BD11000537E9 /* modal */ = { 156 | isa = PBXGroup; 157 | children = ( 158 | 36226C9720C7B62B002F44A7 /* Utility */, 159 | 36226C9220C7ACEF002F44A7 /* ColorObjects */, 160 | 36226C9A20C7E81B002F44A7 /* Array2D.swift */, 161 | 3668B5442104DD5600BD1AB4 /* Category.swift */, 162 | 3668B5422104D7A400BD1AB4 /* Level.swift */, 163 | ); 164 | path = modal; 165 | sourceTree = ""; 166 | }; 167 | 3668B54F210CD16C00BD1AB4 /* fonts */ = { 168 | isa = PBXGroup; 169 | children = ( 170 | 3668B54B210CD16800BD1AB4 /* Disposable_bold.ttf */, 171 | 3668B54C210CD16800BD1AB4 /* Disposable.ttf */, 172 | ); 173 | path = fonts; 174 | sourceTree = ""; 175 | }; 176 | 36921956210E25D500E778CA /* levelJsons */ = { 177 | isa = PBXGroup; 178 | children = ( 179 | 36921957210E25E700E778CA /* dogs */, 180 | ); 181 | path = levelJsons; 182 | sourceTree = ""; 183 | }; 184 | 36921957210E25E700E778CA /* dogs */ = { 185 | isa = PBXGroup; 186 | children = ( 187 | 3651FC9021127B44002E0B9C /* dog1.json */, 188 | ); 189 | path = dogs; 190 | sourceTree = ""; 191 | }; 192 | B2441BAF206DACC00060E453 = { 193 | isa = PBXGroup; 194 | children = ( 195 | B2441BBA206DACC10060E453 /* ColorByNumber */, 196 | B2441BB9206DACC10060E453 /* Products */, 197 | ); 198 | sourceTree = ""; 199 | }; 200 | B2441BB9206DACC10060E453 /* Products */ = { 201 | isa = PBXGroup; 202 | children = ( 203 | B2441BB8206DACC10060E453 /* ColorByNumber.app */, 204 | ); 205 | name = Products; 206 | sourceTree = ""; 207 | }; 208 | B2441BBA206DACC10060E453 /* ColorByNumber */ = { 209 | isa = PBXGroup; 210 | children = ( 211 | 36346B292376BD11000537E9 /* modal */, 212 | 36346B282376BCFC000537E9 /* Views */, 213 | 36346B272376BCDD000537E9 /* resources */, 214 | B2441BBB206DACC10060E453 /* AppDelegate.swift */, 215 | B2441BC3206DACC10060E453 /* GameViewController.swift */, 216 | B2441BC5206DACC10060E453 /* Main.storyboard */, 217 | B2441BC8206DACC10060E453 /* Assets.xcassets */, 218 | B2441BCA206DACC10060E453 /* LaunchScreen.storyboard */, 219 | B2441BCD206DACC10060E453 /* Info.plist */, 220 | 36E8EF3020BE7FA7002FEC8F /* Tile.swift */, 221 | ); 222 | path = ColorByNumber; 223 | sourceTree = ""; 224 | }; 225 | /* End PBXGroup section */ 226 | 227 | /* Begin PBXNativeTarget section */ 228 | B2441BB7206DACC10060E453 /* ColorByNumber */ = { 229 | isa = PBXNativeTarget; 230 | buildConfigurationList = B2441BD0206DACC10060E453 /* Build configuration list for PBXNativeTarget "ColorByNumber" */; 231 | buildPhases = ( 232 | B2441BB4206DACC10060E453 /* Sources */, 233 | B2441BB5206DACC10060E453 /* Frameworks */, 234 | B2441BB6206DACC10060E453 /* Resources */, 235 | ); 236 | buildRules = ( 237 | ); 238 | dependencies = ( 239 | ); 240 | name = ColorByNumber; 241 | productName = "SKCamera Demo"; 242 | productReference = B2441BB8206DACC10060E453 /* ColorByNumber.app */; 243 | productType = "com.apple.product-type.application"; 244 | }; 245 | /* End PBXNativeTarget section */ 246 | 247 | /* Begin PBXProject section */ 248 | B2441BB0206DACC00060E453 /* Project object */ = { 249 | isa = PBXProject; 250 | attributes = { 251 | LastSwiftUpdateCheck = 0920; 252 | LastUpgradeCheck = 0930; 253 | ORGANIZATIONNAME = WoodyApps; 254 | TargetAttributes = { 255 | B2441BB7206DACC10060E453 = { 256 | CreatedOnToolsVersion = 9.2; 257 | ProvisioningStyle = Automatic; 258 | }; 259 | }; 260 | }; 261 | buildConfigurationList = B2441BB3206DACC00060E453 /* Build configuration list for PBXProject "ColorByNumber" */; 262 | compatibilityVersion = "Xcode 8.0"; 263 | developmentRegion = en; 264 | hasScannedForEncodings = 0; 265 | knownRegions = ( 266 | en, 267 | Base, 268 | ); 269 | mainGroup = B2441BAF206DACC00060E453; 270 | productRefGroup = B2441BB9206DACC10060E453 /* Products */; 271 | projectDirPath = ""; 272 | projectRoot = ""; 273 | targets = ( 274 | B2441BB7206DACC10060E453 /* ColorByNumber */, 275 | ); 276 | }; 277 | /* End PBXProject section */ 278 | 279 | /* Begin PBXResourcesBuildPhase section */ 280 | B2441BB6206DACC10060E453 /* Resources */ = { 281 | isa = PBXResourcesBuildPhase; 282 | buildActionMask = 2147483647; 283 | files = ( 284 | 3668B54E210CD16800BD1AB4 /* Disposable.ttf in Resources */, 285 | B2441BC7206DACC10060E453 /* Main.storyboard in Resources */, 286 | 3668B54D210CD16800BD1AB4 /* Disposable_bold.ttf in Resources */, 287 | 3651FC9621127B44002E0B9C /* dog1.json in Resources */, 288 | B2441BC9206DACC10060E453 /* Assets.xcassets in Resources */, 289 | 3633A86B20D077AE0099D139 /* ColorBoxesCollectionViewCell.xib in Resources */, 290 | 3668B53D2103E4AE00BD1AB4 /* DoneTickTableViewCell.xib in Resources */, 291 | B2441BCC206DACC10060E453 /* LaunchScreen.storyboard in Resources */, 292 | ); 293 | runOnlyForDeploymentPostprocessing = 0; 294 | }; 295 | /* End PBXResourcesBuildPhase section */ 296 | 297 | /* Begin PBXSourcesBuildPhase section */ 298 | B2441BB4206DACC10060E453 /* Sources */ = { 299 | isa = PBXSourcesBuildPhase; 300 | buildActionMask = 2147483647; 301 | files = ( 302 | 3657303B2132F38A0050984D /* GameScene+ParticleExtension.swift in Sources */, 303 | B2441BC2206DACC10060E453 /* GameScene.swift in Sources */, 304 | 362865EC20D0F10800BD9103 /* ColorBox.swift in Sources */, 305 | 3668B5452104DD5600BD1AB4 /* Category.swift in Sources */, 306 | 3633A86A20D077AE0099D139 /* ColorBoxesCollectionViewCell.swift in Sources */, 307 | 36226C9D20CE9465002F44A7 /* AllColors.swift in Sources */, 308 | 3633A86720D0654C0099D139 /* CollectionView.swift in Sources */, 309 | 3668B54A210CA2D900BD1AB4 /* CategoryNode.swift in Sources */, 310 | 36226C9B20C7E81B002F44A7 /* Array2D.swift in Sources */, 311 | B2441BD4206F24380060E453 /* DemoCamera.swift in Sources */, 312 | 3668B53C2103E4AE00BD1AB4 /* DoneTickTableViewCell.swift in Sources */, 313 | 36E8EF3120BE7FA7002FEC8F /* Tile.swift in Sources */, 314 | 36226C9620C7B329002F44A7 /* Colors.swift in Sources */, 315 | 36226CA020CF9B3D002F44A7 /* TableViewCell.swift in Sources */, 316 | 36226CA220CF9B47002F44A7 /* Helpers.swift in Sources */, 317 | 36226C9920C7B63F002F44A7 /* Utilily.swift in Sources */, 318 | 36921955210D231700E778CA /* LevelNode.swift in Sources */, 319 | 3633A86520D063E10099D139 /* Table.swift in Sources */, 320 | B2441BC4206DACC10060E453 /* GameViewController.swift in Sources */, 321 | 3668B552210CF3CA00BD1AB4 /* LevelScreen.swift in Sources */, 322 | 36226C9420C7AD0F002F44A7 /* ColorPixel.swift in Sources */, 323 | 3668B5432104D7A400BD1AB4 /* Level.swift in Sources */, 324 | B2441BBC206DACC10060E453 /* AppDelegate.swift in Sources */, 325 | ); 326 | runOnlyForDeploymentPostprocessing = 0; 327 | }; 328 | /* End PBXSourcesBuildPhase section */ 329 | 330 | /* Begin PBXVariantGroup section */ 331 | B2441BC5206DACC10060E453 /* Main.storyboard */ = { 332 | isa = PBXVariantGroup; 333 | children = ( 334 | B2441BC6206DACC10060E453 /* Base */, 335 | ); 336 | name = Main.storyboard; 337 | sourceTree = ""; 338 | }; 339 | B2441BCA206DACC10060E453 /* LaunchScreen.storyboard */ = { 340 | isa = PBXVariantGroup; 341 | children = ( 342 | B2441BCB206DACC10060E453 /* Base */, 343 | ); 344 | name = LaunchScreen.storyboard; 345 | sourceTree = ""; 346 | }; 347 | /* End PBXVariantGroup section */ 348 | 349 | /* Begin XCBuildConfiguration section */ 350 | B2441BCE206DACC10060E453 /* Debug */ = { 351 | isa = XCBuildConfiguration; 352 | buildSettings = { 353 | ALWAYS_SEARCH_USER_PATHS = NO; 354 | CLANG_ANALYZER_NONNULL = YES; 355 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 356 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 357 | CLANG_CXX_LIBRARY = "libc++"; 358 | CLANG_ENABLE_MODULES = YES; 359 | CLANG_ENABLE_OBJC_ARC = YES; 360 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 361 | CLANG_WARN_BOOL_CONVERSION = YES; 362 | CLANG_WARN_COMMA = YES; 363 | CLANG_WARN_CONSTANT_CONVERSION = YES; 364 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 365 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 366 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 367 | CLANG_WARN_EMPTY_BODY = YES; 368 | CLANG_WARN_ENUM_CONVERSION = YES; 369 | CLANG_WARN_INFINITE_RECURSION = YES; 370 | CLANG_WARN_INT_CONVERSION = YES; 371 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 372 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 373 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 374 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 375 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 376 | CLANG_WARN_STRICT_PROTOTYPES = YES; 377 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 378 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 379 | CLANG_WARN_UNREACHABLE_CODE = YES; 380 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 381 | CODE_SIGN_IDENTITY = "iPhone Developer"; 382 | COPY_PHASE_STRIP = NO; 383 | DEBUG_INFORMATION_FORMAT = dwarf; 384 | ENABLE_STRICT_OBJC_MSGSEND = YES; 385 | ENABLE_TESTABILITY = YES; 386 | GCC_C_LANGUAGE_STANDARD = gnu11; 387 | GCC_DYNAMIC_NO_PIC = NO; 388 | GCC_NO_COMMON_BLOCKS = YES; 389 | GCC_OPTIMIZATION_LEVEL = 0; 390 | GCC_PREPROCESSOR_DEFINITIONS = ( 391 | "DEBUG=1", 392 | "$(inherited)", 393 | ); 394 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 395 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 396 | GCC_WARN_UNDECLARED_SELECTOR = YES; 397 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 398 | GCC_WARN_UNUSED_FUNCTION = YES; 399 | GCC_WARN_UNUSED_VARIABLE = YES; 400 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 401 | MTL_ENABLE_DEBUG_INFO = YES; 402 | ONLY_ACTIVE_ARCH = YES; 403 | SDKROOT = iphoneos; 404 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 405 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 406 | }; 407 | name = Debug; 408 | }; 409 | B2441BCF206DACC10060E453 /* Release */ = { 410 | isa = XCBuildConfiguration; 411 | buildSettings = { 412 | ALWAYS_SEARCH_USER_PATHS = NO; 413 | CLANG_ANALYZER_NONNULL = YES; 414 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 415 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 416 | CLANG_CXX_LIBRARY = "libc++"; 417 | CLANG_ENABLE_MODULES = YES; 418 | CLANG_ENABLE_OBJC_ARC = YES; 419 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 420 | CLANG_WARN_BOOL_CONVERSION = YES; 421 | CLANG_WARN_COMMA = YES; 422 | CLANG_WARN_CONSTANT_CONVERSION = YES; 423 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 424 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 425 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 426 | CLANG_WARN_EMPTY_BODY = YES; 427 | CLANG_WARN_ENUM_CONVERSION = YES; 428 | CLANG_WARN_INFINITE_RECURSION = YES; 429 | CLANG_WARN_INT_CONVERSION = YES; 430 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 431 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 432 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 433 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 434 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 435 | CLANG_WARN_STRICT_PROTOTYPES = YES; 436 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 437 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 438 | CLANG_WARN_UNREACHABLE_CODE = YES; 439 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 440 | CODE_SIGN_IDENTITY = "iPhone Developer"; 441 | COPY_PHASE_STRIP = NO; 442 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 443 | ENABLE_NS_ASSERTIONS = NO; 444 | ENABLE_STRICT_OBJC_MSGSEND = YES; 445 | GCC_C_LANGUAGE_STANDARD = gnu11; 446 | GCC_NO_COMMON_BLOCKS = YES; 447 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 448 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 449 | GCC_WARN_UNDECLARED_SELECTOR = YES; 450 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 451 | GCC_WARN_UNUSED_FUNCTION = YES; 452 | GCC_WARN_UNUSED_VARIABLE = YES; 453 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 454 | MTL_ENABLE_DEBUG_INFO = NO; 455 | SDKROOT = iphoneos; 456 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 457 | VALIDATE_PRODUCT = YES; 458 | }; 459 | name = Release; 460 | }; 461 | B2441BD1206DACC10060E453 /* Debug */ = { 462 | isa = XCBuildConfiguration; 463 | buildSettings = { 464 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 465 | CODE_SIGN_STYLE = Automatic; 466 | DEVELOPMENT_TEAM = UK8B2C8578; 467 | INFOPLIST_FILE = ColorByNumber/Info.plist; 468 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 469 | PRODUCT_BUNDLE_IDENTIFIER = araibkarim.colorbynumber; 470 | PRODUCT_NAME = "$(TARGET_NAME)"; 471 | SWIFT_VERSION = 4.0; 472 | TARGETED_DEVICE_FAMILY = "1,2"; 473 | }; 474 | name = Debug; 475 | }; 476 | B2441BD2206DACC10060E453 /* Release */ = { 477 | isa = XCBuildConfiguration; 478 | buildSettings = { 479 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 480 | CODE_SIGN_STYLE = Automatic; 481 | DEVELOPMENT_TEAM = UK8B2C8578; 482 | INFOPLIST_FILE = ColorByNumber/Info.plist; 483 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 484 | PRODUCT_BUNDLE_IDENTIFIER = araibkarim.colorbynumber; 485 | PRODUCT_NAME = "$(TARGET_NAME)"; 486 | SWIFT_VERSION = 4.0; 487 | TARGETED_DEVICE_FAMILY = "1,2"; 488 | }; 489 | name = Release; 490 | }; 491 | /* End XCBuildConfiguration section */ 492 | 493 | /* Begin XCConfigurationList section */ 494 | B2441BB3206DACC00060E453 /* Build configuration list for PBXProject "ColorByNumber" */ = { 495 | isa = XCConfigurationList; 496 | buildConfigurations = ( 497 | B2441BCE206DACC10060E453 /* Debug */, 498 | B2441BCF206DACC10060E453 /* Release */, 499 | ); 500 | defaultConfigurationIsVisible = 0; 501 | defaultConfigurationName = Release; 502 | }; 503 | B2441BD0206DACC10060E453 /* Build configuration list for PBXNativeTarget "ColorByNumber" */ = { 504 | isa = XCConfigurationList; 505 | buildConfigurations = ( 506 | B2441BD1206DACC10060E453 /* Debug */, 507 | B2441BD2206DACC10060E453 /* Release */, 508 | ); 509 | defaultConfigurationIsVisible = 0; 510 | defaultConfigurationName = Release; 511 | }; 512 | /* End XCConfigurationList section */ 513 | }; 514 | rootObject = B2441BB0206DACC00060E453 /* Project object */; 515 | } 516 | -------------------------------------------------------------------------------- /ColorByNumber/Views/GameScene.swift: -------------------------------------------------------------------------------- 1 | // 2 | // GameScene.swift 3 | // SKCamera Demo 4 | // 5 | // In any scene implementing the demo camera you will need to: 6 | // 1. Configure the camers 7 | // 2. Set the scene's camera to the demo camera instance 8 | // 3. Add the camera node as a child of the scene (so HUD can be displayed) 9 | // 4. Call the camera's update function from the scene's update function 10 | // 11 | // Created by Araib on 6/6/18. 12 | // Copyright © 2018 WoodyApps. All rights reserved. 13 | // 14 | 15 | import SpriteKit 16 | import GameplayKit 17 | var NumColumns = 0; 18 | var NumRows = 0; 19 | 20 | // MARK: Particle Enum 21 | enum ColorsForParticles { 22 | 23 | static let red = UIColor(red: 1.0, green: 0.0, blue: 77.0/255.0, alpha: 1.0) 24 | static let blue = UIColor.blue 25 | static let green = UIColor(red: 35.0/255.0 , green: 233/255, blue: 173/255.0, alpha: 1.0) 26 | static let yellow = UIColor(red: 1, green: 209/255, blue: 77.0/255.0, alpha: 1.0) 27 | 28 | } 29 | 30 | enum Images { 31 | 32 | static let box = UIImage(named: "Box")! 33 | static let triangle = UIImage(named: "Triangle")! 34 | static let circle = UIImage(named: "Circle")! 35 | static let swirl = UIImage(named: "Spiral")! 36 | 37 | } 38 | 39 | class GameScene: SKScene, DemoCameraOnChange { 40 | // MARK: Zoom Delegate 41 | func onChange(x: CGFloat, y: CGFloat, size: CGFloat) { 42 | 43 | if(size > 4){ 44 | let columns = NumColumns 45 | let rows = NumRows 46 | DispatchQueue.main.async { 47 | //Your code 48 | for column in 0...columns - 1 { 49 | for row in 0...rows - 1 { 50 | 51 | let colorPixel = self.gridAT(column: column, row: row) 52 | if(colorPixel != nil){ 53 | if(colorPixel?.isWhiteArea)!{ 54 | 55 | }else{ 56 | colorPixel?.node.hideNumber() 57 | } 58 | } 59 | } 60 | 61 | } 62 | 63 | } 64 | }else { 65 | let columns = NumColumns 66 | let rows = NumRows 67 | DispatchQueue.main.async { 68 | //Your code 69 | for column in 0...columns - 1 { 70 | for row in 0...rows - 1 { 71 | 72 | let colorPixel = self.gridAT(column: column, row: row) 73 | if(colorPixel != nil){ 74 | if(colorPixel?.isWhiteArea)!{ 75 | 76 | }else{ 77 | colorPixel?.node.showNumber() 78 | } 79 | } 80 | } 81 | 82 | } 83 | 84 | } 85 | } 86 | } 87 | // MARK: Particle Emitter 88 | 89 | var emitter = CAEmitterLayer() 90 | 91 | var colors:[UIColor] = [ 92 | ColorsForParticles.red, 93 | ColorsForParticles.blue, 94 | ColorsForParticles.green, 95 | ColorsForParticles.yellow 96 | ] 97 | 98 | var images:[UIImage] = [ 99 | Images.box, 100 | Images.triangle, 101 | Images.circle, 102 | Images.swirl 103 | ] 104 | 105 | var velocities:[Int] = [ 106 | 100, 107 | 90, 108 | 150, 109 | 200 110 | ] 111 | 112 | // MARK: Properties 113 | 114 | // The game layer node holds our demo game objects. 115 | // In a typical game this might be called backgroundLayer to hold all the background nodes, 116 | // or enemyLayer to hold all of the enemy sprite nodes, these types of SKNodes are used to keep the 117 | // game objects organized and easier to work with. 118 | 119 | 120 | var categoryData : Category! 121 | var currentLeveL : Level! 122 | var gameViewController : GameViewController! 123 | let PREFS_ColoredPixel = "ColoredPixel" 124 | 125 | let gameLayer: SKNode! 126 | fileprivate var grid : Array2D! 127 | var allPointColors = [String]() 128 | var uniqueColors = [Colors]() 129 | var allHexColors = [String]() 130 | var allColorsArrayToTrackCount = [AllColors] () 131 | // The whole point of this project is to demonstrate our SKCameraNode subclass! 132 | let demoCamera: DemoCamera! 133 | var colorBoxArray = [ColorBox] () 134 | 135 | 136 | // MARK: Initializers 137 | 138 | // Init 139 | override init(size: CGSize) { 140 | 141 | // Initialize the game layer node that will hold our game pieces and 142 | // move the gameLayer node to the center of the scene 143 | gameLayer = SKNode() 144 | gameLayer.position = CGPoint(x: 0, y: 0) 145 | 146 | // Initailize the demo camera 147 | demoCamera = DemoCamera() 148 | demoCamera.showScale() 149 | demoCamera.showPosition() 150 | demoCamera.showViewport() 151 | 152 | 153 | // Call the super class initializer 154 | super.init(size: size) 155 | 156 | // Set the scene's camera 157 | // If you do not add the camera as a child of the scene panning and zooming will still work, 158 | // but none of the children of the camera will be rendered. So, no HUD or game controls. 159 | addChild(demoCamera) 160 | camera = demoCamera 161 | 162 | 163 | // Add the game layer node to the scene 164 | addChild(gameLayer) 165 | self.backgroundColor = UIColor.white 166 | demoCamera.delegate = self 167 | 168 | } 169 | 170 | // When not using an .sks file to build our scenes, we must have this method 171 | required init?(coder aDecoder: NSCoder) { 172 | fatalError("Coder not used in this app") 173 | } 174 | 175 | // MARK: Scene Lifecycle 176 | 177 | override func didMove(to view: SKView) { 178 | // Call any custom code to setup the scene 179 | NumRows = currentLeveL.size 180 | NumColumns = currentLeveL.size 181 | demoCamera.setZoomRange(zoom: CGFloat(currentLeveL.zoom)) 182 | grid = Array2D(columns: NumColumns, rows: NumRows) 183 | gameViewController.initCollectionView (gameScene : self) 184 | gameViewController.showBackButton () 185 | readJSON() 186 | removeCharactersFromColor () 187 | setGameColors() 188 | addGamePieces() 189 | //addParticleEffect () 190 | } 191 | 192 | // Called before each frame is rendered 193 | override func update(_ currentTime: TimeInterval) { 194 | // Update the camera each frame 195 | demoCamera.update() 196 | } 197 | 198 | // MARK: Init Methods 199 | 200 | // This function just sets up a bunch of shape nodes so we can demonstrate the camera panning and zooming. 201 | private func addGamePieces() { 202 | // Keeping column and row numbers even will keep the game centered about the origin because we're working with integers 203 | let previouslyPlayedData = getColorPixelForEachLevel() 204 | let columns = NumColumns 205 | let rows = NumRows 206 | var i = 0 207 | for column in 0...columns - 1 { 208 | for row in 0...rows - 1 { 209 | print("\(column)"+"-"+"\(row)") 210 | let colorPixel = gridAT(column: column, row: row) 211 | if(colorPixel?.isWhiteArea)!{ 212 | 213 | } else{ 214 | // let node = Tile(color: (colorPixel?.hex.grayColor)!,size: CGSize(width: 100, height: 100)) 215 | let isSolved = previouslyPlayedData [i] 216 | 217 | let node = Tile() 218 | node.background = SKSpriteNode(color: (colorPixel?.hex.grayColor)!,size: CGSize(width: 100, height: 100)) 219 | node.background.position = CGPoint(x: 0, y: 0) 220 | node.column = column 221 | node.row = row 222 | node.background.name = "Tile" 223 | node.backgroundStroke = SKSpriteNode(color: UIColor.black,size: CGSize(width: 104, height: 104)) 224 | node.addChild ( node.backgroundStroke); 225 | node.addChild (node.background) 226 | node.backgroundStroke.name = "Tile" 227 | node.text = SKLabelNode.init(fontNamed: "DisposableDroidBB") 228 | node.text.text = colorPixel?.getNumber() 229 | node.text.fontSize = 30 230 | node.text.position = CGPoint(x: 0, y: 0) 231 | node.text.fontColor = SKColor.black 232 | node.addChild (node.text) 233 | node.text.name = "Tile" 234 | 235 | /* node.shape = SKShapeNode(rectOf: CGSize(width: 100, height: 100)) 236 | node.shape.lineWidth = 2 237 | node.shape.fillColor = (colorPixel?.hex.grayColor)! 238 | node.shape.strokeColor = UIColor.black 239 | */ 240 | // node.addChild (node.shape) 241 | 242 | node.mainColor = (colorPixel?.hex.mainHex)! 243 | node.name = "\(column)"+"-"+"\(row)" 244 | node.position = CGPoint(x: (column * 103) - (columns * 60) + 60, y: (row * 103) - (rows * 60) + 60) 245 | if(isSolved){ 246 | colorPixel?.setColor(color: (colorPixel?.hex)!) 247 | node.text.removeFromParent() 248 | node.background.color = (colorPixel?.hex.mainColor)! 249 | node.background.alpha = 1.0 250 | node.background.isHidden = false 251 | node.backgroundStroke.color = (colorPixel?.hex.mainColor)! 252 | 253 | for i in 0...self.allColorsArrayToTrackCount.count - 1 { 254 | let colorObject = self.allColorsArrayToTrackCount [i] 255 | if (colorObject.index == colorPixel?.hex.number){ 256 | let countEnded = colorObject.subtractToCount() 257 | if(countEnded){ 258 | print("CountEnded") 259 | for j in 0...self.gameViewController.colorBoxArray.count - 1 { 260 | let colorBox = self.gameViewController.colorBoxArray[j] 261 | if(colorBox.index == colorPixel?.hex.number){ 262 | colorBox.isTouchAble = false 263 | self.gameViewController.reloadDataAfterColorCountCompletion () 264 | print("CountEnded","Turn into Tick") 265 | 266 | break 267 | } 268 | } 269 | 270 | } 271 | } 272 | } 273 | 274 | }else{ 275 | 276 | } 277 | colorPixel?.node = node 278 | 279 | 280 | 281 | 282 | gameLayer.addChild(node) 283 | } 284 | i = i + 1 285 | } 286 | } 287 | let centerGamePiece = SKShapeNode(circleOfRadius: 5.0) 288 | centerGamePiece.strokeColor = .red 289 | centerGamePiece.fillColor = .red 290 | centerGamePiece.position = CGPoint(x: 0, y: 0) 291 | gameLayer.addChild(centerGamePiece) 292 | 293 | } 294 | 295 | private func setGameColors (){ 296 | 297 | // for () 298 | let columns = NumColumns 299 | let rows = NumRows 300 | var i = 0 301 | 302 | 303 | 304 | 305 | var row = rows - 1 306 | while row > -1 { 307 | for column in 0...columns - 1 { 308 | let colorString = allHexColors[i] 309 | 310 | if(colorString != "ffffff"){ 311 | 312 | for colortype in uniqueColors{ 313 | if(colortype.mainHex == colorString){ 314 | let color = ColorPixel(col: column, row : row, hex : colortype ) 315 | grid [column,row] = color 316 | break; 317 | 318 | } else{ 319 | 320 | } 321 | } 322 | }else{ 323 | let color = ColorPixel (col: column, row : row) 324 | grid [column,row] = color 325 | } 326 | i=i+1 327 | } 328 | row -= 1 329 | } 330 | 331 | 332 | } 333 | 334 | func removeCharactersFromColor (){ 335 | for i in (0.., with event: UIEvent?) { 407 | let touch = touches.first 408 | let touchLocation = touch?.location(in: self) 409 | let targetNode = atPoint(touchLocation!) 410 | if(targetNode.name == "Tile"){ 411 | if let targetNode = atPoint(touchLocation!) as? 412 | Tile{ 413 | if(!gameViewController.isScrolling){ 414 | paintTappedTile(tile: targetNode) 415 | } 416 | }else if let targetNode = atPoint(touchLocation!) as? 417 | SKLabelNode{ 418 | 419 | if(!gameViewController.isScrolling){ 420 | paintTappedTile(tile: targetNode.parent as! Tile) 421 | } 422 | }else if let targetNode = atPoint(touchLocation!) as? 423 | SKSpriteNode{ 424 | if(!gameViewController.isScrolling){ 425 | // targetNode.background.color = Utility.hexStringToUIColor(hex: targetNode.mainColor) 426 | paintTappedTile(tile: targetNode.parent as! Tile) 427 | } 428 | } 429 | } 430 | 431 | } 432 | 433 | func paintTappedTile (tile : Tile){ 434 | let col = tile.column 435 | let row = tile.row 436 | let colorPixel = gridAT(column: col, row: row) 437 | 438 | if(!self.gameViewController.isFill_Selected){ 439 | self.gameViewController.isFill_Selected = false 440 | if(colorPixel?.currentState == ColorPixel_Constants.STATE_DRAWN_CorrectColor){ 441 | 442 | }else{ 443 | for color in colorBoxArray { 444 | if (color.index == gameViewController.currentColorIndex){ 445 | print("indexCurrentIndex",gameViewController.currentColorIndex); 446 | colorPixel?.setColor(color: color.color) 447 | break; 448 | } 449 | } 450 | if(colorPixel?.currentState == ColorPixel_Constants.STATE_DRAWN_CorrectColor){ 451 | saveColorPixelForEachLevel () 452 | colorPixel?.node.text.removeFromParent() 453 | colorPixel?.node.background.color = (colorPixel?.hex.mainColor)! 454 | colorPixel?.node.background.alpha = 1.0 455 | colorPixel?.node.background.isHidden = false 456 | colorPixel?.node.backgroundStroke.color = (colorPixel?.hex.mainColor)! 457 | for i in 0...self.allColorsArrayToTrackCount.count - 1 { 458 | let colorObject = self.allColorsArrayToTrackCount [i] 459 | if (colorObject.index == colorPixel?.hex.number){ 460 | let countEnded = colorObject.subtractToCount() 461 | if(countEnded){ 462 | print("CountEnded") 463 | for j in 0...self.gameViewController.colorBoxArray.count - 1 { 464 | let colorBox = self.gameViewController.colorBoxArray[j] 465 | if(colorBox.index == colorPixel?.hex.number){ 466 | colorBox.isTouchAble = false 467 | self.gameViewController.reloadDataAfterColorCountCompletion () 468 | print("CountEnded","Turn into Tick") 469 | endGame() 470 | break 471 | } 472 | } 473 | 474 | } 475 | } 476 | } 477 | 478 | 479 | }else if(colorPixel?.currentState == ColorPixel_Constants.STATE_DRAWN_IncorrectCOLOR){ 480 | // colorPixel?.node.background.alpha = 0.5 481 | colorPixel?.node.background.color = (colorPixel?.currentColor)! 482 | // colorPixel?.node.background.isHidden = true 483 | // colorPixel?.node.backgroundStroke.color = (colorPixel?.currentColor)! 484 | // colorPixel?.node.backgroundStroke.alpha = 0.5 485 | }else if(colorPixel?.currentState == ColorPixel_Constants.STATE_NOT_DRAWN){ 486 | 487 | } 488 | } 489 | }else{ 490 | useFill(x: col, y: row) 491 | } 492 | 493 | } 494 | // MARK: Fill Function 495 | 496 | func useFill (x : Int, y : Int){ 497 | let startingCol = x - 3 498 | let endingCol = x + 3 499 | let startingRow = y - 3 500 | let endingRow = y + 3 501 | let colorPixel = gridAT(column: x, row: y) 502 | if(colorPixel?.currentState == ColorPixel_Constants.STATE_DRAWN_CorrectColor){ 503 | 504 | return 505 | } 506 | if(self.gameViewController.UseFill()){ 507 | for col in startingCol...endingCol { 508 | for row in startingRow...endingRow { 509 | if(col < 0 || row < 0){ 510 | 511 | }else if (col >= NumColumns || row >= NumRows){ 512 | 513 | }else { 514 | let colorPixel = gridAT(column: col, row: row) 515 | if(colorPixel?.isWhiteArea)!{ 516 | 517 | } else{ 518 | colorPixel?.setColor(color: (colorPixel?.hex)!) 519 | saveColorPixelForEachLevel () 520 | colorPixel?.node.text.removeFromParent() 521 | colorPixel?.node.background.color = (colorPixel?.hex.mainColor)! 522 | colorPixel?.node.background.alpha = 1.0 523 | colorPixel?.node.background.isHidden = false 524 | colorPixel?.node.backgroundStroke.color = (colorPixel?.hex.mainColor)! 525 | for i in 0...self.allColorsArrayToTrackCount.count - 1 { 526 | let colorObject = self.allColorsArrayToTrackCount [i] 527 | if (colorObject.index == colorPixel?.hex.number){ 528 | let countEnded = colorObject.subtractToCount() 529 | if(countEnded){ 530 | print("CountEnded") 531 | for j in 0...self.gameViewController.colorBoxArray.count - 1 { 532 | let colorBox = self.gameViewController.colorBoxArray[j] 533 | if(colorBox.index == colorPixel?.hex.number){ 534 | colorBox.isTouchAble = false 535 | self.gameViewController.reloadDataAfterColorCountCompletion () 536 | print("CountEnded","Turn into Tick") 537 | endGame() 538 | break 539 | } 540 | } 541 | 542 | } 543 | } 544 | } 545 | } 546 | } 547 | } 548 | } 549 | } 550 | } 551 | 552 | // MARK: EndGame 553 | func endGame (){ 554 | var gameEnded = true 555 | 556 | for i in 0...self.gameViewController.colorBoxArray.count - 1 { 557 | let colorObject = self.allColorsArrayToTrackCount [i] 558 | if(colorObject.count == 0){ 559 | 560 | }else{ 561 | gameEnded = false 562 | break 563 | } 564 | } 565 | 566 | if(gameEnded){ 567 | print("GAMEENDED") 568 | addParticleEffect () 569 | }else{ 570 | 571 | } 572 | 573 | 574 | } 575 | 576 | func saveColorPixelForEachLevel (){ 577 | let queue = DispatchQueue(label: "com.app.queue", qos: .background) 578 | queue.sync { 579 | var arrayOfBoolToSave = [Bool] () 580 | let columns = NumColumns 581 | let rows = NumRows 582 | for column in 0...columns - 1 { 583 | for row in 0...rows - 1 { 584 | let pixel = gridAT(column: column, row: row) 585 | if(pixel?.currentState == ColorPixel_Constants.STATE_DRAWN_CorrectColor){ 586 | let isColored = true 587 | arrayOfBoolToSave.append(isColored) 588 | }else{ 589 | let isColored = false 590 | arrayOfBoolToSave.append(isColored) 591 | } 592 | } 593 | 594 | } 595 | 596 | UserDefaults.standard.set(arrayOfBoolToSave, forKey: getPrefsString ()) 597 | } 598 | 599 | 600 | } 601 | func getPrefsString () -> String { 602 | let prefs = PREFS_ColoredPixel + "_" + "\(self.currentLeveL.categoryID)" + "_" + "\(self.currentLeveL.id)" 603 | return prefs 604 | } 605 | func getColorPixelForEachLevel() -> [Bool]{ 606 | var data = [Bool] () 607 | if let tempData = UserDefaults.standard.array(forKey: getPrefsString ()) as? [Bool] { 608 | data = tempData 609 | }else{ 610 | 611 | let columns = NumColumns 612 | let rows = NumRows 613 | for _ in 0...columns - 1 { 614 | for _ in 0...rows - 1 { 615 | data.append(false) 616 | } 617 | } 618 | } 619 | 620 | return data 621 | } 622 | // MARK: Back to Level Screen 623 | public func moveBackToLevelScreen (){ 624 | moveToLevelScreen (categoryData: self.categoryData) 625 | } 626 | 627 | func moveToLevelScreen (categoryData : Category){ 628 | self.removeParticleEffect() 629 | removeGestures() 630 | let levelScreen = LevelScreen(size: (self.view?.bounds.size)!) 631 | levelScreen.scaleMode = .resizeFill 632 | levelScreen.gameViewController = self.gameViewController 633 | levelScreen.categoryData = categoryData 634 | let skView = self.view 635 | skView?.presentScene(levelScreen) 636 | } 637 | // MARK: Remove Gestures 638 | func removeGestures(){ 639 | for gesture in (self.view?.gestureRecognizers)!{ 640 | self.view?.removeGestureRecognizer(gesture) 641 | } 642 | } 643 | 644 | // MARK: Utiliy methods 645 | public func UIColorFromRGB(_ rgbValue: String) -> UIColor { 646 | return UIColor( 647 | red: CGFloat((rgbValue.hexaToInt & 0xFF0000) >> 16) / 255.0, 648 | green: CGFloat((rgbValue.hexaToInt & 0x00FF00) >> 8) / 255.0, 649 | blue: CGFloat(rgbValue.hexaToInt & 0x0000FF) / 255.0, 650 | alpha: CGFloat(1.0) 651 | ) 652 | } 653 | 654 | func setInitialColors (UniqueColorArray : [String]){ 655 | var color = Utility.hexStringToUIColor(hex: "#f7f7f7"); 656 | for i in 0 ..< UniqueColorArray.count { 657 | let main_ColorHex = UniqueColorArray [i] 658 | color = color.darker(by: 5)! 659 | let colorObject = Colors (hex: main_ColorHex, mainColor: Utility.hexStringToUIColor(hex: main_ColorHex), grayColor: color, number: i + 1) 660 | self.uniqueColors.append(colorObject) 661 | } 662 | } 663 | 664 | func gridAT(column: Int, row: Int) -> ColorPixel? { 665 | assert(column >= 0 && column < NumColumns) 666 | assert(row >= 0 && row < NumRows) 667 | return grid[column, row] 668 | } 669 | 670 | func convertToDictionary(text: String) -> Any? { 671 | 672 | if let data = text.data(using: .utf8) { 673 | do { 674 | return try JSONSerialization.jsonObject(with: data, options: []) as? Any 675 | } catch { 676 | print(error.localizedDescription) 677 | } 678 | } 679 | 680 | return nil 681 | 682 | } 683 | 684 | func convertToArray(text: String) -> Any? { 685 | 686 | if let data = text.data(using: .utf8) { 687 | 688 | do { 689 | return try JSONSerialization.jsonObject(with: data, options: []) as? [String] 690 | } catch { 691 | print(error.localizedDescription) 692 | } 693 | 694 | } 695 | 696 | return nil 697 | 698 | } 699 | func hexStringToUIColor (hex:String) -> UIColor { 700 | var cString:String = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased() 701 | 702 | if (cString.hasPrefix("#")) { 703 | cString.remove(at: cString.startIndex) 704 | } 705 | 706 | if ((cString.count) != 6) { 707 | print("weird",hex); 708 | return UIColor.cyan 709 | } 710 | 711 | var rgbValue:UInt32 = 0 712 | Scanner(string: cString).scanHexInt32(&rgbValue) 713 | 714 | return UIColor( 715 | red: CGFloat((rgbValue & 0xFF0000) >> 16) / 255.0, 716 | green: CGFloat((rgbValue & 0x00FF00) >> 8) / 255.0, 717 | blue: CGFloat(rgbValue & 0x0000FF) / 255.0, 718 | alpha: CGFloat(1.0) 719 | ) 720 | } 721 | } 722 | // MARK: Extensions 723 | extension UIColor { 724 | convenience init(red: Int, green: Int, blue: Int) { 725 | assert(red >= 0 && red <= 255, "Invalid red component") 726 | assert(green >= 0 && green <= 255, "Invalid green component") 727 | assert(blue >= 0 && blue <= 255, "Invalid blue component") 728 | 729 | self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: 1.0) 730 | } 731 | 732 | convenience init(rgb: Int) { 733 | self.init( 734 | red: (rgb >> 16) & 0xFF, 735 | green: (rgb >> 8) & 0xFF, 736 | blue: rgb & 0xFF 737 | ) 738 | } 739 | func lighter(by percentage:CGFloat=30.0) -> UIColor? { 740 | return self.adjust(by: abs(percentage) ) 741 | } 742 | 743 | func darker(by percentage:CGFloat=30.0) -> UIColor? { 744 | return self.adjust(by: -1 * abs(percentage) ) 745 | } 746 | 747 | func adjust(by percentage:CGFloat=30.0) -> UIColor? { 748 | var r:CGFloat=0, g:CGFloat=0, b:CGFloat=0, a:CGFloat=0; 749 | if(self.getRed(&r, green: &g, blue: &b, alpha: &a)){ 750 | return UIColor(red: min(r + percentage/100, 1.0), 751 | green: min(g + percentage/100, 1.0), 752 | blue: min(b + percentage/100, 1.0), 753 | alpha: a) 754 | }else{ 755 | return nil 756 | } 757 | } 758 | 759 | 760 | } 761 | extension String { 762 | var hexaToInt : Int { return Int(strtoul(self, nil, 16)) } 763 | var hexaToDouble : Double { return Double(strtoul(self, nil, 16)) } 764 | var hexaToBinary : String { return String(hexaToInt, radix: 2) } 765 | var decimalToHexa : String { return String(Int(self) ?? 0, radix: 16)} 766 | var decimalToBinary: String { return String(Int(self) ?? 0, radix: 2) } 767 | var binaryToInt : Int { return Int(strtoul(self, nil, 2)) } 768 | var binaryToDouble : Double { return Double(strtoul(self, nil, 2)) } 769 | var binaryToHexa : String { return String(binaryToInt, radix: 16) } 770 | func removeCharacters(from forbiddenChars: CharacterSet) -> String { 771 | let passed = self.unicodeScalars.filter { !forbiddenChars.contains($0) } 772 | return String(String.UnicodeScalarView(passed)) 773 | } 774 | 775 | func removeCharacters(from: String) -> String { 776 | return removeCharacters(from: CharacterSet(charactersIn: from)) 777 | } 778 | } 779 | extension Int { 780 | var binaryString: String { return String(self, radix: 2) } 781 | var hexaString : String { return String(self, radix: 16) } 782 | var doubleValue : Double { return Double(self) } 783 | } 784 | --------------------------------------------------------------------------------