commit 7731be4ccb26495599aa2548ed56fb1cbcc25e46 Author: Amy G. Bowersox Date: Sun May 24 21:56:11 2020 -0600 Initial version of Privyet, after finishing tutorial on Bloc Web site diff --git a/Privyet.xcodeproj/project.pbxproj b/Privyet.xcodeproj/project.pbxproj new file mode 100644 index 0000000..109cfc8 --- /dev/null +++ b/Privyet.xcodeproj/project.pbxproj @@ -0,0 +1,647 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + E1EB2FB2247A33F200AA6A24 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1EB2FB1247A33F200AA6A24 /* AppDelegate.swift */; }; + E1EB2FB6247A33F200AA6A24 /* Actions.sks in Resources */ = {isa = PBXBuildFile; fileRef = E1EB2FB5247A33F200AA6A24 /* Actions.sks */; }; + E1EB2FB8247A33F200AA6A24 /* GameScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1EB2FB7247A33F200AA6A24 /* GameScene.swift */; }; + E1EB2FBA247A33F200AA6A24 /* GameViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1EB2FB9247A33F200AA6A24 /* GameViewController.swift */; }; + E1EB2FBD247A33F200AA6A24 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E1EB2FBB247A33F200AA6A24 /* Main.storyboard */; }; + E1EB2FBF247A340600AA6A24 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E1EB2FBE247A340600AA6A24 /* Assets.xcassets */; }; + E1EB2FC2247A340600AA6A24 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E1EB2FC0247A340600AA6A24 /* LaunchScreen.storyboard */; }; + E1EB2FCD247A340700AA6A24 /* PrivyetTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1EB2FCC247A340700AA6A24 /* PrivyetTests.swift */; }; + E1EB2FD8247A340700AA6A24 /* PrivyetUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1EB2FD7247A340700AA6A24 /* PrivyetUITests.swift */; }; + E1EB2FE6247A37EB00AA6A24 /* Sounds in Resources */ = {isa = PBXBuildFile; fileRef = E1EB2FE5247A37EB00AA6A24 /* Sounds */; }; + E1EB2FE9247A3CB900AA6A24 /* Array2D.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1EB2FE8247A3CB900AA6A24 /* Array2D.swift */; }; + E1EB2FEB247A408800AA6A24 /* Block.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1EB2FEA247A408800AA6A24 /* Block.swift */; }; + E1EB2FED247A459200AA6A24 /* Shape.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1EB2FEC247A459200AA6A24 /* Shape.swift */; }; + E1EB2FEF247A4D6E00AA6A24 /* SquareShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1EB2FEE247A4D6E00AA6A24 /* SquareShape.swift */; }; + E1EB2FF1247A4F4900AA6A24 /* TShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1EB2FF0247A4F4900AA6A24 /* TShape.swift */; }; + E1EB2FF3247A543000AA6A24 /* LineShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1EB2FF2247A543000AA6A24 /* LineShape.swift */; }; + E1EB2FF5247A55CF00AA6A24 /* LShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1EB2FF4247A55CF00AA6A24 /* LShape.swift */; }; + E1EB2FF7247A58D900AA6A24 /* JShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1EB2FF6247A58D900AA6A24 /* JShape.swift */; }; + E1EB2FF9247A5C8200AA6A24 /* SShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1EB2FF8247A5C8200AA6A24 /* SShape.swift */; }; + E1EB2FFB247A5E4200AA6A24 /* ZShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1EB2FFA247A5E4200AA6A24 /* ZShape.swift */; }; + E1EB2FFD247AF6ED00AA6A24 /* Privyet.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1EB2FFC247AF6ED00AA6A24 /* Privyet.swift */; }; + E1EB2FFE247B2FFA00AA6A24 /* Sprites.atlas in Resources */ = {isa = PBXBuildFile; fileRef = E1EB2FE7247A380100AA6A24 /* Sprites.atlas */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + E1EB2FC9247A340700AA6A24 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E1EB2FA6247A33F200AA6A24 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E1EB2FAD247A33F200AA6A24; + remoteInfo = Privyet; + }; + E1EB2FD4247A340700AA6A24 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E1EB2FA6247A33F200AA6A24 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E1EB2FAD247A33F200AA6A24; + remoteInfo = Privyet; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + E1EB2FAE247A33F200AA6A24 /* Privyet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Privyet.app; sourceTree = BUILT_PRODUCTS_DIR; }; + E1EB2FB1247A33F200AA6A24 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + E1EB2FB5247A33F200AA6A24 /* Actions.sks */ = {isa = PBXFileReference; lastKnownFileType = file.sks; path = Actions.sks; sourceTree = ""; }; + E1EB2FB7247A33F200AA6A24 /* GameScene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameScene.swift; sourceTree = ""; }; + E1EB2FB9247A33F200AA6A24 /* GameViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameViewController.swift; sourceTree = ""; }; + E1EB2FBC247A33F200AA6A24 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + E1EB2FBE247A340600AA6A24 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + E1EB2FC1247A340600AA6A24 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + E1EB2FC3247A340600AA6A24 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + E1EB2FC8247A340700AA6A24 /* PrivyetTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PrivyetTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + E1EB2FCC247A340700AA6A24 /* PrivyetTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivyetTests.swift; sourceTree = ""; }; + E1EB2FCE247A340700AA6A24 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + E1EB2FD3247A340700AA6A24 /* PrivyetUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PrivyetUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + E1EB2FD7247A340700AA6A24 /* PrivyetUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivyetUITests.swift; sourceTree = ""; }; + E1EB2FD9247A340700AA6A24 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + E1EB2FE5247A37EB00AA6A24 /* Sounds */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Sounds; sourceTree = ""; }; + E1EB2FE7247A380100AA6A24 /* Sprites.atlas */ = {isa = PBXFileReference; lastKnownFileType = folder.skatlas; path = Sprites.atlas; sourceTree = ""; }; + E1EB2FE8247A3CB900AA6A24 /* Array2D.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Array2D.swift; sourceTree = ""; }; + E1EB2FEA247A408800AA6A24 /* Block.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Block.swift; sourceTree = ""; }; + E1EB2FEC247A459200AA6A24 /* Shape.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Shape.swift; sourceTree = ""; }; + E1EB2FEE247A4D6E00AA6A24 /* SquareShape.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SquareShape.swift; sourceTree = ""; }; + E1EB2FF0247A4F4900AA6A24 /* TShape.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TShape.swift; sourceTree = ""; }; + E1EB2FF2247A543000AA6A24 /* LineShape.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LineShape.swift; sourceTree = ""; }; + E1EB2FF4247A55CF00AA6A24 /* LShape.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LShape.swift; sourceTree = ""; }; + E1EB2FF6247A58D900AA6A24 /* JShape.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JShape.swift; sourceTree = ""; }; + E1EB2FF8247A5C8200AA6A24 /* SShape.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SShape.swift; sourceTree = ""; }; + E1EB2FFA247A5E4200AA6A24 /* ZShape.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZShape.swift; sourceTree = ""; }; + E1EB2FFC247AF6ED00AA6A24 /* Privyet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Privyet.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + E1EB2FAB247A33F200AA6A24 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E1EB2FC5247A340700AA6A24 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E1EB2FD0247A340700AA6A24 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + E1EB2FA5247A33F200AA6A24 = { + isa = PBXGroup; + children = ( + E1EB2FB0247A33F200AA6A24 /* Privyet */, + E1EB2FCB247A340700AA6A24 /* PrivyetTests */, + E1EB2FD6247A340700AA6A24 /* PrivyetUITests */, + E1EB2FAF247A33F200AA6A24 /* Products */, + ); + sourceTree = ""; + }; + E1EB2FAF247A33F200AA6A24 /* Products */ = { + isa = PBXGroup; + children = ( + E1EB2FAE247A33F200AA6A24 /* Privyet.app */, + E1EB2FC8247A340700AA6A24 /* PrivyetTests.xctest */, + E1EB2FD3247A340700AA6A24 /* PrivyetUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + E1EB2FB0247A33F200AA6A24 /* Privyet */ = { + isa = PBXGroup; + children = ( + E1EB2FB1247A33F200AA6A24 /* AppDelegate.swift */, + E1EB2FB5247A33F200AA6A24 /* Actions.sks */, + E1EB2FB7247A33F200AA6A24 /* GameScene.swift */, + E1EB2FB9247A33F200AA6A24 /* GameViewController.swift */, + E1EB2FE7247A380100AA6A24 /* Sprites.atlas */, + E1EB2FE5247A37EB00AA6A24 /* Sounds */, + E1EB2FBB247A33F200AA6A24 /* Main.storyboard */, + E1EB2FBE247A340600AA6A24 /* Assets.xcassets */, + E1EB2FC0247A340600AA6A24 /* LaunchScreen.storyboard */, + E1EB2FC3247A340600AA6A24 /* Info.plist */, + E1EB2FE8247A3CB900AA6A24 /* Array2D.swift */, + E1EB2FEA247A408800AA6A24 /* Block.swift */, + E1EB2FEC247A459200AA6A24 /* Shape.swift */, + E1EB2FEE247A4D6E00AA6A24 /* SquareShape.swift */, + E1EB2FF0247A4F4900AA6A24 /* TShape.swift */, + E1EB2FF2247A543000AA6A24 /* LineShape.swift */, + E1EB2FF4247A55CF00AA6A24 /* LShape.swift */, + E1EB2FF6247A58D900AA6A24 /* JShape.swift */, + E1EB2FF8247A5C8200AA6A24 /* SShape.swift */, + E1EB2FFA247A5E4200AA6A24 /* ZShape.swift */, + E1EB2FFC247AF6ED00AA6A24 /* Privyet.swift */, + ); + path = Privyet; + sourceTree = ""; + }; + E1EB2FCB247A340700AA6A24 /* PrivyetTests */ = { + isa = PBXGroup; + children = ( + E1EB2FCC247A340700AA6A24 /* PrivyetTests.swift */, + E1EB2FCE247A340700AA6A24 /* Info.plist */, + ); + path = PrivyetTests; + sourceTree = ""; + }; + E1EB2FD6247A340700AA6A24 /* PrivyetUITests */ = { + isa = PBXGroup; + children = ( + E1EB2FD7247A340700AA6A24 /* PrivyetUITests.swift */, + E1EB2FD9247A340700AA6A24 /* Info.plist */, + ); + path = PrivyetUITests; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + E1EB2FAD247A33F200AA6A24 /* Privyet */ = { + isa = PBXNativeTarget; + buildConfigurationList = E1EB2FDC247A340700AA6A24 /* Build configuration list for PBXNativeTarget "Privyet" */; + buildPhases = ( + E1EB2FAA247A33F200AA6A24 /* Sources */, + E1EB2FAB247A33F200AA6A24 /* Frameworks */, + E1EB2FAC247A33F200AA6A24 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Privyet; + productName = Privyet; + productReference = E1EB2FAE247A33F200AA6A24 /* Privyet.app */; + productType = "com.apple.product-type.application"; + }; + E1EB2FC7247A340700AA6A24 /* PrivyetTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = E1EB2FDF247A340700AA6A24 /* Build configuration list for PBXNativeTarget "PrivyetTests" */; + buildPhases = ( + E1EB2FC4247A340700AA6A24 /* Sources */, + E1EB2FC5247A340700AA6A24 /* Frameworks */, + E1EB2FC6247A340700AA6A24 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + E1EB2FCA247A340700AA6A24 /* PBXTargetDependency */, + ); + name = PrivyetTests; + productName = PrivyetTests; + productReference = E1EB2FC8247A340700AA6A24 /* PrivyetTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + E1EB2FD2247A340700AA6A24 /* PrivyetUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = E1EB2FE2247A340700AA6A24 /* Build configuration list for PBXNativeTarget "PrivyetUITests" */; + buildPhases = ( + E1EB2FCF247A340700AA6A24 /* Sources */, + E1EB2FD0247A340700AA6A24 /* Frameworks */, + E1EB2FD1247A340700AA6A24 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + E1EB2FD5247A340700AA6A24 /* PBXTargetDependency */, + ); + name = PrivyetUITests; + productName = PrivyetUITests; + productReference = E1EB2FD3247A340700AA6A24 /* PrivyetUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + E1EB2FA6247A33F200AA6A24 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1150; + LastUpgradeCheck = 1150; + ORGANIZATIONNAME = "Erbosoft Metaverse Design Solutions"; + TargetAttributes = { + E1EB2FAD247A33F200AA6A24 = { + CreatedOnToolsVersion = 11.5; + }; + E1EB2FC7247A340700AA6A24 = { + CreatedOnToolsVersion = 11.5; + TestTargetID = E1EB2FAD247A33F200AA6A24; + }; + E1EB2FD2247A340700AA6A24 = { + CreatedOnToolsVersion = 11.5; + TestTargetID = E1EB2FAD247A33F200AA6A24; + }; + }; + }; + buildConfigurationList = E1EB2FA9247A33F200AA6A24 /* Build configuration list for PBXProject "Privyet" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = E1EB2FA5247A33F200AA6A24; + productRefGroup = E1EB2FAF247A33F200AA6A24 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + E1EB2FAD247A33F200AA6A24 /* Privyet */, + E1EB2FC7247A340700AA6A24 /* PrivyetTests */, + E1EB2FD2247A340700AA6A24 /* PrivyetUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + E1EB2FAC247A33F200AA6A24 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E1EB2FFE247B2FFA00AA6A24 /* Sprites.atlas in Resources */, + E1EB2FE6247A37EB00AA6A24 /* Sounds in Resources */, + E1EB2FBD247A33F200AA6A24 /* Main.storyboard in Resources */, + E1EB2FBF247A340600AA6A24 /* Assets.xcassets in Resources */, + E1EB2FC2247A340600AA6A24 /* LaunchScreen.storyboard in Resources */, + E1EB2FB6247A33F200AA6A24 /* Actions.sks in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E1EB2FC6247A340700AA6A24 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E1EB2FD1247A340700AA6A24 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + E1EB2FAA247A33F200AA6A24 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E1EB2FF5247A55CF00AA6A24 /* LShape.swift in Sources */, + E1EB2FEF247A4D6E00AA6A24 /* SquareShape.swift in Sources */, + E1EB2FB8247A33F200AA6A24 /* GameScene.swift in Sources */, + E1EB2FF7247A58D900AA6A24 /* JShape.swift in Sources */, + E1EB2FED247A459200AA6A24 /* Shape.swift in Sources */, + E1EB2FE9247A3CB900AA6A24 /* Array2D.swift in Sources */, + E1EB2FF3247A543000AA6A24 /* LineShape.swift in Sources */, + E1EB2FF9247A5C8200AA6A24 /* SShape.swift in Sources */, + E1EB2FF1247A4F4900AA6A24 /* TShape.swift in Sources */, + E1EB2FFD247AF6ED00AA6A24 /* Privyet.swift in Sources */, + E1EB2FEB247A408800AA6A24 /* Block.swift in Sources */, + E1EB2FBA247A33F200AA6A24 /* GameViewController.swift in Sources */, + E1EB2FFB247A5E4200AA6A24 /* ZShape.swift in Sources */, + E1EB2FB2247A33F200AA6A24 /* AppDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E1EB2FC4247A340700AA6A24 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E1EB2FCD247A340700AA6A24 /* PrivyetTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E1EB2FCF247A340700AA6A24 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + E1EB2FD8247A340700AA6A24 /* PrivyetUITests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + E1EB2FCA247A340700AA6A24 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = E1EB2FAD247A33F200AA6A24 /* Privyet */; + targetProxy = E1EB2FC9247A340700AA6A24 /* PBXContainerItemProxy */; + }; + E1EB2FD5247A340700AA6A24 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = E1EB2FAD247A33F200AA6A24 /* Privyet */; + targetProxy = E1EB2FD4247A340700AA6A24 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + E1EB2FBB247A33F200AA6A24 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + E1EB2FBC247A33F200AA6A24 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + E1EB2FC0247A340600AA6A24 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + E1EB2FC1247A340600AA6A24 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + E1EB2FDA247A340700AA6A24 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + 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 = 13.5; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + E1EB2FDB247A340700AA6A24 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + 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 = 13.5; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + E1EB2FDD247A340700AA6A24 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = Privyet/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 0.1; + PRODUCT_BUNDLE_IDENTIFIER = com.erbosoft.Privyet; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + E1EB2FDE247A340700AA6A24 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = Privyet/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 0.1; + PRODUCT_BUNDLE_IDENTIFIER = com.erbosoft.Privyet; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + E1EB2FE0247A340700AA6A24 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = PrivyetTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.5; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.erbosoft.PrivyetTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Privyet.app/Privyet"; + }; + name = Debug; + }; + E1EB2FE1247A340700AA6A24 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = PrivyetTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.5; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.erbosoft.PrivyetTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Privyet.app/Privyet"; + }; + name = Release; + }; + E1EB2FE3247A340700AA6A24 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = PrivyetUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.erbosoft.PrivyetUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = Privyet; + }; + name = Debug; + }; + E1EB2FE4247A340700AA6A24 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + INFOPLIST_FILE = PrivyetUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.erbosoft.PrivyetUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = Privyet; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + E1EB2FA9247A33F200AA6A24 /* Build configuration list for PBXProject "Privyet" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1EB2FDA247A340700AA6A24 /* Debug */, + E1EB2FDB247A340700AA6A24 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E1EB2FDC247A340700AA6A24 /* Build configuration list for PBXNativeTarget "Privyet" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1EB2FDD247A340700AA6A24 /* Debug */, + E1EB2FDE247A340700AA6A24 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E1EB2FDF247A340700AA6A24 /* Build configuration list for PBXNativeTarget "PrivyetTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1EB2FE0247A340700AA6A24 /* Debug */, + E1EB2FE1247A340700AA6A24 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E1EB2FE2247A340700AA6A24 /* Build configuration list for PBXNativeTarget "PrivyetUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E1EB2FE3247A340700AA6A24 /* Debug */, + E1EB2FE4247A340700AA6A24 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = E1EB2FA6247A33F200AA6A24 /* Project object */; +} diff --git a/Privyet.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Privyet.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..791eb15 --- /dev/null +++ b/Privyet.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Privyet.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/Privyet.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/Privyet.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/Privyet.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/Privyet.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/Privyet.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/Privyet.xcodeproj/project.xcworkspace/xcuserdata/amy.xcuserdatad/WorkspaceSettings.xcsettings b/Privyet.xcodeproj/project.xcworkspace/xcuserdata/amy.xcuserdatad/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..379adbe --- /dev/null +++ b/Privyet.xcodeproj/project.xcworkspace/xcuserdata/amy.xcuserdatad/WorkspaceSettings.xcsettings @@ -0,0 +1,18 @@ + + + + + BuildLocationStyle + UseAppPreferences + CustomBuildLocationType + RelativeToDerivedData + DerivedDataLocationStyle + Default + IssueFilterStyle + ShowActiveSchemeOnly + LiveSourceIssuesEnabled + + ShowSharedSchemesAutomaticallyEnabled + + + diff --git a/Privyet.xcodeproj/xcuserdata/amy.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/Privyet.xcodeproj/xcuserdata/amy.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..e502563 --- /dev/null +++ b/Privyet.xcodeproj/xcuserdata/amy.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,6 @@ + + + diff --git a/Privyet.xcodeproj/xcuserdata/amy.xcuserdatad/xcschemes/xcschememanagement.plist b/Privyet.xcodeproj/xcuserdata/amy.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..b6d4338 --- /dev/null +++ b/Privyet.xcodeproj/xcuserdata/amy.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + Privyet.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/Privyet/Actions.sks b/Privyet/Actions.sks new file mode 100644 index 0000000..0530520 Binary files /dev/null and b/Privyet/Actions.sks differ diff --git a/Privyet/AppDelegate.swift b/Privyet/AppDelegate.swift new file mode 100644 index 0000000..93b9cdc --- /dev/null +++ b/Privyet/AppDelegate.swift @@ -0,0 +1,41 @@ +// +// AppDelegate.swift +// Privyet +// +// Created by Amy Bowersox on 5/23/20. +// Copyright © 2020 Erbosoft Metaverse Design Solutions. All rights reserved. +// + +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> 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 invalidate graphics rendering callbacks. 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. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + 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. + } + + +} + diff --git a/Privyet/Array2D.swift b/Privyet/Array2D.swift new file mode 100644 index 0000000..19ef462 --- /dev/null +++ b/Privyet/Array2D.swift @@ -0,0 +1,32 @@ +// +// Array2D.swift +// Privyet +// +// Created by Amy Bowersox on 5/23/20. +// Copyright © 2020 Erbosoft Metaverse Design Solutions. All rights reserved. +// + +import Foundation + +class Array2D { + let columns: Int + let rows: Int + + var array: Array + + init(columns: Int, rows: Int) { + self.columns = columns + self.rows = rows + + array = Array(repeating: nil, count: rows * columns) + } + + subscript(column: Int, row: Int) -> T? { + get { + return array[(row * columns) + column] + } + set(newValue) { + array[(row * columns) + column] = newValue + } + } +} diff --git a/Privyet/Assets.xcassets/AppIcon.appiconset/Contents.json b/Privyet/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..cc04b5f --- /dev/null +++ b/Privyet/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,101 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "filename" : "icon-29pt.png", + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "filename" : "icon-40pt.png", + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "filename" : "icon-60pt.png", + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Privyet/Assets.xcassets/AppIcon.appiconset/icon-29pt.png b/Privyet/Assets.xcassets/AppIcon.appiconset/icon-29pt.png new file mode 100644 index 0000000..35b81a9 Binary files /dev/null and b/Privyet/Assets.xcassets/AppIcon.appiconset/icon-29pt.png differ diff --git a/Privyet/Assets.xcassets/AppIcon.appiconset/icon-40pt.png b/Privyet/Assets.xcassets/AppIcon.appiconset/icon-40pt.png new file mode 100644 index 0000000..09f81cb Binary files /dev/null and b/Privyet/Assets.xcassets/AppIcon.appiconset/icon-40pt.png differ diff --git a/Privyet/Assets.xcassets/AppIcon.appiconset/icon-60pt.png b/Privyet/Assets.xcassets/AppIcon.appiconset/icon-60pt.png new file mode 100644 index 0000000..96648ad Binary files /dev/null and b/Privyet/Assets.xcassets/AppIcon.appiconset/icon-60pt.png differ diff --git a/Privyet/Assets.xcassets/Contents.json b/Privyet/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/Privyet/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Privyet/Assets.xcassets/background.imageset/Contents.json b/Privyet/Assets.xcassets/background.imageset/Contents.json new file mode 100644 index 0000000..8799a3c --- /dev/null +++ b/Privyet/Assets.xcassets/background.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "background.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "background@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Privyet/Assets.xcassets/background.imageset/background.png b/Privyet/Assets.xcassets/background.imageset/background.png new file mode 100644 index 0000000..91461ae Binary files /dev/null and b/Privyet/Assets.xcassets/background.imageset/background.png differ diff --git a/Privyet/Assets.xcassets/background.imageset/background@2x.png b/Privyet/Assets.xcassets/background.imageset/background@2x.png new file mode 100644 index 0000000..78a9a59 Binary files /dev/null and b/Privyet/Assets.xcassets/background.imageset/background@2x.png differ diff --git a/Privyet/Assets.xcassets/gameboard.imageset/Contents.json b/Privyet/Assets.xcassets/gameboard.imageset/Contents.json new file mode 100644 index 0000000..f37a394 --- /dev/null +++ b/Privyet/Assets.xcassets/gameboard.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "gameboard.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "gameboard@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Privyet/Assets.xcassets/gameboard.imageset/gameboard.png b/Privyet/Assets.xcassets/gameboard.imageset/gameboard.png new file mode 100644 index 0000000..924ad1e Binary files /dev/null and b/Privyet/Assets.xcassets/gameboard.imageset/gameboard.png differ diff --git a/Privyet/Assets.xcassets/gameboard.imageset/gameboard@2x.png b/Privyet/Assets.xcassets/gameboard.imageset/gameboard@2x.png new file mode 100644 index 0000000..f5bd959 Binary files /dev/null and b/Privyet/Assets.xcassets/gameboard.imageset/gameboard@2x.png differ diff --git a/Privyet/Assets.xcassets/whitebg.imageset/Contents.json b/Privyet/Assets.xcassets/whitebg.imageset/Contents.json new file mode 100644 index 0000000..897aad4 --- /dev/null +++ b/Privyet/Assets.xcassets/whitebg.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "whitebg.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "whitebg@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Privyet/Assets.xcassets/whitebg.imageset/whitebg.png b/Privyet/Assets.xcassets/whitebg.imageset/whitebg.png new file mode 100644 index 0000000..7870680 Binary files /dev/null and b/Privyet/Assets.xcassets/whitebg.imageset/whitebg.png differ diff --git a/Privyet/Assets.xcassets/whitebg.imageset/whitebg@2x.png b/Privyet/Assets.xcassets/whitebg.imageset/whitebg@2x.png new file mode 100644 index 0000000..4db158b Binary files /dev/null and b/Privyet/Assets.xcassets/whitebg.imageset/whitebg@2x.png differ diff --git a/Privyet/Block.swift b/Privyet/Block.swift new file mode 100644 index 0000000..251fce3 --- /dev/null +++ b/Privyet/Block.swift @@ -0,0 +1,75 @@ +// +// Block.swift +// Privyet +// +// Created by Amy Bowersox on 5/23/20. +// Copyright © 2020 Erbosoft Metaverse Design Solutions. All rights reserved. +// + +import Foundation +import SpriteKit + +let NumberOfColors: UInt32 = 6 + +enum BlockColor: Int, CustomStringConvertible { + case Blue = 0, Orange, Purple, Red, Teal, Yellow + + var spriteName: String { + switch self { + case .Blue: + return "blue" + case .Orange: + return "orange" + case .Purple: + return "purple" + case .Red: + return "red" + case .Teal: + return "teal" + case .Yellow: + return "yellow" + } + } + + var description: String { + return self.spriteName + } + + static func random() -> BlockColor { + return BlockColor(rawValue:Int(arc4random_uniform(NumberOfColors)))! + } +} + +class Block: Hashable, CustomStringConvertible { + // Constants + let color: BlockColor + + // Properties + var column: Int + var row: Int + var sprite: SKSpriteNode? + + var spriteName: String { + return color.spriteName + } + + static func == (lhs: Block, rhs: Block) -> Bool { + return lhs.column == rhs.column && lhs.row == rhs.row + && lhs.color.rawValue == rhs.color.rawValue + } + + func hash(into hasher: inout Hasher) { + hasher.combine(column) + hasher.combine(row) + } + + var description: String { + return "\(color): [\(column), \(row)]" + } + + init(column: Int, row: Int, color: BlockColor) { + self.column = column + self.row = row + self.color = color + } +} diff --git a/Privyet/GameScene.swift b/Privyet/GameScene.swift new file mode 100644 index 0000000..1ceafc9 --- /dev/null +++ b/Privyet/GameScene.swift @@ -0,0 +1,191 @@ +// +// GameScene.swift +// Privyet +// +// Created by Amy Bowersox on 5/23/20. +// Copyright © 2020 Erbosoft Metaverse Design Solutions. All rights reserved. +// + +import SpriteKit +import GameplayKit + +let BlockSize: CGFloat = 20.0 + +let TickLengthLevelOne = TimeInterval(600) + +class GameScene: SKScene { + let gameLayer = SKNode() + let shapeLayer = SKNode() + let LayerPosition = CGPoint(x: 6, y: -6) + + var tick: (() -> ())? + var tickLengthMillis = TickLengthLevelOne + var lastTick: NSDate? + + var textureCache = Dictionary() + var textureAtlas: SKTextureAtlas? + + required init(coder aDecoder: NSCoder) { + fatalError("NSCoder not supported") + } + + override init(size: CGSize) { + super.init(size: size) + print("Init scene with size \(size)") + + textureAtlas = SKTextureAtlas(named: "Sprites") + + anchorPoint = CGPoint(x: 0, y: 1.0) + + let background = SKSpriteNode(imageNamed: "background") + print("Background is sized \(background.size)") + background.position = CGPoint(x: 0, y: 0) + background.anchorPoint = CGPoint(x: 0, y: 1.0) + addChild(background) + + addChild(gameLayer) + + let gameBoardTexture = SKTexture(imageNamed: "gameboard") + let gameBoard = SKSpriteNode(texture: gameBoardTexture, size: CGSize(width: BlockSize * CGFloat(NumColumns), height: BlockSize * CGFloat(NumRows))) + gameBoard.anchorPoint = CGPoint(x: 0, y: 1.0) + gameBoard.position = LayerPosition + + shapeLayer.position = LayerPosition + shapeLayer.addChild(gameBoard) + gameLayer.addChild(shapeLayer) + + run(SKAction.repeatForever(SKAction.playSoundFileNamed("Sounds/theme.mp3", waitForCompletion: true))) + } + + func playSound(sound: String) { + run(SKAction.playSoundFileNamed(sound, waitForCompletion: false)) + } + + override func update(_ currentTime: TimeInterval) { + // Called before each frame is rendered + guard let lastTick = lastTick else { + return + } + let timePassed = lastTick.timeIntervalSinceNow * -1000.0 + if timePassed > tickLengthMillis { + self.lastTick = NSDate() + tick?() + } + + } + + func startTicking() { + lastTick = NSDate() + } + + func stopTicking() { + lastTick = nil + } + + func pointForColumn(column: Int, row: Int) -> CGPoint { + let x = LayerPosition.x + (CGFloat(column) * BlockSize) + (BlockSize / 2) + let y = LayerPosition.y - ((CGFloat(row) * BlockSize) + (BlockSize / 2)) + return CGPoint(x: x, y: y) + } + + func addPreviewShapeToScene(shape: Shape, completion: @escaping () -> ()) { + for block in shape.blocks { + var texture = textureCache[block.spriteName] + if texture == nil { + texture = textureAtlas?.textureNamed(block.spriteName) + textureCache[block.spriteName] = texture + } + let sprite = SKSpriteNode(texture: texture) + + sprite.position = pointForColumn(column: block.column, row: block.row - 2) + shapeLayer.addChild(sprite) + block.sprite = sprite + + // Animation + sprite.alpha = 0 + + let moveAction = SKAction.move(to: pointForColumn(column: block.column, row: block.row), duration: TimeInterval(0.2)) + moveAction.timingMode = .easeOut + let fadeInAction = SKAction.fadeAlpha(to: 0.7, duration: 0.4) + fadeInAction.timingMode = .easeOut + sprite.run(SKAction.group([moveAction, fadeInAction])) + } + let waitAction = SKAction.wait(forDuration: 0.4) + let completeAction = SKAction.run(completion) + run(SKAction.sequence([waitAction, completeAction])) + } + + func movePreviewShape(shape: Shape, completion: @escaping () -> ()) { + for block in shape.blocks { + let sprite = block.sprite! + let moveTo = pointForColumn(column: block.column, row: block.row) + let moveToAction: SKAction = SKAction.move(to: moveTo, duration: 0.4) + moveToAction.timingMode = .easeOut + sprite.run(SKAction.group([moveToAction, SKAction.fadeAlpha(to: 1.0, duration: 0.2)])) + } + let waitAction = SKAction.wait(forDuration: 0.2) + let completeAction = SKAction.run(completion) + run(SKAction.sequence([waitAction, completeAction])) + } + + func redrawShape(shape: Shape, completion: @escaping () -> ()) { + for block in shape.blocks { + let sprite = block.sprite! + let moveTo = pointForColumn(column: block.column, row: block.row) + let moveToAction: SKAction = SKAction.move(to: moveTo, duration: 0.05) + moveToAction.timingMode = .easeOut + sprite.run(moveToAction) + if block == shape.blocks.last { + sprite.run(SKAction.run(completion)) + } + } + } + + func animateCollapsingLines(linesToRemove: Array>, fallenBlocks: Array>, completion: @escaping () -> ()) { + var longestDuration: TimeInterval = 0 + + for (columnIdx, column) in fallenBlocks.enumerated() { + for (blockIdx, block) in column.enumerated() { + let newPosition = pointForColumn(column: block.column, row: block.row) + let sprite = block.sprite! + + let delay = (TimeInterval(columnIdx) * 0.05) + (TimeInterval(blockIdx) * 0.05) + let duration = TimeInterval(((sprite.position.y - newPosition.y) / BlockSize) * 0.1) + let moveAction = SKAction.move(to: newPosition, duration: duration) + moveAction.timingMode = .easeOut + sprite.run(SKAction.sequence([SKAction.wait(forDuration: delay), moveAction])) + longestDuration = max(longestDuration, duration + delay) + } + } + + for rowToRemove in linesToRemove { + for block in rowToRemove { + let randomRadius = CGFloat(UInt(arc4random_uniform(400) + 100)) + let goLeft = arc4random_uniform(100) % 2 == 0 + + var point = pointForColumn(column: block.column, row: block.row) + point = CGPoint(x: point.x + (goLeft ? -randomRadius : randomRadius), y: point.y) + + let randomDuration = TimeInterval(arc4random_uniform(2)) + 0.5 + + var startAngle = CGFloat(Double.pi) + var endAngle = startAngle * 2 + if (goLeft) { + endAngle = startAngle + startAngle = 0 + } + + let archPath = UIBezierPath(arcCenter: point, radius: randomRadius, startAngle: startAngle, endAngle: endAngle, clockwise: goLeft) + + let archAction = SKAction.follow(archPath.cgPath, asOffset: false, orientToPath: true, duration: randomDuration) + archAction.timingMode = .easeIn + let sprite = block.sprite! + sprite.zPosition = 100 + sprite.run(SKAction.sequence([ + SKAction.group([archAction, SKAction.fadeOut(withDuration: TimeInterval(randomDuration))]), + SKAction.removeFromParent()])) + } + } + run(SKAction.sequence([SKAction.wait(forDuration: longestDuration), SKAction.run(completion)])) + } +} diff --git a/Privyet/GameViewController.swift b/Privyet/GameViewController.swift new file mode 100644 index 0000000..92e7dd0 --- /dev/null +++ b/Privyet/GameViewController.swift @@ -0,0 +1,164 @@ +// +// GameViewController.swift +// Privyet +// +// Created by Amy Bowersox on 5/23/20. +// Copyright © 2020 Erbosoft Metaverse Design Solutions. All rights reserved. +// + +import UIKit +import SpriteKit +import GameplayKit + +class GameViewController: UIViewController, PrivyetDelegate, UIGestureRecognizerDelegate { + var scene: GameScene! + var privyet: Privyet! + var panPointReference: CGPoint? + + @IBOutlet weak var scoreLabel: UILabel! + @IBOutlet weak var levelLabel: UILabel! + + override func viewDidLoad() { + super.viewDidLoad() + + // Configure the view + let skView = view as! SKView + skView.isMultipleTouchEnabled = false + + // Create and configure the scene + scene = GameScene(size: skView.bounds.size) + scene.scaleMode = .aspectFill + + scene.tick = didTick + + privyet = Privyet() + privyet.delegate = self + privyet.beginGame() + + // Present the scene + skView.presentScene(scene) + } + + override var prefersStatusBarHidden: Bool { + return true + } + + @IBAction func didTap(_ sender: UITapGestureRecognizer) { + privyet.rotateShape() + } + + @IBAction func didPan(_ sender: UIPanGestureRecognizer) { + let currentPoint = sender.translation(in: self.view) + if let originalPoint = panPointReference { + if abs(currentPoint.x - originalPoint.x) > (BlockSize * 0.9) { + if sender.velocity(in: self.view).x > CGFloat(0) { + privyet.moveShapeRight() + panPointReference = currentPoint + } else { + privyet.moveShapeLeft() + panPointReference = currentPoint + } + } + } else if sender.state == .began { + panPointReference = currentPoint + } + } + + @IBAction func didSwipe(_ sender: UISwipeGestureRecognizer) { + privyet.dropShape() + } + + func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { + return true + } + + func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool { + if gestureRecognizer is UISwipeGestureRecognizer { + if otherGestureRecognizer is UIPanGestureRecognizer { + return true + } + } else if gestureRecognizer is UIPanGestureRecognizer { + if otherGestureRecognizer is UITapGestureRecognizer { + return true + } + } + return false + } + + func didTick() { + privyet.letShapeFall() + } + + func nextShape() { + let newShapes = privyet.newShape() + guard let fallingShape = newShapes.fallingShape else { + return + } + self.scene.addPreviewShapeToScene(shape: newShapes.nextShape!) { } + self.scene.movePreviewShape(shape: fallingShape) { + self.view.isUserInteractionEnabled = true + self.scene.startTicking() + } + } + + func gameDidBegin(privyet: Privyet) { + levelLabel.text = "\(privyet.level)" + scoreLabel.text = "\(privyet.score)" + scene.tickLengthMillis = TickLengthLevelOne + + // The following is false when restarting a new game + if privyet.nextShape != nil && privyet.nextShape!.blocks[0].sprite == nil { + scene.addPreviewShapeToScene(shape: privyet.nextShape!) { + self.nextShape() + } + } else { + nextShape() + } + } + + func gameDidEnd(privyet: Privyet) { + view.isUserInteractionEnabled = false + scene.stopTicking() + scene.playSound(sound: "Sounds/gameover.mp3") + scene.animateCollapsingLines(linesToRemove: privyet.removeAllBlocks(), fallenBlocks: privyet.removeAllBlocks()) { + privyet.beginGame() + } + } + + func gameDidLevelUp(privyet: Privyet) { + levelLabel.text = "\(privyet.level)" + if scene.tickLengthMillis >= 100 { + scene.tickLengthMillis -= 100 + } else if scene.tickLengthMillis >= 50 { + scene.tickLengthMillis -= 50 + } + scene.playSound(sound: "Sounds/levelup.mp3") + } + + func gameShapeDidDrop(privyet: Privyet) { + scene.stopTicking() + scene.redrawShape(shape: privyet.fallingShape!) { + privyet.letShapeFall() + } + scene.playSound(sound: "Sounds/drop.mp3") + } + + func gameShapeDidLand(privyet: Privyet) { + scene.stopTicking() + self.view.isUserInteractionEnabled = false + let removedLines = privyet.removeCompletedLines() + if removedLines.linesRemoved.count > 0 { + self.scoreLabel.text = "\(privyet.score)" + scene.animateCollapsingLines(linesToRemove: removedLines.linesRemoved, fallenBlocks: removedLines.fallenBlocks) { + self.gameShapeDidLand(privyet: privyet) + } + self.scene.playSound(sound: "Sounds/bomb.mp3") + } else { + nextShape() + } + } + + func gameShapeDidMove(privyet: Privyet) { + scene.redrawShape(shape: privyet.fallingShape!) { } + } +} diff --git a/Privyet/Info.plist b/Privyet/Info.plist new file mode 100644 index 0000000..04bf75b --- /dev/null +++ b/Privyet/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + $(MARKETING_VERSION) + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarHidden + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/Privyet/JShape.swift b/Privyet/JShape.swift new file mode 100644 index 0000000..d2ceb2b --- /dev/null +++ b/Privyet/JShape.swift @@ -0,0 +1,51 @@ +// +// JShape.swift +// Privyet +// +// Created by Amy Bowersox on 5/24/20. +// Copyright © 2020 Erbosoft Metaverse Design Solutions. All rights reserved. +// + +import Foundation +class JShape: Shape { + /* + Orientation 0: + | * | 0 | + | | 1 | + | 3 | 2 | + + Orientation 90: + | 3 | * | | + | 2 | 1 | 0 | + + Orientation 180: + | 2*| 3 | + | 1 | | + | 0 | | + + Orientation 270: + | 0 | 1*| 2 | + | | | 3 | + + * marks the row/column indicator for the shape + */ + // Rotates around block #1 + + override var blockRowColumnPositions: [Orientation : Array<(columnDiff: Int, rowDiff: Int)>] { + return [ + Orientation.Zero: [(1, 0), (1, 1), (1, 2), (0, 2)], + Orientation.Ninety: [(1, 1), (0, 1), (-1, 1), (-1, 0)], + Orientation.OneEighty: [(0, 2), (0, 1), (0, 0), (1, 0)], + Orientation.TwoSeventy: [(-1, 0), (0, 0), (1, 0), (1, 1)] + ] + } + + override var bottomBlocksForOrientations: [Orientation : Array] { + return [ + Orientation.Zero: [blocks[ThirdBlockIdx], blocks[FourthBlockIdx]], + Orientation.Ninety: [blocks[FirstBlockIdx], blocks[SecondBlockIdx], blocks[ThirdBlockIdx]], + Orientation.OneEighty: [blocks[FirstBlockIdx], blocks[FourthBlockIdx]], + Orientation.TwoSeventy: [blocks[FirstBlockIdx], blocks[SecondBlockIdx], blocks[FourthBlockIdx]] + ] + } +} diff --git a/Privyet/LShape.swift b/Privyet/LShape.swift new file mode 100644 index 0000000..ba7f0a8 --- /dev/null +++ b/Privyet/LShape.swift @@ -0,0 +1,52 @@ +// +// LShape.swift +// Privyet +// +// Created by Amy Bowersox on 5/24/20. +// Copyright © 2020 Erbosoft Metaverse Design Solutions. All rights reserved. +// + +import Foundation +class LShape: Shape { + /* + Orientation 0: + | 0*| | + | 1 | | + | 2 | 3 | + + Orientation 90: + | | * | | + | 2 | 1 | 0 | + | 3 | | | + + Orientation 180: + | 3 | 2*| | + | | 1 | | + | | 0 | | + + Orientation 270: + | | * | 3 | + | 0 | 1 | 2 | + + * marks the row/column indicator for the shape + */ + // Pivots about block #1 + + override var blockRowColumnPositions: [Orientation : Array<(columnDiff: Int, rowDiff: Int)>] { + return [ + Orientation.Zero: [(0, 0), (0, 1), (0, 2), (1, 2)], + Orientation.Ninety: [(1, 1), (0, 1), (-1, 1), (-1, 2)], + Orientation.OneEighty: [(0, 2), (0, 1), (0, 0), (-1, 0)], + Orientation.TwoSeventy: [(-1, 1), (0, 1), (1, 1), (1, 0)] + ] + } + + override var bottomBlocksForOrientations: [Orientation : Array] { + return [ + Orientation.Zero: [blocks[ThirdBlockIdx], blocks[FourthBlockIdx]], + Orientation.Ninety: [blocks[FirstBlockIdx], blocks[SecondBlockIdx], blocks[FourthBlockIdx]], + Orientation.OneEighty: [blocks[FirstBlockIdx], blocks[FourthBlockIdx]], + Orientation.TwoSeventy: [blocks[FirstBlockIdx], blocks[SecondBlockIdx], blocks[ThirdBlockIdx]] + ] + } +} diff --git a/Privyet/LineShape.swift b/Privyet/LineShape.swift new file mode 100644 index 0000000..55fafe0 --- /dev/null +++ b/Privyet/LineShape.swift @@ -0,0 +1,42 @@ +// +// LineShape.swift +// Privyet +// +// Created by Amy Bowersox on 5/24/20. +// Copyright © 2020 Erbosoft Metaverse Design Solutions. All rights reserved. +// + +import Foundation +class LineShape: Shape { + /* + Orientations 0 and 180: + | 0*| + | 1 | + | 2 | + | 3 | + + Orientations 90 and 270: + | 0 | 1*| 2 | 3 | + + * markes the row-column indicator for the shape + */ + // Hinges about the second block + + override var blockRowColumnPositions: [Orientation : Array<(columnDiff: Int, rowDiff: Int)>] { + return [ + Orientation.Zero: [(0, 0), (0, 1), (0, 2), (0, 3)], + Orientation.Ninety: [(-1, 0), (0, 0), (1, 0), (2, 0)], + Orientation.OneEighty: [(0, 0), (0, 1), (0, 2), (0, 3)], + Orientation.TwoSeventy: [(-1, 0), (0, 0), (1, 0), (2, 0)] + ] + } + + override var bottomBlocksForOrientations: [Orientation : Array] { + return [ + Orientation.Zero: [blocks[FourthBlockIdx]], + Orientation.Ninety: blocks, + Orientation.OneEighty: [blocks[FourthBlockIdx]], + Orientation.TwoSeventy: blocks + ] + } +} diff --git a/Privyet/Privyet.swift b/Privyet/Privyet.swift new file mode 100644 index 0000000..bb51dcf --- /dev/null +++ b/Privyet/Privyet.swift @@ -0,0 +1,255 @@ +// +// Privyet.swift +// Privyet +// +// Created by Amy Bowersox on 5/24/20. +// Copyright © 2020 Erbosoft Metaverse Design Solutions. All rights reserved. +// + +import Foundation + +let NumColumns = 10 +let NumRows = 20 + +let StartingColumn = 4 +let StartingRow = 0 + +let PreviewColumn = 12 +let PreviewRow = 1 + +let PointsPerLine = 10 +let LevelThreshold = 500 + +protocol PrivyetDelegate { + // Invoked when the current round of Privyet ends + func gameDidEnd(privyet: Privyet) + + // Invoked after a game has begun + func gameDidBegin(privyet: Privyet) + + // Invoked when the falling shape has become part of the game board + func gameShapeDidLand(privyet: Privyet) + + // Invoked when the falling shape has changed its location + func gameShapeDidMove(privyet: Privyet) + + // invoked when the falling shape has changed its location after being dropped + func gameShapeDidDrop(privyet: Privyet) + + // invoked when the game has reached a new level + func gameDidLevelUp(privyet: Privyet) +} + +class Privyet { + var blockArray: Array2D + var nextShape: Shape? + var fallingShape: Shape? + var delegate: PrivyetDelegate? + + var score = 0 + var level = 1 + + init() { + fallingShape = nil + nextShape = nil + blockArray = Array2D(columns: NumColumns, rows: NumRows) + } + + func beginGame() { + if (nextShape == nil) { + nextShape = Shape.random(startingColumn: PreviewColumn, startingRow: PreviewRow) + } + delegate?.gameDidBegin(privyet: self) + } + + func newShape() -> (fallingShape: Shape?, nextShape: Shape?) { + fallingShape = nextShape + nextShape = Shape.random(startingColumn: PreviewColumn, startingRow: PreviewRow) + fallingShape?.moveTo(column: StartingColumn, row: StartingRow) + + guard detectIllegalPlacement() == false else { + nextShape = fallingShape + nextShape!.moveTo(column: PreviewColumn, row: PreviewRow) + endGame() + return (nil, nil) + } + + return (fallingShape, nextShape) + } + + func detectIllegalPlacement() -> Bool { + guard let shape = fallingShape else { + return false + } + for block in shape.blocks { + if block.column < 0 || block.column >= NumColumns || block.row < 0 || block.row >= NumRows { + return true + } else if blockArray[block.column, block.row] != nil { + return true + } + } + return false + } + + func settleShape() { + guard let shape = fallingShape else { + return + } + for block in shape.blocks { + blockArray[block.column, block.row] = block + } + fallingShape = nil + delegate?.gameShapeDidLand(privyet: self) + } + + func detectTouch() -> Bool { + guard let shape = fallingShape else { + return false + } + for bottomBlock in shape.bottomBlocks { + if bottomBlock.row == NumRows - 1 || blockArray[bottomBlock.column, bottomBlock.row + 1] != nil { + return true + } + } + return false + } + + func endGame() { + score = 0 + level = 1 + delegate?.gameDidEnd(privyet: self) + } + + func removeCompletedLines() -> (linesRemoved: Array>, fallenBlocks: Array>) { + var removedLines = Array>() + for row in (1..() + for column in 0..= level * LevelThreshold { + level += 1 + delegate?.gameDidLevelUp(privyet: self) + } + var fallenBlocks = Array>() + for column in 0..() + for row in (1.. 0 { + fallenBlocks.append(fallenBlocksArray) + } + } + return (removedLines, fallenBlocks) + } + + func removeAllBlocks() -> Array> { + var allBlocks = Array>() + for row in 0..() + for column in 0..] { + return [ + Orientation.Zero: [(0, 0), (0, 1), (1, 1), (1, 2)], + Orientation.Ninety: [(2, 0), (1, 0), (1, 1), (0, 1)], + Orientation.OneEighty: [(0, 0), (0, 1), (1, 1), (1, 2)], + Orientation.TwoSeventy: [(2, 0), (1, 0), (1, 1), (0, 1)] + ] + } + + override var bottomBlocksForOrientations: [Orientation : Array] { + return [ + Orientation.Zero: [blocks[SecondBlockIdx], blocks[FourthBlockIdx]], + Orientation.Ninety: [blocks[FirstBlockIdx], blocks[ThirdBlockIdx], blocks[FourthBlockIdx]], + Orientation.OneEighty: [blocks[SecondBlockIdx], blocks[FourthBlockIdx]], + Orientation.TwoSeventy: [blocks[FirstBlockIdx], blocks[ThirdBlockIdx], blocks[FourthBlockIdx]] + ] + } +} diff --git a/Privyet/Shape.swift b/Privyet/Shape.swift new file mode 100644 index 0000000..87399b3 --- /dev/null +++ b/Privyet/Shape.swift @@ -0,0 +1,194 @@ +// +// Shape.swift +// Privyet +// +// Created by Amy Bowersox on 5/24/20. +// Copyright © 2020 Erbosoft Metaverse Design Solutions. All rights reserved. +// + +import Foundation +import SpriteKit + +let NumOrientations: UInt32 = 4 + +enum Orientation: Int, CustomStringConvertible { + case Zero = 0, Ninety, OneEighty, TwoSeventy + + var description: String { + switch self { + case .Zero: + return "0" + case .Ninety: + return "90" + case .OneEighty: + return "180" + case .TwoSeventy: + return "270" + } + } + + static func random() -> Orientation { + return Orientation(rawValue:Int(arc4random_uniform(NumOrientations)))! + } + + static func rotate(orientation: Orientation, clockwise: Bool) -> Orientation { + var rotated = orientation.rawValue + (clockwise ? 1 : -1) + if rotated > Orientation.TwoSeventy.rawValue { + rotated = Orientation.Zero.rawValue + } else if rotated < 0 { + rotated = Orientation.TwoSeventy.rawValue + } + return Orientation(rawValue:rotated)! + } +} + +// The number of total shape varieties +let NumShapeTypes: UInt32 = 7 + +// Shape indexes +let FirstBlockIdx: Int = 0 +let SecondBlockIdx: Int = 1 +let ThirdBlockIdx: Int = 2 +let FourthBlockIdx: Int = 3 + +class Shape: Hashable, CustomStringConvertible { + // The color of the shape + let color: BlockColor + + // The blocks comprising the shape + var blocks = Array() + // The current orientation of the shape + var orientation: Orientation + // The column and row representing the shape's anchor point + var column, row: Int + + // Required overrides + + // Subclasses must override this property + var blockRowColumnPositions: [Orientation: Array<(columnDiff: Int, rowDiff: Int)>] { + return [:] + } + + // Subclasses must override this property + var bottomBlocksForOrientations: [Orientation: Array] { + return [:] + } + + var bottomBlocks: Array { + guard let bottomBlocks = bottomBlocksForOrientations[orientation] else { + return [] + } + return bottomBlocks + } + + // Equatable + static func == (lhs: Shape, rhs: Shape) -> Bool { + return lhs.row == rhs.row && lhs.column == rhs.column + } + + // Hashable + func hash(into hasher: inout Hasher) { + blocks.forEach {b in + hasher.combine(b.hashValue) + } + } + + // CustomStringConvertible + var description: String { + return "\(color) block facing \(orientation): \(blocks[FirstBlockIdx]), \(blocks[SecondBlockIdx]), \(blocks[ThirdBlockIdx]), \(blocks[FourthBlockIdx])" + } + + init(column: Int, row: Int, color: BlockColor, orientation: Orientation) { + self.color = color + self.column = column + self.row = row + self.orientation = orientation + initializeBlocks() + } + + convenience init(column: Int, row: Int) { + self.init(column: column, row: row, color: BlockColor.random(), orientation: Orientation.random()) + } + + final func initializeBlocks() { + guard let blockRowColumnTranslations = blockRowColumnPositions[orientation] else { + return + } + + blocks = blockRowColumnTranslations.map { (diff) -> Block in + return Block(column: column + diff.columnDiff, row: row + diff.rowDiff, color: color) + } + } + + final func rotateBlocks(orientation: Orientation) { + guard let blockRowColumnTranslation: Array<(columnDiff: Int, rowDiff: Int)> = blockRowColumnPositions[orientation] else { + return + } + for (idx, diff) in blockRowColumnTranslation.enumerated() { + blocks[idx].column = column + diff.columnDiff + blocks[idx].row = row + diff.rowDiff + } + } + + final func rotateClockwise() { + let newOrientation = Orientation.rotate(orientation: orientation, clockwise: true) + rotateBlocks(orientation: newOrientation) + orientation = newOrientation + } + + final func rotateCounterClockwise() { + let newOrientation = Orientation.rotate(orientation: orientation, clockwise: false) + rotateBlocks(orientation: newOrientation) + orientation = newOrientation + } + + final func lowerShapeByOneRow() { + shiftBy(columns: 0, rows: 1) + } + + final func raiseShapeByOneRow() { + shiftBy(columns: 0, rows: -1) + } + + final func shiftRightByOneColumn() { + shiftBy(columns: 1, rows: 0) + } + + final func shiftLeftByOneColumn() { + shiftBy(columns: -1, rows: 0) + } + + final func shiftBy(columns: Int, rows: Int) { + self.column += columns + self.row += rows + for block in blocks { + block.column += columns + block.row += rows + } + } + + final func moveTo(column: Int, row: Int) { + self.column = column + self.row = row + rotateBlocks(orientation: orientation) + } + + final class func random(startingColumn: Int, startingRow: Int) -> Shape { + switch Int(arc4random_uniform(NumShapeTypes)) { + case 0: + return SquareShape(column: startingColumn, row: startingRow) + case 1: + return LineShape(column: startingColumn, row: startingRow) + case 2: + return TShape(column: startingColumn, row: startingRow) + case 3: + return LShape(column: startingColumn, row: startingRow) + case 4: + return JShape(column: startingColumn, row: startingRow) + case 5: + return SShape(column: startingColumn, row: startingRow) + default: + return ZShape(column: startingColumn, row: startingRow) + } + } +} diff --git a/Privyet/Sounds/bomb.mp3 b/Privyet/Sounds/bomb.mp3 new file mode 100755 index 0000000..b3188c7 Binary files /dev/null and b/Privyet/Sounds/bomb.mp3 differ diff --git a/Privyet/Sounds/drop.mp3 b/Privyet/Sounds/drop.mp3 new file mode 100755 index 0000000..18451bc Binary files /dev/null and b/Privyet/Sounds/drop.mp3 differ diff --git a/Privyet/Sounds/gameover.mp3 b/Privyet/Sounds/gameover.mp3 new file mode 100755 index 0000000..124972c Binary files /dev/null and b/Privyet/Sounds/gameover.mp3 differ diff --git a/Privyet/Sounds/levelup.mp3 b/Privyet/Sounds/levelup.mp3 new file mode 100755 index 0000000..6e16a31 Binary files /dev/null and b/Privyet/Sounds/levelup.mp3 differ diff --git a/Privyet/Sounds/theme.mp3 b/Privyet/Sounds/theme.mp3 new file mode 100755 index 0000000..cbcc353 Binary files /dev/null and b/Privyet/Sounds/theme.mp3 differ diff --git a/Privyet/Sprites.atlas/blue.png b/Privyet/Sprites.atlas/blue.png new file mode 100755 index 0000000..16337e9 Binary files /dev/null and b/Privyet/Sprites.atlas/blue.png differ diff --git a/Privyet/Sprites.atlas/blue@2x.png b/Privyet/Sprites.atlas/blue@2x.png new file mode 100755 index 0000000..9deb295 Binary files /dev/null and b/Privyet/Sprites.atlas/blue@2x.png differ diff --git a/Privyet/Sprites.atlas/orange.png b/Privyet/Sprites.atlas/orange.png new file mode 100755 index 0000000..ffd8099 Binary files /dev/null and b/Privyet/Sprites.atlas/orange.png differ diff --git a/Privyet/Sprites.atlas/orange@2x.png b/Privyet/Sprites.atlas/orange@2x.png new file mode 100755 index 0000000..92c328f Binary files /dev/null and b/Privyet/Sprites.atlas/orange@2x.png differ diff --git a/Privyet/Sprites.atlas/purple.png b/Privyet/Sprites.atlas/purple.png new file mode 100755 index 0000000..b9c02a2 Binary files /dev/null and b/Privyet/Sprites.atlas/purple.png differ diff --git a/Privyet/Sprites.atlas/purple@2x.png b/Privyet/Sprites.atlas/purple@2x.png new file mode 100755 index 0000000..b4d0409 Binary files /dev/null and b/Privyet/Sprites.atlas/purple@2x.png differ diff --git a/Privyet/Sprites.atlas/red.png b/Privyet/Sprites.atlas/red.png new file mode 100755 index 0000000..524a39f Binary files /dev/null and b/Privyet/Sprites.atlas/red.png differ diff --git a/Privyet/Sprites.atlas/red@2x.png b/Privyet/Sprites.atlas/red@2x.png new file mode 100755 index 0000000..3fba602 Binary files /dev/null and b/Privyet/Sprites.atlas/red@2x.png differ diff --git a/Privyet/Sprites.atlas/teal.png b/Privyet/Sprites.atlas/teal.png new file mode 100755 index 0000000..736fcd1 Binary files /dev/null and b/Privyet/Sprites.atlas/teal.png differ diff --git a/Privyet/Sprites.atlas/teal@2x.png b/Privyet/Sprites.atlas/teal@2x.png new file mode 100755 index 0000000..246b293 Binary files /dev/null and b/Privyet/Sprites.atlas/teal@2x.png differ diff --git a/Privyet/Sprites.atlas/yellow.png b/Privyet/Sprites.atlas/yellow.png new file mode 100755 index 0000000..f2c9ff1 Binary files /dev/null and b/Privyet/Sprites.atlas/yellow.png differ diff --git a/Privyet/Sprites.atlas/yellow@2x.png b/Privyet/Sprites.atlas/yellow@2x.png new file mode 100755 index 0000000..e4e50d0 Binary files /dev/null and b/Privyet/Sprites.atlas/yellow@2x.png differ diff --git a/Privyet/SquareShape.swift b/Privyet/SquareShape.swift new file mode 100644 index 0000000..4fd0e3e --- /dev/null +++ b/Privyet/SquareShape.swift @@ -0,0 +1,36 @@ +// +// SquareShape.swift +// Privyet +// +// Created by Amy Bowersox on 5/24/20. +// Copyright © 2020 Erbosoft Metaverse Design Solutions. All rights reserved. +// + +import Foundation +class SquareShape: Shape { + /* + | 0*| 1 | + | 2 | 3 | + + * marks the row/column indicator for this shape + */ + // The square shape wll not rotate + + override var blockRowColumnPositions: [Orientation : Array<(columnDiff: Int, rowDiff: Int)>] { + return [ + Orientation.Zero: [(0, 0), (1, 0), (0, 1), (1, 1)], + Orientation.Ninety: [(0, 0), (1, 0), (0, 1), (1, 1)], + Orientation.OneEighty: [(0, 0), (1, 0), (0, 1), (1, 1)], + Orientation.TwoSeventy: [(0, 0), (1, 0), (0, 1), (1, 1)] + ] + } + + override var bottomBlocksForOrientations: [Orientation : Array] { + return [ + Orientation.Zero: [blocks[ThirdBlockIdx], blocks[FourthBlockIdx]], + Orientation.Ninety: [blocks[ThirdBlockIdx], blocks[FourthBlockIdx]], + Orientation.OneEighty: [blocks[ThirdBlockIdx], blocks[FourthBlockIdx]], + Orientation.TwoSeventy: [blocks[ThirdBlockIdx], blocks[FourthBlockIdx]] + ] + } +} diff --git a/Privyet/TShape.swift b/Privyet/TShape.swift new file mode 100644 index 0000000..f319979 --- /dev/null +++ b/Privyet/TShape.swift @@ -0,0 +1,51 @@ +// +// TShape.swift +// Privyet +// +// Created by Amy Bowersox on 5/24/20. +// Copyright © 2020 Erbosoft Metaverse Design Solutions. All rights reserved. +// + +import Foundation +class TShape: Shape { + /* + Orientation 0: + | * | 0 | | + | 1 | 2 | 3 | + + Orientation 90: + | * | 1 | | + | | 2 | 0 | + | | 3 | | + + Orientation 180: + | * | | | + | 3 | 2 | 1 | + | | 0 | | + + Orientation 270: + | * | 3 | | + | 0 | 2 | | + | | 1 | | + + * marks the row/column indicator for the shape + */ + + override var blockRowColumnPositions: [Orientation : Array<(columnDiff: Int, rowDiff: Int)>] { + return [ + Orientation.Zero: [(1, 0), (0, 1), (1, 1), (2, 1)], + Orientation.Ninety: [(2, 1), (1, 0), (1, 1), (1, 2)], + Orientation.OneEighty: [(1, 2), (2, 1), (1, 1), (0, 1)], + Orientation.TwoSeventy: [(0, 1), (1, 2), (1, 1), (1, 0)] + ] + } + + override var bottomBlocksForOrientations: [Orientation : Array] { + return [ + Orientation.Zero: [blocks[SecondBlockIdx], blocks[ThirdBlockIdx], blocks[FourthBlockIdx]], + Orientation.Ninety: [blocks[FirstBlockIdx], blocks[FourthBlockIdx]], + Orientation.OneEighty: [blocks[FirstBlockIdx], blocks[SecondBlockIdx], blocks[FourthBlockIdx]], + Orientation.TwoSeventy: [blocks[FirstBlockIdx], blocks[SecondBlockIdx]] + ] + } +} diff --git a/Privyet/ZShape.swift b/Privyet/ZShape.swift new file mode 100644 index 0000000..a7740bd --- /dev/null +++ b/Privyet/ZShape.swift @@ -0,0 +1,41 @@ +// +// ZShape.swift +// Privyet +// +// Created by Amy Bowersox on 5/24/20. +// Copyright © 2020 Erbosoft Metaverse Design Solutions. All rights reserved. +// + +import Foundation +class ZShape: Shape { + /* + Orientations 0 and 180: + | * | 0 | + | 2 | 1 | + | 3 | | + + Orientations 90 and 270: + | 0*| 1 | | + | | 2 | 3 | + + * marks the row/column indicator for the shape + */ + + override var blockRowColumnPositions: [Orientation : Array<(columnDiff: Int, rowDiff: Int)>] { + return [ + Orientation.Zero: [(1, 0), (1, 1), (0, 1), (0, 2)], + Orientation.Ninety: [(0, 0), (1, 0), (1, 1), (2, 1)], + Orientation.OneEighty: [(1, 0), (1, 1), (0, 1), (0, 2)], + Orientation.TwoSeventy: [(0, 0), (1, 0), (1, 1), (2, 1)] + ] + } + + override var bottomBlocksForOrientations: [Orientation : Array] { + return [ + Orientation.Zero: [blocks[SecondBlockIdx], blocks[FourthBlockIdx]], + Orientation.Ninety: [blocks[FirstBlockIdx], blocks[ThirdBlockIdx], blocks[FourthBlockIdx]], + Orientation.OneEighty: [blocks[SecondBlockIdx], blocks[FourthBlockIdx]], + Orientation.TwoSeventy: [blocks[FirstBlockIdx], blocks[ThirdBlockIdx], blocks[FourthBlockIdx]] + ] + } +}