diff --git a/Rect/Rect.xcodeproj/project.pbxproj b/Rect/Rect.xcodeproj/project.pbxproj new file mode 100644 index 0000000..4b50440 --- /dev/null +++ b/Rect/Rect.xcodeproj/project.pbxproj @@ -0,0 +1,611 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 8312CFF01BE5472C001AF047 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8312CFEF1BE5472C001AF047 /* AppDelegate.swift */; }; + 8312CFF21BE5472C001AF047 /* GameScene.sks in Resources */ = {isa = PBXBuildFile; fileRef = 8312CFF11BE5472C001AF047 /* GameScene.sks */; }; + 8312CFF41BE5472C001AF047 /* GameScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8312CFF31BE5472C001AF047 /* GameScene.swift */; }; + 8312CFF61BE5472C001AF047 /* GameViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8312CFF51BE5472C001AF047 /* GameViewController.swift */; }; + 8312CFF91BE5472C001AF047 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8312CFF71BE5472C001AF047 /* Main.storyboard */; }; + 8312CFFB1BE5472C001AF047 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8312CFFA1BE5472C001AF047 /* Assets.xcassets */; }; + 8312CFFE1BE5472C001AF047 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8312CFFC1BE5472C001AF047 /* LaunchScreen.storyboard */; }; + 8312D0091BE5472C001AF047 /* RectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8312D0081BE5472C001AF047 /* RectTests.swift */; }; + 8312D0141BE5472C001AF047 /* RectUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8312D0131BE5472C001AF047 /* RectUITests.swift */; }; + 8312D0351BE54E3F001AF047 /* libz.1.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 8312D0341BE54E3F001AF047 /* libz.1.dylib */; }; + 8312D03B1BE54F5A001AF047 /* JSTileMap.m in Sources */ = {isa = PBXBuildFile; fileRef = 8312D0381BE54F5A001AF047 /* JSTileMap.m */; }; + 8312D03C1BE54F5A001AF047 /* LFCGzipUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 8312D03A1BE54F5A001AF047 /* LFCGzipUtility.m */; }; + 8312D03F1BE54FE8001AF047 /* level1_sprites.png in Resources */ = {isa = PBXBuildFile; fileRef = 8312D03D1BE54FE8001AF047 /* level1_sprites.png */; }; + 8312D0431BE55043001AF047 /* gameEntities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8312D0421BE55043001AF047 /* gameEntities.swift */; }; + 8312D0461BE553D1001AF047 /* gate.png in Resources */ = {isa = PBXBuildFile; fileRef = 8312D0441BE553D1001AF047 /* gate.png */; }; + 8312D0471BE553D1001AF047 /* lift.png in Resources */ = {isa = PBXBuildFile; fileRef = 8312D0451BE553D1001AF047 /* lift.png */; }; + 8312D04F1BE5AF41001AF047 /* level1.tmx in Resources */ = {isa = PBXBuildFile; fileRef = 8312D04E1BE5AF41001AF047 /* level1.tmx */; }; + 8312D0521BE5B00D001AF047 /* level2_sprites.png in Resources */ = {isa = PBXBuildFile; fileRef = 8312D0501BE5B00C001AF047 /* level2_sprites.png */; }; + 83AED40B1BE811FE0057F64E /* level3_sprites.png in Resources */ = {isa = PBXBuildFile; fileRef = 83AED4031BE811FE0057F64E /* level3_sprites.png */; }; + 83AED40C1BE811FE0057F64E /* level3.tmx in Resources */ = {isa = PBXBuildFile; fileRef = 83AED4041BE811FE0057F64E /* level3.tmx */; }; + 83AED40D1BE811FE0057F64E /* level4_sprites.png in Resources */ = {isa = PBXBuildFile; fileRef = 83AED4051BE811FE0057F64E /* level4_sprites.png */; }; + 83AED40E1BE811FE0057F64E /* level4.tmx in Resources */ = {isa = PBXBuildFile; fileRef = 83AED4061BE811FE0057F64E /* level4.tmx */; }; + 83AED40F1BE811FE0057F64E /* level5_sprites.png in Resources */ = {isa = PBXBuildFile; fileRef = 83AED4071BE811FE0057F64E /* level5_sprites.png */; }; + 83AED4101BE811FE0057F64E /* level5.tmx in Resources */ = {isa = PBXBuildFile; fileRef = 83AED4081BE811FE0057F64E /* level5.tmx */; }; + 83AED4111BE811FE0057F64E /* level6_sprites.png in Resources */ = {isa = PBXBuildFile; fileRef = 83AED4091BE811FE0057F64E /* level6_sprites.png */; }; + 83AED4121BE811FE0057F64E /* level6.tmx in Resources */ = {isa = PBXBuildFile; fileRef = 83AED40A1BE811FE0057F64E /* level6.tmx */; }; + 83AED4141BE818AB0057F64E /* level2.tmx in Resources */ = {isa = PBXBuildFile; fileRef = 83AED4131BE818AB0057F64E /* level2.tmx */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 8312D0051BE5472C001AF047 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8312CFE41BE5472C001AF047 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8312CFEB1BE5472C001AF047; + remoteInfo = Rect; + }; + 8312D0101BE5472C001AF047 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8312CFE41BE5472C001AF047 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8312CFEB1BE5472C001AF047; + remoteInfo = Rect; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 8312CFEC1BE5472C001AF047 /* Rect.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Rect.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 8312CFEF1BE5472C001AF047 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 8312CFF11BE5472C001AF047 /* GameScene.sks */ = {isa = PBXFileReference; lastKnownFileType = file.sks; path = GameScene.sks; sourceTree = ""; }; + 8312CFF31BE5472C001AF047 /* GameScene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameScene.swift; sourceTree = ""; }; + 8312CFF51BE5472C001AF047 /* GameViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameViewController.swift; sourceTree = ""; }; + 8312CFF81BE5472C001AF047 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 8312CFFA1BE5472C001AF047 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 8312CFFD1BE5472C001AF047 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 8312CFFF1BE5472C001AF047 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 8312D0041BE5472C001AF047 /* RectTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RectTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 8312D0081BE5472C001AF047 /* RectTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RectTests.swift; sourceTree = ""; }; + 8312D00A1BE5472C001AF047 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 8312D00F1BE5472C001AF047 /* RectUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RectUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 8312D0131BE5472C001AF047 /* RectUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RectUITests.swift; sourceTree = ""; }; + 8312D0151BE5472C001AF047 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 8312D0341BE54E3F001AF047 /* libz.1.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.1.dylib; path = ../../../../usr/lib/libz.1.dylib; sourceTree = ""; }; + 8312D0361BE54F59001AF047 /* Rect-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Rect-Bridging-Header.h"; sourceTree = ""; }; + 8312D0371BE54F5A001AF047 /* JSTileMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTileMap.h; sourceTree = ""; }; + 8312D0381BE54F5A001AF047 /* JSTileMap.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JSTileMap.m; sourceTree = ""; }; + 8312D0391BE54F5A001AF047 /* LFCGzipUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LFCGzipUtility.h; sourceTree = ""; }; + 8312D03A1BE54F5A001AF047 /* LFCGzipUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LFCGzipUtility.m; sourceTree = ""; }; + 8312D03D1BE54FE8001AF047 /* level1_sprites.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = level1_sprites.png; sourceTree = ""; }; + 8312D0421BE55043001AF047 /* gameEntities.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = gameEntities.swift; sourceTree = ""; }; + 8312D0441BE553D1001AF047 /* gate.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = gate.png; sourceTree = ""; }; + 8312D0451BE553D1001AF047 /* lift.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = lift.png; sourceTree = ""; }; + 8312D04E1BE5AF41001AF047 /* level1.tmx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = level1.tmx; sourceTree = ""; }; + 8312D0501BE5B00C001AF047 /* level2_sprites.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = level2_sprites.png; sourceTree = ""; }; + 83AED4031BE811FE0057F64E /* level3_sprites.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = level3_sprites.png; sourceTree = ""; }; + 83AED4041BE811FE0057F64E /* level3.tmx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = level3.tmx; sourceTree = ""; }; + 83AED4051BE811FE0057F64E /* level4_sprites.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = level4_sprites.png; sourceTree = ""; }; + 83AED4061BE811FE0057F64E /* level4.tmx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = level4.tmx; sourceTree = ""; }; + 83AED4071BE811FE0057F64E /* level5_sprites.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = level5_sprites.png; sourceTree = ""; }; + 83AED4081BE811FE0057F64E /* level5.tmx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = level5.tmx; sourceTree = ""; }; + 83AED4091BE811FE0057F64E /* level6_sprites.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = level6_sprites.png; sourceTree = ""; }; + 83AED40A1BE811FE0057F64E /* level6.tmx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = level6.tmx; sourceTree = ""; }; + 83AED4131BE818AB0057F64E /* level2.tmx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = level2.tmx; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8312CFE91BE5472C001AF047 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8312D0351BE54E3F001AF047 /* libz.1.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8312D0011BE5472C001AF047 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8312D00C1BE5472C001AF047 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 8312CFE31BE5472C001AF047 = { + isa = PBXGroup; + children = ( + 8312D0341BE54E3F001AF047 /* libz.1.dylib */, + 8312CFEE1BE5472C001AF047 /* Rect */, + 8312D0071BE5472C001AF047 /* RectTests */, + 8312D0121BE5472C001AF047 /* RectUITests */, + 8312CFED1BE5472C001AF047 /* Products */, + ); + sourceTree = ""; + }; + 8312CFED1BE5472C001AF047 /* Products */ = { + isa = PBXGroup; + children = ( + 8312CFEC1BE5472C001AF047 /* Rect.app */, + 8312D0041BE5472C001AF047 /* RectTests.xctest */, + 8312D00F1BE5472C001AF047 /* RectUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 8312CFEE1BE5472C001AF047 /* Rect */ = { + isa = PBXGroup; + children = ( + 8312D0371BE54F5A001AF047 /* JSTileMap.h */, + 8312D0381BE54F5A001AF047 /* JSTileMap.m */, + 8312D0391BE54F5A001AF047 /* LFCGzipUtility.h */, + 8312D03A1BE54F5A001AF047 /* LFCGzipUtility.m */, + 8312D0411BE54FEB001AF047 /* tmxMap */, + 8312CFEF1BE5472C001AF047 /* AppDelegate.swift */, + 8312CFF11BE5472C001AF047 /* GameScene.sks */, + 8312CFF31BE5472C001AF047 /* GameScene.swift */, + 8312CFF51BE5472C001AF047 /* GameViewController.swift */, + 8312D0421BE55043001AF047 /* gameEntities.swift */, + 8312CFF71BE5472C001AF047 /* Main.storyboard */, + 8312CFFA1BE5472C001AF047 /* Assets.xcassets */, + 8312CFFC1BE5472C001AF047 /* LaunchScreen.storyboard */, + 8312CFFF1BE5472C001AF047 /* Info.plist */, + 8312D0361BE54F59001AF047 /* Rect-Bridging-Header.h */, + ); + path = Rect; + sourceTree = ""; + }; + 8312D0071BE5472C001AF047 /* RectTests */ = { + isa = PBXGroup; + children = ( + 8312D0081BE5472C001AF047 /* RectTests.swift */, + 8312D00A1BE5472C001AF047 /* Info.plist */, + ); + path = RectTests; + sourceTree = ""; + }; + 8312D0121BE5472C001AF047 /* RectUITests */ = { + isa = PBXGroup; + children = ( + 8312D0131BE5472C001AF047 /* RectUITests.swift */, + 8312D0151BE5472C001AF047 /* Info.plist */, + ); + path = RectUITests; + sourceTree = ""; + }; + 8312D0411BE54FEB001AF047 /* tmxMap */ = { + isa = PBXGroup; + children = ( + 8312D03D1BE54FE8001AF047 /* level1_sprites.png */, + 8312D04E1BE5AF41001AF047 /* level1.tmx */, + 8312D0501BE5B00C001AF047 /* level2_sprites.png */, + 83AED4131BE818AB0057F64E /* level2.tmx */, + 83AED4031BE811FE0057F64E /* level3_sprites.png */, + 83AED4041BE811FE0057F64E /* level3.tmx */, + 83AED4051BE811FE0057F64E /* level4_sprites.png */, + 83AED4061BE811FE0057F64E /* level4.tmx */, + 83AED4071BE811FE0057F64E /* level5_sprites.png */, + 83AED4081BE811FE0057F64E /* level5.tmx */, + 83AED4091BE811FE0057F64E /* level6_sprites.png */, + 83AED40A1BE811FE0057F64E /* level6.tmx */, + 8312D0441BE553D1001AF047 /* gate.png */, + 8312D0451BE553D1001AF047 /* lift.png */, + ); + name = tmxMap; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 8312CFEB1BE5472C001AF047 /* Rect */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8312D0181BE5472C001AF047 /* Build configuration list for PBXNativeTarget "Rect" */; + buildPhases = ( + 8312CFE81BE5472C001AF047 /* Sources */, + 8312CFE91BE5472C001AF047 /* Frameworks */, + 8312CFEA1BE5472C001AF047 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Rect; + productName = Rect; + productReference = 8312CFEC1BE5472C001AF047 /* Rect.app */; + productType = "com.apple.product-type.application"; + }; + 8312D0031BE5472C001AF047 /* RectTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8312D01B1BE5472C001AF047 /* Build configuration list for PBXNativeTarget "RectTests" */; + buildPhases = ( + 8312D0001BE5472C001AF047 /* Sources */, + 8312D0011BE5472C001AF047 /* Frameworks */, + 8312D0021BE5472C001AF047 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 8312D0061BE5472C001AF047 /* PBXTargetDependency */, + ); + name = RectTests; + productName = RectTests; + productReference = 8312D0041BE5472C001AF047 /* RectTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 8312D00E1BE5472C001AF047 /* RectUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8312D01E1BE5472C001AF047 /* Build configuration list for PBXNativeTarget "RectUITests" */; + buildPhases = ( + 8312D00B1BE5472C001AF047 /* Sources */, + 8312D00C1BE5472C001AF047 /* Frameworks */, + 8312D00D1BE5472C001AF047 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 8312D0111BE5472C001AF047 /* PBXTargetDependency */, + ); + name = RectUITests; + productName = RectUITests; + productReference = 8312D00F1BE5472C001AF047 /* RectUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 8312CFE41BE5472C001AF047 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0700; + LastUpgradeCheck = 0700; + ORGANIZATIONNAME = "Peter Zhu"; + TargetAttributes = { + 8312CFEB1BE5472C001AF047 = { + CreatedOnToolsVersion = 7.0; + }; + 8312D0031BE5472C001AF047 = { + CreatedOnToolsVersion = 7.0; + TestTargetID = 8312CFEB1BE5472C001AF047; + }; + 8312D00E1BE5472C001AF047 = { + CreatedOnToolsVersion = 7.0; + TestTargetID = 8312CFEB1BE5472C001AF047; + }; + }; + }; + buildConfigurationList = 8312CFE71BE5472C001AF047 /* Build configuration list for PBXProject "Rect" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 8312CFE31BE5472C001AF047; + productRefGroup = 8312CFED1BE5472C001AF047 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 8312CFEB1BE5472C001AF047 /* Rect */, + 8312D0031BE5472C001AF047 /* RectTests */, + 8312D00E1BE5472C001AF047 /* RectUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8312CFEA1BE5472C001AF047 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 83AED40D1BE811FE0057F64E /* level4_sprites.png in Resources */, + 8312CFF21BE5472C001AF047 /* GameScene.sks in Resources */, + 8312D0471BE553D1001AF047 /* lift.png in Resources */, + 8312D0521BE5B00D001AF047 /* level2_sprites.png in Resources */, + 8312D04F1BE5AF41001AF047 /* level1.tmx in Resources */, + 83AED4141BE818AB0057F64E /* level2.tmx in Resources */, + 83AED40C1BE811FE0057F64E /* level3.tmx in Resources */, + 8312D03F1BE54FE8001AF047 /* level1_sprites.png in Resources */, + 83AED4121BE811FE0057F64E /* level6.tmx in Resources */, + 83AED40E1BE811FE0057F64E /* level4.tmx in Resources */, + 83AED40F1BE811FE0057F64E /* level5_sprites.png in Resources */, + 8312CFFE1BE5472C001AF047 /* LaunchScreen.storyboard in Resources */, + 8312CFFB1BE5472C001AF047 /* Assets.xcassets in Resources */, + 83AED40B1BE811FE0057F64E /* level3_sprites.png in Resources */, + 83AED4111BE811FE0057F64E /* level6_sprites.png in Resources */, + 8312CFF91BE5472C001AF047 /* Main.storyboard in Resources */, + 83AED4101BE811FE0057F64E /* level5.tmx in Resources */, + 8312D0461BE553D1001AF047 /* gate.png in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8312D0021BE5472C001AF047 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8312D00D1BE5472C001AF047 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8312CFE81BE5472C001AF047 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8312CFF41BE5472C001AF047 /* GameScene.swift in Sources */, + 8312D03C1BE54F5A001AF047 /* LFCGzipUtility.m in Sources */, + 8312CFF61BE5472C001AF047 /* GameViewController.swift in Sources */, + 8312CFF01BE5472C001AF047 /* AppDelegate.swift in Sources */, + 8312D0431BE55043001AF047 /* gameEntities.swift in Sources */, + 8312D03B1BE54F5A001AF047 /* JSTileMap.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8312D0001BE5472C001AF047 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8312D0091BE5472C001AF047 /* RectTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8312D00B1BE5472C001AF047 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8312D0141BE5472C001AF047 /* RectUITests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 8312D0061BE5472C001AF047 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8312CFEB1BE5472C001AF047 /* Rect */; + targetProxy = 8312D0051BE5472C001AF047 /* PBXContainerItemProxy */; + }; + 8312D0111BE5472C001AF047 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 8312CFEB1BE5472C001AF047 /* Rect */; + targetProxy = 8312D0101BE5472C001AF047 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 8312CFF71BE5472C001AF047 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 8312CFF81BE5472C001AF047 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 8312CFFC1BE5472C001AF047 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 8312CFFD1BE5472C001AF047 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 8312D0161BE5472C001AF047 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 8312D0171BE5472C001AF047 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 8312D0191BE5472C001AF047 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + INFOPLIST_FILE = Rect/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zhukaihan.Rect; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Rect/Rect-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 8312D01A1BE5472C001AF047 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + INFOPLIST_FILE = Rect/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zhukaihan.Rect; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Rect/Rect-Bridging-Header.h"; + }; + name = Release; + }; + 8312D01C1BE5472C001AF047 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + DEBUG_INFORMATION_FORMAT = dwarf; + INFOPLIST_FILE = RectTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zhukaihan.RectTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Rect.app/Rect"; + }; + name = Debug; + }; + 8312D01D1BE5472C001AF047 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + INFOPLIST_FILE = RectTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zhukaihan.RectTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Rect.app/Rect"; + }; + name = Release; + }; + 8312D01F1BE5472C001AF047 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + DEBUG_INFORMATION_FORMAT = dwarf; + INFOPLIST_FILE = RectUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zhukaihan.RectUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_TARGET_NAME = Rect; + USES_XCTRUNNER = YES; + }; + name = Debug; + }; + 8312D0201BE5472C001AF047 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + INFOPLIST_FILE = RectUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.zhukaihan.RectUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_TARGET_NAME = Rect; + USES_XCTRUNNER = YES; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 8312CFE71BE5472C001AF047 /* Build configuration list for PBXProject "Rect" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8312D0161BE5472C001AF047 /* Debug */, + 8312D0171BE5472C001AF047 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8312D0181BE5472C001AF047 /* Build configuration list for PBXNativeTarget "Rect" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8312D0191BE5472C001AF047 /* Debug */, + 8312D01A1BE5472C001AF047 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8312D01B1BE5472C001AF047 /* Build configuration list for PBXNativeTarget "RectTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8312D01C1BE5472C001AF047 /* Debug */, + 8312D01D1BE5472C001AF047 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8312D01E1BE5472C001AF047 /* Build configuration list for PBXNativeTarget "RectUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 8312D01F1BE5472C001AF047 /* Debug */, + 8312D0201BE5472C001AF047 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 8312CFE41BE5472C001AF047 /* Project object */; +} diff --git a/Rect/Rect.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Rect/Rect.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..a533980 --- /dev/null +++ b/Rect/Rect.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Rect/Rect.xcodeproj/project.xcworkspace/xcuserdata/PeterZhu.xcuserdatad/UserInterfaceState.xcuserstate b/Rect/Rect.xcodeproj/project.xcworkspace/xcuserdata/PeterZhu.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..783c69c Binary files /dev/null and b/Rect/Rect.xcodeproj/project.xcworkspace/xcuserdata/PeterZhu.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/Rect/Rect.xcodeproj/xcuserdata/PeterZhu.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/Rect/Rect.xcodeproj/xcuserdata/PeterZhu.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..fe2b454 --- /dev/null +++ b/Rect/Rect.xcodeproj/xcuserdata/PeterZhu.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,5 @@ + + + diff --git a/Rect/Rect.xcodeproj/xcuserdata/PeterZhu.xcuserdatad/xcschemes/Rect.xcscheme b/Rect/Rect.xcodeproj/xcuserdata/PeterZhu.xcuserdatad/xcschemes/Rect.xcscheme new file mode 100644 index 0000000..cfad639 --- /dev/null +++ b/Rect/Rect.xcodeproj/xcuserdata/PeterZhu.xcuserdatad/xcschemes/Rect.xcscheme @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Rect/Rect.xcodeproj/xcuserdata/PeterZhu.xcuserdatad/xcschemes/xcschememanagement.plist b/Rect/Rect.xcodeproj/xcuserdata/PeterZhu.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..7b6c886 --- /dev/null +++ b/Rect/Rect.xcodeproj/xcuserdata/PeterZhu.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,32 @@ + + + + + SchemeUserState + + Rect.xcscheme + + orderHint + 0 + + + SuppressBuildableAutocreation + + 8312CFEB1BE5472C001AF047 + + primary + + + 8312D0031BE5472C001AF047 + + primary + + + 8312D00E1BE5472C001AF047 + + primary + + + + + diff --git a/Rect/Rect/AppDelegate.swift b/Rect/Rect/AppDelegate.swift new file mode 100644 index 0000000..7480ca1 --- /dev/null +++ b/Rect/Rect/AppDelegate.swift @@ -0,0 +1,46 @@ +// +// AppDelegate.swift +// Rect +// +// Created by Peter Zhu on 15/10/31. +// Copyright © 2015年 Peter Zhu. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { + // Override point for customization after application launch. + return true + } + + func applicationWillResignActive(application: UIApplication) { + // 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. + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(application: UIApplication) { + // 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. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(application: UIApplication) { + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(application: UIApplication) { + // 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. + } + + func applicationWillTerminate(application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/Rect/Rect/Assets.xcassets/AppIcon.appiconset/Contents.json b/Rect/Rect/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..36d2c80 --- /dev/null +++ b/Rect/Rect/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Rect/Rect/Assets.xcassets/Contents.json b/Rect/Rect/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/Rect/Rect/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Rect/Rect/Assets.xcassets/Spaceship.imageset/Contents.json b/Rect/Rect/Assets.xcassets/Spaceship.imageset/Contents.json new file mode 100644 index 0000000..6799334 --- /dev/null +++ b/Rect/Rect/Assets.xcassets/Spaceship.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x", + "filename" : "Spaceship.png" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Rect/Rect/Assets.xcassets/Spaceship.imageset/Spaceship.png b/Rect/Rect/Assets.xcassets/Spaceship.imageset/Spaceship.png new file mode 100644 index 0000000..e2ebb08 Binary files /dev/null and b/Rect/Rect/Assets.xcassets/Spaceship.imageset/Spaceship.png differ diff --git a/Rect/Rect/Assets.xcassets/bodyPart.imageset/Contents.json b/Rect/Rect/Assets.xcassets/bodyPart.imageset/Contents.json new file mode 100644 index 0000000..e9cd40e --- /dev/null +++ b/Rect/Rect/Assets.xcassets/bodyPart.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "part.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Rect/Rect/Assets.xcassets/bodyPart.imageset/part.png b/Rect/Rect/Assets.xcassets/bodyPart.imageset/part.png new file mode 100644 index 0000000..9511dad Binary files /dev/null and b/Rect/Rect/Assets.xcassets/bodyPart.imageset/part.png differ diff --git a/Rect/Rect/Assets.xcassets/enemy1.imageset/Contents.json b/Rect/Rect/Assets.xcassets/enemy1.imageset/Contents.json new file mode 100644 index 0000000..cc75052 --- /dev/null +++ b/Rect/Rect/Assets.xcassets/enemy1.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "enemy2.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Rect/Rect/Assets.xcassets/enemy1.imageset/enemy2.png b/Rect/Rect/Assets.xcassets/enemy1.imageset/enemy2.png new file mode 100644 index 0000000..ca34c77 Binary files /dev/null and b/Rect/Rect/Assets.xcassets/enemy1.imageset/enemy2.png differ diff --git a/Rect/Rect/Assets.xcassets/enemy2.imageset/Contents.json b/Rect/Rect/Assets.xcassets/enemy2.imageset/Contents.json new file mode 100644 index 0000000..d39dd10 --- /dev/null +++ b/Rect/Rect/Assets.xcassets/enemy2.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "enemy1.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Rect/Rect/Assets.xcassets/enemy2.imageset/enemy1.png b/Rect/Rect/Assets.xcassets/enemy2.imageset/enemy1.png new file mode 100644 index 0000000..9be3f15 Binary files /dev/null and b/Rect/Rect/Assets.xcassets/enemy2.imageset/enemy1.png differ diff --git a/Rect/Rect/Assets.xcassets/player1.imageset/Contents.json b/Rect/Rect/Assets.xcassets/player1.imageset/Contents.json new file mode 100644 index 0000000..9ee89cf --- /dev/null +++ b/Rect/Rect/Assets.xcassets/player1.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "player1.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Rect/Rect/Assets.xcassets/player1.imageset/player1.png b/Rect/Rect/Assets.xcassets/player1.imageset/player1.png new file mode 100644 index 0000000..cdc011a Binary files /dev/null and b/Rect/Rect/Assets.xcassets/player1.imageset/player1.png differ diff --git a/Rect/Rect/Assets.xcassets/player2.imageset/Contents.json b/Rect/Rect/Assets.xcassets/player2.imageset/Contents.json new file mode 100644 index 0000000..b9779ee --- /dev/null +++ b/Rect/Rect/Assets.xcassets/player2.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "player2.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Rect/Rect/Assets.xcassets/player2.imageset/player2.png b/Rect/Rect/Assets.xcassets/player2.imageset/player2.png new file mode 100644 index 0000000..b117025 Binary files /dev/null and b/Rect/Rect/Assets.xcassets/player2.imageset/player2.png differ diff --git a/Rect/Rect/Assets.xcassets/player3.imageset/Contents.json b/Rect/Rect/Assets.xcassets/player3.imageset/Contents.json new file mode 100644 index 0000000..5df8053 --- /dev/null +++ b/Rect/Rect/Assets.xcassets/player3.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "player3.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Rect/Rect/Assets.xcassets/player3.imageset/player3.png b/Rect/Rect/Assets.xcassets/player3.imageset/player3.png new file mode 100644 index 0000000..593a568 Binary files /dev/null and b/Rect/Rect/Assets.xcassets/player3.imageset/player3.png differ diff --git a/Rect/Rect/Assets.xcassets/player4.imageset/Contents.json b/Rect/Rect/Assets.xcassets/player4.imageset/Contents.json new file mode 100644 index 0000000..887e0a9 --- /dev/null +++ b/Rect/Rect/Assets.xcassets/player4.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "player4.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Rect/Rect/Assets.xcassets/player4.imageset/player4.png b/Rect/Rect/Assets.xcassets/player4.imageset/player4.png new file mode 100644 index 0000000..8a6c37a Binary files /dev/null and b/Rect/Rect/Assets.xcassets/player4.imageset/player4.png differ diff --git a/Rect/Rect/Assets.xcassets/refillBody.imageset/Contents.json b/Rect/Rect/Assets.xcassets/refillBody.imageset/Contents.json new file mode 100644 index 0000000..56aa568 --- /dev/null +++ b/Rect/Rect/Assets.xcassets/refillBody.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "refillBody.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Rect/Rect/Assets.xcassets/refillBody.imageset/refillBody.png b/Rect/Rect/Assets.xcassets/refillBody.imageset/refillBody.png new file mode 100644 index 0000000..0c01ee3 Binary files /dev/null and b/Rect/Rect/Assets.xcassets/refillBody.imageset/refillBody.png differ diff --git a/Rect/Rect/Base.lproj/LaunchScreen.storyboard b/Rect/Rect/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..2e721e1 --- /dev/null +++ b/Rect/Rect/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Rect/Rect/Base.lproj/Main.storyboard b/Rect/Rect/Base.lproj/Main.storyboard new file mode 100644 index 0000000..c357626 --- /dev/null +++ b/Rect/Rect/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Rect/Rect/GameScene.sks b/Rect/Rect/GameScene.sks new file mode 100644 index 0000000..61eb4fe Binary files /dev/null and b/Rect/Rect/GameScene.sks differ diff --git a/Rect/Rect/GameScene.swift b/Rect/Rect/GameScene.swift new file mode 100644 index 0000000..e69a937 --- /dev/null +++ b/Rect/Rect/GameScene.swift @@ -0,0 +1,408 @@ +// +// GameScene.swift +// Rect +// +// Created by Peter Zhu on 15/10/31. +// Copyright (c) 2015年 Peter Zhu. All rights reserved. +// + +import SpriteKit + +enum BodyType: UInt32 { + case player = 1 + case ground = 2 + case door = 4 + case bodyPart = 8 + case button = 16 + case enemy = 32 + case refillBody = 64 + case all = 1023 +} + +class GameScene: SKScene, SKPhysicsContactDelegate { + + var levelNum: Int = 1 + var player = Player() + var map = JSTileMap(named: "level1.tmx") + var leftButton = SKSpriteNode(color: UIColor(red: 255, green: 255, blue: 255, alpha: 0.5), size: CGSizeMake(100, 1000)) + var rightButton = SKSpriteNode(color: UIColor(red: 255, green: 255, blue: 255, alpha: 0.5), size: CGSizeMake(100, 1000)) + var jumpButton = SKSpriteNode(color: UIColor(red: 255, green: 255, blue: 255, alpha: 0.5), size: CGSizeMake(100, 1000)) + var finalTouchName = "" + var viewScale: CGFloat = 1 + + override func didMoveToView(view: SKView) { + /* Setup your scene here */ + + self.physicsWorld.contactDelegate = self + + self.backgroundColor = SKColor.blackColor() + self.view?.multipleTouchEnabled = true + + self.anchorPoint = CGPoint(x: 0.5, y: 0.5) + self.position = CGPoint(x: 0, y: 0) //Change the scenes anchor point to the bottom left and position it correctly + self.size = CGSizeMake(self.size.width / viewScale, self.size.height / viewScale) + + //let rect = map.calculateAccumulatedFrame() //This is not necessarily needed but returns the CGRect actually used by the tileMap, not just the space it could take up. You may want to use it later + map.position = CGPoint(x: 0, y: 0) //Position in the bottom left + map.setScale(1) + map.name = "map" + self.addChild(map!) + + addFloor() + + self.player.position = CGPointMake(150, map.calculateAccumulatedFrame().height - 274) + self.map.addChild(self.player) + + let overLay = SKSpriteNode(color: UIColor(red: 0, green: 0, blue: 0, alpha: 0), size: CGSizeMake(self.frame.width, self.frame.height)) + overLay.name = "overLay" + overLay.zPosition = 98 + self.addChild(overLay) + + leftButton.name = "leftButton" + leftButton.position = CGPointMake(-self.frame.width / 2 + (50 / viewScale), 0) + leftButton.size = CGSizeMake(100 / viewScale, self.frame.height) + leftButton.zPosition = 100 + self.addChild(leftButton) + + rightButton.name = "rightButton" + rightButton.position = CGPointMake(self.frame.width / 2 - (50 / viewScale), 0) + rightButton.size = CGSizeMake(100 / viewScale, self.frame.height) + rightButton.zPosition = 99 + self.addChild(rightButton) + + jumpButton.name = "jumpButton" + jumpButton.position = CGPointMake(0, -self.frame.height / 2 + (150 / viewScale)) + jumpButton.size = CGSizeMake(self.frame.width, 100 / viewScale) + jumpButton.zPosition = 101 + self.addChild(jumpButton) + } + + func loadLevel(level: Int) { + player.removeAllActions() + + map.removeFromParent() + player.removeFromParent() + + map = JSTileMap(named: "level" + String(level) + ".tmx") + self.player.position = CGPointMake(150, map.calculateAccumulatedFrame().height - 274) + self.player.refill() + self.addChild(self.map) + addFloor() + self.map.addChild(self.player) + } + + func reScale() { + self.size = CGSizeMake(self.size.width / viewScale, self.size.height / viewScale) + leftButton.position = CGPointMake(-self.frame.width / 2 + (50 / viewScale), 0) + leftButton.size = CGSizeMake(100 / viewScale, self.frame.height) + rightButton.position = CGPointMake(self.frame.width / 2 - (50 / viewScale), 0) + rightButton.size = CGSizeMake(100 / viewScale, self.frame.height) + jumpButton.position = CGPointMake(0, -self.frame.height / 2 + (150 / viewScale)) + jumpButton.size = CGSizeMake(self.frame.width, 100 / viewScale) + } + + override func didFinishUpdate() { + self.centerOnNode(player)//self.childNodeWithName("worldCamera")!) + //player.parent!.position = player.position + } + + func centerOnNode(node: SKNode) { + let cameraPositionInScene: CGPoint = (node.scene?.convertPoint(node.position, fromNode: node.parent!))! + node.parent!.position = CGPointMake(node.parent!.position.x - cameraPositionInScene.x, node.parent!.position.y - cameraPositionInScene.y) + } + + func addFloor() { + for objectGroup in self.map.objectGroups{ + if objectGroup.groupName == "Collision" { + for object in (objectGroup.objects as NSArray) { + let nodeWidth = CGFloat(((object.valueForKey("width")! as AnyObject) as! NSString).doubleValue) + let nodeHeight = CGFloat(((object.valueForKey("height")! as AnyObject) as! NSString).doubleValue) + let nodeX = CGFloat((object.valueForKey("x")! as AnyObject) as! NSNumber) + let nodeY = CGFloat((object.valueForKey("y")! as AnyObject) as! NSNumber) + + let node = SKSpriteNode(color: UIColor(red: 0, green: 0, blue: 0, alpha: 1), size: CGSize(width: nodeWidth, height: nodeHeight)) + node.name = "ground" + node.position = CGPointMake(nodeX + nodeWidth / 2, nodeY + nodeHeight / 2) + node.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: nodeWidth, height: nodeHeight)) + node.physicsBody!.dynamic = false + node.physicsBody?.pinned = true + node.physicsBody?.usesPreciseCollisionDetection = true + node.physicsBody?.friction = 0 + node.physicsBody?.restitution = 0 + node.physicsBody?.categoryBitMask = BodyType.ground.rawValue + node.physicsBody?.contactTestBitMask = BodyType.all.rawValue + node.physicsBody?.collisionBitMask = BodyType.all.rawValue + + self.map.addChild(node) + } + } else if objectGroup.groupName == "door" { + for object in (objectGroup.objects as NSArray) { + let nodeWidth = CGFloat(((object.valueForKey("width")! as AnyObject) as! NSString).doubleValue) + let nodeHeight = CGFloat(((object.valueForKey("height")! as AnyObject) as! NSString).doubleValue) + let nodeX = CGFloat((object.valueForKey("x")! as AnyObject) as! NSNumber) + let nodeY = CGFloat((object.valueForKey("y")! as AnyObject) as! NSNumber) + + let node = SKSpriteNode(color: UIColor(red: 0, green: 0, blue: 0, alpha: 0), size: CGSize(width: nodeWidth, height: nodeHeight)) + node.name = "door" + node.position = CGPointMake(nodeX + nodeWidth / 2, nodeY + nodeHeight / 2) + node.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: nodeWidth, height: nodeHeight)) + node.physicsBody?.affectedByGravity = false + node.physicsBody!.dynamic = false + node.physicsBody?.pinned = true + node.physicsBody?.usesPreciseCollisionDetection = true + node.physicsBody?.friction = 0 + node.physicsBody?.restitution = 0 + node.physicsBody?.categoryBitMask = BodyType.door.rawValue + node.physicsBody?.contactTestBitMask = BodyType.all.rawValue + node.physicsBody?.collisionBitMask = BodyType.all.rawValue + + self.map.addChild(node) + } + } else if objectGroup.groupName == "lift" { + for object in (objectGroup.objects as NSArray) { + let nodeWidth = CGFloat(((object.valueForKey("width")! as AnyObject) as! NSString).doubleValue) + let nodeHeight = CGFloat(((object.valueForKey("height")! as AnyObject) as! NSString).doubleValue) + let nodeX = CGFloat((object.valueForKey("x")! as AnyObject) as! NSNumber) + let nodeY = CGFloat((object.valueForKey("y")! as AnyObject) as! NSNumber) + let finalPos = Int(((object.valueForKey("finalPosition")! as AnyObject) as! NSString).doubleValue) + let pairButtonNum = Int(((object.valueForKey("buttonNum")! as AnyObject) as! NSString).doubleValue) + let liftDirection = String((object.valueForKey("direction")! as AnyObject) as! NSString) + + let node = lift(positionPt: CGPointMake(nodeX + nodeWidth / 2, nodeY + nodeHeight / 2), size: CGSizeMake(nodeWidth, nodeHeight)) + node.name = "lift" + String(pairButtonNum) + node.matchButtonNum = pairButtonNum + node.finalPosition = finalPos as Int + node.direction = liftDirection + node.checkConditioningLift() + + self.map.addChild(node) + } + } else if objectGroup.groupName == "button" { + for object in (objectGroup.objects as NSArray) { + let nodeWidth = CGFloat(((object.valueForKey("width")! as AnyObject) as! NSString).doubleValue) + let nodeHeight = CGFloat(((object.valueForKey("height")! as AnyObject) as! NSString).doubleValue) + let nodeX = CGFloat((object.valueForKey("x")! as AnyObject) as! NSNumber) + let nodeY = CGFloat((object.valueForKey("y")! as AnyObject) as! NSNumber) + let liftNum = Int(((object.valueForKey("liftNum")! as AnyObject) as! NSString).doubleValue) + + let node = button(positionPt: CGPointMake(nodeX + nodeWidth / 2, nodeY + nodeHeight / 2), size: CGSize(width: nodeWidth, height: nodeHeight)) + node.name = "button" + node.matchLiftNum = liftNum + + self.map.addChild(node) + } + } else if objectGroup.groupName == "enemy" { + for object in (objectGroup.objects as NSArray) { + let nodeWidth = CGFloat(((object.valueForKey("width")! as AnyObject) as! NSString).doubleValue) + let nodeHeight = CGFloat(((object.valueForKey("height")! as AnyObject) as! NSString).doubleValue) + let nodeX = CGFloat((object.valueForKey("x")! as AnyObject) as! NSNumber) + let nodeY = CGFloat((object.valueForKey("y")! as AnyObject) as! NSNumber) + + let node = enemy(positionPt: CGPointMake(nodeX + nodeHeight / 2, nodeY + nodeHeight / 2), range: CGSize(width: nodeWidth, height: nodeHeight)) + node.name = "enemy" + + self.map.addChild(node) + } + } else if objectGroup.groupName == "refillBody" { + for object in (objectGroup.objects as NSArray) { + let nodeWidth = CGFloat(((object.valueForKey("width")! as AnyObject) as! NSString).doubleValue) + let nodeHeight = CGFloat(((object.valueForKey("height")! as AnyObject) as! NSString).doubleValue) + let nodeX = CGFloat((object.valueForKey("x")! as AnyObject) as! NSNumber) + let nodeY = CGFloat((object.valueForKey("y")! as AnyObject) as! NSNumber) + + let node = refillBody(positionPt: CGPointMake(nodeX + nodeWidth / 2, nodeY + nodeHeight / 2), size: CGSizeMake(nodeWidth, nodeHeight)) + node.name = "refillBody" + + self.map.addChild(node) + } + } + } + } + + override func touchesBegan(touches: Set, withEvent event: UIEvent?) { + /* Called when a touch begins */ + var lastTouch = touches.first + + for touch in touches { + if touch.timestamp > lastTouch!.timestamp { + let location = touch.locationInNode(self) + let node = self.nodeAtPoint(location) + if node != map { + lastTouch = touch + } + } + } + + let location = lastTouch!.locationInNode(self) + let node = self.nodeAtPoint(location) + switch node.name { + case ("leftButton"?): + player.removeAllActions() + player.runAction(SKAction.repeatActionForever(SKAction.moveByX(-30, y: 0, duration: 0.1))) + case ("rightButton"?): + player.removeAllActions() + player.runAction(SKAction.repeatActionForever(SKAction.moveByX(30, y: 0, duration: 0.1))) + case ("jumpButton"?): + if (player.physicsBody?.velocity.dy == 0) { + player.physicsBody?.applyImpulse(CGVectorMake(0, 20 - CGFloat(player.bodySize) * 4)) + } + case ("overLay"?): + if player.shrink() { + shootBodyPart(location) + } + default: true + } + if (node.name == "leftButton") || (node.name == "rightButton") { + finalTouchName = node.name! + } + + } + + override func touchesEnded(touches: Set, withEvent event: UIEvent?) { + for touch in touches { + let location = touch.locationInNode(self) + let node = self.nodeAtPoint(location) + + if (node != map) { + switch node.name! { + case ("leftButton"), ("rightButton"): + if node.name == finalTouchName { + player.removeAllActions() + } + default: true + } + } + } + } + + func didBeginContact(contact: SKPhysicsContact) { + + if (contact.bodyA.node != nil) && (contact.bodyB.node != nil) { + let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask + + print(contactMask) + + switch contactMask { + case (BodyType.player.rawValue | BodyType.door.rawValue): + if player.bodySize == 1 { + levelNum++ + loadLevel(levelNum) + } + case (BodyType.bodyPart.rawValue | BodyType.player.rawValue): + if contact.bodyA.node?.name == "bodyPart" { + if (contact.bodyA.node as! bodyPart).collidedWithGround { + contact.bodyA.node?.removeFromParent() + player.enlarge() + } + } else { + if (contact.bodyB.node as! bodyPart).collidedWithGround { + contact.bodyB.node?.removeFromParent() + player.enlarge() + } + } + case (BodyType.bodyPart.rawValue | BodyType.ground.rawValue): + if contact.bodyA.node?.name == "bodyPart" { + contact.bodyA.node?.removeAllActions() + contact.bodyA.node?.physicsBody?.affectedByGravity = true + (contact.bodyA.node as! bodyPart).collidedWithGround = true + + } else { + contact.bodyB.node?.removeAllActions() + contact.bodyB.node?.physicsBody?.affectedByGravity = true + (contact.bodyB.node as! bodyPart).collidedWithGround = true + } + case (BodyType.player.rawValue | BodyType.button.rawValue): + if (contact.bodyA.node?.name == "button") { + let matchLiftName = "lift" + String((contact.bodyA.node as! button).matchLiftNum) + let matchLift = map.childNodeWithName(matchLiftName) as! lift + matchLift.moveLift() + + } else { + let matchLiftName = "lift" + String((contact.bodyB.node as! button).matchLiftNum) + print(matchLiftName) + let matchLift = map.childNodeWithName(matchLiftName) as! lift + matchLift.moveLift() + } + case (BodyType.bodyPart.rawValue | BodyType.button.rawValue): + if (contact.bodyA.node?.name == "button") { + let matchLiftName = "lift" + String((contact.bodyA.node as! button).matchLiftNum) + let matchLift = map.childNodeWithName(matchLiftName) as! lift + matchLift.moveLift() + } else { + let matchLiftName = "lift" + String((contact.bodyB.node as! button).matchLiftNum) + print(matchLiftName) + let matchLift = map.childNodeWithName(matchLiftName) as! lift + matchLift.moveLift() + } + if contact.bodyA.node?.name == "bodyPart" { + contact.bodyA.node?.removeAllActions() + contact.bodyA.node?.physicsBody?.affectedByGravity = true + (contact.bodyA.node as! bodyPart).collidedWithGround = true + + } else { + contact.bodyB.node?.removeAllActions() + contact.bodyB.node?.physicsBody?.affectedByGravity = true + (contact.bodyB.node as! bodyPart).collidedWithGround = true + } + case (BodyType.bodyPart.rawValue | BodyType.enemy.rawValue): + print(contact.bodyA.node, contact.bodyB.node) + if (contact.bodyA.node?.name == "enemy") { + if !(contact.bodyB.node as! bodyPart).usedOnEnemy { + (contact.bodyA.node as! enemy).hitted() + (contact.bodyB.node as! bodyPart).usedOnEnemy = true + } + } else { + if !(contact.bodyA.node as! bodyPart).usedOnEnemy { + (contact.bodyB.node as! enemy).hitted() + (contact.bodyA.node as! bodyPart).usedOnEnemy = true + } + } + if contact.bodyA.node?.name == "bodyPart" { + contact.bodyA.node?.removeAllActions() + contact.bodyA.node?.physicsBody?.affectedByGravity = true + (contact.bodyA.node as! bodyPart).collidedWithGround = true + + } else { + contact.bodyB.node?.removeAllActions() + contact.bodyB.node?.physicsBody?.affectedByGravity = true + (contact.bodyB.node as! bodyPart).collidedWithGround = true + } + case (BodyType.player.rawValue | BodyType.enemy.rawValue): + loadLevel(levelNum) + case (BodyType.player.rawValue | BodyType.refillBody.rawValue): + player.refill() + if contact.bodyA.node?.name == "refillBody" { + contact.bodyA.node?.removeFromParent() + } else { + contact.bodyB.node?.removeFromParent() + } + default: true + } + } + + } + + func didEndContact(contact: SKPhysicsContact) { + let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask + + switch contactMask { + case (BodyType.player.rawValue | BodyType.ground.rawValue): + true + case (BodyType.player.rawValue | BodyType.door.rawValue): + print("next level") + default: true + } + } + + func shootBodyPart(location: CGPoint) { + let aBodyPart = bodyPart() + let position = CGPointMake(player.position.x, player.position.y + player.frame.height - aBodyPart.frame.height) + aBodyPart.position = position + aBodyPart.runAction(SKAction.repeatActionForever(SKAction.moveBy(CGVector(dx: (self.map.convertPoint(location, fromNode: self.scene!).x - aBodyPart.position.x), dy: (self.map.convertPoint(location, fromNode: self.scene!).y) - aBodyPart.position.y), duration: 1))) + self.map.addChild(aBodyPart) + } + + override func update(currentTime: CFTimeInterval) { + /* Called before each frame is rendered */ + } +} diff --git a/Rect/Rect/GameViewController.swift b/Rect/Rect/GameViewController.swift new file mode 100644 index 0000000..e45e11a --- /dev/null +++ b/Rect/Rect/GameViewController.swift @@ -0,0 +1,54 @@ +// +// GameViewController.swift +// Rect +// +// Created by Peter Zhu on 15/10/31. +// Copyright (c) 2015年 Peter Zhu. All rights reserved. +// + +import UIKit +import SpriteKit + +class GameViewController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + + if let scene = GameScene(fileNamed:"GameScene") { + // Configure the view. + let skView = self.view as! SKView + skView.showsFPS = true + skView.showsNodeCount = true + + /* Sprite Kit applies additional optimizations to improve rendering performance */ + skView.ignoresSiblingOrder = true + + /* Set the scale mode to scale to fit the window */ + scene.scaleMode = .AspectFill + + skView.presentScene(scene) + } + } + + override func shouldAutorotate() -> Bool { + return true + } + + override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask { + /*if UIDevice.currentDevice().userInterfaceIdiom == .Phone { + return .AllButUpsideDown + } else { + return .All + }*/ + return .Landscape + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Release any cached data, images, etc that aren't in use. + } + + override func prefersStatusBarHidden() -> Bool { + return true + } +} diff --git a/Rect/Rect/Info.plist b/Rect/Rect/Info.plist new file mode 100644 index 0000000..44468d2 --- /dev/null +++ b/Rect/Rect/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Rect/Rect/JSTileMap.h b/Rect/Rect/JSTileMap.h new file mode 100755 index 0000000..8b0164b --- /dev/null +++ b/Rect/Rect/JSTileMap.h @@ -0,0 +1,200 @@ +// +// JSTileMap.h +// TMXMapSample +// +// Created by Jeremy on 6/11/13. +// Copyright (c) 2013 Jeremy. All rights reserved. +// + +#import +#import + +#import "LFCGzipUtility.h" + + +enum +{ + TMXLayerAttributeNone = 1 << 0, + TMXLayerAttributeBase64 = 1 << 1, + TMXLayerAttributeGzip = 1 << 2, + TMXLayerAttributeZlib = 1 << 3, +}; + +typedef enum +{ + TMXPropertyNone, + TMXPropertyMap, + TMXPropertyLayer, + TMXPropertyObjectGroup, + TMXPropertyObject, + TMXPropertyTile, + TMXPropertyImageLayer +} PropertyType; + +typedef enum +{ + kTileDiagonalFlag = 0x20000000, + kTileVerticalFlag = 0x40000000, + kTileHorizontalFlag = 0x80000000, + + kFlippedAll = (kTileHorizontalFlag | kTileVerticalFlag | kTileDiagonalFlag), + kFlippedMask = ~(kFlippedAll), +} TMXTileFlags; + +typedef enum +{ + OrientationStyle_Orthogonal, + OrientationStyle_Isometric +} OrientationStyle; + + +@interface TMXTilesetInfo : NSObject + +@property (readonly, nonatomic) NSString* name; +@property (readonly, nonatomic) unsigned int firstGid; +@property (readonly, nonatomic) CGSize tileSize; +@property (readonly, nonatomic) CGSize unitTileSize; +@property (readonly, nonatomic) unsigned int spacing; +@property (readonly, nonatomic) unsigned int margin; +@property (readonly, nonatomic) NSString* sourceImage; +@property (readonly, nonatomic) CGSize imageSize; +@property (readonly, nonatomic) int atlasTilesPerRow; +@property (readonly, nonatomic) int atlasTilesPerCol; +@property (readonly, nonatomic) SKTexture* atlasTexture; + +-(instancetype)initWithGid:(int)gid attributes:(NSDictionary*)attributes; +-(void)setSourceImage:(NSString *)sourceImage; + +-(int)rowFromGid:(int)gid; +-(int)colFromGid:(int)gid; +-(SKTexture*)textureForGid:(int)gid; + +/** Given the location of the upper left corner of a tile in this tileset, + returns a new SKTexture for that tile. */ +-(SKTexture*)textureAtPoint:(CGPoint)p; + +@end + +@class TMXLayer; + +@interface TMXLayerInfo : NSObject +@property (strong, nonatomic) NSString *name; +@property (assign, nonatomic) CGSize layerGridSize; +@property (assign, nonatomic) int* tiles; +@property (assign, nonatomic) BOOL visible; +@property (assign, nonatomic) CGFloat opacity; +@property (assign, nonatomic) unsigned int minGID; +@property (assign, nonatomic) unsigned int maxGID; +@property (strong, nonatomic) NSMutableDictionary *properties; +@property (assign, nonatomic) CGPoint offset; +@property (assign, nonatomic) TMXLayer* layer; + +-(int)tileGidAtCoord:(CGPoint)coord; + +// debugging +- (void)logLayerGIDs; + +@end + +@interface TMXImageLayer : NSObject +@property (strong, nonatomic) NSString* name; +@property (strong, nonatomic) NSMutableDictionary *properties; +@property (strong, nonatomic) NSString* imageSource; +//@property (strong, nonatomic) NSString* transparencyColor; // Will maybe support this in the future. I think this is what the "trans" property is... +@end + + +@interface TMXObjectGroup : NSObject +@property (strong, nonatomic) NSString *groupName; +@property (assign, nonatomic) CGPoint positionOffset; +@property (strong, nonatomic) NSMutableArray *objects; +@property (strong, nonatomic) NSMutableDictionary *properties; + +- (NSDictionary *)objectNamed:(NSString *)objectName; // returns the first object with the specified name. Nil, if no object matches +- (NSArray *)objectsNamed:(NSString *)objectName; // returns an NSArray of objects with the specified name +- (id)propertyNamed:(NSString *)propertyName; // returns the property with the specified name + +@end + +@class JSTileMap; + +@interface TMXLayer : SKNode +@property (strong, nonatomic) TMXLayerInfo* layerInfo; +@property (strong, nonatomic) NSMutableSet* tileInfo; // contains TMXTilesetInfo objects +@property (assign, nonatomic) CGSize mapTileSize; + +/** Returns the width of the layer (layerGridSize.width * mapTileSize.width) */ +@property (readonly,nonatomic) CGFloat layerWidth; + +/** Returns the height of the layer (layerGridSize.height * mapTileSize.height) */ +@property (readonly,nonatomic) CGFloat layerHeight; + +/** Returns the JSTileMap that contains this layer */ +@property (weak, nonatomic) JSTileMap* map; + +- (CGPoint)pointForCoord:(CGPoint)coord; +- (CGPoint)coordForPoint:(CGPoint)point; + +- (void)removeTileAtCoord:(CGPoint)coord; +- (SKSpriteNode*)tileAt:(CGPoint)point; +- (SKSpriteNode*)tileAtCoord:(CGPoint)coord; +- (int)tileGidAt:(CGPoint)point; +- (id) propertyWithName:(NSString*)name; +- (NSDictionary*)properties; + +@end + + +@interface JSTileMap : SKNode + +@property (assign, nonatomic) CGSize mapSize; +@property (assign, nonatomic) CGSize tileSize; +@property (assign, nonatomic) PropertyType parentElement; +@property (assign, nonatomic) int parentGID; +@property (assign, nonatomic) unsigned int orientation; + +// minimum and maximum range of zPositioning of the map. +@property (readonly) CGFloat minZPositioning; +@property (readonly) CGFloat maxZPositioning; + +// tmx filename +@property (strong, nonatomic) NSString *filename; + +// tmx resource path +@property (strong, nonatomic) NSString *resources; + +// tilesets +@property (strong, nonatomic) NSMutableArray* tilesets; + +// tile properties +@property (strong, nonatomic) NSMutableDictionary* tileProperties; + +// properties +@property (strong, nonatomic) NSMutableDictionary* properties; + +// layers +@property (strong, nonatomic) NSMutableArray* layers; + +// image layers +@property (strong, nonatomic) NSMutableArray* imageLayers; + +// object groups +@property (strong, nonatomic) NSMutableArray* objectGroups; + +// xml tile gids +@property (strong, nonatomic) NSMutableArray* gidData; + ++ (JSTileMap*)mapNamed:(NSString*)mapName; ++ (JSTileMap*)mapNamed:(NSString*)mapName withBaseZPosition:(CGFloat)baseZPosition andZOrderModifier:(CGFloat)zOrderModifier; + +-(TMXLayer*)layerNamed:(NSString*)name; +-(TMXObjectGroup*)groupNamed:(NSString*)name; + +-(TMXTilesetInfo*)tilesetInfoForGid:(int)gID; +-(NSDictionary*)propertiesForGid:(int)gID; + +// debugging +- (void)logGIDs; + + +@end diff --git a/Rect/Rect/JSTileMap.m b/Rect/Rect/JSTileMap.m new file mode 100755 index 0000000..a0be15d --- /dev/null +++ b/Rect/Rect/JSTileMap.m @@ -0,0 +1,1344 @@ +// +// JSTileMap.m +// TMXMapSample +// +// Created by Jeremy on 6/11/13. +// Copyright (c) 2013 Jeremy. All rights reserved. +// + + +#import "JSTileMap.h" + + +@interface JSTileMap () +{ + NSMutableString* currentString; + BOOL storingCharacters; + int currentFirstGID; + int layerAttributes; +} + +@property int zOrderCount; + +@end + +@interface TMXLayerInfo () +@property int zOrderCount; +@end + +@interface TMXObjectGroup () +@property int zOrderCount; +@end + +@interface TMXImageLayer () +@property int zOrderCount; +@end + +@interface TMXTilesetInfo () +@property (nonatomic,strong) NSMutableDictionary* textureCache; +@end + + +#pragma mark - + + +@implementation TMXLayer + + +- (CGPoint)pointForCoord:(CGPoint)coord +{ + return + CGPointMake(coord.x * _mapTileSize.width + _mapTileSize.width / 2, + [self layerHeight] - (coord.y * _mapTileSize.height + _mapTileSize.height / 2)); +} + +- (CGPoint) coordForPoint:(CGPoint) inPoint +{ + // invert y axis + inPoint.y = [self layerHeight] - inPoint.y; + + int x = inPoint.x / _mapTileSize.width; + int y = inPoint.y / _mapTileSize.height; + + return CGPointMake(x, y); +} + + +-(int)tileGidAt:(CGPoint)point +{ + // get index + CGPoint pt = [self coordForPoint:point]; + int idx = pt.x + (pt.y * self.layerInfo.layerGridSize.width); + + // bounds check, invalid GID if out of bounds + if(idx > (_layerInfo.layerGridSize.width * _layerInfo.layerGridSize.height) || + idx < 0) + { + NSAssert(true, @"index out of bounds!"); + return 0; + } + + // return the Gid + return _layerInfo.tiles[ idx ]; +} + + +- (SKSpriteNode*)tileAt:(CGPoint)point +{ + return [self tileAtCoord:[self coordForPoint:point]]; +} + +- (SKSpriteNode*)tileAtCoord:(CGPoint)coord +{ + NSString* nodeName = [NSString stringWithFormat:@"*/%d",(int)(coord.x + coord.y * _layerInfo.layerGridSize.width)]; + return (SKSpriteNode*)[self childNodeWithName:nodeName]; +} + + +//#warning need to write setTileGidAt: + + +-(void)removeTileAtCoord:(CGPoint)coord +{ + uint32_t gid = [self.layerInfo tileGidAtCoord:coord]; + + if( gid ) + { + int z = coord.x + coord.y * self.layerInfo.layerGridSize.width; + + // remove tile from GID map + self.layerInfo.tiles[z] = 0; + + SKNode* tileNode = [self tileAtCoord:coord]; + if(tileNode) + [tileNode removeFromParent]; + } +} + + +- (NSDictionary*)properties +{ + return self.layerInfo.properties; +} + + +- (id) propertyWithName:(NSString*)name +{ + return self.layerInfo.properties[name]; +} + + +#pragma mark - + + ++(id) layerWithTilesetInfo:(NSArray*)tilesets layerInfo:(TMXLayerInfo*)layerInfo mapInfo:(JSTileMap*)mapInfo +{ + TMXLayer* layer = [TMXLayer node]; + layer.map = mapInfo; + + // basic properties from layerInfo + layer.layerInfo = layerInfo; + layer.layerInfo.layer = layer; + layer.mapTileSize = mapInfo.tileSize; + layer.alpha = layerInfo.opacity; + layer.position = layerInfo.offset; + + // recalc the offset if we are isometriic + if (mapInfo.orientation == OrientationStyle_Isometric) + { + layer.position = CGPointMake((layer.mapTileSize.width / 2.0) * (layer.position.x - layer.position.y), + (layer.mapTileSize.height / 2.0) * (-layer.position.x - layer.position.y)); + } + + NSMutableDictionary* layerNodes = [NSMutableDictionary dictionaryWithCapacity:tilesets.count]; + + // loop through the tiles + for (int col = 0; col < layerInfo.layerGridSize.width; col++) + { + for (int row = 0; row < layerInfo.layerGridSize.height; row++) + { + // get the gID + UInt32 gID = layerInfo.tiles[col + (int)(row * layerInfo.layerGridSize.width)]; + + // mask off the flip bits and remember their result. + UInt32 flipXY = gID & (kTileHorizontalFlag | kTileVerticalFlag); + bool flipDiag = (gID & kTileDiagonalFlag) != 0; + gID = gID & kFlippedMask; + + // skip 0 GIDs + if (!gID) + continue; + + // get the tileset for the passed gID. This will allow us to support multiple tilesets! + TMXTilesetInfo* tilesetInfo = [mapInfo tilesetInfoForGid:gID]; + [layer.tileInfo addObject:tilesetInfo]; + + if (tilesetInfo) // should never be nil? + { + SKTexture* texture = [tilesetInfo textureForGid:gID]; + SKSpriteNode* sprite = [SKSpriteNode spriteNodeWithTexture:texture]; + sprite.name = [NSString stringWithFormat:@"%d",(int)(col + row * layerInfo.layerGridSize.width)]; + + // make sure it's in the right position. + if (mapInfo.orientation == OrientationStyle_Isometric) + { + sprite.position = CGPointMake((layer.mapTileSize.width / 2.0) * (layerInfo.layerGridSize.width + col - row - 1), + (layer.mapTileSize.height / 2.0) * ((layerInfo.layerGridSize.height * 2 - col - row) - 2) ); + } + else + { + sprite.position = CGPointMake(col * layer.mapTileSize.width + tilesetInfo.tileSize.width/2.0, + (mapInfo.mapSize.height * (layer.mapTileSize.height)) - ((row + 1) * layer.mapTileSize.height) + tilesetInfo.tileSize.height/2.0); + } + + // flip sprites if necessary + if (flipDiag) { + if (flipXY == kTileHorizontalFlag) { + sprite.zRotation = -M_PI_2; // rotate clockwise by 90-degree + } else if (flipXY == kTileVerticalFlag) { + sprite.zRotation = M_PI_2; // rotate counter-clockwise by 90-degree + } else if (flipXY == (kTileHorizontalFlag | kTileVerticalFlag)) { + sprite.zRotation = -M_PI_2; // rotate clockwise by 90-degree + sprite.xScale *= -1; // hozontal flip + } else { + sprite.zRotation = M_PI_2; // rotate counter-clockwise by 90-degree + sprite.xScale *= -1; // hozontal flip + } + } else { + if (flipXY & kTileHorizontalFlag) { + sprite.xScale *= -1; // hozontal flip + } + if (flipXY & kTileVerticalFlag) { + sprite.yScale *= -1; // vertical flip + } + } + + // add sprite to correct node for this tileset + SKNode* layerNode = layerNodes[tilesetInfo.name]; + if (!layerNode) { + layerNode = [[SKNode alloc] init]; + layerNodes[tilesetInfo.name] = layerNode; + } + [layerNode addChild:sprite]; + +#ifdef DEBUG +// CGRect textRect = [texture textureRect]; +// NSLog(@"atlasNum %2d (%2d,%2d), gid (%d,%d), rect (%f, %f, %f, %f) sprite.pos (%3.2f,%3.2f) flipx%2d flipy%2d flipDiag%2d", gID+1, row, col, [tilesetInfo rowFromGid:gID], [tilesetInfo colFromGid:gID], textRect.origin.x, textRect.origin.y, textRect.size.width, textRect.size.height, sprite.position.x, sprite.position.y, flipX, flipY, flipDiag); +#endif + + } + } + } + + // add nodes for any tilesets that were used in this layer + for (SKNode* layerNode in layerNodes.allValues) { + if (layerNode.children.count > 0) { + [layer addChild:layerNode]; + } + } + + [layer calculateAccumulatedFrame]; + + return layer; +} + +-(CGFloat)layerWidth +{ + return self.layerInfo.layerGridSize.width * self.mapTileSize.width; +} + +-(CGFloat)layerHeight +{ + return self.layerInfo.layerGridSize.height * self.mapTileSize.height; +} + +-(void)encodeWithCoder:(NSCoder *)aCoder +{ + [super encodeWithCoder:aCoder]; + + [aCoder encodeObject:_layerInfo forKey:@"TMXLayerLayerInfo"]; + [aCoder encodeObject:_tileInfo forKey:@"TMXLayerTileInfo"]; +#if TARGET_OSX + NSPoint p = {.x = _mapTileSize.width, .y = _mapTileSize.height}; + [aCoder encodePoint:p forKey:@"TMXLayerTileSize"]; +#else + [aCoder encodeCGSize:_mapTileSize forKey:@"TMXLayerTileSize"]; +#endif + [aCoder encodeObject:_map forKey:@"TMXLayerMap"]; +} + +-(instancetype)initWithCoder:(NSCoder *)aDecoder +{ + if(self = [super initWithCoder:aDecoder]) + { + _layerInfo = [aDecoder decodeObjectForKey:@"TMXLayerLayerInfo"]; + _tileInfo = [aDecoder decodeObjectForKey:@"TMXLayerTileInfo"]; +#if TARGET_OSX + NSPoint p = [aDecoder decodePointForKey:@"TMXLayerTileSize"]; + _mapTileSize = CGSizeMake(p.x, p.y); +#else + _mapTileSize = [aDecoder decodeCGSizeForKey:@"TMXLayerTileSize"]; +#endif + _map = [aDecoder decodeObjectForKey:@"TMXLayerMap"]; + } + return self; +} + +@end + + +#pragma mark - + + +@implementation TMXLayerInfo + +- (id)init +{ + self = [super init]; + if (self) { + self.properties = [NSMutableDictionary dictionary]; + } + return self; +} + +-(void)dealloc +{ + free(_tiles); +} + +-(int)tileGidAtCoord:(CGPoint)coord +{ + int idx = coord.x + coord.y * _layerGridSize.width; + + NSAssert(idx < (_layerGridSize.width * _layerGridSize.height), @"index out of bounds!"); + + return _tiles[ idx ]; +} + +-(void)encodeWithCoder:(NSCoder *)aCoder +{ + [aCoder encodeObject:_name forKey:@"TMXLayerInfoName"]; +#if TARGET_OSX + NSPoint p = {.x = _layerGridSize.width, .y = _layerGridSize.height}; + [aCoder encodePoint:p forKey:@"TMXLayerInfoGridSize"]; +#else + [aCoder encodeCGSize:_layerGridSize forKey:@"TMXLayerInfoGridSize"]; +#endif + [aCoder encodeObject:[NSData dataWithBytes:(void*)_tiles + length:sizeof(int)*(_layerGridSize.width*_layerGridSize.height)] + forKey:@"TMXLayerInfoTiles"]; + [aCoder encodeBool:_visible forKey:@"TMXLayerInfoVisible"]; + [aCoder encodeFloat:_opacity forKey:@"TMXLayerInfoOpacity"]; + [aCoder encodeInteger:_minGID forKey:@"TMXLayerInfoMinGid"]; + [aCoder encodeInteger:_maxGID forKey:@"TMXLayerInfoMaxGid"]; + + [aCoder encodeObject:_properties forKey:@"TMXLayerInfoProperties"]; +#if TARGET_OSX + [aCoder encodePoint:_offset forKey:@"TMXLayerInfoOffset"]; +#else + [aCoder encodeCGPoint:_offset forKey:@"TMXLayerInfoOffset"]; +#endif + [aCoder encodeObject:_layer forKey:@"TMXLayerInfoLayer"]; + [aCoder encodeInteger:_zOrderCount forKey:@"TMXLayerInfoZOrderCount"]; +} + +-(instancetype)initWithCoder:(NSCoder *)aDecoder +{ + if(self = [super init]) + { + _name = [aDecoder decodeObjectForKey:@"TMXLayerInfoName"]; +#if TARGET_OSX + NSPoint p = [aDecoder decodePointForKey:@"TMXLayerInfoGridSize"]; + _layerGridSize = CGSizeMake(p.x, p.y); +#else + _layerGridSize = [aDecoder decodeCGSizeForKey:@"TMXLayerInfoGridSize"]; +#endif + + NSData* data = [aDecoder decodeObjectForKey:@"TMXLayerInfoTiles"]; + int* temp = (int*)[data bytes]; + _tiles = malloc(sizeof(int)*(_layerGridSize.width*_layerGridSize.height)); + for(int i = 0; i < (_layerGridSize.width*_layerGridSize.height); ++i) { + _tiles[i] = temp[i]; + } + + _visible = [aDecoder decodeBoolForKey:@"TMXLayerInfoVisible"]; + _opacity = [aDecoder decodeFloatForKey:@"TMXLayerInfoOpacity"]; + _minGID = [aDecoder decodeIntForKey:@"TMXLayerInfoMinGid"]; + _maxGID = [aDecoder decodeIntForKey:@"TMXLayerInfoMaxGid"]; + + _properties = [aDecoder decodeObjectForKey:@"TMXLayerInfoProperties"]; +#if TARGET_OSX + _offset = [aDecoder decodePointForKey:@"TMXLayerInfoOffset"]; +#else + _offset = [aDecoder decodeCGPointForKey:@"TMXLayerInfoOffset"]; +#endif + _layer = [aDecoder decodeObjectForKey:@"TMXLayerInfoLayer"]; + _zOrderCount = [aDecoder decodeIntForKey:@"TMXLayerInfoZOrderCount"]; + } + return self; +} + + +- (void)logLayerGIDs +{ + NSMutableString *str = [NSMutableString string]; + + // header row + [str appendString:@" grid "]; + for (int i = 0; i < _layerGridSize.width; i++) + { + [str appendFormat:@"%3d", i]; + } + [str appendString:@"\r"]; + + for (int x = 0; x < _layerGridSize.width * _layerGridSize.height; x++) + { + if (x % (int)(_layerGridSize.width) == 0) + [str appendFormat:@"\r %3ld ", lrint(x / _layerGridSize.width)]; + + [str appendFormat:@"%3d", _tiles[x]]; + } + + NSLog(@"Layer '%@':\r\r%@\r\r", _name, str); +} + + +@end + +@implementation TMXObjectGroup + +- (id)init +{ + self = [super init]; + if (self) { + self.objects = [NSMutableArray array]; + self.properties = [NSMutableDictionary dictionary]; + } + return self; +} + +-(void)encodeWithCoder:(NSCoder *)aCoder +{ + [aCoder encodeObject:_groupName forKey:@"TMXObjectGroupName"]; +#if TARGET_OSX + [aCoder encodePoint:_positionOffset forKey:@"TMSObjectGroupPosOffset"]; +#else + [aCoder encodeCGPoint:_positionOffset forKey:@"TMSObjectGroupPosOffset"]; +#endif + [aCoder encodeObject:_objects forKey:@"TMXObjectGroupObjects"]; + [aCoder encodeObject:_properties forKey:@"TMXObjectGroupProperties"]; + [aCoder encodeInteger:_zOrderCount forKey:@"TMXObjectGroupZOrderCount"]; +} + +-(instancetype)initWithCoder:(NSCoder *)aDecoder +{ + if(self = [super init]) + { + _groupName = [aDecoder decodeObjectForKey:@"TMXObjectGroupName"]; +#if TARGET_OSX + _positionOffset = [aDecoder decodePointForKey:@"TMSObjectGroupPosOffset"]; +#else + _positionOffset = [aDecoder decodeCGPointForKey:@"TMSObjectGroupPosOffset"]; +#endif + _objects = [aDecoder decodeObjectForKey:@"TMXObjectGroupObjects"]; + _properties = [aDecoder decodeObjectForKey:@"TMXObjectGroupProperties"]; + _zOrderCount = [aDecoder decodeIntForKey:@"TMXObjectGroupZOrderCount"]; + } + return self; +} + +- (NSDictionary *)objectNamed:(NSString *)objectName { + __block NSDictionary *object = nil; + [self.objects enumerateObjectsUsingBlock:^(NSDictionary *obj, NSUInteger idx, BOOL *stop) { + if ([[obj valueForKey:@"name"] isEqualToString:objectName]) { + object = obj; + *stop = YES; + } + }]; + + return object; +} + +- (NSArray *)objectsNamed:(NSString *)objectName { + NSMutableArray *objects = [NSMutableArray arrayWithCapacity:self.objects.count]; + [self.objects enumerateObjectsUsingBlock:^(NSDictionary *obj, NSUInteger idx, BOOL *stop) { + if ([[obj valueForKey:@"name"] isEqualToString:objectName]) { + [objects addObject:obj]; + } + }]; + + return objects; +} + +- (id)propertyNamed:(NSString *)propertyName { + return [self.properties valueForKey:propertyName]; +} + +@end + + +@implementation TMXImageLayer + +- (id)init +{ + self = [super init]; + if (self) { + self.properties = [NSMutableDictionary dictionary]; + } + return self; +} + +-(void)encodeWithCoder:(NSCoder *)aCoder +{ + [aCoder encodeObject:_name forKey:@"TMXImageLayerName"]; + [aCoder encodeObject:_imageSource forKey:@"TMXImageLayerSource"]; + [aCoder encodeObject:_properties forKey:@"TMXImageLayerProperties"]; + [aCoder encodeInteger:_zOrderCount forKey:@"TMXImageLayerZOrderCount"]; +} + +-(instancetype)initWithCoder:(NSCoder *)aDecoder +{ + if(self = [super init]) + { + _name = [aDecoder decodeObjectForKey:@"TMXImageLayerName"]; + _imageSource = [aDecoder decodeObjectForKey:@"TMXImageLayerSource"]; + _properties = [aDecoder decodeObjectForKey:@"TMXImageLayerProperties"]; + _zOrderCount = [aDecoder decodeIntForKey:@"TMXImageLayerZOrderCount"]; + } + return self; +} + +@end + + +@implementation TMXTilesetInfo + +-(instancetype)initWithGid:(int)gID attributes:(NSDictionary*)attributes +{ + if((self = [super init])) + { + _name = [attributes[@"name"] copy]; + _firstGid = gID; + _spacing = [attributes[@"spacing"] intValue]; + _margin = [attributes[@"margin"] intValue]; + _tileSize = CGSizeMake([attributes[@"tilewidth"] intValue], + [attributes[@"tileheight"] intValue]); + + _textureCache = [NSMutableDictionary dictionary]; + + } + return self; +} + +-(void)setSourceImage:(NSString *)sourceImage +{ + _sourceImage = [sourceImage copy]; +#if TARGET_OSX + NSImageRep* atlas = [NSImageRep imageRepWithContentsOfFile:_sourceImage]; +#else + UIImage* atlas = [UIImage imageWithContentsOfFile:_sourceImage]; +#endif + _imageSize = atlas.size; +// _atlasTexture = [SKTexture textureWithImage:atlas]; // CML: There seems to be a bug where creating with Image instead of ImageNamed breaks the + _atlasTexture = [SKTexture textureWithImageNamed:_sourceImage]; // archiving. + + NSLog(@"texture image: %@\rSize (%f, %f)", _sourceImage, _atlasTexture.size.width, _atlasTexture.size.height); + + _unitTileSize = CGSizeMake(_tileSize.width / _imageSize.width, + _tileSize.height / _imageSize.height); + + _atlasTilesPerRow = (_imageSize.width - _margin * 2 + _spacing) / (_tileSize.width + _spacing); + _atlasTilesPerCol = (_imageSize.height - _margin * 2 + _spacing) / (_tileSize.height + _spacing); +} + +-(int)rowFromGid:(int)gid +{ + return gid / self.atlasTilesPerRow; +} + +-(int)colFromGid:(int)gid +{ + return gid % self.atlasTilesPerRow; +} + +-(SKTexture*)textureForGid:(int)gid +{ + gid = gid & kFlippedMask; + gid -= self.firstGid; + + SKTexture* texture = self.textureCache[@(gid)]; + if(!texture) + { + CGFloat rowOffset = ( (((self.tileSize.height + self.spacing) * [self rowFromGid:gid]) + self.margin) / self.imageSize.height); + CGFloat colOffset = ( (((self.tileSize.width + self.spacing) * [self colFromGid:gid]) + self.margin) / self.imageSize.width); + // reverse y axis + rowOffset = 1.0 - rowOffset - self.unitTileSize.height; + + // note that the width and height of the tiles are always the same in TMX maps or the atlas (GIDs) couldn't be calculated consistently. + CGRect rect = CGRectMake(colOffset, rowOffset, + self.unitTileSize.width, self.unitTileSize.height); + + texture = [SKTexture textureWithRect:rect inTexture:self.atlasTexture]; + texture.usesMipmaps = YES; + texture.filteringMode = SKTextureFilteringNearest; + self.textureCache[@(gid)] = texture; + + // tile data +#ifdef DEBUG +// NSLog(@"The regular atlas is %f x %f. Tile size is %f x % f plus %d spaces between each tile.", self.atlasTexture.size.width, self.atlasTexture.size.height, self.tileSize.width, self.tileSize.height, self.spacing); +// NSLog(@"Tile margins for this atlas are %d. This means the atlas image is inset by this amount, from both the top left and bottom right.", self.margin); +// NSLog(@"gid %d is row %d, col %d of the atlas. (map base gid is %d)", gid, [self rowFromGid:gid] + 1, [self colFromGid:gid] + 1, self.firstGid); +// NSLog(@"This means that the tile x offset is %f%% into the atlas and %f%% from the top-left of the atlas.", colOffset, rowOffset); +// NSLog(@"The adjusted tile size in percentages is %f wide and %f tall.", self.unitTileSize.width, self.unitTileSize.height); +#endif + } + return texture; +} + +-(SKTexture*)textureAtPoint:(CGPoint)p +{ + SKTexture *atlas = self.atlasTexture; + return [SKTexture textureWithRect: + CGRectMake(p.x / atlas.size.width, 1.0-((p.y + self.tileSize.height) / atlas.size.height), + self.unitTileSize.width, self.unitTileSize.height) + inTexture:atlas]; +} + +-(void)encodeWithCoder:(NSCoder *)aCoder +{ + [aCoder encodeObject:_name forKey:@"TMXTilesetName"]; + [aCoder encodeInteger:_firstGid forKey:@"TMXTilesetFirstGid"]; +#if TARGET_OSX + NSPoint p = {.x = _tileSize.width, .y = _tileSize.height}; + [aCoder encodePoint:p forKey:@"TMXTilesetTileSize"]; + p.x = _unitTileSize.width; p.y = _unitTileSize.height; + [aCoder encodePoint:p forKey:@"TMXTilesetUnitTileSize"]; + p.x = _imageSize.width; p.y = _imageSize.height; + [aCoder encodePoint:p forKey:@"TMXTilesetImageSize"]; +#else + [aCoder encodeCGSize:_tileSize forKey:@"TMXTilesetTileSize"]; + [aCoder encodeCGSize:_unitTileSize forKey:@"TMXTilesetUnitTileSize"]; + [aCoder encodeCGSize:_imageSize forKey:@"TMXTilesetImageSize"]; +#endif + [aCoder encodeInteger:_spacing forKey:@"TMXTilesetSpacing"]; + [aCoder encodeInteger:_margin forKey:@"TMXTilesetMargin"]; + [aCoder encodeObject:_sourceImage forKey:@"TMXTilesetSourceImage"]; + [aCoder encodeInteger:_atlasTilesPerRow forKey:@"TMXTilesetTilesPerRow"]; + [aCoder encodeInteger:_atlasTilesPerCol forKey:@"TMXTilesetTilesPerCol"]; + [aCoder encodeObject:_atlasTexture forKey:@"TMXTilesetAtlasTexture"]; + [aCoder encodeObject:_textureCache forKey:@"TMXTilesetTextureCache"]; +} + +-(instancetype)initWithCoder:(NSCoder *)aDecoder +{ + if(self = [super init]) + { + _name = [aDecoder decodeObjectForKey:@"TMXTilesetName"]; + _firstGid = [aDecoder decodeIntForKey:@"TMXTilesetFirstGid"]; +#if TARGET_OSX + NSPoint p = [aDecoder decodePointForKey:@"TMXTilesetTileSize"]; + _tileSize = CGSizeMake(p.x, p.y); + p = [aDecoder decodePointForKey:@"TMXTilesetUnitTileSize"]; + _unitTileSize = CGSizeMake(p.x, p.y); + p = [aDecoder decodePointForKey:@"TMXTilesetImageSize"]; + _imageSize = CGSizeMake(p.x, p.y); +#else + _tileSize = [aDecoder decodeCGSizeForKey:@"TMXTilesetTileSize"]; + _unitTileSize = [aDecoder decodeCGSizeForKey:@"TMXTilesetUnitTileSize"]; + _imageSize = [aDecoder decodeCGSizeForKey:@"TMXTilesetImageSize"]; +#endif + _spacing = [aDecoder decodeIntForKey:@"TMXTilesetSpacing"]; + _margin = [aDecoder decodeIntForKey:@"TMXTilesetMargin"]; + _sourceImage = [aDecoder decodeObjectForKey:@"TMXTilesetSourceImage"]; + _atlasTilesPerRow = [aDecoder decodeIntForKey:@"TMXTilesetTilesPerRow"]; + _atlasTilesPerCol = [aDecoder decodeIntForKey:@"TMXTilesetTilesPerCol"]; + _atlasTexture = [aDecoder decodeObjectForKey:@"TMXTilesetAtlasTexture"]; + _textureCache = [aDecoder decodeObjectForKey:@"TMXTilesetTextureCache"]; + } + return self; +} + +@end + + +@implementation JSTileMap + + ++ (JSTileMap*)mapNamed:(NSString*)mapName +{ + // zOrder offset. Make this bigger if you want more space between layers. + // higher numbers act further away. + return [JSTileMap mapNamed:mapName withBaseZPosition:0.0f andZOrderModifier:-20.0f]; +} + + ++ (JSTileMap*)mapNamed:(NSString*)mapName withBaseZPosition:(CGFloat)baseZPosition andZOrderModifier:(CGFloat)zOrderModifier +{ + // create the map + JSTileMap* map = [[JSTileMap alloc] init]; + + // get the TMX map filename + NSString* name = mapName; + NSString* extension = nil; + + // split the extension off if there is one passed + if ([mapName rangeOfString:@"."].location != NSNotFound) + { + name = [mapName stringByDeletingPathExtension]; + extension = [mapName pathExtension]; + } + + // load the TMX map from disk + NSString* path = [[NSBundle mainBundle] pathForResource:name ofType:extension]; + NSData* mapData = [NSData dataWithContentsOfFile:path]; + + // set the filename + map.filename = path; + + // parse the map + NSXMLParser* parser = [[NSXMLParser alloc] initWithData:mapData]; + parser.delegate = map; + parser.shouldProcessNamespaces = NO; + parser.shouldReportNamespacePrefixes = NO; + parser.shouldResolveExternalEntities = NO; + BOOL parsed = [parser parse]; + if (!parsed) + { + NSLog(@"Error parsing map! \n%@", [parser parserError]); + return nil; + } + + // set zPosition range + if (baseZPosition < (baseZPosition + (zOrderModifier * (map.zOrderCount + 1)))) + { + map->_minZPositioning = baseZPosition; + map->_maxZPositioning = baseZPosition + (zOrderModifier * (map.zOrderCount + 1)); + } + else + { + map->_maxZPositioning = baseZPosition; + map->_minZPositioning = baseZPosition + (zOrderModifier * (map.zOrderCount + 1)); + } + + // now actually using the data begins. + + // add layers + for( TMXLayerInfo *layerInfo in map.layers ) + { + if( layerInfo.visible ) + { + TMXLayer *child = [TMXLayer layerWithTilesetInfo:map.tilesets layerInfo:layerInfo mapInfo:map]; + child.zPosition = baseZPosition + ((map.zOrderCount - layerInfo.zOrderCount) * zOrderModifier); +#ifdef DEBUG + NSLog(@"Layer %@ has zPosition %f", layerInfo.name, child.zPosition); +#endif + [map addChild:child]; + } + } + + // add tile objects + for (TMXObjectGroup* objectGroup in map.objectGroups) + { +#ifdef DEBUG + NSLog(@"Object Group %@ has zPosition %f", objectGroup.groupName, (baseZPosition + (map.zOrderCount - objectGroup.zOrderCount) * zOrderModifier)); +#endif + + for (NSDictionary* obj in objectGroup.objects) + { + NSString* num = obj[@"gid"]; + if (num && [num intValue]) + { + TMXTilesetInfo* tileset = [map tilesetInfoForGid:[num intValue]]; + if (tileset) // add a tile object if it is apropriate. + { + CGFloat x = [obj[@"x"] floatValue]; + CGFloat y = [obj[@"y"] floatValue]; + CGPoint pt; + + if (map.orientation == OrientationStyle_Isometric) + { +//#warning these appear to be incorrect for iso maps when used for tile objects! Unsure why the math is different between objects and regular tiles. + CGPoint coords = [map screenCoordToPosition:CGPointMake(x, y)]; + pt = CGPointMake((map.tileSize.width / 2.0) * (map.tileSize.width + coords.x - coords.y - 1), + (map.tileSize.height / 2.0) * (((map.tileSize.height * 2) - coords.x - coords.y) - 2)); + +// NOTE: +// iso zPositioning may not work as expected for maps with irregular tile sizes. For larger tiles (i.e. a box in front of some floor +// tiles) We would need each layer to have their tiles ordered lower at the bottom coords and higher at the top coords WITHIN THE LAYER, in +// addition to the layers being offset as described below. this could potentially be a lot larger than 20 as a default and may take some +// thinking to fix. + } + else + { + pt = CGPointMake(x + (map.tileSize.width / 2.0), y + (map.tileSize.height / 2.0)); + } + SKTexture* texture = [tileset textureForGid:[num intValue] - tileset.firstGid + 1]; + SKSpriteNode* sprite = [SKSpriteNode spriteNodeWithTexture:texture]; + sprite.position = pt; + sprite.zPosition = baseZPosition + ((map.zOrderCount - objectGroup.zOrderCount) * zOrderModifier); + sprite.name = obj[@"name"]; + [map addChild:sprite]; + +//#warning This needs to be optimized into tilemap layers like our regular layers above for performance reasons. + // this could be problematic... what if a single object group had a bunch of tiles from different tilemaps? Would this cause zOrder problems if we're adding them all to tilemap layers? + } + } + } + } + + // add image layers + for (TMXImageLayer* imageLayer in map.imageLayers) + { + SKSpriteNode* image = [SKSpriteNode spriteNodeWithImageNamed:imageLayer.imageSource]; + image.position = CGPointMake(image.size.width / 2.0, image.size.height / 2.0); + image.zPosition = baseZPosition + ((map.zOrderCount - imageLayer.zOrderCount) * zOrderModifier); + [map addChild:image]; +#ifdef DEBUG + NSLog(@"IMAGE Layer %@ has zPosition %f", imageLayer.name, image.zPosition); +#endif + +//#warning the positioning is off here, seems to be bottom-left instead of top-left. Might be off on the rest of the sprites too...? + } + + return map; +} + + +- (CGPoint)screenCoordToPosition:(CGPoint)screenCoord +{ + CGPoint retVal; + retVal.x = screenCoord.x / self.tileSize.width; + retVal.y = screenCoord.y / self.tileSize.height; + + return retVal; +} + + +-(TMXTilesetInfo*)tilesetInfoForGid:(int)gID +{ + if (!gID) + return nil; + + for (TMXTilesetInfo* tileset in self.tilesets) + { + // check to see if the gID is in the info's atlas gID range. If not, skip this one and go to the next. + int lastPossibleGid = tileset.firstGid + (tileset.atlasTilesPerRow * tileset.atlasTilesPerCol) - 1; + if (gID < tileset.firstGid || gID > lastPossibleGid) + continue; + + return tileset; + } + + return nil; // should never get here? +} + + +-(NSDictionary*)propertiesForGid:(int)gID +{ + return self.tileProperties[@(gID)]; +} + + +-(TMXLayer*)layerNamed:(NSString*)name +{ + for(TMXLayerInfo* layerInfo in self.layers) + { + if ([name isEqualToString:layerInfo.name]) + return layerInfo.layer; + } + return nil; +} + +-(TMXObjectGroup*)groupNamed:(NSString*)name +{ + for(TMXObjectGroup* group in self.objectGroups) + { + if ([name isEqualToString:group.groupName]) + return group; + } + return nil; +} + +- (id)init +{ + self = [super init]; + if (self) + { + currentFirstGID = 0; + currentString = [NSMutableString string]; + storingCharacters = NO; + layerAttributes = TMXLayerAttributeNone; + + self.zOrderCount = 1; + self.parentElement = TMXPropertyNone; + self.tilesets = [NSMutableArray array]; + self.tileProperties = [NSMutableDictionary dictionary]; + self.properties = [NSMutableDictionary dictionary]; + self.layers = [NSMutableArray array]; + self.imageLayers = [NSMutableArray array]; + self.objectGroups = [NSMutableArray array]; + self.resources = nil; // possible future resources path + } + return self; +} + +-(void)encodeWithCoder:(NSCoder *)aCoder +{ + [super encodeWithCoder:aCoder]; + +#if TARGET_OSX + NSPoint p = {.x = _mapSize.width, .y = _mapSize.height}; + [aCoder encodePoint:p forKey:@"JSTileMapMapSize"]; + p.x = _tileSize.width; p.y = _tileSize.height; + [aCoder encodePoint:p forKey:@"JSTileMapTileSize"]; +#else + [aCoder encodeCGSize:_mapSize forKey:@"JSTileMapMapSize"]; + [aCoder encodeCGSize:_tileSize forKey:@"JSTileMapTileSize"]; +#endif + [aCoder encodeInt:_parentElement forKey:@"JSTileMapParentElement"]; + [aCoder encodeInteger:_parentGID forKey:@"JSTileMapParentGid"]; + [aCoder encodeInt:_orientation forKey:@"JSTileMapOrientation"]; + [aCoder encodeObject:_filename forKey:@"JSTileMapFilename"]; + [aCoder encodeObject:_resources forKey:@"JSTileMapResources"]; + [aCoder encodeObject:_tilesets forKey:@"JSTileMapTilesets"]; + [aCoder encodeObject:_tileProperties forKey:@"JSTileMapTileProperties"]; + [aCoder encodeObject:_properties forKey:@"JSTileMapProperties"]; + [aCoder encodeObject:_layers forKey:@"JSTileMapLayers"]; + [aCoder encodeObject:_imageLayers forKey:@"JSTileMapImageLayers"]; + [aCoder encodeObject:_objectGroups forKey:@"JSTileMapObjectGroups"]; + [aCoder encodeObject:_gidData forKey:@"JSTileMapGidData"]; + [aCoder encodeInteger:_zOrderCount forKey:@"JSTileMapZOrderCount"]; + + // parsing variables -- not sure they need to be coded, but just in case + [aCoder encodeObject:currentString forKey:@"JSTileMapCurrentString"]; + [aCoder encodeBool:storingCharacters forKey:@"JSTileMapStoringChars"]; + [aCoder encodeInteger:currentFirstGID forKey:@"JSTileMapCurrentFirstGid"]; + [aCoder encodeInteger:layerAttributes forKey:@"JSTileMapLayerAttributes"]; +} + +-(instancetype)initWithCoder:(NSCoder *)aDecoder +{ + if(self = [super initWithCoder:aDecoder]) + { +#if TARGET_OSX + NSPoint p = [aDecoder decodePointForKey:@"JSTileMapMapSize"]; + _mapSize = CGSizeMake(p.x, p.y); + p = [aDecoder decodePointForKey:@"JSTileMapTileSize"]; + _tileSize = CGSizeMake(p.x, p.y); +#else + _mapSize = [aDecoder decodeCGSizeForKey:@"JSTileMapMapSize"]; + _tileSize = [aDecoder decodeCGSizeForKey:@"JSTileMapTileSize"]; +#endif + _parentElement = [aDecoder decodeIntForKey:@"JSTileMapParentElement"]; + _parentGID = [aDecoder decodeIntForKey:@"JSTileMapParentGid"]; + _orientation = [aDecoder decodeIntForKey:@"JSTileMapOrientation"]; + _filename = [aDecoder decodeObjectForKey:@"JSTileMapFilename"]; + _resources = [aDecoder decodeObjectForKey:@"JSTileMapResources"]; + _tilesets = [aDecoder decodeObjectForKey:@"JSTileMapTilesets"]; + _tileProperties = [aDecoder decodeObjectForKey:@"JSTileMapTileProperties"]; + _properties = [aDecoder decodeObjectForKey:@"JSTileMapProperties"]; + _layers = [aDecoder decodeObjectForKey:@"JSTileMapLayers"]; + _objectGroups = [aDecoder decodeObjectForKey:@"JSTileMapObjectGroups"]; + _gidData = [aDecoder decodeObjectForKey:@"JSTileMapGidData"]; + _imageLayers = [aDecoder decodeObjectForKey:@"JSTileMapImageLayers"]; + _zOrderCount = [aDecoder decodeIntForKey:@"JSTileMapZOrderCount"]; + + // parsing variables -- not sure they need to be coded, but just in case + currentString = [aDecoder decodeObjectForKey:@"JSTileMapCurrentString"]; + storingCharacters = [aDecoder decodeBoolForKey:@"JSTileMapStoringChars"]; + currentFirstGID = [aDecoder decodeIntForKey:@"JSTileMapCurrentFirstGid"]; + layerAttributes = [aDecoder decodeIntForKey:@"JSTileMapLayerAttributes"]; + } + return self; +} + + +#pragma mark - debugging + + +- (void)logGIDs +{ + for (TMXLayerInfo *layerInfo in _layers) + { + [layerInfo logLayerGIDs]; + } + +} + +#pragma mark - parsing + + +// the XML parser calls here with all the elements +-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict +{ + if([elementName isEqualToString:@"map"]) + { + NSString* orientationStr = attributeDict[@"orientation"]; + if ([[orientationStr lowercaseString] isEqualToString:@"orthogonal"]) + { + self.orientation = OrientationStyle_Orthogonal; + } + else if ( [[orientationStr lowercaseString] isEqualToString:@"isometric"]) + { + self.orientation = OrientationStyle_Isometric; + } + else + { + NSLog(@"Unsupported orientation: %@", attributeDict[@"orientation"]); + [parser abortParsing]; + } + + self.mapSize = CGSizeMake([attributeDict[@"width"] intValue], [attributeDict[@"height"] intValue]); + self.tileSize = CGSizeMake([attributeDict[@"tilewidth"] intValue], [attributeDict[@"tileheight"] intValue]); + + // The parent element is now "map" + self.parentElement = TMXPropertyMap; + } + else if([elementName isEqualToString:@"tileset"]) + { + // If this has an external tileset we're done + NSString *externalTilesetFilename = attributeDict[@"source"]; + if (externalTilesetFilename) + { + NSLog(@"External tilesets unsupported!"); + [parser abortParsing]; + return; + } + + int gID; + if(currentFirstGID == 0) { + gID = [attributeDict[@"firstgid"] intValue]; + } else { + gID = currentFirstGID; + currentFirstGID = 0; + } + + TMXTilesetInfo *tileset = [[TMXTilesetInfo alloc] initWithGid:gID + attributes:attributeDict]; + [self.tilesets addObject:tileset]; + } + else if([elementName isEqualToString:@"tile"]) + { + if (!storingCharacters) + { + TMXTilesetInfo* info = [self.tilesets lastObject]; + NSMutableDictionary* dict = [NSMutableDictionary dictionaryWithCapacity:3]; + self.parentGID = info.firstGid + [attributeDict[@"id"] intValue]; + (self.tileProperties)[@(self.parentGID)] = dict; + + self.parentElement = TMXPropertyTile; + } + else + { + if (!self.gidData) + self.gidData = [NSMutableArray array]; + + // remember XML gids for the data tag in the order they come in. + [self.gidData addObject:attributeDict[@"gid"]]; + } + + } + else if([elementName isEqualToString:@"layer"]) + { + TMXLayerInfo* layer = [[TMXLayerInfo alloc] init]; + layer.name = attributeDict[@"name"]; + layer.layerGridSize = CGSizeMake([attributeDict[@"width"] intValue], [attributeDict[@"height"] intValue]); + layer.visible = ![attributeDict[@"visible"] isEqualToString:@"0"]; + layer.offset = CGPointMake([attributeDict[@"x"] intValue], [attributeDict[@"y"] intValue]); + layer.opacity = 1.0; + if( attributeDict[@"opacity"] ) + layer.opacity = [attributeDict[@"opacity"] floatValue]; + + layer.zOrderCount = self.zOrderCount; + self.zOrderCount++; + + [self.layers addObject:layer]; + + self.parentElement = TMXPropertyLayer; + + } + else if([elementName isEqualToString:@"imagelayer"]) + { + TMXImageLayer* imageLayer = [[TMXImageLayer alloc] init]; + imageLayer.name = attributeDict[@"name"]; + imageLayer.zOrderCount = self.zOrderCount; + self.zOrderCount++; + + [self.imageLayers addObject:imageLayer]; + + self.parentElement = TMXPropertyImageLayer; + } + else if([elementName isEqualToString:@"objectgroup"]) + { + TMXObjectGroup *objectGroup = [[TMXObjectGroup alloc] init]; + objectGroup.groupName = attributeDict[@"name"]; + + CGPoint positionOffset; + positionOffset.x = [attributeDict[@"x"] intValue] * self.tileSize.width; + positionOffset.y = [attributeDict[@"y"] intValue] * self.tileSize.height; + objectGroup.positionOffset = positionOffset; + + objectGroup.zOrderCount = self.zOrderCount; + self.zOrderCount++; + + [self.objectGroups addObject:objectGroup]; + + // The parent element is now "objectgroup" + self.parentElement = TMXPropertyObjectGroup; + + } + else if([elementName isEqualToString:@"image"]) + { + if (self.parentElement == TMXPropertyImageLayer) + { + TMXImageLayer* imageLayer = [self.imageLayers lastObject]; + imageLayer.imageSource = attributeDict[@"source"]; + // imageLayer.transparencyColor = attributeDict[@"trans"]; + } + else + { + TMXTilesetInfo *tileset = [self.tilesets lastObject]; + + // build full path + NSString* imageName = attributeDict[@"source"]; + NSString* path = [self.filename stringByDeletingLastPathComponent]; + if (!path) + path = self.resources; + [tileset setSourceImage:[path stringByAppendingPathComponent:imageName]]; + } + } + else if([elementName isEqualToString:@"data"]) + { + NSString *encoding = attributeDict[@"encoding"]; + NSString *compression = attributeDict[@"compression"]; + + storingCharacters = YES; + + if( [encoding isEqualToString:@"base64"] ) + { + layerAttributes |= TMXLayerAttributeBase64; + + if([compression isEqualToString:@"gzip"]) + layerAttributes |= TMXLayerAttributeGzip; + else if([compression isEqualToString:@"zlib"]) + layerAttributes |= TMXLayerAttributeZlib; + } + } + else if([elementName isEqualToString:@"object"]) + { + TMXObjectGroup *objectGroup = [self.objectGroups lastObject]; + + // The value for "type" was blank or not a valid class name + // Create an instance of TMXObjectInfo to store the object and its properties + NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:10]; + + // Parse everything automatically + NSArray *array = @[@"name", @"type", @"width", @"height", @"gid"]; + for( id key in array ) { + NSObject *obj = attributeDict[key]; + if( obj ) + dict[key] = obj; + } + + // But X and Y since they need special treatment + // X + NSString *value = attributeDict[@"x"]; + if( value ) + { + int x = [value intValue] + objectGroup.positionOffset.x; + dict[@"x"] = @(x); + } + + // Y + value = attributeDict[@"y"]; + if( value ) + { + int y = [value intValue] + objectGroup.positionOffset.y; + // Correct y position. (Tiled's origin is top-left. SpriteKit's origin is bottom-left) + y = (_mapSize.height * _tileSize.height) - y - [attributeDict[@"height"] intValue]; + dict[@"y"] = @(y); + } + + // Add the object to the objectGroup + [[objectGroup objects] addObject:dict]; + + // The parent element is now "object" + self.parentElement = TMXPropertyObject; + + } + else if([elementName isEqualToString:@"property"]) + { + if ( self.parentElement == TMXPropertyNone ) + { + NSLog( @"TMX tile map: Parent element is unsupported. Cannot add property named '%@' with value '%@'", attributeDict[@"name"], attributeDict[@"value"]); + } + else if ( self.parentElement == TMXPropertyMap ) + { + // The parent element is the map + (self.properties)[attributeDict[@"name"]] = attributeDict[@"value"]; + } + else if ( self.parentElement == TMXPropertyLayer ) + { + // The parent element is the last layer + TMXLayerInfo *layer = [self.layers lastObject]; + // Add the property to the layer + [layer properties][attributeDict[@"name"]] = attributeDict[@"value"]; + } + else if ( self.parentElement == TMXPropertyImageLayer) + { + TMXImageLayer* imageLayer = [self.imageLayers lastObject]; + [imageLayer properties][attributeDict[@"name"]] = attributeDict[@"value"]; + } + else if ( self.parentElement == TMXPropertyObjectGroup ) + { + // The parent element is the last object group + TMXObjectGroup *objectGroup = [self.objectGroups lastObject]; + [objectGroup properties][attributeDict[@"name"]] = attributeDict[@"value"]; + } + else if ( self.parentElement == TMXPropertyObject ) + { + // The parent element is the last object + TMXObjectGroup *objectGroup = [self.objectGroups lastObject]; + NSMutableDictionary *dict = [[objectGroup objects] lastObject]; + + NSString *propertyName = attributeDict[@"name"]; + NSString *propertyValue = attributeDict[@"value"]; + + dict[propertyName] = propertyValue; + } + else if ( self.parentElement == TMXPropertyTile ) + { + NSMutableDictionary* dict = (self.tileProperties)[@(self.parentGID)]; + NSString *propertyName = attributeDict[@"name"]; + NSString *propertyValue = attributeDict[@"value"]; + dict[propertyName] = propertyValue; + } + } + else if ([elementName isEqualToString:@"polygon"]) + { + // find parent object's dict and add polygon-points to it + TMXObjectGroup *objectGroup = [self.objectGroups lastObject]; + NSMutableDictionary *dict = [[objectGroup objects] lastObject]; + dict[@"polygonPoints"] = attributeDict[@"points"]; + } + else if ([elementName isEqualToString:@"polyline"]) + { + // find parent object's dict and add polyline-points to it + TMXObjectGroup *objectGroup = [self.objectGroups lastObject]; + NSMutableDictionary *dict = [[objectGroup objects] lastObject]; + dict[@"polylinePoints"] = attributeDict[@"points"]; + } + else if ([elementName isEqualToString:@"ellipse"]) + { + // find parent object's dict and add ellipse to it + TMXObjectGroup *objectGroup = [self.objectGroups lastObject]; + NSMutableDictionary *dict = [[objectGroup objects] lastObject]; + [dict setObject:[NSNumber numberWithBool:YES] forKey:@"ellipse"]; + } +} + + +- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName +{ + unsigned int len = 0; + + if([elementName isEqualToString:@"data"]) + { + storingCharacters = NO; + TMXLayerInfo *layer = [self.layers lastObject]; + + if (layerAttributes & TMXLayerAttributeBase64) + { + // clean whitespace from string + currentString = [NSMutableString stringWithString:[currentString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]]; + + NSData* buffer = [[NSData alloc] initWithBase64EncodedString:currentString options:0]; + if( ! buffer.length ) { + NSLog(@"TiledMap: decode data error"); + [parser abortParsing]; + return; + } + + len = (unsigned int)buffer.length; + + if( layerAttributes & (TMXLayerAttributeGzip | TMXLayerAttributeZlib) ) + { + unsigned char *deflated; + CGSize s = [layer layerGridSize]; + int sizeHint = s.width * s.height * sizeof(uint32_t); + + int inflatedLen = InflateMemoryWithHint((unsigned char*)[buffer bytes], len, &deflated, sizeHint); + NSAssert( inflatedLen == sizeHint, @"CCTMXXMLParser: Hint failed!"); + + if( ! deflated ) + { + NSLog(@"TiledMap: inflate data error"); + [parser abortParsing]; + return; + } + + layer.tiles = (int*) deflated; + } + else + { + char* tileArray = malloc(buffer.length); + memmove(tileArray, buffer.bytes, buffer.length); + layer.tiles = (int*) tileArray; + } + } + else + { + // convert to binary gid data + if (self.gidData.count) + { + layer.tiles = malloc(self.gidData.count * sizeof(unsigned int)); + int x = 0; + for (NSString* gid in self.gidData) + { + layer.tiles[x] = (int)[gid longLongValue]; + x++; + } + } + } + + [self.gidData removeAllObjects]; + currentString = [NSMutableString string]; + + } + else if ([elementName isEqualToString:@"map"]) + { + // The map element has ended + self.parentElement = TMXPropertyNone; + } + else if ([elementName isEqualToString:@"layer"]) + { + // The layer element has ended + self.parentElement = TMXPropertyNone; + } + else if ([elementName isEqualToString:@"objectgroup"]) + { + // The objectgroup element has ended + self.parentElement = TMXPropertyNone; + } + else if ([elementName isEqualToString:@"object"]) + { + // The object element has ended + self.parentElement = TMXPropertyNone; + } +} + + +- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string +{ + if (storingCharacters) + [currentString appendString:string]; +} + + +-(void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError +{ + NSLog(@"Error on XML Parse: %@", [parseError localizedDescription]); +} + + +@end \ No newline at end of file diff --git a/Rect/Rect/LFCGzipUtility.h b/Rect/Rect/LFCGzipUtility.h new file mode 100755 index 0000000..673c342 --- /dev/null +++ b/Rect/Rect/LFCGzipUtility.h @@ -0,0 +1,37 @@ +/** + @file LFCGzipUtility.h + @author Clint Harris (www.clintharris.net) + + Modified (added inflatefunction) By Jeremy Stone + + Note: The code in this file has been commented so as to be compatible with + Doxygen, a tool for automatically generating HTML-based documentation from + source code. See http://www.doxygen.org for more info. + */ + +#import +#import "zlib.h" + +@interface LFCGzipUtility : NSObject +{ + +} + +/*************************************************************************** + Uses zlib to compress the given data. Note that gzip headers will be added so + that the data can be easily decompressed using a tool like WinZip, gunzip, etc. + + Note: Special thanks to Robbie Hanson of Deusty Designs for sharing sample code + showing how deflateInit2() can be used to make zlib generate a compressed file + with gzip headers: + http://deusty.blogspot.com/2007/07/gzip-compressiondecompression.html + + @param pUncompressedData memory buffer of bytes to compress + @return Compressed data as an NSData object + */ ++(NSData*) gzipData: (NSData*)pUncompressedData; + +@end + +// taken from cocos2d and slightly modified +int InflateMemoryWithHint(unsigned char *in, unsigned int inLength, unsigned char **out, unsigned int outLengthHint ); diff --git a/Rect/Rect/LFCGzipUtility.m b/Rect/Rect/LFCGzipUtility.m new file mode 100755 index 0000000..99da94c --- /dev/null +++ b/Rect/Rect/LFCGzipUtility.m @@ -0,0 +1,268 @@ +/** + @file LFCGzipUtility.m + @author Clint Harris (www.clintharris.net) + + Note: The code in this file has been commented so as to be compatible with + Doxygen, a tool for automatically generating HTML-based documentation from + source code. See http://www.doxygen.org for more info. + */ + +#import "LFCGzipUtility.h" + +@implementation LFCGzipUtility + +/******************************************************************************* + See header for documentation. + */ ++(NSData*) gzipData: (NSData*)pUncompressedData +{ + /* + Special thanks to Robbie Hanson of Deusty Designs for sharing sample code + showing how deflateInit2() can be used to make zlib generate a compressed + file with gzip headers: + http://deusty.blogspot.com/2007/07/gzip-compressiondecompression.html + */ + + if (!pUncompressedData || [pUncompressedData length] == 0) + { + NSLog(@"%s: Error: Can't compress an empty or null NSData object.", __func__); + return nil; + } + + /* Before we can begin compressing (aka "deflating") data using the zlib + functions, we must initialize zlib. Normally this is done by calling the + deflateInit() function; in this case, however, we'll use deflateInit2() so + that the compressed data will have gzip headers. This will make it easy to + decompress the data later using a tool like gunzip, WinZip, etc. + + deflateInit2() accepts many parameters, the first of which is a C struct of + type "z_stream" defined in zlib.h. The properties of this struct are used to + control how the compression algorithms work. z_stream is also used to + maintain pointers to the "input" and "output" byte buffers (next_in/out) as + well as information about how many bytes have been processed, how many are + left to process, etc. */ + z_stream zlibStreamStruct; + zlibStreamStruct.zalloc = Z_NULL; // Set zalloc, zfree, and opaque to Z_NULL so + zlibStreamStruct.zfree = Z_NULL; // that when we call deflateInit2 they will be + zlibStreamStruct.opaque = Z_NULL; // updated to use default allocation functions. + zlibStreamStruct.total_out = 0; // Total number of output bytes produced so far + zlibStreamStruct.next_in = (Bytef*)[pUncompressedData bytes]; // Pointer to input bytes + zlibStreamStruct.avail_in = (unsigned int)[pUncompressedData length]; // Number of input bytes left to process + + /* Initialize the zlib deflation (i.e. compression) internals with deflateInit2(). + The parameters are as follows: + + z_streamp strm - Pointer to a zstream struct + int level - Compression level. Must be Z_DEFAULT_COMPRESSION, or between + 0 and 9: 1 gives best speed, 9 gives best compression, 0 gives + no compression. + int method - Compression method. Only method supported is "Z_DEFLATED". + int windowBits - Base two logarithm of the maximum window size (the size of + the history buffer). It should be in the range 8..15. Add + 16 to windowBits to write a simple gzip header and trailer + around the compressed data instead of a zlib wrapper. The + gzip header will have no file name, no extra data, no comment, + no modification time (set to zero), no header crc, and the + operating system will be set to 255 (unknown). + int memLevel - Amount of memory allocated for internal compression state. + 1 uses minimum memory but is slow and reduces compression + ratio; 9 uses maximum memory for optimal speed. Default value + is 8. + int strategy - Used to tune the compression algorithm. Use the value + Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data + produced by a filter (or predictor), or Z_HUFFMAN_ONLY to + force Huffman encoding only (no string match) */ + int initError = deflateInit2(&zlibStreamStruct, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY); + if (initError != Z_OK) + { + NSString *errorMsg = nil; + switch (initError) + { + case Z_STREAM_ERROR: + errorMsg = @"Invalid parameter passed in to function."; + break; + case Z_MEM_ERROR: + errorMsg = @"Insufficient memory."; + break; + case Z_VERSION_ERROR: + errorMsg = @"The version of zlib.h and the version of the library linked do not match."; + break; + default: + errorMsg = @"Unknown error code."; + break; + } + NSLog(@"%s: deflateInit2() Error: \"%@\" Message: \"%s\"", __func__, errorMsg, zlibStreamStruct.msg); + // [errorMsg release]; + return nil; + } + + // Create output memory buffer for compressed data. The zlib documentation states that + // destination buffer size must be at least 0.1% larger than avail_in plus 12 bytes. + NSMutableData *compressedData = [NSMutableData dataWithLength:[pUncompressedData length] * 1.01 + 12]; + + int deflateStatus; + do + { + // Store location where next byte should be put in next_out + zlibStreamStruct.next_out = [compressedData mutableBytes] + zlibStreamStruct.total_out; + + // Calculate the amount of remaining free space in the output buffer + // by subtracting the number of bytes that have been written so far + // from the buffer's total capacity + zlibStreamStruct.avail_out = (unsigned int)([compressedData length] - zlibStreamStruct.total_out); + + /* deflate() compresses as much data as possible, and stops/returns when + the input buffer becomes empty or the output buffer becomes full. If + deflate() returns Z_OK, it means that there are more bytes left to + compress in the input buffer but the output buffer is full; the output + buffer should be expanded and deflate should be called again (i.e., the + loop should continue to rune). If deflate() returns Z_STREAM_END, the + end of the input stream was reached (i.e.g, all of the data has been + compressed) and the loop should stop. */ + deflateStatus = deflate(&zlibStreamStruct, Z_FINISH); + + } while ( deflateStatus == Z_OK ); + + // Check for zlib error and convert code to usable error message if appropriate + if (deflateStatus != Z_STREAM_END) + { + NSString *errorMsg = nil; + switch (deflateStatus) + { + case Z_ERRNO: + errorMsg = @"Error occured while reading file."; + break; + case Z_STREAM_ERROR: + errorMsg = @"The stream state was inconsistent (e.g., next_in or next_out was NULL)."; + break; + case Z_DATA_ERROR: + errorMsg = @"The deflate data was invalid or incomplete."; + break; + case Z_MEM_ERROR: + errorMsg = @"Memory could not be allocated for processing."; + break; + case Z_BUF_ERROR: + errorMsg = @"Ran out of output buffer for writing compressed bytes."; + break; + case Z_VERSION_ERROR: + errorMsg = @"The version of zlib.h and the version of the library linked do not match."; + break; + default: + errorMsg = @"Unknown error code."; + break; + } + NSLog(@"%s: zlib error while attempting compression: \"%@\" Message: \"%s\"", __func__, errorMsg, zlibStreamStruct.msg); + // [errorMsg release]; + + // Free data structures that were dynamically created for the stream. + deflateEnd(&zlibStreamStruct); + + return nil; + } + // Free data structures that were dynamically created for the stream. + deflateEnd(&zlibStreamStruct); + [compressedData setLength: zlibStreamStruct.total_out]; + NSLog(@"%s: Compressed file from %d KB to %d KB", __func__, (int)[pUncompressedData length]/1024, (int)[compressedData length]/1024); + + return compressedData; +} + +@end + + + +// from cocos2d, un-zipping code: + +#define BUFFER_INC_FACTOR (2) + +static int inflateMemoryWithHintX(unsigned char *in, unsigned int inLength, unsigned char **out, unsigned int *outLength, unsigned int outlengthHint ) +{ + /* ret value */ + int err = Z_OK; + + int bufferSize = outlengthHint; + *out = (unsigned char*) malloc(bufferSize); + + z_stream d_stream; /* decompression stream */ + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = in; + d_stream.avail_in = inLength; + d_stream.next_out = *out; + d_stream.avail_out = bufferSize; + + /* window size to hold 256k */ + if( (err = inflateInit2(&d_stream, 15 + 32)) != Z_OK ) + return err; + + for (;;) { + err = inflate(&d_stream, Z_NO_FLUSH); + + if (err == Z_STREAM_END) + break; + + switch (err) { + case Z_NEED_DICT: + err = Z_DATA_ERROR; + case Z_DATA_ERROR: + case Z_MEM_ERROR: + inflateEnd(&d_stream); + return err; + } + + // not enough memory ? + if (err != Z_STREAM_END) { + + unsigned char *tmp = realloc(*out, bufferSize * BUFFER_INC_FACTOR); + + /* not enough memory, ouch */ + if (! tmp ) { + NSLog(@"ZipUtils: realloc failed"); + inflateEnd(&d_stream); + return Z_MEM_ERROR; + } + /* only assign to *out if tmp is valid. it's not guaranteed that realloc will reuse the memory */ + *out = tmp; + + d_stream.next_out = *out + bufferSize; + d_stream.avail_out = bufferSize; + bufferSize *= BUFFER_INC_FACTOR; + } + } + + + *outLength = bufferSize - d_stream.avail_out; + err = inflateEnd(&d_stream); + return err; +} + +int InflateMemoryWithHint(unsigned char *in, unsigned int inLength, unsigned char **out, unsigned int outLengthHint ) +{ + unsigned int outLength = 0; + int err = inflateMemoryWithHintX((unsigned char*)in, inLength, out, &outLength, outLengthHint ); + + if (err != Z_OK || *out == NULL) { + if (err == Z_MEM_ERROR) + NSLog(@"ZipUtils: Out of memory while decompressing map data!"); + + else if (err == Z_VERSION_ERROR) + NSLog(@"ZipUtils: Incompatible zlib version!"); + + else if (err == Z_DATA_ERROR) + NSLog(@"ZipUtils: Incorrect zlib compressed data!"); + + else + NSLog(@"ZipUtils: Unknown error while decompressing map data!"); + + free(*out); + *out = NULL; + outLength = 0; + } + + return outLength; +} + + + diff --git a/Rect/Rect/Rect-Bridging-Header.h b/Rect/Rect/Rect-Bridging-Header.h new file mode 100644 index 0000000..c029463 --- /dev/null +++ b/Rect/Rect/Rect-Bridging-Header.h @@ -0,0 +1,7 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + + +#import "JSTileMap.h" +#import "LFCGzipUtility.h" \ No newline at end of file diff --git a/Rect/Rect/gameEntities.swift b/Rect/Rect/gameEntities.swift new file mode 100644 index 0000000..33588e7 --- /dev/null +++ b/Rect/Rect/gameEntities.swift @@ -0,0 +1,252 @@ +// +// Player.swift +// Rect +// +// Created by Peter Zhu on 15/10/31. +// Copyright © 2015年 Peter Zhu. All rights reserved. +// + +import UIKit +import SpriteKit + +class Player: SKSpriteNode{ + var groundCount = 0 + var bodySize = 1 // 1 is largest, 4 smallest + + init() { + super.init(texture: SKTexture(imageNamed: "player1"), color: UIColor(red: 0, green: 0, blue: 0, alpha: 0), size: CGSizeMake(20, 32)) + self.name = "player" + configPhysicsBody() + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func shrink() -> Bool { + if bodySize < 4 { + bodySize++ + self.texture = SKTexture(imageNamed: ("player" + String(bodySize))) + self.size = (self.texture?.size())! + configPhysicsBody() + return true + } else { + return false + } + } + + func enlarge() -> Bool { + if bodySize > 1 { + bodySize-- + self.texture = SKTexture(imageNamed: ("player" + String(bodySize))) + self.size = (self.texture?.size())! + configPhysicsBody() + return true + } else { + return false + } + } + + func refill() { + bodySize = 1 + self.texture = SKTexture(imageNamed: "player" + String(bodySize)) + self.size = (self.texture?.size())! + configPhysicsBody() + } + + func configPhysicsBody() { + self.physicsBody = SKPhysicsBody(rectangleOfSize: self.size) + self.physicsBody?.affectedByGravity = true + self.physicsBody?.allowsRotation = false + self.physicsBody?.usesPreciseCollisionDetection = true + self.physicsBody?.friction = 0 + self.physicsBody?.restitution = 0 + //self.physicsBody?.mass = CGFloat(bodySize) + //print(self.physicsBody?.area) + self.physicsBody?.dynamic = true + self.physicsBody?.categoryBitMask = BodyType.player.rawValue + self.physicsBody?.contactTestBitMask = BodyType.all.rawValue + self.physicsBody?.collisionBitMask = BodyType.all.rawValue + } +} + +class bodyPart: SKSpriteNode { + + var collidedWithGround = false + var usedOnEnemy = false + + init() { + super.init(texture: SKTexture(imageNamed: "bodyPart"), color: UIColor(red: 0, green: 0, blue: 255, alpha: 0), size: CGSizeMake(16, 7)) + + self.name = "bodyPart" + self.physicsBody = SKPhysicsBody(rectangleOfSize: self.size) + self.physicsBody?.affectedByGravity = false + self.physicsBody?.allowsRotation = false + self.physicsBody?.dynamic = true + self.physicsBody?.usesPreciseCollisionDetection = true + self.physicsBody?.friction = 0 + self.physicsBody?.restitution = 0 + self.physicsBody?.categoryBitMask = BodyType.bodyPart.rawValue + self.physicsBody?.contactTestBitMask = BodyType.all.rawValue + self.physicsBody?.collisionBitMask = BodyType.all.rawValue + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} + +class lift: SKSpriteNode { + + var matchButtonNum = 0 + var finalPosition = 0 + var direction = "up" + var timerForCheckingEnemy = NSTimer() + + init(positionPt: CGPoint, size: CGSize) { + super.init(texture: nil, color: UIColor(red: 0, green: 0, blue: 0, alpha: 1), size: size) + + self.color = UIColor.blackColor() + self.position = positionPt + self.physicsBody = SKPhysicsBody(rectangleOfSize: self.size) + self.physicsBody?.affectedByGravity = false + self.physicsBody!.dynamic = false + self.physicsBody?.usesPreciseCollisionDetection = true + self.physicsBody?.friction = 0 + self.physicsBody?.restitution = 0 + self.physicsBody?.categoryBitMask = BodyType.ground.rawValue + self.physicsBody?.contactTestBitMask = BodyType.all.rawValue + self.physicsBody?.collisionBitMask = BodyType.all.rawValue + } + + func checkConditioningLift() { + if (matchButtonNum == -1) { + timerForCheckingEnemy = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "checkEnemyClear", userInfo: nil, repeats: true) + } + } + + func checkEnemyClear() { + print("timer fire") + if (self.parent?.childNodeWithName("enemy") == nil) { + self.moveLift() + timerForCheckingEnemy.invalidate() + } + } + + func moveLift() { + if (direction == "up") || (direction == "down") { + //nodeY + nodeHeight / 2 + self.runAction(SKAction.moveToY((self.parent?.calculateAccumulatedFrame().height)! - (CGFloat(self.finalPosition) + self.size.height - self.size.height / 2), duration: 1)) + } else if (direction == "left") || (direction == "right") { + self.runAction(SKAction.moveToX(CGFloat(self.finalPosition) + self.size.width / 2, duration: 1)) + } + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + +} + +class button: SKSpriteNode { + + var matchLiftNum = 0 + + init(positionPt: CGPoint, size: CGSize) { + super.init(texture: nil, color: UIColor(red: 255, green: 255, blue: 255, alpha: 0), size: size) + + self.position = positionPt + self.physicsBody = SKPhysicsBody(rectangleOfSize: self.size) + self.physicsBody?.affectedByGravity = false + self.physicsBody!.dynamic = false + self.physicsBody?.pinned = true + self.physicsBody?.usesPreciseCollisionDetection = true + self.physicsBody?.friction = 0 + self.physicsBody?.restitution = 0 + self.physicsBody?.categoryBitMask = BodyType.button.rawValue + self.physicsBody?.contactTestBitMask = BodyType.all.rawValue + self.physicsBody?.collisionBitMask = BodyType.all.rawValue + + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + +} + +class enemy: SKSpriteNode { + + var enemySize = 1 + + init(positionPt: CGPoint, range: CGSize) { + super.init(texture: SKTexture(imageNamed: "enemy1"), color: UIColor(red: 255, green: 255, blue: 255, alpha: 0), size: CGSizeMake(32, 32)) + + self.name = "enemy" + self.position = positionPt + self.physicsBody = SKPhysicsBody(circleOfRadius: 16) + self.physicsBody?.affectedByGravity = true + self.physicsBody!.dynamic = true + self.physicsBody?.usesPreciseCollisionDetection = true + self.physicsBody?.friction = 0 + self.physicsBody?.restitution = 0 + self.physicsBody?.categoryBitMask = BodyType.enemy.rawValue + self.physicsBody?.contactTestBitMask = BodyType.all.rawValue + self.physicsBody?.collisionBitMask = BodyType.all.rawValue + + self.runAction(SKAction.repeatActionForever(SKAction.sequence([ + SKAction.moveToX(range.width + self.position.x, duration: 2), + SKAction.moveToX(self.position.x, duration: 2) + ]))) + } + + func hitted() { + if enemySize < 2 { + enemySize++ + self.texture = SKTexture(imageNamed: ("enemy" + String(enemySize))) + self.size = (self.texture?.size())! + self.name = "enemy" + + self.physicsBody = SKPhysicsBody(circleOfRadius: self.size.width / 2) + self.physicsBody?.affectedByGravity = true + self.physicsBody!.dynamic = true + self.physicsBody?.usesPreciseCollisionDetection = true + self.physicsBody?.friction = 0 + self.physicsBody?.restitution = 0 + self.physicsBody?.categoryBitMask = BodyType.enemy.rawValue + self.physicsBody?.contactTestBitMask = BodyType.all.rawValue + self.physicsBody?.collisionBitMask = BodyType.all.rawValue + } else { + self.removeFromParent() + } + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} + +class refillBody: SKSpriteNode { + init(positionPt: CGPoint, size: CGSize) { + super.init(texture: SKTexture(imageNamed: "refillBody"), color: UIColor(red: 58, green: 122, blue: 79, alpha: 1), size: size) + + //self.colorBlendFactor = 1 + self.color = UIColor(red: 58, green: 122, blue: 79, alpha: 1) + self.name = "refillBody" + self.position = positionPt + self.physicsBody = SKPhysicsBody(rectangleOfSize: self.size) + self.physicsBody?.affectedByGravity = false + self.physicsBody!.dynamic = false + self.physicsBody?.pinned = true + self.physicsBody?.usesPreciseCollisionDetection = true + self.physicsBody?.friction = 0 + self.physicsBody?.restitution = 0 + self.physicsBody?.categoryBitMask = BodyType.refillBody.rawValue + self.physicsBody?.contactTestBitMask = BodyType.all.rawValue + self.physicsBody?.collisionBitMask = BodyType.all.rawValue + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} \ No newline at end of file diff --git a/Rect/Rect/gate.png b/Rect/Rect/gate.png new file mode 100644 index 0000000..03adb2e Binary files /dev/null and b/Rect/Rect/gate.png differ diff --git a/Rect/Rect/level1.tmx b/Rect/Rect/level1.tmx new file mode 100644 index 0000000..5f431ce --- /dev/null +++ b/Rect/Rect/level1.tmx @@ -0,0 +1,22 @@ + + + + + + + + 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 + + + + + + + + + + + + + + diff --git a/Rect/Rect/level1_sprites.png b/Rect/Rect/level1_sprites.png new file mode 100644 index 0000000..070fe26 Binary files /dev/null and b/Rect/Rect/level1_sprites.png differ diff --git a/Rect/Rect/level2.tmx b/Rect/Rect/level2.tmx new file mode 100644 index 0000000..481db6e --- /dev/null +++ b/Rect/Rect/level2.tmx @@ -0,0 +1,51 @@ + + + + + + + + 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Rect/Rect/level2_sprites.png b/Rect/Rect/level2_sprites.png new file mode 100644 index 0000000..bd83e94 Binary files /dev/null and b/Rect/Rect/level2_sprites.png differ diff --git a/Rect/Rect/level3.tmx b/Rect/Rect/level3.tmx new file mode 100644 index 0000000..9cdec4e --- /dev/null +++ b/Rect/Rect/level3.tmx @@ -0,0 +1,49 @@ + + + + + + + + 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Rect/Rect/level3_sprites.png b/Rect/Rect/level3_sprites.png new file mode 100644 index 0000000..344cfbf Binary files /dev/null and b/Rect/Rect/level3_sprites.png differ diff --git a/Rect/Rect/level4.tmx b/Rect/Rect/level4.tmx new file mode 100644 index 0000000..f6410c9 --- /dev/null +++ b/Rect/Rect/level4.tmx @@ -0,0 +1,28 @@ + + + + + + + + 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 + + + + + + + + + + + + + + + + + + + + diff --git a/Rect/Rect/level4_sprites.png b/Rect/Rect/level4_sprites.png new file mode 100644 index 0000000..7f674e2 Binary files /dev/null and b/Rect/Rect/level4_sprites.png differ diff --git a/Rect/Rect/level5.tmx b/Rect/Rect/level5.tmx new file mode 100644 index 0000000..a4e863f --- /dev/null +++ b/Rect/Rect/level5.tmx @@ -0,0 +1,87 @@ + + + + + + + + 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Rect/Rect/level5_sprites.png b/Rect/Rect/level5_sprites.png new file mode 100644 index 0000000..3a0c1c1 Binary files /dev/null and b/Rect/Rect/level5_sprites.png differ diff --git a/Rect/Rect/level6.tmx b/Rect/Rect/level6.tmx new file mode 100644 index 0000000..f4609b3 --- /dev/null +++ b/Rect/Rect/level6.tmx @@ -0,0 +1,120 @@ + + + + + + + + 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Rect/Rect/level6_sprites.png b/Rect/Rect/level6_sprites.png new file mode 100644 index 0000000..325d854 Binary files /dev/null and b/Rect/Rect/level6_sprites.png differ diff --git a/Rect/Rect/lift.png b/Rect/Rect/lift.png new file mode 100644 index 0000000..2f22deb Binary files /dev/null and b/Rect/Rect/lift.png differ diff --git a/Rect/RectTests/Info.plist b/Rect/RectTests/Info.plist new file mode 100644 index 0000000..ba72822 --- /dev/null +++ b/Rect/RectTests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/Rect/RectTests/RectTests.swift b/Rect/RectTests/RectTests.swift new file mode 100644 index 0000000..0c39824 --- /dev/null +++ b/Rect/RectTests/RectTests.swift @@ -0,0 +1,36 @@ +// +// RectTests.swift +// RectTests +// +// Created by Peter Zhu on 15/10/31. +// Copyright © 2015年 Peter Zhu. All rights reserved. +// + +import XCTest +@testable import Rect + +class RectTests: XCTestCase { + + override func setUp() { + super.setUp() + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testExample() { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testPerformanceExample() { + // This is an example of a performance test case. + self.measureBlock { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/Rect/RectUITests/Info.plist b/Rect/RectUITests/Info.plist new file mode 100644 index 0000000..ba72822 --- /dev/null +++ b/Rect/RectUITests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/Rect/RectUITests/RectUITests.swift b/Rect/RectUITests/RectUITests.swift new file mode 100644 index 0000000..23e6278 --- /dev/null +++ b/Rect/RectUITests/RectUITests.swift @@ -0,0 +1,36 @@ +// +// RectUITests.swift +// RectUITests +// +// Created by Peter Zhu on 15/10/31. +// Copyright © 2015年 Peter Zhu. All rights reserved. +// + +import XCTest + +class RectUITests: XCTestCase { + + override func setUp() { + super.setUp() + + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. + XCUIApplication().launch() + + // 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. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + super.tearDown() + } + + func testExample() { + // Use recording to get started writing UI tests. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + +}