diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e69de29
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/Flappy-Bird-Game.iml b/.idea/Flappy-Bird-Game.iml
new file mode 100644
index 0000000..24643cc
--- /dev/null
+++ b/.idea/Flappy-Bird-Game.iml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..8f4877b
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/FlappyBird.xcodeproj/project.pbxproj b/FlappyBird.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..b836761
--- /dev/null
+++ b/FlappyBird.xcodeproj/project.pbxproj
@@ -0,0 +1,473 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 46;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 43745200193D163700654986 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 437451FF193D163700654986 /* AppDelegate.swift */; };
+ 43745202193D163700654986 /* GameScene.sks in Resources */ = {isa = PBXBuildFile; fileRef = 43745201193D163700654986 /* GameScene.sks */; };
+ 43745204193D163800654986 /* GameScene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43745203193D163800654986 /* GameScene.swift */; };
+ 43745206193D163800654986 /* GameViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43745205193D163800654986 /* GameViewController.swift */; };
+ 43745209193D163800654986 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 43745207193D163800654986 /* Main.storyboard */; };
+ 4374520B193D163800654986 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4374520A193D163800654986 /* Images.xcassets */; };
+ 43745217193D163800654986 /* FlappyBirdTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43745216193D163800654986 /* FlappyBirdTests.swift */; };
+ 437A3DBA193D326A00909BA0 /* bird.atlas in Resources */ = {isa = PBXBuildFile; fileRef = 437A3DB9193D326A00909BA0 /* bird.atlas */; };
+ 6E1623E01E24FC4E00FB2C72 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6E1623DF1E24FC4E00FB2C72 /* LaunchScreen.storyboard */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 43745211193D163800654986 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 437451F2193D163700654986 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 437451F9193D163700654986;
+ remoteInfo = FlappyBird;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ 437451FA193D163700654986 /* FlappyBird.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FlappyBird.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 437451FE193D163700654986 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ 437451FF193D163700654986 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ 43745201193D163700654986 /* GameScene.sks */ = {isa = PBXFileReference; lastKnownFileType = file.sks; path = GameScene.sks; sourceTree = ""; };
+ 43745203193D163800654986 /* GameScene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameScene.swift; sourceTree = ""; };
+ 43745205193D163800654986 /* GameViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameViewController.swift; sourceTree = ""; };
+ 43745208193D163800654986 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
+ 4374520A193D163800654986 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
+ 43745210193D163800654986 /* FlappyBirdTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FlappyBirdTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ 43745215193D163800654986 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ 43745216193D163800654986 /* FlappyBirdTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlappyBirdTests.swift; sourceTree = ""; };
+ 437A3DB9193D326A00909BA0 /* bird.atlas */ = {isa = PBXFileReference; lastKnownFileType = folder.skatlas; path = bird.atlas; sourceTree = ""; };
+ 6E1623DF1E24FC4E00FB2C72 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 437451F7193D163700654986 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 4374520D193D163800654986 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 437451F1193D163700654986 = {
+ isa = PBXGroup;
+ children = (
+ 437451FC193D163700654986 /* FlappyBird */,
+ 43745213193D163800654986 /* FlappyBirdTests */,
+ 437451FB193D163700654986 /* Products */,
+ );
+ sourceTree = "";
+ usesTabs = 0;
+ };
+ 437451FB193D163700654986 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 437451FA193D163700654986 /* FlappyBird.app */,
+ 43745210193D163800654986 /* FlappyBirdTests.xctest */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 437451FC193D163700654986 /* FlappyBird */ = {
+ isa = PBXGroup;
+ children = (
+ 6E1623DF1E24FC4E00FB2C72 /* LaunchScreen.storyboard */,
+ 437451FF193D163700654986 /* AppDelegate.swift */,
+ 43745201193D163700654986 /* GameScene.sks */,
+ 43745203193D163800654986 /* GameScene.swift */,
+ 43745205193D163800654986 /* GameViewController.swift */,
+ 43745207193D163800654986 /* Main.storyboard */,
+ 4374520A193D163800654986 /* Images.xcassets */,
+ 437A3DB9193D326A00909BA0 /* bird.atlas */,
+ 437451FD193D163700654986 /* Supporting Files */,
+ );
+ path = FlappyBird;
+ sourceTree = "";
+ };
+ 437451FD193D163700654986 /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ 437451FE193D163700654986 /* Info.plist */,
+ );
+ name = "Supporting Files";
+ sourceTree = "";
+ };
+ 43745213193D163800654986 /* FlappyBirdTests */ = {
+ isa = PBXGroup;
+ children = (
+ 43745216193D163800654986 /* FlappyBirdTests.swift */,
+ 43745214193D163800654986 /* Supporting Files */,
+ );
+ path = FlappyBirdTests;
+ sourceTree = "";
+ };
+ 43745214193D163800654986 /* Supporting Files */ = {
+ isa = PBXGroup;
+ children = (
+ 43745215193D163800654986 /* Info.plist */,
+ );
+ name = "Supporting Files";
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 437451F9193D163700654986 /* FlappyBird */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 4374521A193D163800654986 /* Build configuration list for PBXNativeTarget "FlappyBird" */;
+ buildPhases = (
+ 437451F6193D163700654986 /* Sources */,
+ 437451F7193D163700654986 /* Frameworks */,
+ 437451F8193D163700654986 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = FlappyBird;
+ productName = FlappyBird;
+ productReference = 437451FA193D163700654986 /* FlappyBird.app */;
+ productType = "com.apple.product-type.application";
+ };
+ 4374520F193D163800654986 /* FlappyBirdTests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 4374521D193D163800654986 /* Build configuration list for PBXNativeTarget "FlappyBirdTests" */;
+ buildPhases = (
+ 4374520C193D163800654986 /* Sources */,
+ 4374520D193D163800654986 /* Frameworks */,
+ 4374520E193D163800654986 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 43745212193D163800654986 /* PBXTargetDependency */,
+ );
+ name = FlappyBirdTests;
+ productName = FlappyBirdTests;
+ productReference = 43745210193D163800654986 /* FlappyBirdTests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 437451F2193D163700654986 /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastSwiftMigration = 0700;
+ LastSwiftUpdateCheck = 0700;
+ LastUpgradeCheck = 1110;
+ ORGANIZATIONNAME = Fullstack.io;
+ TargetAttributes = {
+ 437451F9193D163700654986 = {
+ CreatedOnToolsVersion = 6.0;
+ LastSwiftMigration = 1110;
+ };
+ 4374520F193D163800654986 = {
+ CreatedOnToolsVersion = 6.0;
+ LastSwiftMigration = 1110;
+ TestTargetID = 437451F9193D163700654986;
+ };
+ };
+ };
+ buildConfigurationList = 437451F5193D163700654986 /* Build configuration list for PBXProject "FlappyBird" */;
+ compatibilityVersion = "Xcode 3.2";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 437451F1193D163700654986;
+ productRefGroup = 437451FB193D163700654986 /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 437451F9193D163700654986 /* FlappyBird */,
+ 4374520F193D163800654986 /* FlappyBirdTests */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 437451F8193D163700654986 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 4374520B193D163800654986 /* Images.xcassets in Resources */,
+ 43745202193D163700654986 /* GameScene.sks in Resources */,
+ 437A3DBA193D326A00909BA0 /* bird.atlas in Resources */,
+ 6E1623E01E24FC4E00FB2C72 /* LaunchScreen.storyboard in Resources */,
+ 43745209193D163800654986 /* Main.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 4374520E193D163800654986 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 437451F6193D163700654986 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 43745204193D163800654986 /* GameScene.swift in Sources */,
+ 43745206193D163800654986 /* GameViewController.swift in Sources */,
+ 43745200193D163700654986 /* AppDelegate.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 4374520C193D163800654986 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 43745217193D163800654986 /* FlappyBirdTests.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ 43745212193D163800654986 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 437451F9193D163700654986 /* FlappyBird */;
+ targetProxy = 43745211193D163800654986 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+ 43745207193D163800654986 /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 43745208193D163800654986 /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 43745218193D163800654986 /* 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_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_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_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ 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_SYMBOLS_PRIVATE_EXTERN = NO;
+ 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 = 8.0;
+ METAL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 43745219193D163800654986 /* 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_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_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_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = YES;
+ 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 = 8.0;
+ METAL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 4374521B193D163800654986 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ INFOPLIST_FILE = FlappyBird/Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 17.2;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = "io.fullstack.${PRODUCT_NAME:rfc1034identifier}";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_SWIFT3_OBJC_INFERENCE = Default;
+ SWIFT_VERSION = 5.0;
+ };
+ name = Debug;
+ };
+ 4374521C193D163800654986 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ INFOPLIST_FILE = FlappyBird/Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 17.2;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
+ PRODUCT_BUNDLE_IDENTIFIER = "io.fullstack.${PRODUCT_NAME:rfc1034identifier}";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_SWIFT3_OBJC_INFERENCE = Default;
+ SWIFT_VERSION = 5.0;
+ };
+ name = Release;
+ };
+ 4374521E193D163800654986 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/FlappyBird.app/FlappyBird";
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(SDKROOT)/Developer/Library/Frameworks",
+ "$(inherited)",
+ );
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ INFOPLIST_FILE = FlappyBirdTests/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ METAL_ENABLE_DEBUG_INFO = YES;
+ PRODUCT_BUNDLE_IDENTIFIER = "io.fullstack.${PRODUCT_NAME:rfc1034identifier}";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_SWIFT3_OBJC_INFERENCE = On;
+ SWIFT_VERSION = 5.0;
+ TEST_HOST = "$(BUNDLE_LOADER)";
+ };
+ name = Debug;
+ };
+ 4374521F193D163800654986 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/FlappyBird.app/FlappyBird";
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(SDKROOT)/Developer/Library/Frameworks",
+ "$(inherited)",
+ );
+ INFOPLIST_FILE = FlappyBirdTests/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+ METAL_ENABLE_DEBUG_INFO = NO;
+ PRODUCT_BUNDLE_IDENTIFIER = "io.fullstack.${PRODUCT_NAME:rfc1034identifier}";
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_SWIFT3_OBJC_INFERENCE = On;
+ SWIFT_VERSION = 5.0;
+ TEST_HOST = "$(BUNDLE_LOADER)";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 437451F5193D163700654986 /* Build configuration list for PBXProject "FlappyBird" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 43745218193D163800654986 /* Debug */,
+ 43745219193D163800654986 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 4374521A193D163800654986 /* Build configuration list for PBXNativeTarget "FlappyBird" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 4374521B193D163800654986 /* Debug */,
+ 4374521C193D163800654986 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 4374521D193D163800654986 /* Build configuration list for PBXNativeTarget "FlappyBirdTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 4374521E193D163800654986 /* Debug */,
+ 4374521F193D163800654986 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 437451F2193D163700654986 /* Project object */;
+}
diff --git a/FlappyBird.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/FlappyBird.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..379da4d
--- /dev/null
+++ b/FlappyBird.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/FlappyBird.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/FlappyBird.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..18d9810
--- /dev/null
+++ b/FlappyBird.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/FlappyBird.xcodeproj/project.xcworkspace/xcuserdata/davidnguyen.xcuserdatad/UserInterfaceState.xcuserstate b/FlappyBird.xcodeproj/project.xcworkspace/xcuserdata/davidnguyen.xcuserdatad/UserInterfaceState.xcuserstate
new file mode 100644
index 0000000..e3fe0d9
Binary files /dev/null and b/FlappyBird.xcodeproj/project.xcworkspace/xcuserdata/davidnguyen.xcuserdatad/UserInterfaceState.xcuserstate differ
diff --git a/FlappyBird.xcodeproj/xcuserdata/davidnguyen.xcuserdatad/xcschemes/xcschememanagement.plist b/FlappyBird.xcodeproj/xcuserdata/davidnguyen.xcuserdatad/xcschemes/xcschememanagement.plist
new file mode 100644
index 0000000..1d7931a
--- /dev/null
+++ b/FlappyBird.xcodeproj/xcuserdata/davidnguyen.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -0,0 +1,14 @@
+
+
+
+
+ SchemeUserState
+
+ FlappyBird.xcscheme_^#shared#^_
+
+ orderHint
+ 0
+
+
+
+
diff --git a/FlappyBird/AppDelegate.swift b/FlappyBird/AppDelegate.swift
new file mode 100644
index 0000000..37580e3
--- /dev/null
+++ b/FlappyBird/AppDelegate.swift
@@ -0,0 +1,28 @@
+import UIKit
+
+@UIApplicationMain
+class AppDelegate: UIResponder, UIApplicationDelegate {
+
+ var window: UIWindow?
+
+
+ func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
+ return true
+ }
+
+ func applicationWillResignActive(_ application: UIApplication) {
+ }
+
+ func applicationDidEnterBackground(_ application: UIApplication) {
+ }
+
+ func applicationWillEnterForeground(_ application: UIApplication) {
+ }
+
+ func applicationDidBecomeActive(_ application: UIApplication) {
+ }
+
+ func applicationWillTerminate(_ application: UIApplication) {
+ }
+
+}
diff --git a/FlappyBird/Base.lproj/Main.storyboard b/FlappyBird/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..30e8353
--- /dev/null
+++ b/FlappyBird/Base.lproj/Main.storyboard
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FlappyBird/GameScene.sks b/FlappyBird/GameScene.sks
new file mode 100644
index 0000000..9d1dc06
Binary files /dev/null and b/FlappyBird/GameScene.sks differ
diff --git a/FlappyBird/GameScene.swift b/FlappyBird/GameScene.swift
new file mode 100644
index 0000000..7aa134a
--- /dev/null
+++ b/FlappyBird/GameScene.swift
@@ -0,0 +1,247 @@
+import SpriteKit
+
+class GameScene: SKScene, SKPhysicsContactDelegate{
+ let verticalPipeGap = 150.0
+
+ var newGameButton: SKLabelNode!
+
+ var bird:SKSpriteNode!
+ var skyColor:SKColor!
+ var pipeTextureUp:SKTexture!
+ var pipeTextureDown:SKTexture!
+ var movePipesAndRemove:SKAction!
+ var moving:SKNode!
+ var pipes:SKNode!
+ var canRestart = Bool()
+ var scoreLabelNode:SKLabelNode!
+ var score = NSInteger()
+
+ let birdCategory: UInt32 = 1 << 0
+ let worldCategory: UInt32 = 1 << 1
+ let pipeCategory: UInt32 = 1 << 2
+ let scoreCategory: UInt32 = 1 << 3
+
+ override func didMove(to view: SKView) {
+
+ canRestart = true
+
+ self.physicsWorld.gravity = CGVector( dx: 0.0, dy: -5.0 )
+ self.physicsWorld.contactDelegate = self
+
+ skyColor = SKColor(red: 81.0/255.0, green: 192.0/255.0, blue: 201.0/255.0, alpha: 1.0)
+ self.backgroundColor = skyColor
+
+ moving = SKNode()
+ self.addChild(moving)
+ pipes = SKNode()
+ moving.addChild(pipes)
+
+ let groundTexture = SKTexture(imageNamed: "land")
+ groundTexture.filteringMode = .nearest
+
+ let moveGroundSprite = SKAction.moveBy(x: -groundTexture.size().width * 2.0, y: 0, duration: TimeInterval(0.02 * groundTexture.size().width * 2.0))
+ let resetGroundSprite = SKAction.moveBy(x: groundTexture.size().width * 2.0, y: 0, duration: 0.0)
+ let moveGroundSpritesForever = SKAction.repeatForever(SKAction.sequence([moveGroundSprite,resetGroundSprite]))
+
+ for i in 0 ..< 2 + Int(self.frame.size.width / ( groundTexture.size().width * 2 )) {
+ let i = CGFloat(i)
+ let sprite = SKSpriteNode(texture: groundTexture)
+ sprite.setScale(2.0)
+ sprite.position = CGPoint(x: i * sprite.size.width, y: sprite.size.height / 2.0)
+ sprite.run(moveGroundSpritesForever)
+ moving.addChild(sprite)
+ }
+
+ let skyTexture = SKTexture(imageNamed: "sky")
+ skyTexture.filteringMode = .nearest
+
+ let moveSkySprite = SKAction.moveBy(x: -skyTexture.size().width * 2.0, y: 0, duration: TimeInterval(0.1 * skyTexture.size().width * 2.0))
+ let resetSkySprite = SKAction.moveBy(x: skyTexture.size().width * 2.0, y: 0, duration: 0.0)
+ let moveSkySpritesForever = SKAction.repeatForever(SKAction.sequence([moveSkySprite,resetSkySprite]))
+
+ for i in 0 ..< 2 + Int(self.frame.size.width / ( skyTexture.size().width * 2 )) {
+ let i = CGFloat(i)
+ let sprite = SKSpriteNode(texture: skyTexture)
+ sprite.setScale(2.0)
+ sprite.zPosition = -20
+ sprite.position = CGPoint(x: i * sprite.size.width, y: sprite.size.height / 2.0 + groundTexture.size().height * 2.0)
+ sprite.run(moveSkySpritesForever)
+ moving.addChild(sprite)
+ }
+
+ pipeTextureUp = SKTexture(imageNamed: "PipeUp")
+ pipeTextureUp.filteringMode = .nearest
+ pipeTextureDown = SKTexture(imageNamed: "PipeDown")
+ pipeTextureDown.filteringMode = .nearest
+
+ let distanceToMove = CGFloat(self.frame.size.width + 2.0 * pipeTextureUp.size().width)
+ let movePipes = SKAction.moveBy(x: -distanceToMove, y:0.0, duration:TimeInterval(0.01 * distanceToMove))
+ let removePipes = SKAction.removeFromParent()
+ movePipesAndRemove = SKAction.sequence([movePipes, removePipes])
+
+ let spawn = SKAction.run(spawnPipes)
+ let delay = SKAction.wait(forDuration: TimeInterval(2.0))
+ let spawnThenDelay = SKAction.sequence([spawn, delay])
+ let spawnThenDelayForever = SKAction.repeatForever(spawnThenDelay)
+ self.run(spawnThenDelayForever)
+
+ let birdTexture1 = SKTexture(imageNamed: "bird-01")
+ birdTexture1.filteringMode = .nearest
+ let birdTexture2 = SKTexture(imageNamed: "bird-02")
+ birdTexture2.filteringMode = .nearest
+
+ let anim = SKAction.animate(with: [birdTexture1, birdTexture2], timePerFrame: 0.2)
+ let flap = SKAction.repeatForever(anim)
+
+ bird = SKSpriteNode(texture: birdTexture1)
+ bird.setScale(2.0)
+ bird.position = CGPoint(x: self.frame.size.width * 0.35, y:self.frame.size.height * 0.6)
+ bird.run(flap)
+
+
+ bird.physicsBody = SKPhysicsBody(circleOfRadius: bird.size.height / 2.0)
+ bird.physicsBody?.isDynamic = true
+ bird.physicsBody?.allowsRotation = false
+
+ bird.physicsBody?.categoryBitMask = birdCategory
+ bird.physicsBody?.collisionBitMask = worldCategory | pipeCategory
+ bird.physicsBody?.contactTestBitMask = worldCategory | pipeCategory
+
+ self.addChild(bird)
+
+ let ground = SKNode()
+ ground.position = CGPoint(x: 0, y: groundTexture.size().height)
+ ground.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: self.frame.size.width, height: groundTexture.size().height * 2.0))
+ ground.physicsBody?.isDynamic = false
+ ground.physicsBody?.categoryBitMask = worldCategory
+ self.addChild(ground)
+
+ score = 0
+ scoreLabelNode = SKLabelNode(fontNamed:"VT323")
+ scoreLabelNode.fontSize = 36
+ scoreLabelNode.position = CGPoint( x: self.frame.midX, y: 3 * self.frame.size.height / 4 )
+ scoreLabelNode.zPosition = 100
+ scoreLabelNode.text = String(score)
+ self.addChild(scoreLabelNode)
+
+ newGameButton = SKLabelNode(fontNamed: "VT323")
+ newGameButton.text = "New Game"
+ newGameButton.fontSize = 20
+ newGameButton.fontColor = SKColor.white
+ newGameButton.position = CGPoint(x: self.frame.midX, y: scoreLabelNode.frame.minY - newGameButton.frame.height - 70)
+ newGameButton.isHidden = true
+ self.addChild(newGameButton)
+ }
+
+ func spawnPipes() {
+ let pipePair = SKNode()
+ pipePair.position = CGPoint( x: self.frame.size.width + pipeTextureUp.size().width * 2, y: 0 )
+ pipePair.zPosition = -10
+
+ let height = UInt32( self.frame.size.height / 4)
+ let y = Double(arc4random_uniform(height) + height)
+
+ let pipeDown = SKSpriteNode(texture: pipeTextureDown)
+ pipeDown.setScale(2.0)
+ pipeDown.position = CGPoint(x: 0.0, y: y + Double(pipeDown.size.height) + verticalPipeGap)
+
+
+ pipeDown.physicsBody = SKPhysicsBody(rectangleOf: pipeDown.size)
+ pipeDown.physicsBody?.isDynamic = false
+ pipeDown.physicsBody?.categoryBitMask = pipeCategory
+ pipeDown.physicsBody?.contactTestBitMask = birdCategory
+ pipePair.addChild(pipeDown)
+
+ let pipeUp = SKSpriteNode(texture: pipeTextureUp)
+ pipeUp.setScale(2.0)
+ pipeUp.position = CGPoint(x: 0.0, y: y)
+
+ pipeUp.physicsBody = SKPhysicsBody(rectangleOf: pipeUp.size)
+ pipeUp.physicsBody?.isDynamic = false
+ pipeUp.physicsBody?.categoryBitMask = pipeCategory
+ pipeUp.physicsBody?.contactTestBitMask = birdCategory
+ pipePair.addChild(pipeUp)
+
+ let contactNode = SKNode()
+ contactNode.position = CGPoint( x: pipeDown.size.width + bird.size.width / 2, y: self.frame.midY )
+ contactNode.physicsBody = SKPhysicsBody(rectangleOf: CGSize( width: pipeUp.size.width, height: self.frame.size.height ))
+ contactNode.physicsBody?.isDynamic = false
+ contactNode.physicsBody?.categoryBitMask = scoreCategory
+ contactNode.physicsBody?.contactTestBitMask = birdCategory
+ pipePair.addChild(contactNode)
+
+ pipePair.run(movePipesAndRemove)
+ pipes.addChild(pipePair)
+
+ }
+
+ func resetScene (){
+ bird.position = CGPoint(x: self.frame.size.width / 2.5, y: self.frame.midY)
+ bird.physicsBody?.velocity = CGVector( dx: 0, dy: 0 )
+ bird.physicsBody?.collisionBitMask = worldCategory | pipeCategory
+ bird.speed = 1.0
+ bird.zRotation = 0.0
+
+ pipes.removeAllChildren()
+
+ canRestart = false
+
+ score = 0
+ scoreLabelNode.text = String(score)
+
+ moving.speed = 1
+ }
+ override func touchesBegan(_ touches: Set, with event: UIEvent?) {
+ if moving.speed > 0 {
+ for _ in touches {
+ bird.physicsBody?.velocity = CGVector(dx: 0, dy: 0)
+ bird.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 30))
+ }
+ }
+ else if canRestart {
+ for touch in touches {
+ let location = touch.location(in: self)
+ if newGameButton.contains(location) {
+ resetScene()
+ newGameButton.isHidden = true
+ }
+ }
+ }
+ }
+
+ override func update(_ currentTime: TimeInterval) {
+ let value = bird.physicsBody!.velocity.dy * ( bird.physicsBody!.velocity.dy < 0 ? 0.003 : 0.001 )
+ bird.zRotation = min( max(-1, value), 0.5 )
+ }
+
+ func didBegin(_ contact: SKPhysicsContact) {
+ if moving.speed > 0 {
+ if ( contact.bodyA.categoryBitMask & scoreCategory ) == scoreCategory || ( contact.bodyB.categoryBitMask & scoreCategory ) == scoreCategory {
+ score += 1
+ scoreLabelNode.text = String(score)
+
+ scoreLabelNode.run(SKAction.sequence([SKAction.scale(to: 1.5, duration:TimeInterval(0.1)), SKAction.scale(to: 1.0, duration:TimeInterval(0.1))]))
+ }
+ else {
+
+ moving.speed = 0
+
+ bird.physicsBody?.collisionBitMask = worldCategory
+ bird.run( SKAction.rotate(byAngle: CGFloat(Double.pi) * CGFloat(bird.position.y) * 0.01, duration:1), completion:{self.bird.speed = 0 })
+
+
+ self.removeAction(forKey: "flash")
+ self.run(SKAction.sequence([SKAction.repeat(SKAction.sequence([SKAction.run({
+ self.backgroundColor = SKColor(red: 1, green: 0, blue: 0, alpha: 1.0)
+ }),SKAction.wait(forDuration: TimeInterval(0.05)), SKAction.run({
+ self.backgroundColor = self.skyColor
+ }), SKAction.wait(forDuration: TimeInterval(0.05))]), count:4), SKAction.run({
+ self.canRestart = true
+ })]), withKey: "flash")
+ }
+ }
+ else {
+ newGameButton.isHidden = false
+ }
+ }
+}
diff --git a/FlappyBird/GameViewController.swift b/FlappyBird/GameViewController.swift
new file mode 100644
index 0000000..e12f723
--- /dev/null
+++ b/FlappyBird/GameViewController.swift
@@ -0,0 +1,58 @@
+import UIKit
+import SpriteKit
+
+extension SKNode {
+ class func unarchiveFromFile(_ file : String) -> SKNode? {
+
+ let path = Bundle.main.path(forResource: file, ofType: "sks")
+
+ let sceneData: Data?
+ do {
+ sceneData = try Data(contentsOf: URL(fileURLWithPath: path!), options: .mappedIfSafe)
+ } catch _ {
+ sceneData = nil
+ }
+ let archiver = NSKeyedUnarchiver(forReadingWith: sceneData!)
+
+ archiver.setClass(self.classForKeyedUnarchiver(), forClassName: "SKScene")
+ let scene = archiver.decodeObject(forKey: NSKeyedArchiveRootObjectKey) as! GameScene
+ archiver.finishDecoding()
+ return scene
+ }
+}
+
+class GameViewController: UIViewController {
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
+ let skView = self.view as! SKView
+ skView.showsFPS = true
+ skView.showsNodeCount = true
+
+ skView.ignoresSiblingOrder = true
+
+ scene.scaleMode = .aspectFill
+
+ skView.presentScene(scene)
+ }
+ }
+
+ override var shouldAutorotate : Bool {
+ return true
+ }
+
+ override var supportedInterfaceOrientations : UIInterfaceOrientationMask {
+ if UIDevice.current.userInterfaceIdiom == .phone {
+ return UIInterfaceOrientationMask.allButUpsideDown
+ } else {
+ return UIInterfaceOrientationMask.all
+ }
+ }
+
+ override func didReceiveMemoryWarning() {
+ super.didReceiveMemoryWarning()
+ }
+
+}
diff --git a/FlappyBird/Images.xcassets/AppIcon.appiconset/Contents.json b/FlappyBird/Images.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..26f7a9b
--- /dev/null
+++ b/FlappyBird/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,102 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "20x20"
+ },
+ {
+ "idiom" : "iphone",
+ "scale" : "3x",
+ "size" : "20x20"
+ },
+ {
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "29x29"
+ },
+ {
+ "idiom" : "iphone",
+ "scale" : "3x",
+ "size" : "29x29"
+ },
+ {
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "40x40"
+ },
+ {
+ "idiom" : "iphone",
+ "scale" : "3x",
+ "size" : "40x40"
+ },
+ {
+ "filename" : "DALL·E 2024-02-27 14.25.43 - Design a vibrant and engaging app icon that captures the essence of the Flappy Bird game. The icon should feature a stylized, cartoonish bird mid-flig-3.png",
+ "idiom" : "iphone",
+ "scale" : "2x",
+ "size" : "60x60"
+ },
+ {
+ "filename" : "DALL·E 2024-02-27 14.25.43 - Design a vibrant and engaging app icon that captures the essence of the Flappy Bird game. The icon should feature a stylized, cartoonish bird mid-flig-2.png",
+ "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"
+ },
+ {
+ "filename" : "DALL·E 2024-02-27 14.25.43 - Design a vibrant and engaging app icon that captures the essence of the Flappy Bird game. The icon should feature a stylized, cartoonish bird mid-flig-4.png",
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "76x76"
+ },
+ {
+ "idiom" : "ipad",
+ "scale" : "2x",
+ "size" : "83.5x83.5"
+ },
+ {
+ "filename" : "DALL·E 2024-02-27 14.25.43 - Design a vibrant and engaging app icon that captures the essence of the Flappy Bird game. The icon should feature a stylized, cartoonish bird mid-flig.png",
+ "idiom" : "ios-marketing",
+ "scale" : "1x",
+ "size" : "1024x1024"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git "a/FlappyBird/Images.xcassets/AppIcon.appiconset/DALL\302\267E 2024-02-27 14.25.43 - Design a vibrant and engaging app icon that captures the essence of the Flappy Bird game. The icon should feature a stylized, cartoonish bird mid-flig-2.png" "b/FlappyBird/Images.xcassets/AppIcon.appiconset/DALL\302\267E 2024-02-27 14.25.43 - Design a vibrant and engaging app icon that captures the essence of the Flappy Bird game. The icon should feature a stylized, cartoonish bird mid-flig-2.png"
new file mode 100644
index 0000000..60a5988
Binary files /dev/null and "b/FlappyBird/Images.xcassets/AppIcon.appiconset/DALL\302\267E 2024-02-27 14.25.43 - Design a vibrant and engaging app icon that captures the essence of the Flappy Bird game. The icon should feature a stylized, cartoonish bird mid-flig-2.png" differ
diff --git "a/FlappyBird/Images.xcassets/AppIcon.appiconset/DALL\302\267E 2024-02-27 14.25.43 - Design a vibrant and engaging app icon that captures the essence of the Flappy Bird game. The icon should feature a stylized, cartoonish bird mid-flig-3.png" "b/FlappyBird/Images.xcassets/AppIcon.appiconset/DALL\302\267E 2024-02-27 14.25.43 - Design a vibrant and engaging app icon that captures the essence of the Flappy Bird game. The icon should feature a stylized, cartoonish bird mid-flig-3.png"
new file mode 100644
index 0000000..f9824a7
Binary files /dev/null and "b/FlappyBird/Images.xcassets/AppIcon.appiconset/DALL\302\267E 2024-02-27 14.25.43 - Design a vibrant and engaging app icon that captures the essence of the Flappy Bird game. The icon should feature a stylized, cartoonish bird mid-flig-3.png" differ
diff --git "a/FlappyBird/Images.xcassets/AppIcon.appiconset/DALL\302\267E 2024-02-27 14.25.43 - Design a vibrant and engaging app icon that captures the essence of the Flappy Bird game. The icon should feature a stylized, cartoonish bird mid-flig-4.png" "b/FlappyBird/Images.xcassets/AppIcon.appiconset/DALL\302\267E 2024-02-27 14.25.43 - Design a vibrant and engaging app icon that captures the essence of the Flappy Bird game. The icon should feature a stylized, cartoonish bird mid-flig-4.png"
new file mode 100644
index 0000000..c9bc36c
Binary files /dev/null and "b/FlappyBird/Images.xcassets/AppIcon.appiconset/DALL\302\267E 2024-02-27 14.25.43 - Design a vibrant and engaging app icon that captures the essence of the Flappy Bird game. The icon should feature a stylized, cartoonish bird mid-flig-4.png" differ
diff --git "a/FlappyBird/Images.xcassets/AppIcon.appiconset/DALL\302\267E 2024-02-27 14.25.43 - Design a vibrant and engaging app icon that captures the essence of the Flappy Bird game. The icon should feature a stylized, cartoonish bird mid-flig.png" "b/FlappyBird/Images.xcassets/AppIcon.appiconset/DALL\302\267E 2024-02-27 14.25.43 - Design a vibrant and engaging app icon that captures the essence of the Flappy Bird game. The icon should feature a stylized, cartoonish bird mid-flig.png"
new file mode 100644
index 0000000..7b4e6c8
Binary files /dev/null and "b/FlappyBird/Images.xcassets/AppIcon.appiconset/DALL\302\267E 2024-02-27 14.25.43 - Design a vibrant and engaging app icon that captures the essence of the Flappy Bird game. The icon should feature a stylized, cartoonish bird mid-flig.png" differ
diff --git a/FlappyBird/Images.xcassets/Contents.json b/FlappyBird/Images.xcassets/Contents.json
new file mode 100644
index 0000000..da4a164
--- /dev/null
+++ b/FlappyBird/Images.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
\ No newline at end of file
diff --git a/FlappyBird/Images.xcassets/PipeDown.imageset/Contents.json b/FlappyBird/Images.xcassets/PipeDown.imageset/Contents.json
new file mode 100644
index 0000000..43e7808
--- /dev/null
+++ b/FlappyBird/Images.xcassets/PipeDown.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "PipeDown.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/FlappyBird/Images.xcassets/PipeDown.imageset/PipeDown.png b/FlappyBird/Images.xcassets/PipeDown.imageset/PipeDown.png
new file mode 100644
index 0000000..9a7db61
Binary files /dev/null and b/FlappyBird/Images.xcassets/PipeDown.imageset/PipeDown.png differ
diff --git a/FlappyBird/Images.xcassets/PipeUp.imageset/Contents.json b/FlappyBird/Images.xcassets/PipeUp.imageset/Contents.json
new file mode 100644
index 0000000..c546114
--- /dev/null
+++ b/FlappyBird/Images.xcassets/PipeUp.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "PipeUp.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/FlappyBird/Images.xcassets/PipeUp.imageset/PipeUp.png b/FlappyBird/Images.xcassets/PipeUp.imageset/PipeUp.png
new file mode 100644
index 0000000..1a8ade2
Binary files /dev/null and b/FlappyBird/Images.xcassets/PipeUp.imageset/PipeUp.png differ
diff --git a/FlappyBird/Images.xcassets/land.imageset/Contents.json b/FlappyBird/Images.xcassets/land.imageset/Contents.json
new file mode 100644
index 0000000..ea791ee
--- /dev/null
+++ b/FlappyBird/Images.xcassets/land.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "land.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/FlappyBird/Images.xcassets/land.imageset/land.png b/FlappyBird/Images.xcassets/land.imageset/land.png
new file mode 100644
index 0000000..6f34834
Binary files /dev/null and b/FlappyBird/Images.xcassets/land.imageset/land.png differ
diff --git a/FlappyBird/Images.xcassets/scoreboard.imageset/Contents.json b/FlappyBird/Images.xcassets/scoreboard.imageset/Contents.json
new file mode 100644
index 0000000..a15dba1
--- /dev/null
+++ b/FlappyBird/Images.xcassets/scoreboard.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "scoreboard.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/FlappyBird/Images.xcassets/scoreboard.imageset/scoreboard.png b/FlappyBird/Images.xcassets/scoreboard.imageset/scoreboard.png
new file mode 100644
index 0000000..71064f0
Binary files /dev/null and b/FlappyBird/Images.xcassets/scoreboard.imageset/scoreboard.png differ
diff --git a/FlappyBird/Images.xcassets/sky.imageset/Contents.json b/FlappyBird/Images.xcassets/sky.imageset/Contents.json
new file mode 100644
index 0000000..5ced6cb
--- /dev/null
+++ b/FlappyBird/Images.xcassets/sky.imageset/Contents.json
@@ -0,0 +1,21 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "sky.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/FlappyBird/Images.xcassets/sky.imageset/sky.png b/FlappyBird/Images.xcassets/sky.imageset/sky.png
new file mode 100644
index 0000000..c508f88
Binary files /dev/null and b/FlappyBird/Images.xcassets/sky.imageset/sky.png differ
diff --git a/FlappyBird/Info.plist b/FlappyBird/Info.plist
new file mode 100644
index 0000000..b4bf987
--- /dev/null
+++ b/FlappyBird/Info.plist
@@ -0,0 +1,36 @@
+
+
+
+
+ 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
+
+
+
diff --git a/FlappyBird/LaunchScreen.storyboard b/FlappyBird/LaunchScreen.storyboard
new file mode 100644
index 0000000..6d4b260
--- /dev/null
+++ b/FlappyBird/LaunchScreen.storyboard
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FlappyBird/bird.atlas/bird-01.png b/FlappyBird/bird.atlas/bird-01.png
new file mode 100644
index 0000000..5de8a1e
Binary files /dev/null and b/FlappyBird/bird.atlas/bird-01.png differ
diff --git a/FlappyBird/bird.atlas/bird-02.png b/FlappyBird/bird.atlas/bird-02.png
new file mode 100644
index 0000000..2366b29
Binary files /dev/null and b/FlappyBird/bird.atlas/bird-02.png differ
diff --git a/FlappyBird/bird.atlas/bird-03.png b/FlappyBird/bird.atlas/bird-03.png
new file mode 100644
index 0000000..59c719f
Binary files /dev/null and b/FlappyBird/bird.atlas/bird-03.png differ
diff --git a/FlappyBird/bird.atlas/bird-04.png b/FlappyBird/bird.atlas/bird-04.png
new file mode 100644
index 0000000..6019c74
Binary files /dev/null and b/FlappyBird/bird.atlas/bird-04.png differ
diff --git a/FlappyBirdTests/FlappyBirdTests.swift b/FlappyBirdTests/FlappyBirdTests.swift
new file mode 100644
index 0000000..e0f2e7f
--- /dev/null
+++ b/FlappyBirdTests/FlappyBirdTests.swift
@@ -0,0 +1,22 @@
+import XCTest
+
+class FlappyBirdTests: XCTestCase {
+
+ override func setUp() {
+ super.setUp()
+ }
+
+ override func tearDown() {
+ super.tearDown()
+ }
+
+ func testExample() {
+ XCTAssert(true, "Pass")
+ }
+
+ func testPerformanceExample() {
+ self.measure() {
+ }
+ }
+
+}
diff --git a/FlappyBirdTests/Info.plist b/FlappyBirdTests/Info.plist
new file mode 100644
index 0000000..6d32c15
--- /dev/null
+++ b/FlappyBirdTests/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/README.md b/README.md
new file mode 100644
index 0000000..aedc338
--- /dev/null
+++ b/README.md
@@ -0,0 +1,68 @@
+# Flappy Bird Game in Swift
+
+This project is a version of the popular mobile game Flappy Bird, developed using Swift and SpriteKit for iOS. The game aims to replicate the original's gameplay, featuring a bird that the player navigates between a series of obstacles by tapping the screen to make the bird fly. The goal is to achieve the highest possible score by avoiding the pipes.
+
+## Features
+
+- Classic Flappy Bird gameplay
+- Score tracking with high score memory
+- Simple tap control
+- Endless game mode
+- Sound effects and background music
+
+## Requirements
+
+- iOS 14.0+
+- Xcode 12.0+
+- Swift 5.3+
+
+## Installation
+
+To run this game on your device, follow these steps:
+
+1. Clone the repository to your local machine:
+
+```
+git clone https://github.com/hoangsonww/FlappyBirdGame.git
+```
+
+2. Open the project in Xcode:
+
+```
+open FlappyBirdGame.xcodeproj
+```
+
+3. Select your target device or simulator.
+
+4. Press `Cmd + R` to build and run the project on your selected device or simulator.
+
+## How to Play
+
+- Tap anywhere on the screen to make the bird flap its wings and fly.
+- Avoid the pipes by flying through the gaps between them.
+- The game ends if the bird touches the pipes or falls to the ground.
+- Try to beat your highest score!
+
+## Contributing
+
+Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make are **greatly appreciated**.
+
+To contribute to Flappy Bird Game Clone, follow these steps:
+
+1. Fork the project.
+2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`).
+3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`).
+4. Push to the Branch (`git push origin feature/AmazingFeature`).
+5. Open a Pull Request.
+
+## License
+
+Distributed under the MIT License. See `LICENSE.md` for more information.
+
+## Acknowledgements
+
+- [Original Flappy Bird Game](https://en.wikipedia.org/wiki/Flappy_Bird)
+- [SpriteKit Documentation](https://developer.apple.com/documentation/spritekit)
+- [Swift Programming Language](https://swift.org/documentation/)
+
+---