├── .swift-version ├── JDGamesLoading.podspec ├── JDGamesLoading.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcuserdata │ └── JamesDouble.xcuserdatad │ └── xcschemes │ ├── JDGamesLoading.xcscheme │ └── xcschememanagement.plist ├── JDGamesLoading ├── AppDelegate.swift ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist ├── JDGamesLoading │ ├── JDBreaksScene.swift │ ├── JDGamesConfiguration.swift │ ├── JDGamesLoading.swift │ ├── JDPingPongScene.swift │ ├── JDPuzzleScene.swift │ └── JDSnackScene.swift └── ViewController.swift ├── JDGamesLoadingTests ├── Info.plist └── JDGamesLoadingTests.swift ├── JDGamesLoadingUITests ├── Info.plist └── JDGamesLoadingUITests.swift ├── LICENSE ├── README.md └── Readme_img ├── BreakGameDemo.gif ├── JDPuzzleDemo.gif ├── Logomakr_3Y8BMT.png ├── PingPongDemo.gif └── SnackGameDemo.gif /.swift-version: -------------------------------------------------------------------------------- 1 | 3.0 2 | -------------------------------------------------------------------------------- /JDGamesLoading.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'JDGamesLoading' 3 | s.version = '1.3.0' 4 | s.summary = 'Let User play little game when they are waiting' 5 | 6 | s.description = <<-DESC 7 | Let User play little game when they are waiting , Now Have Three Basic game. 8 | DESC 9 | 10 | s.homepage = 'https://github.com/jamesdouble/JDGamesLoading' 11 | s.license = { :type => 'MIT', :file => 'LICENSE' } 12 | s.author = { 'JamesDouble' => 'jameskuo12345@gmail.com' } 13 | s.source = { :git => 'https://github.com/jamesdouble/JDGamesLoading.git', :tag => s.version.to_s } 14 | 15 | s.ios.deployment_target = '8.0' 16 | s.source_files = 'JDGamesLoading/JDGamesLoading/*' 17 | 18 | end 19 | -------------------------------------------------------------------------------- /JDGamesLoading.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 4F08E6F31ECCC06D00131F26 /* JDPuzzleScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F08E6F21ECCC06D00131F26 /* JDPuzzleScene.swift */; }; 11 | 4F5C26EC1E520BC400618FA7 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F5C26EB1E520BC400618FA7 /* AppDelegate.swift */; }; 12 | 4F5C26EE1E520BC400618FA7 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F5C26ED1E520BC400618FA7 /* ViewController.swift */; }; 13 | 4F5C26F11E520BC400618FA7 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4F5C26EF1E520BC400618FA7 /* Main.storyboard */; }; 14 | 4F5C26F31E520BC400618FA7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4F5C26F21E520BC400618FA7 /* Assets.xcassets */; }; 15 | 4F5C26F61E520BC400618FA7 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4F5C26F41E520BC400618FA7 /* LaunchScreen.storyboard */; }; 16 | 4F5C27011E520BC400618FA7 /* JDGamesLoadingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F5C27001E520BC400618FA7 /* JDGamesLoadingTests.swift */; }; 17 | 4F5C270C1E520BC400618FA7 /* JDGamesLoadingUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F5C270B1E520BC400618FA7 /* JDGamesLoadingUITests.swift */; }; 18 | 4F7B8D461EBD9D840030A838 /* JDPingPongScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F7B8D451EBD9D840030A838 /* JDPingPongScene.swift */; }; 19 | 4F7B8D481EBD9D8F0030A838 /* JDSnackScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F7B8D471EBD9D8E0030A838 /* JDSnackScene.swift */; }; 20 | 4F7B8D4A1EBD9D990030A838 /* JDBreaksScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F7B8D491EBD9D990030A838 /* JDBreaksScene.swift */; }; 21 | 4F7B8D4C1EBD9DA40030A838 /* JDGamesLoading.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F7B8D4B1EBD9DA40030A838 /* JDGamesLoading.swift */; }; 22 | 4FB7D1CE1EC443AC004ACAFF /* JDGamesConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FB7D1CD1EC443AC004ACAFF /* JDGamesConfiguration.swift */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXContainerItemProxy section */ 26 | 4F5C26FD1E520BC400618FA7 /* PBXContainerItemProxy */ = { 27 | isa = PBXContainerItemProxy; 28 | containerPortal = 4F5C26E01E520BC400618FA7 /* Project object */; 29 | proxyType = 1; 30 | remoteGlobalIDString = 4F5C26E71E520BC400618FA7; 31 | remoteInfo = JDGamesLoading; 32 | }; 33 | 4F5C27081E520BC400618FA7 /* PBXContainerItemProxy */ = { 34 | isa = PBXContainerItemProxy; 35 | containerPortal = 4F5C26E01E520BC400618FA7 /* Project object */; 36 | proxyType = 1; 37 | remoteGlobalIDString = 4F5C26E71E520BC400618FA7; 38 | remoteInfo = JDGamesLoading; 39 | }; 40 | /* End PBXContainerItemProxy section */ 41 | 42 | /* Begin PBXFileReference section */ 43 | 4F08E6F21ECCC06D00131F26 /* JDPuzzleScene.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JDPuzzleScene.swift; path = JDGamesLoading/JDPuzzleScene.swift; sourceTree = ""; }; 44 | 4F5C26E81E520BC400618FA7 /* JDGamesLoading.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = JDGamesLoading.app; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | 4F5C26EB1E520BC400618FA7 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 46 | 4F5C26ED1E520BC400618FA7 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 47 | 4F5C26F01E520BC400618FA7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 48 | 4F5C26F21E520BC400618FA7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 49 | 4F5C26F51E520BC400618FA7 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 50 | 4F5C26F71E520BC400618FA7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 51 | 4F5C26FC1E520BC400618FA7 /* JDGamesLoadingTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = JDGamesLoadingTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | 4F5C27001E520BC400618FA7 /* JDGamesLoadingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JDGamesLoadingTests.swift; sourceTree = ""; }; 53 | 4F5C27021E520BC400618FA7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 54 | 4F5C27071E520BC400618FA7 /* JDGamesLoadingUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = JDGamesLoadingUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 55 | 4F5C270B1E520BC400618FA7 /* JDGamesLoadingUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JDGamesLoadingUITests.swift; sourceTree = ""; }; 56 | 4F5C270D1E520BC400618FA7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 57 | 4F7B8D451EBD9D840030A838 /* JDPingPongScene.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JDPingPongScene.swift; path = JDGamesLoading/JDPingPongScene.swift; sourceTree = ""; }; 58 | 4F7B8D471EBD9D8E0030A838 /* JDSnackScene.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JDSnackScene.swift; path = JDGamesLoading/JDSnackScene.swift; sourceTree = ""; }; 59 | 4F7B8D491EBD9D990030A838 /* JDBreaksScene.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JDBreaksScene.swift; path = JDGamesLoading/JDBreaksScene.swift; sourceTree = ""; }; 60 | 4F7B8D4B1EBD9DA40030A838 /* JDGamesLoading.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JDGamesLoading.swift; path = JDGamesLoading/JDGamesLoading.swift; sourceTree = ""; }; 61 | 4FB7D1CD1EC443AC004ACAFF /* JDGamesConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JDGamesConfiguration.swift; path = JDGamesLoading/JDGamesConfiguration.swift; sourceTree = ""; }; 62 | /* End PBXFileReference section */ 63 | 64 | /* Begin PBXFrameworksBuildPhase section */ 65 | 4F5C26E51E520BC400618FA7 /* Frameworks */ = { 66 | isa = PBXFrameworksBuildPhase; 67 | buildActionMask = 2147483647; 68 | files = ( 69 | ); 70 | runOnlyForDeploymentPostprocessing = 0; 71 | }; 72 | 4F5C26F91E520BC400618FA7 /* Frameworks */ = { 73 | isa = PBXFrameworksBuildPhase; 74 | buildActionMask = 2147483647; 75 | files = ( 76 | ); 77 | runOnlyForDeploymentPostprocessing = 0; 78 | }; 79 | 4F5C27041E520BC400618FA7 /* Frameworks */ = { 80 | isa = PBXFrameworksBuildPhase; 81 | buildActionMask = 2147483647; 82 | files = ( 83 | ); 84 | runOnlyForDeploymentPostprocessing = 0; 85 | }; 86 | /* End PBXFrameworksBuildPhase section */ 87 | 88 | /* Begin PBXGroup section */ 89 | 4F08E6F11ECCC03700131F26 /* PuzzleGame */ = { 90 | isa = PBXGroup; 91 | children = ( 92 | 4F08E6F21ECCC06D00131F26 /* JDPuzzleScene.swift */, 93 | ); 94 | name = PuzzleGame; 95 | sourceTree = ""; 96 | }; 97 | 4F5C26DF1E520BC400618FA7 = { 98 | isa = PBXGroup; 99 | children = ( 100 | 4F5C26EA1E520BC400618FA7 /* JDGamesLoading */, 101 | 4F5C26FF1E520BC400618FA7 /* JDGamesLoadingTests */, 102 | 4F5C270A1E520BC400618FA7 /* JDGamesLoadingUITests */, 103 | 4F5C26E91E520BC400618FA7 /* Products */, 104 | ); 105 | sourceTree = ""; 106 | }; 107 | 4F5C26E91E520BC400618FA7 /* Products */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | 4F5C26E81E520BC400618FA7 /* JDGamesLoading.app */, 111 | 4F5C26FC1E520BC400618FA7 /* JDGamesLoadingTests.xctest */, 112 | 4F5C27071E520BC400618FA7 /* JDGamesLoadingUITests.xctest */, 113 | ); 114 | name = Products; 115 | sourceTree = ""; 116 | }; 117 | 4F5C26EA1E520BC400618FA7 /* JDGamesLoading */ = { 118 | isa = PBXGroup; 119 | children = ( 120 | 4F5C27191E520C8300618FA7 /* JDGamesLoading */, 121 | 4F5C26EB1E520BC400618FA7 /* AppDelegate.swift */, 122 | 4F5C26ED1E520BC400618FA7 /* ViewController.swift */, 123 | 4F5C26EF1E520BC400618FA7 /* Main.storyboard */, 124 | 4F5C26F21E520BC400618FA7 /* Assets.xcassets */, 125 | 4F5C26F41E520BC400618FA7 /* LaunchScreen.storyboard */, 126 | 4F5C26F71E520BC400618FA7 /* Info.plist */, 127 | ); 128 | path = JDGamesLoading; 129 | sourceTree = ""; 130 | }; 131 | 4F5C26FF1E520BC400618FA7 /* JDGamesLoadingTests */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 4F5C27001E520BC400618FA7 /* JDGamesLoadingTests.swift */, 135 | 4F5C27021E520BC400618FA7 /* Info.plist */, 136 | ); 137 | path = JDGamesLoadingTests; 138 | sourceTree = ""; 139 | }; 140 | 4F5C270A1E520BC400618FA7 /* JDGamesLoadingUITests */ = { 141 | isa = PBXGroup; 142 | children = ( 143 | 4F5C270B1E520BC400618FA7 /* JDGamesLoadingUITests.swift */, 144 | 4F5C270D1E520BC400618FA7 /* Info.plist */, 145 | ); 146 | path = JDGamesLoadingUITests; 147 | sourceTree = ""; 148 | }; 149 | 4F5C27191E520C8300618FA7 /* JDGamesLoading */ = { 150 | isa = PBXGroup; 151 | children = ( 152 | 4F7B8D4B1EBD9DA40030A838 /* JDGamesLoading.swift */, 153 | 4FB7D1CD1EC443AC004ACAFF /* JDGamesConfiguration.swift */, 154 | 4FCDAE9C1E6D4E4200B83D2C /* PingPongGame */, 155 | 4FF1D9581E52ADBB00EBA98E /* SnackGame */, 156 | 4F08E6F11ECCC03700131F26 /* PuzzleGame */, 157 | 4F5C271A1E520C8F00618FA7 /* BreaksGame */, 158 | ); 159 | name = JDGamesLoading; 160 | sourceTree = ""; 161 | }; 162 | 4F5C271A1E520C8F00618FA7 /* BreaksGame */ = { 163 | isa = PBXGroup; 164 | children = ( 165 | 4F7B8D491EBD9D990030A838 /* JDBreaksScene.swift */, 166 | ); 167 | name = BreaksGame; 168 | sourceTree = ""; 169 | }; 170 | 4FCDAE9C1E6D4E4200B83D2C /* PingPongGame */ = { 171 | isa = PBXGroup; 172 | children = ( 173 | 4F7B8D451EBD9D840030A838 /* JDPingPongScene.swift */, 174 | ); 175 | name = PingPongGame; 176 | sourceTree = ""; 177 | }; 178 | 4FF1D9581E52ADBB00EBA98E /* SnackGame */ = { 179 | isa = PBXGroup; 180 | children = ( 181 | 4F7B8D471EBD9D8E0030A838 /* JDSnackScene.swift */, 182 | ); 183 | name = SnackGame; 184 | sourceTree = ""; 185 | }; 186 | /* End PBXGroup section */ 187 | 188 | /* Begin PBXNativeTarget section */ 189 | 4F5C26E71E520BC400618FA7 /* JDGamesLoading */ = { 190 | isa = PBXNativeTarget; 191 | buildConfigurationList = 4F5C27101E520BC400618FA7 /* Build configuration list for PBXNativeTarget "JDGamesLoading" */; 192 | buildPhases = ( 193 | 4F5C26E41E520BC400618FA7 /* Sources */, 194 | 4F5C26E51E520BC400618FA7 /* Frameworks */, 195 | 4F5C26E61E520BC400618FA7 /* Resources */, 196 | ); 197 | buildRules = ( 198 | ); 199 | dependencies = ( 200 | ); 201 | name = JDGamesLoading; 202 | productName = JDGamesLoading; 203 | productReference = 4F5C26E81E520BC400618FA7 /* JDGamesLoading.app */; 204 | productType = "com.apple.product-type.application"; 205 | }; 206 | 4F5C26FB1E520BC400618FA7 /* JDGamesLoadingTests */ = { 207 | isa = PBXNativeTarget; 208 | buildConfigurationList = 4F5C27131E520BC400618FA7 /* Build configuration list for PBXNativeTarget "JDGamesLoadingTests" */; 209 | buildPhases = ( 210 | 4F5C26F81E520BC400618FA7 /* Sources */, 211 | 4F5C26F91E520BC400618FA7 /* Frameworks */, 212 | 4F5C26FA1E520BC400618FA7 /* Resources */, 213 | ); 214 | buildRules = ( 215 | ); 216 | dependencies = ( 217 | 4F5C26FE1E520BC400618FA7 /* PBXTargetDependency */, 218 | ); 219 | name = JDGamesLoadingTests; 220 | productName = JDGamesLoadingTests; 221 | productReference = 4F5C26FC1E520BC400618FA7 /* JDGamesLoadingTests.xctest */; 222 | productType = "com.apple.product-type.bundle.unit-test"; 223 | }; 224 | 4F5C27061E520BC400618FA7 /* JDGamesLoadingUITests */ = { 225 | isa = PBXNativeTarget; 226 | buildConfigurationList = 4F5C27161E520BC400618FA7 /* Build configuration list for PBXNativeTarget "JDGamesLoadingUITests" */; 227 | buildPhases = ( 228 | 4F5C27031E520BC400618FA7 /* Sources */, 229 | 4F5C27041E520BC400618FA7 /* Frameworks */, 230 | 4F5C27051E520BC400618FA7 /* Resources */, 231 | ); 232 | buildRules = ( 233 | ); 234 | dependencies = ( 235 | 4F5C27091E520BC400618FA7 /* PBXTargetDependency */, 236 | ); 237 | name = JDGamesLoadingUITests; 238 | productName = JDGamesLoadingUITests; 239 | productReference = 4F5C27071E520BC400618FA7 /* JDGamesLoadingUITests.xctest */; 240 | productType = "com.apple.product-type.bundle.ui-testing"; 241 | }; 242 | /* End PBXNativeTarget section */ 243 | 244 | /* Begin PBXProject section */ 245 | 4F5C26E01E520BC400618FA7 /* Project object */ = { 246 | isa = PBXProject; 247 | attributes = { 248 | LastSwiftUpdateCheck = 0820; 249 | LastUpgradeCheck = 0820; 250 | ORGANIZATIONNAME = james12345; 251 | TargetAttributes = { 252 | 4F5C26E71E520BC400618FA7 = { 253 | CreatedOnToolsVersion = 8.2; 254 | DevelopmentTeam = 857SMZQ3R8; 255 | ProvisioningStyle = Automatic; 256 | }; 257 | 4F5C26FB1E520BC400618FA7 = { 258 | CreatedOnToolsVersion = 8.2; 259 | ProvisioningStyle = Automatic; 260 | TestTargetID = 4F5C26E71E520BC400618FA7; 261 | }; 262 | 4F5C27061E520BC400618FA7 = { 263 | CreatedOnToolsVersion = 8.2; 264 | ProvisioningStyle = Automatic; 265 | TestTargetID = 4F5C26E71E520BC400618FA7; 266 | }; 267 | }; 268 | }; 269 | buildConfigurationList = 4F5C26E31E520BC400618FA7 /* Build configuration list for PBXProject "JDGamesLoading" */; 270 | compatibilityVersion = "Xcode 3.2"; 271 | developmentRegion = English; 272 | hasScannedForEncodings = 0; 273 | knownRegions = ( 274 | en, 275 | Base, 276 | ); 277 | mainGroup = 4F5C26DF1E520BC400618FA7; 278 | productRefGroup = 4F5C26E91E520BC400618FA7 /* Products */; 279 | projectDirPath = ""; 280 | projectRoot = ""; 281 | targets = ( 282 | 4F5C26E71E520BC400618FA7 /* JDGamesLoading */, 283 | 4F5C26FB1E520BC400618FA7 /* JDGamesLoadingTests */, 284 | 4F5C27061E520BC400618FA7 /* JDGamesLoadingUITests */, 285 | ); 286 | }; 287 | /* End PBXProject section */ 288 | 289 | /* Begin PBXResourcesBuildPhase section */ 290 | 4F5C26E61E520BC400618FA7 /* Resources */ = { 291 | isa = PBXResourcesBuildPhase; 292 | buildActionMask = 2147483647; 293 | files = ( 294 | 4F5C26F61E520BC400618FA7 /* LaunchScreen.storyboard in Resources */, 295 | 4F5C26F31E520BC400618FA7 /* Assets.xcassets in Resources */, 296 | 4F5C26F11E520BC400618FA7 /* Main.storyboard in Resources */, 297 | ); 298 | runOnlyForDeploymentPostprocessing = 0; 299 | }; 300 | 4F5C26FA1E520BC400618FA7 /* Resources */ = { 301 | isa = PBXResourcesBuildPhase; 302 | buildActionMask = 2147483647; 303 | files = ( 304 | ); 305 | runOnlyForDeploymentPostprocessing = 0; 306 | }; 307 | 4F5C27051E520BC400618FA7 /* Resources */ = { 308 | isa = PBXResourcesBuildPhase; 309 | buildActionMask = 2147483647; 310 | files = ( 311 | ); 312 | runOnlyForDeploymentPostprocessing = 0; 313 | }; 314 | /* End PBXResourcesBuildPhase section */ 315 | 316 | /* Begin PBXSourcesBuildPhase section */ 317 | 4F5C26E41E520BC400618FA7 /* Sources */ = { 318 | isa = PBXSourcesBuildPhase; 319 | buildActionMask = 2147483647; 320 | files = ( 321 | 4FB7D1CE1EC443AC004ACAFF /* JDGamesConfiguration.swift in Sources */, 322 | 4F7B8D461EBD9D840030A838 /* JDPingPongScene.swift in Sources */, 323 | 4F5C26EE1E520BC400618FA7 /* ViewController.swift in Sources */, 324 | 4F7B8D481EBD9D8F0030A838 /* JDSnackScene.swift in Sources */, 325 | 4F08E6F31ECCC06D00131F26 /* JDPuzzleScene.swift in Sources */, 326 | 4F7B8D4A1EBD9D990030A838 /* JDBreaksScene.swift in Sources */, 327 | 4F7B8D4C1EBD9DA40030A838 /* JDGamesLoading.swift in Sources */, 328 | 4F5C26EC1E520BC400618FA7 /* AppDelegate.swift in Sources */, 329 | ); 330 | runOnlyForDeploymentPostprocessing = 0; 331 | }; 332 | 4F5C26F81E520BC400618FA7 /* Sources */ = { 333 | isa = PBXSourcesBuildPhase; 334 | buildActionMask = 2147483647; 335 | files = ( 336 | 4F5C27011E520BC400618FA7 /* JDGamesLoadingTests.swift in Sources */, 337 | ); 338 | runOnlyForDeploymentPostprocessing = 0; 339 | }; 340 | 4F5C27031E520BC400618FA7 /* Sources */ = { 341 | isa = PBXSourcesBuildPhase; 342 | buildActionMask = 2147483647; 343 | files = ( 344 | 4F5C270C1E520BC400618FA7 /* JDGamesLoadingUITests.swift in Sources */, 345 | ); 346 | runOnlyForDeploymentPostprocessing = 0; 347 | }; 348 | /* End PBXSourcesBuildPhase section */ 349 | 350 | /* Begin PBXTargetDependency section */ 351 | 4F5C26FE1E520BC400618FA7 /* PBXTargetDependency */ = { 352 | isa = PBXTargetDependency; 353 | target = 4F5C26E71E520BC400618FA7 /* JDGamesLoading */; 354 | targetProxy = 4F5C26FD1E520BC400618FA7 /* PBXContainerItemProxy */; 355 | }; 356 | 4F5C27091E520BC400618FA7 /* PBXTargetDependency */ = { 357 | isa = PBXTargetDependency; 358 | target = 4F5C26E71E520BC400618FA7 /* JDGamesLoading */; 359 | targetProxy = 4F5C27081E520BC400618FA7 /* PBXContainerItemProxy */; 360 | }; 361 | /* End PBXTargetDependency section */ 362 | 363 | /* Begin PBXVariantGroup section */ 364 | 4F5C26EF1E520BC400618FA7 /* Main.storyboard */ = { 365 | isa = PBXVariantGroup; 366 | children = ( 367 | 4F5C26F01E520BC400618FA7 /* Base */, 368 | ); 369 | name = Main.storyboard; 370 | sourceTree = ""; 371 | }; 372 | 4F5C26F41E520BC400618FA7 /* LaunchScreen.storyboard */ = { 373 | isa = PBXVariantGroup; 374 | children = ( 375 | 4F5C26F51E520BC400618FA7 /* Base */, 376 | ); 377 | name = LaunchScreen.storyboard; 378 | sourceTree = ""; 379 | }; 380 | /* End PBXVariantGroup section */ 381 | 382 | /* Begin XCBuildConfiguration section */ 383 | 4F5C270E1E520BC400618FA7 /* Debug */ = { 384 | isa = XCBuildConfiguration; 385 | buildSettings = { 386 | ALWAYS_SEARCH_USER_PATHS = NO; 387 | CLANG_ANALYZER_NONNULL = YES; 388 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 389 | CLANG_CXX_LIBRARY = "libc++"; 390 | CLANG_ENABLE_MODULES = YES; 391 | CLANG_ENABLE_OBJC_ARC = YES; 392 | CLANG_WARN_BOOL_CONVERSION = YES; 393 | CLANG_WARN_CONSTANT_CONVERSION = YES; 394 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 395 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 396 | CLANG_WARN_EMPTY_BODY = YES; 397 | CLANG_WARN_ENUM_CONVERSION = YES; 398 | CLANG_WARN_INFINITE_RECURSION = YES; 399 | CLANG_WARN_INT_CONVERSION = YES; 400 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 401 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 402 | CLANG_WARN_UNREACHABLE_CODE = YES; 403 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 404 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 405 | COPY_PHASE_STRIP = NO; 406 | DEBUG_INFORMATION_FORMAT = dwarf; 407 | ENABLE_STRICT_OBJC_MSGSEND = YES; 408 | ENABLE_TESTABILITY = YES; 409 | GCC_C_LANGUAGE_STANDARD = gnu99; 410 | GCC_DYNAMIC_NO_PIC = NO; 411 | GCC_NO_COMMON_BLOCKS = YES; 412 | GCC_OPTIMIZATION_LEVEL = 0; 413 | GCC_PREPROCESSOR_DEFINITIONS = ( 414 | "DEBUG=1", 415 | "$(inherited)", 416 | ); 417 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 418 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 419 | GCC_WARN_UNDECLARED_SELECTOR = YES; 420 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 421 | GCC_WARN_UNUSED_FUNCTION = YES; 422 | GCC_WARN_UNUSED_VARIABLE = YES; 423 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 424 | MTL_ENABLE_DEBUG_INFO = YES; 425 | ONLY_ACTIVE_ARCH = YES; 426 | SDKROOT = iphoneos; 427 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 428 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 429 | }; 430 | name = Debug; 431 | }; 432 | 4F5C270F1E520BC400618FA7 /* Release */ = { 433 | isa = XCBuildConfiguration; 434 | buildSettings = { 435 | ALWAYS_SEARCH_USER_PATHS = NO; 436 | CLANG_ANALYZER_NONNULL = YES; 437 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 438 | CLANG_CXX_LIBRARY = "libc++"; 439 | CLANG_ENABLE_MODULES = YES; 440 | CLANG_ENABLE_OBJC_ARC = YES; 441 | CLANG_WARN_BOOL_CONVERSION = YES; 442 | CLANG_WARN_CONSTANT_CONVERSION = YES; 443 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 444 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 445 | CLANG_WARN_EMPTY_BODY = YES; 446 | CLANG_WARN_ENUM_CONVERSION = YES; 447 | CLANG_WARN_INFINITE_RECURSION = YES; 448 | CLANG_WARN_INT_CONVERSION = YES; 449 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 450 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 451 | CLANG_WARN_UNREACHABLE_CODE = YES; 452 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 453 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 454 | COPY_PHASE_STRIP = NO; 455 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 456 | ENABLE_NS_ASSERTIONS = NO; 457 | ENABLE_STRICT_OBJC_MSGSEND = YES; 458 | GCC_C_LANGUAGE_STANDARD = gnu99; 459 | GCC_NO_COMMON_BLOCKS = YES; 460 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 461 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 462 | GCC_WARN_UNDECLARED_SELECTOR = YES; 463 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 464 | GCC_WARN_UNUSED_FUNCTION = YES; 465 | GCC_WARN_UNUSED_VARIABLE = YES; 466 | IPHONEOS_DEPLOYMENT_TARGET = 10.2; 467 | MTL_ENABLE_DEBUG_INFO = NO; 468 | SDKROOT = iphoneos; 469 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 470 | VALIDATE_PRODUCT = YES; 471 | }; 472 | name = Release; 473 | }; 474 | 4F5C27111E520BC400618FA7 /* Debug */ = { 475 | isa = XCBuildConfiguration; 476 | buildSettings = { 477 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 478 | DEVELOPMENT_TEAM = 857SMZQ3R8; 479 | INFOPLIST_FILE = JDGamesLoading/Info.plist; 480 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 481 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 482 | PRODUCT_BUNDLE_IDENTIFIER = com.jameskuo12345.JDGamesLoading; 483 | PRODUCT_NAME = "$(TARGET_NAME)"; 484 | SWIFT_VERSION = 3.0; 485 | }; 486 | name = Debug; 487 | }; 488 | 4F5C27121E520BC400618FA7 /* Release */ = { 489 | isa = XCBuildConfiguration; 490 | buildSettings = { 491 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 492 | DEVELOPMENT_TEAM = 857SMZQ3R8; 493 | INFOPLIST_FILE = JDGamesLoading/Info.plist; 494 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 495 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 496 | PRODUCT_BUNDLE_IDENTIFIER = com.jameskuo12345.JDGamesLoading; 497 | PRODUCT_NAME = "$(TARGET_NAME)"; 498 | SWIFT_VERSION = 3.0; 499 | }; 500 | name = Release; 501 | }; 502 | 4F5C27141E520BC400618FA7 /* Debug */ = { 503 | isa = XCBuildConfiguration; 504 | buildSettings = { 505 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 506 | BUNDLE_LOADER = "$(TEST_HOST)"; 507 | INFOPLIST_FILE = JDGamesLoadingTests/Info.plist; 508 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 509 | PRODUCT_BUNDLE_IDENTIFIER = com.jameskuo12345.JDGamesLoadingTests; 510 | PRODUCT_NAME = "$(TARGET_NAME)"; 511 | SWIFT_VERSION = 3.0; 512 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/JDGamesLoading.app/JDGamesLoading"; 513 | }; 514 | name = Debug; 515 | }; 516 | 4F5C27151E520BC400618FA7 /* Release */ = { 517 | isa = XCBuildConfiguration; 518 | buildSettings = { 519 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 520 | BUNDLE_LOADER = "$(TEST_HOST)"; 521 | INFOPLIST_FILE = JDGamesLoadingTests/Info.plist; 522 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 523 | PRODUCT_BUNDLE_IDENTIFIER = com.jameskuo12345.JDGamesLoadingTests; 524 | PRODUCT_NAME = "$(TARGET_NAME)"; 525 | SWIFT_VERSION = 3.0; 526 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/JDGamesLoading.app/JDGamesLoading"; 527 | }; 528 | name = Release; 529 | }; 530 | 4F5C27171E520BC400618FA7 /* Debug */ = { 531 | isa = XCBuildConfiguration; 532 | buildSettings = { 533 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 534 | INFOPLIST_FILE = JDGamesLoadingUITests/Info.plist; 535 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 536 | PRODUCT_BUNDLE_IDENTIFIER = com.jameskuo12345.JDGamesLoadingUITests; 537 | PRODUCT_NAME = "$(TARGET_NAME)"; 538 | SWIFT_VERSION = 3.0; 539 | TEST_TARGET_NAME = JDGamesLoading; 540 | }; 541 | name = Debug; 542 | }; 543 | 4F5C27181E520BC400618FA7 /* Release */ = { 544 | isa = XCBuildConfiguration; 545 | buildSettings = { 546 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 547 | INFOPLIST_FILE = JDGamesLoadingUITests/Info.plist; 548 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 549 | PRODUCT_BUNDLE_IDENTIFIER = com.jameskuo12345.JDGamesLoadingUITests; 550 | PRODUCT_NAME = "$(TARGET_NAME)"; 551 | SWIFT_VERSION = 3.0; 552 | TEST_TARGET_NAME = JDGamesLoading; 553 | }; 554 | name = Release; 555 | }; 556 | /* End XCBuildConfiguration section */ 557 | 558 | /* Begin XCConfigurationList section */ 559 | 4F5C26E31E520BC400618FA7 /* Build configuration list for PBXProject "JDGamesLoading" */ = { 560 | isa = XCConfigurationList; 561 | buildConfigurations = ( 562 | 4F5C270E1E520BC400618FA7 /* Debug */, 563 | 4F5C270F1E520BC400618FA7 /* Release */, 564 | ); 565 | defaultConfigurationIsVisible = 0; 566 | defaultConfigurationName = Release; 567 | }; 568 | 4F5C27101E520BC400618FA7 /* Build configuration list for PBXNativeTarget "JDGamesLoading" */ = { 569 | isa = XCConfigurationList; 570 | buildConfigurations = ( 571 | 4F5C27111E520BC400618FA7 /* Debug */, 572 | 4F5C27121E520BC400618FA7 /* Release */, 573 | ); 574 | defaultConfigurationIsVisible = 0; 575 | defaultConfigurationName = Release; 576 | }; 577 | 4F5C27131E520BC400618FA7 /* Build configuration list for PBXNativeTarget "JDGamesLoadingTests" */ = { 578 | isa = XCConfigurationList; 579 | buildConfigurations = ( 580 | 4F5C27141E520BC400618FA7 /* Debug */, 581 | 4F5C27151E520BC400618FA7 /* Release */, 582 | ); 583 | defaultConfigurationIsVisible = 0; 584 | defaultConfigurationName = Release; 585 | }; 586 | 4F5C27161E520BC400618FA7 /* Build configuration list for PBXNativeTarget "JDGamesLoadingUITests" */ = { 587 | isa = XCConfigurationList; 588 | buildConfigurations = ( 589 | 4F5C27171E520BC400618FA7 /* Debug */, 590 | 4F5C27181E520BC400618FA7 /* Release */, 591 | ); 592 | defaultConfigurationIsVisible = 0; 593 | defaultConfigurationName = Release; 594 | }; 595 | /* End XCConfigurationList section */ 596 | }; 597 | rootObject = 4F5C26E01E520BC400618FA7 /* Project object */; 598 | } 599 | -------------------------------------------------------------------------------- /JDGamesLoading.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /JDGamesLoading.xcodeproj/xcuserdata/JamesDouble.xcuserdatad/xcschemes/JDGamesLoading.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /JDGamesLoading.xcodeproj/xcuserdata/JamesDouble.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | JDGamesLoading.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 4F5C26E71E520BC400618FA7 16 | 17 | primary 18 | 19 | 20 | 4F5C26FB1E520BC400618FA7 21 | 22 | primary 23 | 24 | 25 | 4F5C27061E520BC400618FA7 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /JDGamesLoading/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // JDGamesLoading 4 | // 5 | // Created by 郭介騵 on 2017/2/13. 6 | // Copyright © 2017年 james12345. 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 | -------------------------------------------------------------------------------- /JDGamesLoading/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 | "info" : { 45 | "version" : 1, 46 | "author" : "xcode" 47 | } 48 | } -------------------------------------------------------------------------------- /JDGamesLoading/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 | 27 | 28 | -------------------------------------------------------------------------------- /JDGamesLoading/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 32 | 39 | 46 | 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 | -------------------------------------------------------------------------------- /JDGamesLoading/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /JDGamesLoading/JDGamesLoading/JDBreaksScene.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JDBreaksScene.swift 3 | // JDBreaksLoading 4 | // 5 | // Created by 郭介騵 on 2016/12/14. 6 | // Copyright © 2016年 james12345. All rights reserved. 7 | // 8 | 9 | import SpriteKit 10 | import GameplayKit 11 | 12 | 13 | 14 | struct BreaksBasicSetting { 15 | static let BallCategoryName = "ball" 16 | static let PaddleCategoryName = "paddle" 17 | static let BlockCategoryName = "block" 18 | static let GameMessageName = "gameMessage" 19 | 20 | static let BallCategory : UInt32 = 0x1 << 0 21 | static let BlockCategory : UInt32 = 0x1 << 1 22 | static let PaddleCategory : UInt32 = 0x1 << 2 23 | static let BorderCategory : UInt32 = 0x1 << 3 24 | } 25 | 26 | class JDBreaksBrick:SKShapeNode 27 | { 28 | init(size:CGSize,color:UIColor) { 29 | super.init() 30 | let rect = CGRect(origin: CGPoint.zero, size: size) 31 | self.path = CGPath(rect: rect, transform: nil) 32 | 33 | self.strokeColor = UIColor.black 34 | self.fillColor = color 35 | self.physicsBody = SKPhysicsBody(rectangleOf: self.frame.size) 36 | self.physicsBody!.allowsRotation = false 37 | self.physicsBody!.friction = 0.0 38 | self.physicsBody!.affectedByGravity = false 39 | self.physicsBody!.isDynamic = false 40 | self.name = BreaksBasicSetting.BlockCategoryName 41 | self.physicsBody!.categoryBitMask = BreaksBasicSetting.BlockCategory 42 | self.zPosition = 2 43 | } 44 | required init?(coder aDecoder: NSCoder) { 45 | fatalError("init(coder:) has not been implemented") 46 | } 47 | } 48 | 49 | class JDBallNode:SKShapeNode 50 | { 51 | init(size:CGSize,color:UIColor) { 52 | super.init() 53 | let rect = CGRect(origin: CGPoint.zero, size: size) 54 | self.path = CGPath(roundedRect: rect, cornerWidth: size.width * 0.5, cornerHeight: size.width * 0.5, transform: nil) 55 | // 56 | self.fillColor = color 57 | self.position = CGPoint(x: self.frame.width * 0.5, y: self.frame.width * 0.5) 58 | self.name = BreaksBasicSetting.BallCategoryName 59 | self.physicsBody = SKPhysicsBody(circleOfRadius: self.frame.width * 0.5) 60 | self.physicsBody!.categoryBitMask = BreaksBasicSetting.BallCategory 61 | self.physicsBody!.isDynamic = true 62 | self.physicsBody!.friction = 0.0 63 | self.physicsBody!.restitution = 1.0 64 | self.physicsBody!.linearDamping = 0.0 65 | self.physicsBody!.angularDamping = 0.0 66 | self.physicsBody!.allowsRotation = false 67 | self.physicsBody!.contactTestBitMask = BreaksBasicSetting.BlockCategory 68 | } 69 | required init?(coder aDecoder: NSCoder) { 70 | fatalError("init(coder:) has not been implemented") 71 | } 72 | } 73 | 74 | enum JDPaddleSide 75 | { 76 | case Own 77 | case Enemy 78 | } 79 | 80 | class JDBreakPaddle:SKShapeNode 81 | { 82 | var side:JDPaddleSide = .Own 83 | init(size:CGSize,color:UIColor,radius:CGFloat) { 84 | super.init() 85 | let rect = CGRect(origin: CGPoint.zero, size: size) 86 | self.path = CGPath(roundedRect: rect, cornerWidth: radius, cornerHeight: radius, transform: nil) 87 | // 88 | self.fillColor = color 89 | self.name = BreaksBasicSetting.PaddleCategoryName 90 | self.physicsBody = SKPhysicsBody(rectangleOf: size) 91 | self.physicsBody!.categoryBitMask = BreaksBasicSetting.PaddleCategory 92 | self.physicsBody!.isDynamic = false 93 | self.physicsBody!.allowsRotation = true 94 | self.physicsBody!.angularDamping = 0.1 95 | self.physicsBody!.linearDamping = 0.1 96 | 97 | } 98 | required init?(coder aDecoder: NSCoder) { 99 | fatalError("init(coder:) has not been implemented") 100 | } 101 | } 102 | 103 | 104 | class JDBreaksScene: SKScene 105 | { 106 | var isFingerOnPaddle = false 107 | var ball:JDBallNode! 108 | 109 | var gameWon : Bool = false { 110 | didSet { 111 | if(gameWon) 112 | { 113 | let holdQuene:DispatchQueue = DispatchQueue.global() 114 | let seconds = 0.5 115 | let delay = seconds * Double(NSEC_PER_SEC) 116 | let dispatchTime = DispatchTime.now() + Double(Int64(delay)) / Double(NSEC_PER_SEC) 117 | holdQuene.asyncAfter(deadline: dispatchTime, execute: { 118 | DispatchQueue.main.async(execute: { 119 | self.addBlock() 120 | }) 121 | }) 122 | } 123 | } 124 | } 125 | 126 | var d_ballwidth:CGFloat = 20.0 127 | var ballwidth:CGFloat = 0.0 128 | var ballcolor:UIColor = UIColor.white 129 | 130 | var d_paddlewidth:CGFloat = 60 131 | var paddlewidth:CGFloat = 0.0 132 | var paddlecolor:UIColor = UIColor.white 133 | 134 | var defaultwindowwidth:CGFloat = 200.0 135 | var windowscale:CGFloat = 1.0 136 | 137 | var d_blockwidth:CGFloat = 40.0 138 | var blockwidth:CGFloat = 0.0 139 | var blockscolor:UIColor = UIColor.white 140 | 141 | var RowCount:Int = 2 142 | var ColumnCount:Int = 3 143 | 144 | override func update(_ currentTime: TimeInterval) { 145 | 146 | } 147 | 148 | override init(size: CGSize) { 149 | super.init(size: size) 150 | } 151 | 152 | init(size: CGSize,configuration:JDBreaksGameConfiguration) { 153 | super.init(size: size) 154 | ballcolor = configuration.ball_color 155 | paddlecolor = configuration.paddle_color 156 | blockscolor = configuration.block_color 157 | RowCount = configuration.RowCount 158 | ColumnCount = configuration.ColumnCount 159 | } 160 | 161 | required init?(coder aDecoder: NSCoder) { 162 | fatalError("init(coder:) has not been implemented") 163 | } 164 | 165 | 166 | override func didMove(to view: SKView) { 167 | super.didMove(to: view) 168 | 169 | windowscale = (self.frame.width / defaultwindowwidth) 170 | ballwidth = d_ballwidth * windowscale 171 | paddlewidth = d_paddlewidth * windowscale 172 | blockwidth = d_blockwidth * windowscale 173 | 174 | //Set Border 175 | let borderBody = SKPhysicsBody(edgeLoopFrom: self.frame) 176 | borderBody.friction = 0 177 | self.physicsBody = borderBody 178 | 179 | //Add Ball 180 | ball = JDBallNode(size: CGSize(width: ballwidth, height: ballwidth), color: ballcolor) 181 | self.addChild(ball) 182 | 183 | //No gravity 184 | self.physicsWorld.gravity = CGVector.zero 185 | physicsWorld.contactDelegate = self 186 | ball.physicsBody!.applyImpulse(CGVector(dx: 2.0, dy: -2.0)) 187 | 188 | //Add Paddle 189 | let paddlesize:CGSize = CGSize(width: paddlewidth, height: 15) 190 | let paddle:JDBreakPaddle = JDBreakPaddle(size: paddlesize, color: paddlecolor, radius: 5) 191 | paddle.position = CGPoint(x: self.frame.width * 0.5, y: self.frame.width * 0.2) 192 | self.addChild(paddle) 193 | 194 | addBlock() 195 | 196 | borderBody.categoryBitMask = BreaksBasicSetting.BorderCategory 197 | // 198 | } 199 | 200 | func addBlock() 201 | { 202 | // 新增方塊 203 | let blockWidth:CGFloat = blockwidth 204 | let totalBlocksWidth = blockWidth * CGFloat(ColumnCount) 205 | // 2 206 | let xOffset = (frame.width - totalBlocksWidth) / 2 207 | // 208 | var FirstY:CGFloat = frame.height * 0.8 209 | for _ in 0.. CGFloat { 242 | let rand: CGFloat = CGFloat(Float(arc4random()) / 0xFFFFFFFF) 243 | return (rand) * (to - from) + from 244 | } 245 | 246 | func isGameWon() -> Bool { 247 | var numberOfBricks = 0 248 | self.enumerateChildNodes(withName: BreaksBasicSetting.BlockCategoryName) { 249 | node, stop in 250 | numberOfBricks = numberOfBricks + 1 //有磚塊存在就+1 251 | 252 | } 253 | return numberOfBricks == 0 254 | } 255 | 256 | } 257 | 258 | extension JDBreaksScene 259 | { 260 | override func touchesBegan(_ touches: Set, with event: UIEvent?) { 261 | 262 | let touch = touches.first 263 | let touchLocation = touch!.location(in: self) 264 | 265 | if let body = physicsWorld.body(at: touchLocation) 266 | { 267 | if body.node!.name == BreaksBasicSetting.PaddleCategoryName { 268 | isFingerOnPaddle = true 269 | } 270 | } 271 | 272 | } 273 | 274 | override func touchesMoved(_ touches: Set, with event: UIEvent?) { 275 | // 是否壓著Bar 276 | if isFingerOnPaddle { 277 | // 2 278 | let touch = touches.first 279 | let touchLocation = touch!.location(in: self) 280 | let previousLocation = touch!.previousLocation(in: self) 281 | // 3 282 | let paddle = childNode(withName: BreaksBasicSetting.PaddleCategoryName) as! SKShapeNode 283 | // Take the current position and add the difference between the new and the previous touch locations. 284 | var paddleX = paddle.position.x + (touchLocation.x - previousLocation.x) 285 | // Before repositioning the paddle, limit the position so that the paddle will not go off the screen to the left or right. 286 | paddleX = max(paddleX, paddle.frame.size.width/2) 287 | paddleX = min(paddleX, size.width - paddle.frame.size.width/2) 288 | // 6 289 | paddle.position = CGPoint(x: paddleX, y: paddle.position.y) 290 | } 291 | } 292 | 293 | override func touchesEnded(_ touches: Set, with event: UIEvent?) { 294 | isFingerOnPaddle = false 295 | } 296 | 297 | } 298 | 299 | 300 | extension JDBreaksScene:SKPhysicsContactDelegate 301 | { 302 | /* 303 | Delegate 304 | */ 305 | func didBegin(_ contact: SKPhysicsContact) { 306 | 307 | // 1 308 | var firstBody: SKPhysicsBody 309 | var secondBody: SKPhysicsBody 310 | // 2 311 | if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask { 312 | firstBody = contact.bodyA 313 | secondBody = contact.bodyB 314 | } else { 315 | firstBody = contact.bodyB 316 | secondBody = contact.bodyA 317 | } 318 | // 球碰到磚塊 319 | if firstBody.categoryBitMask == BreaksBasicSetting.BallCategory && secondBody.categoryBitMask == BreaksBasicSetting.BlockCategory { 320 | breakBlock(node: secondBody.node!) 321 | gameWon = isGameWon() 322 | } 323 | } 324 | 325 | } 326 | 327 | 328 | -------------------------------------------------------------------------------- /JDGamesLoading/JDGamesLoading/JDGamesConfiguration.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JDGamesConfiguration.swift 3 | // JDGamesLoading 4 | // 5 | // Created by 郭介騵 on 2017/5/11. 6 | // Copyright © 2017年 james12345. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public class JDGamesConfiguration 12 | { 13 | 14 | } 15 | 16 | public class JDPingPongConfiguration:JDGamesConfiguration{ 17 | var paddle_color:UIColor = UIColor.white 18 | var ball_color:UIColor = UIColor.white 19 | 20 | init(paddlecolor:UIColor,ballcolor:UIColor) { 21 | paddle_color = paddlecolor 22 | ball_color = ballcolor 23 | } 24 | } 25 | 26 | public class JDSnackGameConfiguration:JDGamesConfiguration{ 27 | 28 | var Snack_color:UIColor = UIColor.green 29 | var Food_color:UIColor = UIColor.white 30 | var Snack_Speed:CGFloat = 10.0 31 | 32 | init(snackcolor:UIColor,foodcolor:UIColor,snackspeed:CGFloat) 33 | { 34 | Snack_color = snackcolor 35 | Food_color = foodcolor 36 | Snack_Speed = snackspeed 37 | } 38 | } 39 | 40 | public class JDBreaksGameConfiguration:JDGamesConfiguration{ 41 | var paddle_color:UIColor = UIColor.white 42 | var ball_color:UIColor = UIColor.white 43 | var block_color:UIColor = UIColor.white 44 | var RowCount:Int = 1 45 | var ColumnCount:Int = 3 46 | 47 | init(paddlecolor:UIColor,ballcolor:UIColor,blockcolor:UIColor,RowCount:Int,ColumnCount:Int) 48 | { 49 | paddle_color = paddlecolor 50 | ball_color = ballcolor 51 | block_color = blockcolor 52 | self.RowCount = RowCount 53 | self.ColumnCount = ColumnCount 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /JDGamesLoading/JDGamesLoading/JDGamesLoading.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JDGamesLoading.swift 3 | // JDGamesLoading 4 | // 5 | // Created by 郭介騵 on 2017/2/13. 6 | // Copyright © 2017年 james12345. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SpriteKit 11 | 12 | extension UIApplication { 13 | 14 | class func topViewController(controller: UIViewController? = UIApplication.shared.delegate?.window??.rootViewController) -> UIViewController? { 15 | if let navigationController = controller as? UINavigationController { 16 | return topViewController(controller: navigationController.visibleViewController) 17 | } 18 | if let tabController = controller as? UITabBarController { 19 | if let selected = tabController.selectedViewController { 20 | return topViewController(controller: selected) 21 | } 22 | } 23 | if let presented = controller?.presentedViewController { 24 | return topViewController(controller: presented) 25 | } 26 | return controller 27 | } 28 | } 29 | 30 | public enum GamePack 31 | { 32 | case Breaks 33 | case Snacks 34 | case PingPong 35 | case Puzzle 36 | } 37 | 38 | 39 | public class JDGamesLoading:NSObject 40 | { 41 | static var PrsentedViewController:JDLoadingViewController? 42 | var ChoosingGame:GamePack? 43 | public init(game:GamePack) 44 | { 45 | ChoosingGame = game 46 | JDGamesLoading.PrsentedViewController = JDLoadingViewController(gamesType: game) 47 | JDGamesLoading.PrsentedViewController?.modalPresentationStyle = .overCurrentContext 48 | JDGamesLoading.PrsentedViewController?.modalTransitionStyle = .coverVertical 49 | } 50 | 51 | public func withConfiguration(configuration:JDGamesConfiguration)->JDGamesLoading 52 | { 53 | if let choosinggames = ChoosingGame 54 | { 55 | if let snackConfig = configuration as? JDSnackGameConfiguration,choosinggames == .Snacks 56 | { 57 | JDGamesLoading.PrsentedViewController = JDLoadingViewController(gamesType: choosinggames, config: snackConfig) 58 | } 59 | if let breakConfig = configuration as? JDBreaksGameConfiguration,choosinggames == .Snacks 60 | { 61 | JDGamesLoading.PrsentedViewController = JDLoadingViewController(gamesType: choosinggames, config: breakConfig) 62 | 63 | } 64 | if let pingConfig = configuration as? JDPingPongConfiguration,choosinggames == .PingPong 65 | { 66 | JDGamesLoading.PrsentedViewController = JDLoadingViewController(gamesType: choosinggames, config: pingConfig) 67 | } 68 | JDGamesLoading.PrsentedViewController?.modalPresentationStyle = .overCurrentContext 69 | JDGamesLoading.PrsentedViewController?.modalTransitionStyle = .coverVertical 70 | } 71 | return self 72 | } 73 | 74 | public func show() 75 | { 76 | if let VC = UIApplication.topViewController(),let JDVC = JDGamesLoading.PrsentedViewController 77 | { 78 | VC.present(JDVC, animated: true, completion: nil) 79 | } 80 | } 81 | 82 | public func demoPresent() 83 | { 84 | if let JDVC = JDGamesLoading.PrsentedViewController 85 | { 86 | let NAV = UINavigationController(rootViewController: JDVC) 87 | NAV.modalPresentationStyle = .overCurrentContext 88 | NAV.modalTransitionStyle = .coverVertical 89 | 90 | // 91 | let barButton = UIBarButtonItem(title: "Dismiss", style: .plain, target: self, action: #selector(self.dismiss)) 92 | JDVC.navigationItem.leftBarButtonItem = barButton 93 | // 94 | 95 | if let VC = UIApplication.topViewController() { 96 | VC.present(NAV, animated: true, completion: nil) 97 | } 98 | } 99 | } 100 | 101 | public static func dismiss() 102 | { 103 | if let VC = UIApplication.topViewController() { 104 | VC.dismiss(animated: true, completion: nil) 105 | } 106 | JDGamesLoading.PrsentedViewController?.dismiss(animated: true, completion: nil) 107 | 108 | } 109 | 110 | public func dismiss() 111 | { 112 | if let VC = UIApplication.topViewController() { 113 | VC.dismiss(animated: true, completion: nil) 114 | } 115 | JDGamesLoading.PrsentedViewController?.dismiss(animated: true, completion: nil) 116 | } 117 | } 118 | 119 | class JDLoadingViewController:UIViewController 120 | { 121 | var indicator:UIActivityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.whiteLarge) 122 | var ContainerView:UIView = UIView() 123 | var skview:SKView! 124 | var skscene:SKScene! 125 | var GameType:GamePack = .Breaks 126 | var frame:CGRect! 127 | var gameconfig:JDGamesConfiguration? 128 | 129 | init(gamesType:GamePack) { 130 | super.init(nibName: nil, bundle: nil) 131 | GameType = gamesType 132 | } 133 | 134 | init(gamesType:GamePack,config:JDGamesConfiguration) { 135 | super.init(nibName: nil, bundle: nil) 136 | GameType = gamesType 137 | gameconfig = config 138 | } 139 | 140 | 141 | 142 | required init?(coder aDecoder: NSCoder) { 143 | fatalError("init(coder:) has not been implemented") 144 | } 145 | 146 | override func viewDidLoad() { 147 | super.viewDidLoad() 148 | view.backgroundColor = UIColor.clear 149 | view.isOpaque = false 150 | // 151 | frame = CGRect(x: self.view.frame.width * 1/4 , y: self.view.frame.height * 1/2 - self.view.frame.width * 1/4 , width: self.view.frame.width * 1/2 , height: self.view.frame.width * 1/2) 152 | // 153 | initView() 154 | 155 | let skviewframe:CGRect = CGRect(x: 0, y: 0, width: frame.width, height: frame.height) 156 | if(GameType == .Breaks) 157 | { 158 | if let breakconfig = gameconfig as? JDBreaksGameConfiguration 159 | { 160 | skscene = JDBreaksScene(size: skviewframe.size, configuration: breakconfig) 161 | } 162 | else 163 | { 164 | skscene = JDBreaksScene(size: skviewframe.size) 165 | } 166 | } 167 | else if(GameType == .Snacks) 168 | { 169 | if let sncakconfig = gameconfig as? JDSnackGameConfiguration 170 | { 171 | skscene = JDSnackScene(size: skviewframe.size, configuration: sncakconfig) 172 | } 173 | else 174 | { 175 | skscene = JDSnackScene(size: skviewframe.size) 176 | } 177 | } 178 | else if(GameType == .PingPong) 179 | { 180 | if let pingconfig = gameconfig as? JDPingPongConfiguration 181 | { 182 | skscene = JDPingPongScene(size: skviewframe.size, configuration: pingconfig) 183 | } 184 | else 185 | { 186 | skscene = JDPingPongScene(size: skviewframe.size) 187 | } 188 | } 189 | else if(GameType == .Puzzle) 190 | { 191 | skscene = JDPuzzleScene(size: skviewframe.size) 192 | } 193 | 194 | skscene.backgroundColor = UIColor.clear 195 | skview.presentScene(skscene) 196 | } 197 | 198 | func initView() 199 | { 200 | ContainerView.frame = frame 201 | ContainerView.backgroundColor = UIColor.clear 202 | ContainerView.layer.cornerRadius = 0.25 * frame.width 203 | self.view.addSubview(ContainerView) 204 | 205 | let skviewframe:CGRect = CGRect(x: 0, y: 0, width: frame.width, height: frame.height) 206 | skview = SKView(frame: skviewframe) 207 | skview.backgroundColor = UIColor.clear 208 | skview.layer.cornerRadius = 0.25 * frame.width 209 | skview.alpha = 0.8 210 | skview.allowsTransparency = true 211 | skview.layer.masksToBounds = true 212 | 213 | let bg = UIView(frame: skviewframe) 214 | bg.backgroundColor = UIColor.black 215 | bg.alpha = 0.3 216 | bg.layer.cornerRadius = 0.25 * frame.width 217 | 218 | ContainerView.addSubview(bg) 219 | ContainerView.addSubview(skview) 220 | 221 | indicator.frame = CGRect(x: (frame.width - 30) * 0.5, y: (frame.height - 30) * 0.5, width: 30, height: 30) 222 | indicator.startAnimating() 223 | indicator.isUserInteractionEnabled = false 224 | ContainerView.addSubview(indicator) 225 | } 226 | 227 | } 228 | -------------------------------------------------------------------------------- /JDGamesLoading/JDGamesLoading/JDPingPongScene.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JDPingPongScene.swift 3 | // JDGamesLoading 4 | // 5 | // Created by 郭介騵 on 2017/3/6. 6 | // Copyright © 2017年 james12345. All rights reserved. 7 | // 8 | 9 | import SpriteKit 10 | import GameplayKit 11 | 12 | 13 | 14 | class JDPingPongScene: SKScene 15 | { 16 | var isFingerOnPaddle = false 17 | var ball:JDBallNode! 18 | 19 | var gameWon : Bool = false { 20 | didSet { 21 | if(gameWon) 22 | { 23 | 24 | } 25 | } 26 | } 27 | 28 | var d_ballwidth:CGFloat = 20.0 29 | var ballwidth:CGFloat = 0.0 30 | var ballcolor:UIColor = UIColor.white 31 | 32 | var d_paddlewidth:CGFloat = 60 33 | var paddlewidth:CGFloat = 0.0 34 | var paddlecolor:UIColor = UIColor.white 35 | 36 | var defaultwindowwidth:CGFloat = 200.0 37 | var windowscale:CGFloat = 1.0 38 | 39 | override init(size: CGSize) { 40 | super.init(size: size) 41 | } 42 | 43 | init(size: CGSize,configuration:JDPingPongConfiguration) { 44 | super.init(size: size) 45 | ballcolor = configuration.ball_color 46 | paddlecolor = configuration.paddle_color 47 | } 48 | 49 | required init?(coder aDecoder: NSCoder) { 50 | fatalError("init(coder:) has not been implemented") 51 | } 52 | 53 | override func update(_ currentTime: TimeInterval) { 54 | self.enumerateChildNodes(withName: BreaksBasicSetting.PaddleCategoryName, using: { (node, point) in 55 | if let paddle:JDBreakPaddle = node as? JDBreakPaddle 56 | { 57 | if(paddle.side == .Enemy) 58 | { 59 | paddle.position = CGPoint(x: self.ball.position.x, y: paddle.position.y) 60 | } 61 | } 62 | }) 63 | } 64 | 65 | override func didMove(to view: SKView) { 66 | super.didMove(to: view) 67 | 68 | windowscale = (self.frame.width / defaultwindowwidth) 69 | ballwidth = d_ballwidth * windowscale 70 | paddlewidth = d_paddlewidth * windowscale 71 | 72 | //Set Border 73 | let borderBody = SKPhysicsBody(edgeLoopFrom: self.frame) 74 | borderBody.friction = 0 75 | self.physicsBody = borderBody 76 | 77 | //Add Ball 78 | ball = JDBallNode(size: CGSize(width: ballwidth, height: ballwidth), color: ballcolor) 79 | self.addChild(ball) 80 | 81 | //No gravity 82 | self.physicsWorld.gravity = CGVector.zero 83 | physicsWorld.contactDelegate = self 84 | ball.physicsBody!.applyImpulse(CGVector(dx: 2.0, dy: -2.0)) 85 | 86 | //Add Paddle 87 | let paddlesize:CGSize = CGSize(width: paddlewidth, height: 15) 88 | let paddle:JDBreakPaddle = JDBreakPaddle(size: paddlesize, color: paddlecolor, radius: 5) 89 | paddle.position = CGPoint(x: self.frame.width * 0.5, y: self.frame.width * 0.1) 90 | paddle.side = .Own 91 | self.addChild(paddle) 92 | 93 | let paddle2:JDBreakPaddle = JDBreakPaddle(size: paddlesize, color: paddlecolor, radius: 5) 94 | paddle2.position = CGPoint(x: self.frame.width * 0.5, y: self.frame.width * 0.8) 95 | paddle2.side = .Enemy 96 | self.addChild(paddle2) 97 | 98 | // 99 | borderBody.categoryBitMask = BreaksBasicSetting.BorderCategory 100 | // 101 | } 102 | 103 | func randomFloat(from: CGFloat, to: CGFloat) -> CGFloat { 104 | let rand: CGFloat = CGFloat(Float(arc4random()) / 0xFFFFFFFF) 105 | return (rand) * (to - from) + from 106 | } 107 | 108 | } 109 | 110 | extension JDPingPongScene 111 | { 112 | override func touchesBegan(_ touches: Set, with event: UIEvent?) { 113 | 114 | let touch = touches.first 115 | let touchLocation = touch!.location(in: self) 116 | let node = self.atPoint(touchLocation) 117 | if let paddle:JDBreakPaddle = node as? JDBreakPaddle 118 | { 119 | if(paddle.side == .Own) 120 | { 121 | isFingerOnPaddle = true 122 | } 123 | } 124 | } 125 | 126 | override func touchesMoved(_ touches: Set, with event: UIEvent?) { 127 | // 是否壓著Bar 128 | if isFingerOnPaddle { 129 | // 2 130 | let touch = touches.first 131 | let touchLocation = touch!.location(in: self) 132 | let previousLocation = touch!.previousLocation(in: self) 133 | // 3 134 | self.enumerateChildNodes(withName: BreaksBasicSetting.PaddleCategoryName, using: { (node, point) in 135 | if let paddle:JDBreakPaddle = node as? JDBreakPaddle 136 | { 137 | if(paddle.side == .Own) 138 | { 139 | var paddleX = paddle.position.x + (touchLocation.x - previousLocation.x) 140 | paddleX = max(paddleX, paddle.frame.size.width/2) 141 | paddleX = min(paddleX, self.size.width - paddle.frame.size.width/2) 142 | // 6 143 | paddle.position = CGPoint(x: paddleX, y: paddle.position.y) 144 | } 145 | } 146 | }) 147 | } 148 | } 149 | 150 | override func touchesEnded(_ touches: Set, with event: UIEvent?) { 151 | isFingerOnPaddle = false 152 | } 153 | 154 | } 155 | 156 | 157 | extension JDPingPongScene:SKPhysicsContactDelegate 158 | { 159 | /* 160 | Delegate 161 | */ 162 | func didBegin(_ contact: SKPhysicsContact) { 163 | 164 | // 1 165 | var firstBody: SKPhysicsBody 166 | var secondBody: SKPhysicsBody 167 | // 2 168 | if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask { 169 | firstBody = contact.bodyA 170 | secondBody = contact.bodyB 171 | } else { 172 | firstBody = contact.bodyB 173 | secondBody = contact.bodyA 174 | } 175 | // 球碰到磚塊 176 | if firstBody.categoryBitMask == BreaksBasicSetting.BallCategory && secondBody.categoryBitMask == BreaksBasicSetting.BlockCategory { 177 | 178 | } 179 | } 180 | 181 | } 182 | 183 | 184 | 185 | -------------------------------------------------------------------------------- /JDGamesLoading/JDGamesLoading/JDPuzzleScene.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JDPuzzleScene.swift 3 | // JDGamesLoading 4 | // 5 | // Created by 郭介騵 on 2017/5/18. 6 | // Copyright © 2017年 james12345. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SpriteKit 11 | 12 | struct PuzzleBasicSetting { 13 | static let PuzzleCategoryName = "ball" 14 | 15 | static let BallCategory : UInt32 = 0x1 << 0 16 | static let BlockCategory : UInt32 = 0x1 << 1 17 | static let PaddleCategory : UInt32 = 0x1 << 2 18 | static let BorderCategory : UInt32 = 0x1 << 3 19 | } 20 | 21 | class JDPuzzleGamePuzzle:SKSpriteNode 22 | { 23 | var MyIndex:CGPoint = CGPoint.zero 24 | static var Targettexture:SKTexture? 25 | 26 | 27 | init(size:CGSize,index:CGPoint) { 28 | let textrect:CGRect = CGRect(x: index.x * 1/3, y: index.y * 1/3, width: 1/3, height: 1/3) 29 | let texture:SKTexture = SKTexture(rect: textrect, in: JDPuzzleGamePuzzle.Targettexture!) 30 | super.init(texture: texture, color: UIColor.clear, size: size) 31 | self.name = PuzzleBasicSetting.PuzzleCategoryName 32 | self.MyIndex = index 33 | } 34 | required init?(coder aDecoder: NSCoder) { 35 | fatalError("init(coder:) has not been implemented") 36 | } 37 | 38 | override func touchesBegan(_ touches: Set, with event: UIEvent?) { 39 | print(MyIndex.debugDescription) 40 | print(position.debugDescription) 41 | } 42 | 43 | static func makeAnArray(row:Int,size:CGSize)->[[JDPuzzleGamePuzzle?]] 44 | { 45 | let normalSize:CGSize = CGSize(width: size.width / CGFloat(row), height: size.height / CGFloat(row)) 46 | let rows = row 47 | var Finalarray = [[JDPuzzleGamePuzzle?]]() 48 | 49 | for i in 0..UIImage? 137 | { 138 | UIGraphicsBeginImageContextWithOptions(targetview.bounds.size, false, 0) 139 | let sucess = targetview.drawHierarchy(in: targetview.bounds, afterScreenUpdates: true) 140 | if(sucess) 141 | { 142 | let image = UIGraphicsGetImageFromCurrentImageContext() 143 | return image 144 | } 145 | UIGraphicsEndImageContext() 146 | return nil 147 | } 148 | 149 | if let img = ViewToImage() 150 | { 151 | let texture = SKTexture(image: img) 152 | JDPuzzleGamePuzzle.Targettexture = texture 153 | } 154 | 155 | } 156 | 157 | func randomStarted() 158 | { 159 | var nilindex:CGPoint = CGPoint(x: 1, y: 1) 160 | func randomdirection()->CGVector 161 | { 162 | func randomInt() -> Int { 163 | let randomNum:UInt32 = arc4random_uniform(4) 164 | return Int(randomNum) 165 | } 166 | let vector = [CGVector(dx: 1, dy: 0),CGVector(dx: -1, dy: 0),CGVector(dx: 0, dy: 1),CGVector(dx: 0, dy: -1)] 167 | let rand = randomInt() 168 | return vector[rand] 169 | } 170 | //Start mash 171 | for _ in 0..<30 172 | { 173 | var vectornow = randomdirection() 174 | var targetindex = CGPoint.zero //The choosen Puzzle index 175 | func canMove()->Bool 176 | { 177 | if(vectornow.dx != 0) 178 | { 179 | let testingValue:CGFloat = nilindex.x + vectornow.dx 180 | let bool1:Bool = ( Int(testingValue) < row) && (Int(testingValue) > -1) 181 | if(bool1) 182 | { 183 | targetindex = CGPoint(x: testingValue, y: nilindex.y) 184 | return true 185 | } 186 | } 187 | if(vectornow.dy != 0) 188 | { 189 | let testingValue:CGFloat = nilindex.y + vectornow.dy 190 | let bool2:Bool = ( Int(testingValue) < row) && (Int(testingValue) > -1) 191 | if(bool2) 192 | { 193 | targetindex = CGPoint(x: nilindex.x, y: testingValue) 194 | return true 195 | } 196 | } 197 | return false 198 | } 199 | while !canMove() 200 | { 201 | vectornow = randomdirection() //ReChoosen the target 202 | } 203 | if let puzzle = PuzzleArray[Int(targetindex.y)][Int(targetindex.x)] //Target 204 | { 205 | //Swipe index 206 | let temp1 = puzzle.MyIndex 207 | puzzle.MyIndex = nilindex 208 | nilindex = temp1 209 | //Swipe Array Index 210 | PuzzleArray[Int(puzzle.MyIndex.y)][Int(puzzle.MyIndex.x)] = puzzle 211 | PuzzleArray[Int(nilindex.y)][Int(nilindex.x)] = nil 212 | // 213 | puzzle.position.x = (puzzle.frame.width/2) * (2 * puzzle.MyIndex.x + 1) 214 | puzzle.position.y = (puzzle.frame.width/2) * (2 * puzzle.MyIndex.y + 1) 215 | } 216 | } 217 | } 218 | 219 | 220 | 221 | func isGameWon() -> Bool { 222 | var numberOfBricks = 0 223 | self.enumerateChildNodes(withName: BreaksBasicSetting.BlockCategoryName) { 224 | node, stop in 225 | numberOfBricks = numberOfBricks + 1 //有磚塊存在就+1 226 | 227 | } 228 | return numberOfBricks == 0 229 | } 230 | 231 | } 232 | 233 | extension JDPuzzleScene 234 | { 235 | override func touchesBegan(_ touches: Set, with event: UIEvent?) { 236 | 237 | let touch = touches.first 238 | let touchLocation = touch!.location(in: self) 239 | 240 | if let puzzle = self.atPoint(touchLocation) as? JDPuzzleGamePuzzle 241 | { 242 | HoldedPuzzle = puzzle 243 | puzzle.touchesBegan(touches, with: event) 244 | } 245 | } 246 | 247 | override func touchesMoved(_ touches: Set, with event: UIEvent?) { 248 | if(isMoving) 249 | { 250 | return 251 | } 252 | // 1 253 | let touch = touches.first 254 | let touchLocation = touch!.location(in: self) 255 | let preLocation = touch!.previousLocation(in: self) 256 | if let puzzle = HoldedPuzzle 257 | { 258 | var puzzleMoving:CGVector = CGVector.zero 259 | func moving() 260 | { 261 | self.isMoving = true 262 | let movingaction:SKAction = SKAction.move(by: puzzleMoving, duration: 0.4) 263 | puzzle.run(movingaction, completion: { 264 | self.isMoving = false 265 | }) 266 | HoldedPuzzle = nil 267 | } 268 | let x:Int = Int(puzzle.MyIndex.x) 269 | let y:Int = Int(puzzle.MyIndex.y) 270 | if (touchLocation.x > preLocation.x) { 271 | //finger touch went right 272 | if( x < (row-1)) 273 | { 274 | if(PuzzleArray[y][x+1] == nil) 275 | { 276 | PuzzleArray[y][x+1] = puzzle 277 | PuzzleArray[y][x] = nil 278 | puzzle.MyIndex = CGPoint(x: x+1, y: y) 279 | puzzleMoving.dx = puzzle.frame.width 280 | moving() 281 | } 282 | } 283 | 284 | } else { 285 | //finger touch went left 286 | if( x > 0) 287 | { 288 | if(PuzzleArray[y][x-1] == nil) 289 | { 290 | PuzzleArray[y][x-1] = puzzle 291 | PuzzleArray[y][x] = nil 292 | puzzle.MyIndex = CGPoint(x: x-1, y: y) 293 | puzzleMoving.dx = -puzzle.frame.width 294 | moving() 295 | } 296 | } 297 | } 298 | if (touchLocation.y > preLocation.y) { 299 | //finger touch went upwards 300 | if( y < (row-1)) 301 | { 302 | if(PuzzleArray[y+1][x] == nil) 303 | { 304 | PuzzleArray[y+1][x] = puzzle 305 | PuzzleArray[y][x] = nil 306 | puzzle.MyIndex = CGPoint(x: x, y: y+1) 307 | puzzleMoving.dy = puzzle.frame.width 308 | moving() 309 | } 310 | } 311 | } else { 312 | //finger touch went downwards 313 | if( y > 0) 314 | { 315 | if(PuzzleArray[y-1][x] == nil) 316 | { 317 | PuzzleArray[y-1][x] = puzzle 318 | PuzzleArray[y][x] = nil 319 | puzzle.MyIndex = CGPoint(x: x, y: y-1) 320 | puzzleMoving.dy = -puzzle.frame.width 321 | moving() 322 | } 323 | } 324 | } 325 | 326 | 327 | } 328 | 329 | } 330 | 331 | override func touchesEnded(_ touches: Set, with event: UIEvent?) { 332 | HoldedPuzzle = nil 333 | } 334 | 335 | } 336 | 337 | 338 | extension JDPuzzleScene:SKPhysicsContactDelegate 339 | { 340 | /* 341 | Delegate 342 | */ 343 | func didBegin(_ contact: SKPhysicsContact) { 344 | 345 | // 1 346 | var firstBody: SKPhysicsBody 347 | var secondBody: SKPhysicsBody 348 | // 2 349 | if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask { 350 | firstBody = contact.bodyA 351 | secondBody = contact.bodyB 352 | } else { 353 | firstBody = contact.bodyB 354 | secondBody = contact.bodyA 355 | } 356 | // 球碰到磚塊 357 | if firstBody.categoryBitMask == BreaksBasicSetting.BallCategory && secondBody.categoryBitMask == BreaksBasicSetting.BlockCategory { 358 | 359 | } 360 | } 361 | 362 | } 363 | -------------------------------------------------------------------------------- /JDGamesLoading/JDGamesLoading/JDSnackScene.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JDSnackScene.swift 3 | // JDGamesLoading 4 | // 5 | // Created by 郭介騵 on 2017/2/14. 6 | // Copyright © 2017年 james12345. All rights reserved. 7 | // 8 | 9 | import SpriteKit 10 | import GameplayKit 11 | 12 | 13 | struct SnackBasicSetting { 14 | static let SnackHeadCategoryName = "SnackHead" 15 | static let SnackBodyCategoryName = "SnackBody" 16 | static let FoodCategoryName = "Food" 17 | static let SnackHeadCategory : UInt32 = 0x1 << 0 18 | static let SnackBodyCategory : UInt32 = 0x1 << 1 19 | static let FoodCategory : UInt32 = 0x1 << 2 20 | static var SnackPixelColor:UIColor = UIColor.green 21 | } 22 | 23 | struct TurnRoundPoint { 24 | var turnRoundPosition:CGPoint = CGPoint.zero 25 | var turnRoundDirection:CGVector = CGVector.zero 26 | var PassBodyID:[Int] = [] 27 | } 28 | 29 | class SnackShapeNode:SKShapeNode 30 | { 31 | var PixelSize:CGSize = CGSize.zero 32 | var InstanceDirection:CGVector = CGVector.zero 33 | init(size:CGSize) { 34 | super.init() 35 | let rect = CGRect(origin: CGPoint.zero, size: size) 36 | self.path = CGPath(rect: rect, transform: nil) 37 | PixelSize = size 38 | } 39 | required init?(coder aDecoder: NSCoder) { 40 | fatalError("init(coder:) has not been implemented") 41 | } 42 | } 43 | 44 | class SnackHeadNode:SnackShapeNode 45 | { 46 | 47 | override init(size:CGSize) { 48 | super.init(size:size) 49 | self.fillColor = SnackBasicSetting.SnackPixelColor 50 | self.name = SnackBasicSetting.SnackHeadCategoryName 51 | self.physicsBody = SKPhysicsBody(rectangleOf: PixelSize) 52 | self.physicsBody!.categoryBitMask = SnackBasicSetting.SnackHeadCategory 53 | self.physicsBody!.contactTestBitMask = SnackBasicSetting.FoodCategory 54 | self.physicsBody!.isDynamic = true 55 | self.physicsBody!.collisionBitMask = 0 56 | self.zPosition = 2 57 | 58 | } 59 | 60 | required init?(coder aDecoder: NSCoder) { 61 | fatalError("init(coder:) has not been implemented") 62 | } 63 | } 64 | 65 | class SnackBodyNode:SnackShapeNode 66 | { 67 | var BodyID:Int = 0 68 | override init(size:CGSize) { 69 | super.init(size:size) 70 | self.position = CGPoint.zero 71 | self.fillColor = SnackBasicSetting.SnackPixelColor 72 | self.name = SnackBasicSetting.SnackBodyCategoryName 73 | self.physicsBody = SKPhysicsBody(rectangleOf: PixelSize) 74 | self.physicsBody!.categoryBitMask = SnackBasicSetting.SnackBodyCategory 75 | self.physicsBody!.isDynamic = false 76 | self.physicsBody!.collisionBitMask = 0 77 | self.zPosition = 2 78 | } 79 | 80 | required init?(coder aDecoder: NSCoder) { 81 | fatalError("init(coder:) has not been implemented") 82 | } 83 | } 84 | 85 | 86 | class JDSnackScene: SKScene{ 87 | 88 | /* 89 | Window Size 90 | */ 91 | var defaultwindowwidth:CGFloat = 200.0 92 | var windowscale:CGFloat 93 | { 94 | get{ 95 | return (self.frame.width / defaultwindowwidth) 96 | } 97 | } 98 | /* 99 | Pixel Size 100 | */ 101 | var d_PixelSize:CGSize = CGSize(width: 15.0, height: 15.0) 102 | var PixelSize:CGSize 103 | { 104 | get{ 105 | let size:CGSize = CGSize(width: d_PixelSize.width * windowscale, height: d_PixelSize.width * windowscale) 106 | return size 107 | } 108 | } 109 | /* 110 | Pixel Color 111 | */ 112 | var FoodPixelColor:UIColor = UIColor.white 113 | 114 | /* 115 | Snack 116 | */ 117 | var SnackBodyNodeCount:Int = 0 118 | var SncakSpeed:CGFloat = 50 119 | var HeadPixel:SKShapeNode! 120 | /* 121 | Direction 122 | */ 123 | var NowDirection:CGVector = CGVector(dx: 0.0, dy: 1.0) 124 | var LastTimeInterval:TimeInterval? 125 | var turnroundArr:[TurnRoundPoint] = [TurnRoundPoint]() 126 | 127 | 128 | 129 | override func update(_ currentTime: TimeInterval) { 130 | //Speed 131 | if(LastTimeInterval == nil) 132 | { 133 | LastTimeInterval = currentTime 134 | return 135 | } 136 | let InstanceScale:CGFloat = CGFloat(currentTime - LastTimeInterval!) 137 | let InstanceSpeed:CGFloat = self.SncakSpeed * InstanceScale 138 | let Vecter:CGVector = CGVector(dx: InstanceSpeed * NowDirection.dx, dy: InstanceSpeed * NowDirection.dy) 139 | //Update All Snack 140 | //SnackHead 141 | var LastPixelPoint:CGPoint? 142 | self.enumerateChildNodes(withName: SnackBasicSetting.SnackHeadCategoryName) { 143 | node, stop in 144 | if let snackHead:SnackHeadNode = node as? SnackHeadNode 145 | { 146 | LastPixelPoint = node.position 147 | let newPostition = CGPoint(x: (node.position.x) + (Vecter.dx), y: (node.position.y) + (Vecter.dy)) 148 | snackHead.position = self.TouchTheWallDetect(input: newPostition) 149 | } 150 | } 151 | //SnackBody 152 | var LastDirection:CGVector = NowDirection 153 | self.enumerateChildNodes(withName: SnackBasicSetting.SnackBodyCategoryName) 154 | { 155 | node, stop in 156 | if let NewPosition = LastPixelPoint,let snackBody:SnackBodyNode = node as? SnackBodyNode 157 | { 158 | if(snackBody.InstanceDirection == CGVector.zero) //NewPixel 159 | { 160 | snackBody.position.x = NewPosition.x - LastDirection.dx * self.PixelSize.width 161 | snackBody.position.y = NewPosition.y - LastDirection.dy * self.PixelSize.width 162 | snackBody.InstanceDirection = LastDirection 163 | } 164 | else if(self.turnroundArr.count == 0) //Direct Forward 165 | { 166 | let newPostition = CGPoint(x: snackBody.position.x + snackBody.InstanceDirection.dx * InstanceSpeed, y: snackBody.position.y + snackBody.InstanceDirection.dy * InstanceSpeed) 167 | snackBody.position = self.TouchTheWallDetect(input: newPostition) 168 | } 169 | else //TurnRound 170 | { 171 | var HasMove:Bool = false 172 | let NewX = snackBody.position.x + snackBody.InstanceDirection.dx * InstanceSpeed 173 | let NewY = snackBody.position.y + snackBody.InstanceDirection.dy * InstanceSpeed 174 | var index:Int = 0 175 | for turnRound in self.turnroundArr 176 | { 177 | if(turnRound.PassBodyID.contains(snackBody.BodyID)) //已走過,Pass到下一個turnRound 178 | { 179 | index += 1 180 | continue 181 | } 182 | else if(abs(snackBody.InstanceDirection.dx) == 1 && abs(snackBody.position.y - turnRound.turnRoundPosition.y) < 0.1) //橫向超越 183 | { 184 | let PostiveOrNegative:Bool = (snackBody.InstanceDirection.dx > 0) 185 | let ChekingExceed:Bool = PostiveOrNegative ? (NewX > turnRound.turnRoundPosition.x) : (NewX < turnRound.turnRoundPosition.x) 186 | if(!ChekingExceed) 187 | { 188 | let newPostition = CGPoint(x: NewX, y: NewY) 189 | snackBody.position = self.TouchTheWallDetect(input: newPostition) 190 | HasMove = true 191 | break 192 | } 193 | //確定要轉彎 194 | self.turnroundArr[index].PassBodyID.append(snackBody.BodyID) 195 | let ExceedLength:CGFloat = PostiveOrNegative ? (NewX - turnRound.turnRoundPosition.x) : (turnRound.turnRoundPosition.x - NewX) 196 | let NewX = turnRound.turnRoundPosition.x 197 | let NewY = snackBody.position.y + turnRound.turnRoundDirection.dy * ExceedLength 198 | let newPostition = CGPoint(x: NewX, y: NewY) 199 | snackBody.position = self.TouchTheWallDetect(input: newPostition) 200 | snackBody.InstanceDirection = turnRound.turnRoundDirection 201 | HasMove = true 202 | break 203 | } 204 | else if(abs(snackBody.InstanceDirection.dy) == 1 && abs(snackBody.position.x - turnRound.turnRoundPosition.x) < 0.1) //垂直 205 | { 206 | let PostiveOrNegative:Bool = (snackBody.InstanceDirection.dy > 0) 207 | let ChekingExceed:Bool = PostiveOrNegative ? (NewY > turnRound.turnRoundPosition.y) : (NewY < turnRound.turnRoundPosition.y) 208 | if(!ChekingExceed) 209 | { 210 | let newPostition = CGPoint(x: NewX, y: NewY) 211 | snackBody.position = self.TouchTheWallDetect(input: newPostition) 212 | HasMove = true 213 | break 214 | } 215 | self.turnroundArr[index].PassBodyID.append(snackBody.BodyID) 216 | let ExceedLength:CGFloat = PostiveOrNegative ? (NewY - turnRound.turnRoundPosition.y) : (turnRound.turnRoundPosition.y - NewY) 217 | let NewX = snackBody.position.x + turnRound.turnRoundDirection.dx * ExceedLength 218 | let NewY = turnRound.turnRoundPosition.y 219 | let newPostition = CGPoint(x: NewX, y: NewY) 220 | snackBody.position = self.TouchTheWallDetect(input: newPostition) 221 | snackBody.InstanceDirection = turnRound.turnRoundDirection 222 | HasMove = true 223 | break 224 | } 225 | index += 1 226 | } 227 | if(!HasMove) //No Turn Round 228 | { 229 | let newPostition = CGPoint(x: NewX, y: NewY) 230 | snackBody.position = self.TouchTheWallDetect(input: newPostition) 231 | } 232 | 233 | } 234 | LastDirection = snackBody.InstanceDirection 235 | LastPixelPoint = snackBody.position 236 | } 237 | 238 | } 239 | // 240 | var Index:Int = 0 241 | for turnRound in self.turnroundArr 242 | { 243 | if(turnRound.PassBodyID.count >= self.SnackBodyNodeCount) 244 | { 245 | self.turnroundArr.remove(at: Index) 246 | continue 247 | } 248 | Index += 1 249 | } 250 | LastTimeInterval = currentTime 251 | } 252 | 253 | override init(size: CGSize) { 254 | super.init(size: size) 255 | 256 | self.backgroundColor = UIColor.clear 257 | } 258 | 259 | init(size: CGSize,configuration:JDSnackGameConfiguration) { 260 | super.init(size: size) 261 | SnackBasicSetting.SnackPixelColor = configuration.Snack_color 262 | FoodPixelColor = configuration.Food_color 263 | SncakSpeed = configuration.Snack_Speed 264 | self.backgroundColor = UIColor.clear 265 | } 266 | 267 | required init?(coder aDecoder: NSCoder) { 268 | fatalError("init(coder:) has not been implemented") 269 | } 270 | 271 | 272 | override func didMove(to view: SKView) { 273 | super.didMove(to: view) 274 | //Set Border 275 | let borderBody = SKPhysicsBody(edgeLoopFrom: self.frame) 276 | borderBody.friction = 0 277 | self.physicsBody = borderBody 278 | self.physicsWorld.gravity = CGVector.zero 279 | self.physicsWorld.contactDelegate = self 280 | // 281 | initSnack() 282 | AddrandomFood() 283 | // 284 | let swipeRight:UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(self.swipedRight(sender:))) 285 | swipeRight.direction = .right 286 | view.addGestureRecognizer(swipeRight) 287 | 288 | 289 | let swipeLeft:UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(self.swipedLeft(sender:))) 290 | swipeLeft.direction = .left 291 | view.addGestureRecognizer(swipeLeft) 292 | 293 | 294 | let swipeUp:UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(self.swipedUp(sender:))) 295 | swipeUp.direction = .up 296 | view.addGestureRecognizer(swipeUp) 297 | 298 | 299 | let swipeDown:UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(self.swipedDown(sender:))) 300 | swipeDown.direction = .down 301 | view.addGestureRecognizer(swipeDown) 302 | } 303 | 304 | func initSnack() 305 | { 306 | HeadPixel = SnackHeadNode(size: PixelSize) 307 | HeadPixel.position = CGPoint(x: self.frame.width * 0.5 , y: self.frame.width * 0.5) 308 | self.addChild(HeadPixel) 309 | } 310 | 311 | func AddrandomFood() 312 | { 313 | let randomX:CGFloat = randomFloat(from: 0, to: self.frame.width) 314 | let randomY:CGFloat = randomFloat(from: 0, to: self.frame.height) 315 | let Food:SKShapeNode = SKShapeNode(rectOf: PixelSize) 316 | Food.position = CGPoint(x: randomX, y: randomY) 317 | Food.name = SnackBasicSetting.FoodCategoryName 318 | Food.fillColor = FoodPixelColor 319 | Food.physicsBody = SKPhysicsBody(rectangleOf: PixelSize) 320 | Food.physicsBody!.categoryBitMask = SnackBasicSetting.FoodCategory 321 | Food.physicsBody!.contactTestBitMask = SnackBasicSetting.SnackHeadCategory 322 | Food.physicsBody!.isDynamic = false 323 | Food.physicsBody!.collisionBitMask = 0 324 | Food.zPosition = 2 325 | 326 | self.addChild(Food) 327 | } 328 | 329 | func TouchTheWallDetect(input:CGPoint)->CGPoint 330 | { 331 | var result = input 332 | if(input.x > self.frame.width) 333 | { 334 | let exceedLength:CGFloat = input.x - self.frame.width 335 | result.x = exceedLength 336 | } 337 | else if(input.x < 0) 338 | { 339 | let exceedLength:CGFloat = 0 - input.x 340 | result.x = self.frame.width - exceedLength 341 | } 342 | 343 | if(input.y > self.frame.height) 344 | { 345 | let exceedLength:CGFloat = input.y - self.frame.height 346 | result.y = exceedLength 347 | } 348 | else if(input.y < 0) 349 | { 350 | let exceedLength:CGFloat = 0 - input.y 351 | result.y = self.frame.height - exceedLength 352 | } 353 | return result 354 | } 355 | 356 | func randomFloat(from: CGFloat, to: CGFloat) -> CGFloat { 357 | let rand: CGFloat = CGFloat(Float(arc4random()) / 0xFFFFFFFF) 358 | return (rand) * (to - from) + from 359 | } 360 | } 361 | 362 | extension JDSnackScene 363 | { 364 | func swipedRight(sender:UISwipeGestureRecognizer){ 365 | self.NowDirection = CGVector(dx: 1.0, dy: 0.0) 366 | let NewTureRoundPoint:TurnRoundPoint = TurnRoundPoint.init(turnRoundPosition: HeadPixel.position, turnRoundDirection: NowDirection, PassBodyID: []) 367 | turnroundArr.append(NewTureRoundPoint) 368 | } 369 | 370 | func swipedLeft(sender:UISwipeGestureRecognizer){ 371 | self.NowDirection = CGVector(dx: -1.0, dy: 0.0) 372 | let NewTureRoundPoint:TurnRoundPoint = TurnRoundPoint.init(turnRoundPosition: HeadPixel.position, turnRoundDirection: NowDirection, PassBodyID: []) 373 | turnroundArr.append(NewTureRoundPoint) 374 | } 375 | 376 | func swipedUp(sender:UISwipeGestureRecognizer){ 377 | self.NowDirection = CGVector(dx: 0.0, dy: 1.0) 378 | let NewTureRoundPoint:TurnRoundPoint = TurnRoundPoint.init(turnRoundPosition: HeadPixel.position, turnRoundDirection: NowDirection, PassBodyID: []) 379 | turnroundArr.append(NewTureRoundPoint) 380 | } 381 | 382 | func swipedDown(sender:UISwipeGestureRecognizer){ 383 | self.NowDirection = CGVector(dx: 0.0, dy: -1.0) 384 | let NewTureRoundPoint:TurnRoundPoint = TurnRoundPoint.init(turnRoundPosition: HeadPixel.position, turnRoundDirection: NowDirection, PassBodyID: []) 385 | turnroundArr.append(NewTureRoundPoint) 386 | } 387 | 388 | } 389 | 390 | 391 | extension JDSnackScene:SKPhysicsContactDelegate 392 | { 393 | /* 394 | Delegate 395 | */ 396 | 397 | func didBegin(_ contact: SKPhysicsContact) { 398 | 399 | // 1 400 | var firstBody: SKPhysicsBody 401 | var secondBody: SKPhysicsBody 402 | // 2 403 | if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask { 404 | firstBody = contact.bodyA 405 | secondBody = contact.bodyB 406 | } else { 407 | firstBody = contact.bodyB 408 | secondBody = contact.bodyA 409 | } 410 | 411 | if firstBody.categoryBitMask == SnackBasicSetting.SnackHeadCategory && secondBody.categoryBitMask == SnackBasicSetting.FoodCategory { 412 | if let food = secondBody.node 413 | { 414 | food.removeFromParent() 415 | AddrandomFood() 416 | let newBodyPixel = SnackBodyNode(size: PixelSize) 417 | self.addChild(newBodyPixel) 418 | newBodyPixel.BodyID = SnackBodyNodeCount 419 | SnackBodyNodeCount += 1 420 | } 421 | } 422 | } 423 | 424 | 425 | 426 | } 427 | -------------------------------------------------------------------------------- /JDGamesLoading/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // JDGamesLoading 4 | // 5 | // Created by 郭介騵 on 2017/2/13. 6 | // Copyright © 2017年 james12345. All rights reserved. 7 | // 8 | 9 | 10 | import UIKit 11 | 12 | 13 | 14 | class ViewController: UIViewController { 15 | 16 | var jdgamesloading:JDGamesLoading? 17 | override func viewDidAppear(_ animated: Bool) { 18 | 19 | } 20 | 21 | 22 | @IBAction func ShowSnackGames(_ sender: Any) { 23 | //let snackconfig:JDSnackGameConfiguration = JDSnackGameConfiguration(snackcolor: UIColor.blue, foodcolor: UIColor.brown, snackspeed: 50) 24 | jdgamesloading = JDGamesLoading(game: .Snacks) 25 | jdgamesloading?.demoPresent() 26 | } 27 | 28 | @IBAction func ShowBreakGame(_ sender: Any) { 29 | jdgamesloading = JDGamesLoading(game: .Breaks) 30 | jdgamesloading?.demoPresent() 31 | } 32 | 33 | @IBAction func ShowPingPong(_ sender: Any) { 34 | jdgamesloading = JDGamesLoading(game: .PingPong) 35 | jdgamesloading?.demoPresent() 36 | } 37 | 38 | @IBAction func ShowPuzzle(_ sender: Any) { 39 | jdgamesloading = JDGamesLoading(game: .Puzzle) 40 | jdgamesloading?.demoPresent() 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /JDGamesLoadingTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /JDGamesLoadingTests/JDGamesLoadingTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JDGamesLoadingTests.swift 3 | // JDGamesLoadingTests 4 | // 5 | // Created by 郭介騵 on 2017/2/13. 6 | // Copyright © 2017年 james12345. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import JDGamesLoading 11 | 12 | class JDGamesLoadingTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | // Use XCTAssert and related functions to verify your tests produce the correct results. 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measure { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /JDGamesLoadingUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /JDGamesLoadingUITests/JDGamesLoadingUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JDGamesLoadingUITests.swift 3 | // JDGamesLoadingUITests 4 | // 5 | // Created by 郭介騵 on 2017/2/13. 6 | // Copyright © 2017年 james12345. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class JDGamesLoadingUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | 18 | // In UI tests it is usually best to stop immediately when a failure occurs. 19 | continueAfterFailure = false 20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 21 | XCUIApplication().launch() 22 | 23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 24 | } 25 | 26 | override func tearDown() { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | super.tearDown() 29 | } 30 | 31 | func testExample() { 32 | // Use recording to get started writing UI tests. 33 | // Use XCTAssert and related functions to verify your tests produce the correct results. 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 JAMES郭 - IOS Develop 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JDGamesLoading 2 | (IOS)Let User Play Game When Loading 3 | *** 4 | # Introduction 5 | First, thanks everyone for supporting my last game loading, **JDBreaksLoading**. 6 | 7 | Now, I make more game. After this, I won't make another repositry about gameloading.Now on, New game will be update in this reop. 8 | So ~ **Star & Watch this reop for more game!!** 9 | 10 | Still, don't make user wait too long to play the game~ 11 | 12 | Thanks for using. 13 | 14 | 15 | 16 | # Installation 17 | 1. **Cocoapod** 18 | 19 | Now, You can use Cocoapod ! 20 | 21 | ``` 22 | pod 'JDGamesLoading' 23 | ``` 24 | 2. **Fork my reop.** 25 | 26 | 27 | # Usage 28 | 29 | Now,It's more easier to call the loading then JDBreakLoading. 30 | 31 | Just One Line: 32 | 33 | ```Swift 34 | JDGamesLoading(game: .Breaks).show() 35 | ``` 36 | For Dismiss: 37 | 38 | ```Swift 39 | JDGamesLoading.dismiss() 40 | ``` 41 | 42 | ### GameTypes 43 | * **.Snacks**: 44 | 45 | 46 | * **.PingPong**: 47 | 48 | 49 | * **.Breaks**: 50 | 51 | 52 | * **.Puzzle**: 53 | 54 | 55 | 56 | ### Game Configuration 57 | Because there are more game now, 58 | So I change the way to set the game configuration. 59 | 60 | **Call .withConfiguration(configuration:) Brfore .show()** 61 | 62 | ```Swift 63 | let snackconfig = JDSnackGameConfiguration(snackcolor: UIColor.blue, foodcolor: UIColor.brown, snackspeed: 50) 64 | JDGamesLoading(game: .Snacks).withConfiguration(configuration: snackconfig).show() 65 | ``` 66 | * **JDSnackGameConfiguration**: 67 | 68 | ```Swift 69 | var Snack_color:UIColor = UIColor.green 70 | var Food_color:UIColor = UIColor.white 71 | var Snack_Speed:CGFloat = 10.0 72 | ``` 73 | 74 | * **JDBreaksGameConfiguration**: 75 | 76 | ```Swift 77 | var paddle_color:UIColor = UIColor.white 78 | var ball_color:UIColor = UIColor.white 79 | var block_color:UIColor = UIColor.white 80 | var RowCount:Int = 1 81 | var ColumnCount:Int = 3 82 | ``` 83 | 84 | * **JDPingPongConfiguration**: 85 | 86 | ```Swift 87 | var paddle_color:UIColor = UIColor.white 88 | var ball_color:UIColor = UIColor.white 89 | ``` 90 | 91 | 92 | -------------------------------------------------------------------------------- /Readme_img/BreakGameDemo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesdouble/JDGamesLoading/68ee53106700775381ca11f6620be9b464312958/Readme_img/BreakGameDemo.gif -------------------------------------------------------------------------------- /Readme_img/JDPuzzleDemo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesdouble/JDGamesLoading/68ee53106700775381ca11f6620be9b464312958/Readme_img/JDPuzzleDemo.gif -------------------------------------------------------------------------------- /Readme_img/Logomakr_3Y8BMT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesdouble/JDGamesLoading/68ee53106700775381ca11f6620be9b464312958/Readme_img/Logomakr_3Y8BMT.png -------------------------------------------------------------------------------- /Readme_img/PingPongDemo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesdouble/JDGamesLoading/68ee53106700775381ca11f6620be9b464312958/Readme_img/PingPongDemo.gif -------------------------------------------------------------------------------- /Readme_img/SnackGameDemo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jamesdouble/JDGamesLoading/68ee53106700775381ca11f6620be9b464312958/Readme_img/SnackGameDemo.gif --------------------------------------------------------------------------------