├── .gitignore ├── README.md ├── WappyBird.xcodeproj └── project.pbxproj ├── WappyBird ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ └── LaunchScreen.storyboard ├── Constants.h ├── Helpers │ ├── Math.h │ └── Math.m ├── Info.plist ├── Macros.h ├── Models │ ├── Score.h │ └── Score.m ├── Scenes │ ├── BirdNode.h │ ├── BirdNode.m │ ├── SKScrollingNode.h │ ├── SKScrollingNode.m │ ├── Scene.h │ └── Scene.m ├── ViewController.h ├── ViewController.m ├── images │ ├── back@2x.png │ ├── bird_1@2x.png │ ├── bird_2@2x.png │ ├── bird_3@2x.png │ ├── floor@2x.png │ ├── game_over@2x.png │ ├── get_ready@2x.png │ ├── medal_bronze@2x.png │ ├── medal_gold@2x.png │ ├── medal_plate@2x.png │ ├── medal_platinum@2x.png │ ├── medal_silver@2x.png │ ├── pipe_bottom@2x.png │ ├── pipe_top@2x.png │ └── taptap@2x.png └── main.m ├── WappyBird@Watch Extension ├── Assets.xcassets │ ├── Contents.json │ └── README__ignoredByTemplate__ ├── ExtensionDelegate.h ├── ExtensionDelegate.m ├── Info.plist ├── InterfaceController.h └── InterfaceController.m └── WappyBird@Watch ├── Assets.xcassets ├── AppIcon.appiconset │ └── Contents.json ├── Contents.json └── bird.imageset │ ├── Contents.json │ ├── bird_1@2x.png │ ├── bird_2@2x.png │ └── bird_3@2x.png ├── Base.lproj └── Interface.storyboard └── Info.plist /.gitignore: -------------------------------------------------------------------------------- 1 | #Xcode 2 | .DS_Store 3 | */build/* 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | *.moved-aside 14 | DerivedData 15 | .idea/ 16 | *.hmap 17 | *.xccheckout 18 | 19 | #CocoaPods 20 | Pods 21 | Podfile.lock 22 | *.xcworkspace -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #WappyBird# 2 | 3 | ![Verision](https://img.shields.io/badge/pod-v0.1.0-blue.svg) 4 | ![Platform](https://img.shields.io/badge/platform-watchOS-ff69b4.svg) 5 | ![License](https://img.shields.io/badge/license-MIT-blue.svg) 6 | 7 | Fly your Flappy Bird with Apple Watch! This is an attempt to make Apple Watch a game controller although it's very simple. 8 | 9 | ##Demo## 10 | 11 | ![gif](https://db.tt/ePQVPKUY) 12 | 13 | ##Why## 14 | 1. To show how to use sendMessage in WatchConnectivity framework. 15 | 2. To make Apple Watch a game controller 16 | 17 | ##License## 18 | This code is distributed under the terms and conditions of the MIT license. 19 | 20 | ##Thanks## 21 | Awesome Flappy Bird clone [SprityBird](https://github.com/kirualex/SprityBird) by [@kirualex](https://github.com/kirualex) -------------------------------------------------------------------------------- /WappyBird.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | B823E24F1B8DE88900DA637D /* back@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B823E2401B8DE88900DA637D /* back@2x.png */; settings = {ASSET_TAGS = (); }; }; 11 | B823E2501B8DE88900DA637D /* bird_1@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B823E2411B8DE88900DA637D /* bird_1@2x.png */; settings = {ASSET_TAGS = (); }; }; 12 | B823E2511B8DE88900DA637D /* bird_2@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B823E2421B8DE88900DA637D /* bird_2@2x.png */; settings = {ASSET_TAGS = (); }; }; 13 | B823E2521B8DE88900DA637D /* bird_3@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B823E2431B8DE88900DA637D /* bird_3@2x.png */; settings = {ASSET_TAGS = (); }; }; 14 | B823E2531B8DE88900DA637D /* floor@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B823E2441B8DE88900DA637D /* floor@2x.png */; settings = {ASSET_TAGS = (); }; }; 15 | B823E2541B8DE88900DA637D /* game_over@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B823E2451B8DE88900DA637D /* game_over@2x.png */; settings = {ASSET_TAGS = (); }; }; 16 | B823E2551B8DE88900DA637D /* get_ready@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B823E2461B8DE88900DA637D /* get_ready@2x.png */; settings = {ASSET_TAGS = (); }; }; 17 | B823E2561B8DE88900DA637D /* medal_bronze@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B823E2471B8DE88900DA637D /* medal_bronze@2x.png */; settings = {ASSET_TAGS = (); }; }; 18 | B823E2571B8DE88900DA637D /* medal_gold@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B823E2481B8DE88900DA637D /* medal_gold@2x.png */; settings = {ASSET_TAGS = (); }; }; 19 | B823E2581B8DE88900DA637D /* medal_plate@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B823E2491B8DE88900DA637D /* medal_plate@2x.png */; settings = {ASSET_TAGS = (); }; }; 20 | B823E2591B8DE88900DA637D /* medal_platinum@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B823E24A1B8DE88900DA637D /* medal_platinum@2x.png */; settings = {ASSET_TAGS = (); }; }; 21 | B823E25A1B8DE88900DA637D /* medal_silver@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B823E24B1B8DE88900DA637D /* medal_silver@2x.png */; settings = {ASSET_TAGS = (); }; }; 22 | B823E25B1B8DE88900DA637D /* pipe_bottom@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B823E24C1B8DE88900DA637D /* pipe_bottom@2x.png */; settings = {ASSET_TAGS = (); }; }; 23 | B823E25C1B8DE88900DA637D /* pipe_top@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B823E24D1B8DE88900DA637D /* pipe_top@2x.png */; settings = {ASSET_TAGS = (); }; }; 24 | B823E25D1B8DE88900DA637D /* taptap@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = B823E24E1B8DE88900DA637D /* taptap@2x.png */; settings = {ASSET_TAGS = (); }; }; 25 | B8DFF18C1B8D904D00707959 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = B8DFF18B1B8D904D00707959 /* main.m */; }; 26 | B8DFF18F1B8D904D00707959 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = B8DFF18E1B8D904D00707959 /* AppDelegate.m */; }; 27 | B8DFF1921B8D904D00707959 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B8DFF1911B8D904D00707959 /* ViewController.m */; }; 28 | B8DFF1971B8D904D00707959 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B8DFF1961B8D904D00707959 /* Assets.xcassets */; }; 29 | B8DFF19A1B8D904D00707959 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B8DFF1981B8D904D00707959 /* LaunchScreen.storyboard */; }; 30 | B8DFF1A71B8D907500707959 /* Interface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B8DFF1A51B8D907500707959 /* Interface.storyboard */; }; 31 | B8DFF1A91B8D907500707959 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B8DFF1A81B8D907500707959 /* Assets.xcassets */; }; 32 | B8DFF1B01B8D907500707959 /* WappyBird@Watch Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = B8DFF1AF1B8D907500707959 /* WappyBird@Watch Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 33 | B8DFF1B61B8D907500707959 /* InterfaceController.m in Sources */ = {isa = PBXBuildFile; fileRef = B8DFF1B51B8D907500707959 /* InterfaceController.m */; }; 34 | B8DFF1B91B8D907500707959 /* ExtensionDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = B8DFF1B81B8D907500707959 /* ExtensionDelegate.m */; }; 35 | B8DFF1BB1B8D907500707959 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B8DFF1BA1B8D907500707959 /* Assets.xcassets */; }; 36 | B8DFF1BF1B8D907500707959 /* WappyBird@Watch.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = B8DFF1A31B8D907400707959 /* WappyBird@Watch.app */; }; 37 | B8DFF1CD1B8D93CE00707959 /* Score.m in Sources */ = {isa = PBXBuildFile; fileRef = B8DFF1CC1B8D93CE00707959 /* Score.m */; settings = {ASSET_TAGS = (); }; }; 38 | B8DFF1D51B8D945300707959 /* BirdNode.m in Sources */ = {isa = PBXBuildFile; fileRef = B8DFF1D01B8D945300707959 /* BirdNode.m */; settings = {ASSET_TAGS = (); }; }; 39 | B8DFF1D61B8D945300707959 /* Scene.m in Sources */ = {isa = PBXBuildFile; fileRef = B8DFF1D21B8D945300707959 /* Scene.m */; settings = {ASSET_TAGS = (); }; }; 40 | B8DFF1D71B8D945300707959 /* SKScrollingNode.m in Sources */ = {isa = PBXBuildFile; fileRef = B8DFF1D41B8D945300707959 /* SKScrollingNode.m */; settings = {ASSET_TAGS = (); }; }; 41 | B8DFF1DB1B8D946500707959 /* Math.m in Sources */ = {isa = PBXBuildFile; fileRef = B8DFF1DA1B8D946500707959 /* Math.m */; settings = {ASSET_TAGS = (); }; }; 42 | /* End PBXBuildFile section */ 43 | 44 | /* Begin PBXContainerItemProxy section */ 45 | B8DFF1B11B8D907500707959 /* PBXContainerItemProxy */ = { 46 | isa = PBXContainerItemProxy; 47 | containerPortal = B8DFF17F1B8D904D00707959 /* Project object */; 48 | proxyType = 1; 49 | remoteGlobalIDString = B8DFF1AE1B8D907500707959; 50 | remoteInfo = "WappyBird@Watch Extension"; 51 | }; 52 | B8DFF1BD1B8D907500707959 /* PBXContainerItemProxy */ = { 53 | isa = PBXContainerItemProxy; 54 | containerPortal = B8DFF17F1B8D904D00707959 /* Project object */; 55 | proxyType = 1; 56 | remoteGlobalIDString = B8DFF1A21B8D907400707959; 57 | remoteInfo = "WappyBird@Watch"; 58 | }; 59 | /* End PBXContainerItemProxy section */ 60 | 61 | /* Begin PBXCopyFilesBuildPhase section */ 62 | B8DFF1C31B8D907500707959 /* Embed App Extensions */ = { 63 | isa = PBXCopyFilesBuildPhase; 64 | buildActionMask = 2147483647; 65 | dstPath = ""; 66 | dstSubfolderSpec = 13; 67 | files = ( 68 | B8DFF1B01B8D907500707959 /* WappyBird@Watch Extension.appex in Embed App Extensions */, 69 | ); 70 | name = "Embed App Extensions"; 71 | runOnlyForDeploymentPostprocessing = 0; 72 | }; 73 | B8DFF1C71B8D907500707959 /* Embed Watch Content */ = { 74 | isa = PBXCopyFilesBuildPhase; 75 | buildActionMask = 2147483647; 76 | dstPath = "$(CONTENTS_FOLDER_PATH)/Watch"; 77 | dstSubfolderSpec = 16; 78 | files = ( 79 | B8DFF1BF1B8D907500707959 /* WappyBird@Watch.app in Embed Watch Content */, 80 | ); 81 | name = "Embed Watch Content"; 82 | runOnlyForDeploymentPostprocessing = 0; 83 | }; 84 | /* End PBXCopyFilesBuildPhase section */ 85 | 86 | /* Begin PBXFileReference section */ 87 | B823E2401B8DE88900DA637D /* back@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "back@2x.png"; sourceTree = ""; }; 88 | B823E2411B8DE88900DA637D /* bird_1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "bird_1@2x.png"; sourceTree = ""; }; 89 | B823E2421B8DE88900DA637D /* bird_2@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "bird_2@2x.png"; sourceTree = ""; }; 90 | B823E2431B8DE88900DA637D /* bird_3@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "bird_3@2x.png"; sourceTree = ""; }; 91 | B823E2441B8DE88900DA637D /* floor@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "floor@2x.png"; sourceTree = ""; }; 92 | B823E2451B8DE88900DA637D /* game_over@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "game_over@2x.png"; sourceTree = ""; }; 93 | B823E2461B8DE88900DA637D /* get_ready@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "get_ready@2x.png"; sourceTree = ""; }; 94 | B823E2471B8DE88900DA637D /* medal_bronze@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "medal_bronze@2x.png"; sourceTree = ""; }; 95 | B823E2481B8DE88900DA637D /* medal_gold@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "medal_gold@2x.png"; sourceTree = ""; }; 96 | B823E2491B8DE88900DA637D /* medal_plate@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "medal_plate@2x.png"; sourceTree = ""; }; 97 | B823E24A1B8DE88900DA637D /* medal_platinum@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "medal_platinum@2x.png"; sourceTree = ""; }; 98 | B823E24B1B8DE88900DA637D /* medal_silver@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "medal_silver@2x.png"; sourceTree = ""; }; 99 | B823E24C1B8DE88900DA637D /* pipe_bottom@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "pipe_bottom@2x.png"; sourceTree = ""; }; 100 | B823E24D1B8DE88900DA637D /* pipe_top@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "pipe_top@2x.png"; sourceTree = ""; }; 101 | B823E24E1B8DE88900DA637D /* taptap@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "taptap@2x.png"; sourceTree = ""; }; 102 | B8DFF1871B8D904D00707959 /* WappyBird.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WappyBird.app; sourceTree = BUILT_PRODUCTS_DIR; }; 103 | B8DFF18B1B8D904D00707959 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 104 | B8DFF18D1B8D904D00707959 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 105 | B8DFF18E1B8D904D00707959 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 106 | B8DFF1901B8D904D00707959 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 107 | B8DFF1911B8D904D00707959 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 108 | B8DFF1961B8D904D00707959 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 109 | B8DFF1991B8D904D00707959 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 110 | B8DFF19B1B8D904D00707959 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 111 | B8DFF1A31B8D907400707959 /* WappyBird@Watch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "WappyBird@Watch.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 112 | B8DFF1A61B8D907500707959 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Interface.storyboard; sourceTree = ""; }; 113 | B8DFF1A81B8D907500707959 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 114 | B8DFF1AA1B8D907500707959 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 115 | B8DFF1AF1B8D907500707959 /* WappyBird@Watch Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "WappyBird@Watch Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; 116 | B8DFF1B41B8D907500707959 /* InterfaceController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InterfaceController.h; sourceTree = ""; }; 117 | B8DFF1B51B8D907500707959 /* InterfaceController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InterfaceController.m; sourceTree = ""; }; 118 | B8DFF1B71B8D907500707959 /* ExtensionDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExtensionDelegate.h; sourceTree = ""; }; 119 | B8DFF1B81B8D907500707959 /* ExtensionDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ExtensionDelegate.m; sourceTree = ""; }; 120 | B8DFF1BA1B8D907500707959 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 121 | B8DFF1BC1B8D907500707959 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 122 | B8DFF1C81B8D92A100707959 /* Macros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Macros.h; sourceTree = ""; }; 123 | B8DFF1C91B8D92DE00707959 /* Constants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Constants.h; sourceTree = ""; }; 124 | B8DFF1CB1B8D93CE00707959 /* Score.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Score.h; sourceTree = ""; }; 125 | B8DFF1CC1B8D93CE00707959 /* Score.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Score.m; sourceTree = ""; }; 126 | B8DFF1CF1B8D945300707959 /* BirdNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BirdNode.h; sourceTree = ""; }; 127 | B8DFF1D01B8D945300707959 /* BirdNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BirdNode.m; sourceTree = ""; }; 128 | B8DFF1D11B8D945300707959 /* Scene.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Scene.h; sourceTree = ""; }; 129 | B8DFF1D21B8D945300707959 /* Scene.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Scene.m; sourceTree = ""; }; 130 | B8DFF1D31B8D945300707959 /* SKScrollingNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SKScrollingNode.h; sourceTree = ""; }; 131 | B8DFF1D41B8D945300707959 /* SKScrollingNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SKScrollingNode.m; sourceTree = ""; }; 132 | B8DFF1D91B8D946500707959 /* Math.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Math.h; sourceTree = ""; }; 133 | B8DFF1DA1B8D946500707959 /* Math.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Math.m; sourceTree = ""; }; 134 | /* End PBXFileReference section */ 135 | 136 | /* Begin PBXFrameworksBuildPhase section */ 137 | B8DFF1841B8D904D00707959 /* Frameworks */ = { 138 | isa = PBXFrameworksBuildPhase; 139 | buildActionMask = 2147483647; 140 | files = ( 141 | ); 142 | runOnlyForDeploymentPostprocessing = 0; 143 | }; 144 | B8DFF1AC1B8D907500707959 /* Frameworks */ = { 145 | isa = PBXFrameworksBuildPhase; 146 | buildActionMask = 2147483647; 147 | files = ( 148 | ); 149 | runOnlyForDeploymentPostprocessing = 0; 150 | }; 151 | /* End PBXFrameworksBuildPhase section */ 152 | 153 | /* Begin PBXGroup section */ 154 | B823E23F1B8DE88900DA637D /* images */ = { 155 | isa = PBXGroup; 156 | children = ( 157 | B823E2401B8DE88900DA637D /* back@2x.png */, 158 | B823E2411B8DE88900DA637D /* bird_1@2x.png */, 159 | B823E2421B8DE88900DA637D /* bird_2@2x.png */, 160 | B823E2431B8DE88900DA637D /* bird_3@2x.png */, 161 | B823E2441B8DE88900DA637D /* floor@2x.png */, 162 | B823E2451B8DE88900DA637D /* game_over@2x.png */, 163 | B823E2461B8DE88900DA637D /* get_ready@2x.png */, 164 | B823E2471B8DE88900DA637D /* medal_bronze@2x.png */, 165 | B823E2481B8DE88900DA637D /* medal_gold@2x.png */, 166 | B823E2491B8DE88900DA637D /* medal_plate@2x.png */, 167 | B823E24A1B8DE88900DA637D /* medal_platinum@2x.png */, 168 | B823E24B1B8DE88900DA637D /* medal_silver@2x.png */, 169 | B823E24C1B8DE88900DA637D /* pipe_bottom@2x.png */, 170 | B823E24D1B8DE88900DA637D /* pipe_top@2x.png */, 171 | B823E24E1B8DE88900DA637D /* taptap@2x.png */, 172 | ); 173 | path = images; 174 | sourceTree = ""; 175 | }; 176 | B8DFF17E1B8D904D00707959 = { 177 | isa = PBXGroup; 178 | children = ( 179 | B8DFF1891B8D904D00707959 /* WappyBird */, 180 | B8DFF1A41B8D907500707959 /* WappyBird@Watch */, 181 | B8DFF1B31B8D907500707959 /* WappyBird@Watch Extension */, 182 | B8DFF1881B8D904D00707959 /* Products */, 183 | ); 184 | sourceTree = ""; 185 | }; 186 | B8DFF1881B8D904D00707959 /* Products */ = { 187 | isa = PBXGroup; 188 | children = ( 189 | B8DFF1871B8D904D00707959 /* WappyBird.app */, 190 | B8DFF1A31B8D907400707959 /* WappyBird@Watch.app */, 191 | B8DFF1AF1B8D907500707959 /* WappyBird@Watch Extension.appex */, 192 | ); 193 | name = Products; 194 | sourceTree = ""; 195 | }; 196 | B8DFF1891B8D904D00707959 /* WappyBird */ = { 197 | isa = PBXGroup; 198 | children = ( 199 | B8DFF18D1B8D904D00707959 /* AppDelegate.h */, 200 | B8DFF18E1B8D904D00707959 /* AppDelegate.m */, 201 | B8DFF1C81B8D92A100707959 /* Macros.h */, 202 | B8DFF1C91B8D92DE00707959 /* Constants.h */, 203 | B8DFF1901B8D904D00707959 /* ViewController.h */, 204 | B8DFF1911B8D904D00707959 /* ViewController.m */, 205 | B8DFF1CE1B8D945300707959 /* Scenes */, 206 | B8DFF1CA1B8D93CE00707959 /* Models */, 207 | B8DFF1D81B8D946500707959 /* Helpers */, 208 | B823E23F1B8DE88900DA637D /* images */, 209 | B8DFF1961B8D904D00707959 /* Assets.xcassets */, 210 | B8DFF1981B8D904D00707959 /* LaunchScreen.storyboard */, 211 | B8DFF19B1B8D904D00707959 /* Info.plist */, 212 | B8DFF18A1B8D904D00707959 /* Supporting Files */, 213 | ); 214 | path = WappyBird; 215 | sourceTree = ""; 216 | }; 217 | B8DFF18A1B8D904D00707959 /* Supporting Files */ = { 218 | isa = PBXGroup; 219 | children = ( 220 | B8DFF18B1B8D904D00707959 /* main.m */, 221 | ); 222 | name = "Supporting Files"; 223 | sourceTree = ""; 224 | }; 225 | B8DFF1A41B8D907500707959 /* WappyBird@Watch */ = { 226 | isa = PBXGroup; 227 | children = ( 228 | B8DFF1A51B8D907500707959 /* Interface.storyboard */, 229 | B8DFF1A81B8D907500707959 /* Assets.xcassets */, 230 | B8DFF1AA1B8D907500707959 /* Info.plist */, 231 | ); 232 | path = "WappyBird@Watch"; 233 | sourceTree = ""; 234 | }; 235 | B8DFF1B31B8D907500707959 /* WappyBird@Watch Extension */ = { 236 | isa = PBXGroup; 237 | children = ( 238 | B8DFF1B41B8D907500707959 /* InterfaceController.h */, 239 | B8DFF1B51B8D907500707959 /* InterfaceController.m */, 240 | B8DFF1B71B8D907500707959 /* ExtensionDelegate.h */, 241 | B8DFF1B81B8D907500707959 /* ExtensionDelegate.m */, 242 | B8DFF1BA1B8D907500707959 /* Assets.xcassets */, 243 | B8DFF1BC1B8D907500707959 /* Info.plist */, 244 | ); 245 | path = "WappyBird@Watch Extension"; 246 | sourceTree = ""; 247 | }; 248 | B8DFF1CA1B8D93CE00707959 /* Models */ = { 249 | isa = PBXGroup; 250 | children = ( 251 | B8DFF1CB1B8D93CE00707959 /* Score.h */, 252 | B8DFF1CC1B8D93CE00707959 /* Score.m */, 253 | ); 254 | path = Models; 255 | sourceTree = ""; 256 | }; 257 | B8DFF1CE1B8D945300707959 /* Scenes */ = { 258 | isa = PBXGroup; 259 | children = ( 260 | B8DFF1CF1B8D945300707959 /* BirdNode.h */, 261 | B8DFF1D01B8D945300707959 /* BirdNode.m */, 262 | B8DFF1D11B8D945300707959 /* Scene.h */, 263 | B8DFF1D21B8D945300707959 /* Scene.m */, 264 | B8DFF1D31B8D945300707959 /* SKScrollingNode.h */, 265 | B8DFF1D41B8D945300707959 /* SKScrollingNode.m */, 266 | ); 267 | path = Scenes; 268 | sourceTree = ""; 269 | }; 270 | B8DFF1D81B8D946500707959 /* Helpers */ = { 271 | isa = PBXGroup; 272 | children = ( 273 | B8DFF1D91B8D946500707959 /* Math.h */, 274 | B8DFF1DA1B8D946500707959 /* Math.m */, 275 | ); 276 | path = Helpers; 277 | sourceTree = ""; 278 | }; 279 | /* End PBXGroup section */ 280 | 281 | /* Begin PBXNativeTarget section */ 282 | B8DFF1861B8D904D00707959 /* WappyBird */ = { 283 | isa = PBXNativeTarget; 284 | buildConfigurationList = B8DFF19E1B8D904D00707959 /* Build configuration list for PBXNativeTarget "WappyBird" */; 285 | buildPhases = ( 286 | B8DFF1831B8D904D00707959 /* Sources */, 287 | B8DFF1841B8D904D00707959 /* Frameworks */, 288 | B8DFF1851B8D904D00707959 /* Resources */, 289 | B8DFF1C71B8D907500707959 /* Embed Watch Content */, 290 | ); 291 | buildRules = ( 292 | ); 293 | dependencies = ( 294 | B8DFF1BE1B8D907500707959 /* PBXTargetDependency */, 295 | ); 296 | name = WappyBird; 297 | productName = WappyBird; 298 | productReference = B8DFF1871B8D904D00707959 /* WappyBird.app */; 299 | productType = "com.apple.product-type.application"; 300 | }; 301 | B8DFF1A21B8D907400707959 /* WappyBird@Watch */ = { 302 | isa = PBXNativeTarget; 303 | buildConfigurationList = B8DFF1C41B8D907500707959 /* Build configuration list for PBXNativeTarget "WappyBird@Watch" */; 304 | buildPhases = ( 305 | B8DFF1A11B8D907400707959 /* Resources */, 306 | B8DFF1C31B8D907500707959 /* Embed App Extensions */, 307 | ); 308 | buildRules = ( 309 | ); 310 | dependencies = ( 311 | B8DFF1B21B8D907500707959 /* PBXTargetDependency */, 312 | ); 313 | name = "WappyBird@Watch"; 314 | productName = "WappyBird@Watch"; 315 | productReference = B8DFF1A31B8D907400707959 /* WappyBird@Watch.app */; 316 | productType = "com.apple.product-type.application.watchapp2"; 317 | }; 318 | B8DFF1AE1B8D907500707959 /* WappyBird@Watch Extension */ = { 319 | isa = PBXNativeTarget; 320 | buildConfigurationList = B8DFF1C01B8D907500707959 /* Build configuration list for PBXNativeTarget "WappyBird@Watch Extension" */; 321 | buildPhases = ( 322 | B8DFF1AB1B8D907500707959 /* Sources */, 323 | B8DFF1AC1B8D907500707959 /* Frameworks */, 324 | B8DFF1AD1B8D907500707959 /* Resources */, 325 | ); 326 | buildRules = ( 327 | ); 328 | dependencies = ( 329 | ); 330 | name = "WappyBird@Watch Extension"; 331 | productName = "WappyBird@Watch Extension"; 332 | productReference = B8DFF1AF1B8D907500707959 /* WappyBird@Watch Extension.appex */; 333 | productType = "com.apple.product-type.watchkit2-extension"; 334 | }; 335 | /* End PBXNativeTarget section */ 336 | 337 | /* Begin PBXProject section */ 338 | B8DFF17F1B8D904D00707959 /* Project object */ = { 339 | isa = PBXProject; 340 | attributes = { 341 | LastUpgradeCheck = 0700; 342 | ORGANIZATIONNAME = Peng; 343 | TargetAttributes = { 344 | B8DFF1861B8D904D00707959 = { 345 | CreatedOnToolsVersion = 7.0; 346 | }; 347 | B8DFF1A21B8D907400707959 = { 348 | CreatedOnToolsVersion = 7.0; 349 | }; 350 | B8DFF1AE1B8D907500707959 = { 351 | CreatedOnToolsVersion = 7.0; 352 | }; 353 | }; 354 | }; 355 | buildConfigurationList = B8DFF1821B8D904D00707959 /* Build configuration list for PBXProject "WappyBird" */; 356 | compatibilityVersion = "Xcode 3.2"; 357 | developmentRegion = English; 358 | hasScannedForEncodings = 0; 359 | knownRegions = ( 360 | en, 361 | Base, 362 | ); 363 | mainGroup = B8DFF17E1B8D904D00707959; 364 | productRefGroup = B8DFF1881B8D904D00707959 /* Products */; 365 | projectDirPath = ""; 366 | projectRoot = ""; 367 | targets = ( 368 | B8DFF1861B8D904D00707959 /* WappyBird */, 369 | B8DFF1A21B8D907400707959 /* WappyBird@Watch */, 370 | B8DFF1AE1B8D907500707959 /* WappyBird@Watch Extension */, 371 | ); 372 | }; 373 | /* End PBXProject section */ 374 | 375 | /* Begin PBXResourcesBuildPhase section */ 376 | B8DFF1851B8D904D00707959 /* Resources */ = { 377 | isa = PBXResourcesBuildPhase; 378 | buildActionMask = 2147483647; 379 | files = ( 380 | B823E2511B8DE88900DA637D /* bird_2@2x.png in Resources */, 381 | B823E25B1B8DE88900DA637D /* pipe_bottom@2x.png in Resources */, 382 | B823E2561B8DE88900DA637D /* medal_bronze@2x.png in Resources */, 383 | B823E2541B8DE88900DA637D /* game_over@2x.png in Resources */, 384 | B8DFF19A1B8D904D00707959 /* LaunchScreen.storyboard in Resources */, 385 | B823E2591B8DE88900DA637D /* medal_platinum@2x.png in Resources */, 386 | B823E25D1B8DE88900DA637D /* taptap@2x.png in Resources */, 387 | B823E2501B8DE88900DA637D /* bird_1@2x.png in Resources */, 388 | B823E2531B8DE88900DA637D /* floor@2x.png in Resources */, 389 | B823E2581B8DE88900DA637D /* medal_plate@2x.png in Resources */, 390 | B823E25C1B8DE88900DA637D /* pipe_top@2x.png in Resources */, 391 | B823E2521B8DE88900DA637D /* bird_3@2x.png in Resources */, 392 | B823E24F1B8DE88900DA637D /* back@2x.png in Resources */, 393 | B8DFF1971B8D904D00707959 /* Assets.xcassets in Resources */, 394 | B823E2571B8DE88900DA637D /* medal_gold@2x.png in Resources */, 395 | B823E2551B8DE88900DA637D /* get_ready@2x.png in Resources */, 396 | B823E25A1B8DE88900DA637D /* medal_silver@2x.png in Resources */, 397 | ); 398 | runOnlyForDeploymentPostprocessing = 0; 399 | }; 400 | B8DFF1A11B8D907400707959 /* Resources */ = { 401 | isa = PBXResourcesBuildPhase; 402 | buildActionMask = 2147483647; 403 | files = ( 404 | B8DFF1A91B8D907500707959 /* Assets.xcassets in Resources */, 405 | B8DFF1A71B8D907500707959 /* Interface.storyboard in Resources */, 406 | ); 407 | runOnlyForDeploymentPostprocessing = 0; 408 | }; 409 | B8DFF1AD1B8D907500707959 /* Resources */ = { 410 | isa = PBXResourcesBuildPhase; 411 | buildActionMask = 2147483647; 412 | files = ( 413 | B8DFF1BB1B8D907500707959 /* Assets.xcassets in Resources */, 414 | ); 415 | runOnlyForDeploymentPostprocessing = 0; 416 | }; 417 | /* End PBXResourcesBuildPhase section */ 418 | 419 | /* Begin PBXSourcesBuildPhase section */ 420 | B8DFF1831B8D904D00707959 /* Sources */ = { 421 | isa = PBXSourcesBuildPhase; 422 | buildActionMask = 2147483647; 423 | files = ( 424 | B8DFF1D71B8D945300707959 /* SKScrollingNode.m in Sources */, 425 | B8DFF1D61B8D945300707959 /* Scene.m in Sources */, 426 | B8DFF1921B8D904D00707959 /* ViewController.m in Sources */, 427 | B8DFF1DB1B8D946500707959 /* Math.m in Sources */, 428 | B8DFF1D51B8D945300707959 /* BirdNode.m in Sources */, 429 | B8DFF18F1B8D904D00707959 /* AppDelegate.m in Sources */, 430 | B8DFF1CD1B8D93CE00707959 /* Score.m in Sources */, 431 | B8DFF18C1B8D904D00707959 /* main.m in Sources */, 432 | ); 433 | runOnlyForDeploymentPostprocessing = 0; 434 | }; 435 | B8DFF1AB1B8D907500707959 /* Sources */ = { 436 | isa = PBXSourcesBuildPhase; 437 | buildActionMask = 2147483647; 438 | files = ( 439 | B8DFF1B91B8D907500707959 /* ExtensionDelegate.m in Sources */, 440 | B8DFF1B61B8D907500707959 /* InterfaceController.m in Sources */, 441 | ); 442 | runOnlyForDeploymentPostprocessing = 0; 443 | }; 444 | /* End PBXSourcesBuildPhase section */ 445 | 446 | /* Begin PBXTargetDependency section */ 447 | B8DFF1B21B8D907500707959 /* PBXTargetDependency */ = { 448 | isa = PBXTargetDependency; 449 | target = B8DFF1AE1B8D907500707959 /* WappyBird@Watch Extension */; 450 | targetProxy = B8DFF1B11B8D907500707959 /* PBXContainerItemProxy */; 451 | }; 452 | B8DFF1BE1B8D907500707959 /* PBXTargetDependency */ = { 453 | isa = PBXTargetDependency; 454 | target = B8DFF1A21B8D907400707959 /* WappyBird@Watch */; 455 | targetProxy = B8DFF1BD1B8D907500707959 /* PBXContainerItemProxy */; 456 | }; 457 | /* End PBXTargetDependency section */ 458 | 459 | /* Begin PBXVariantGroup section */ 460 | B8DFF1981B8D904D00707959 /* LaunchScreen.storyboard */ = { 461 | isa = PBXVariantGroup; 462 | children = ( 463 | B8DFF1991B8D904D00707959 /* Base */, 464 | ); 465 | name = LaunchScreen.storyboard; 466 | sourceTree = ""; 467 | }; 468 | B8DFF1A51B8D907500707959 /* Interface.storyboard */ = { 469 | isa = PBXVariantGroup; 470 | children = ( 471 | B8DFF1A61B8D907500707959 /* Base */, 472 | ); 473 | name = Interface.storyboard; 474 | sourceTree = ""; 475 | }; 476 | /* End PBXVariantGroup section */ 477 | 478 | /* Begin XCBuildConfiguration section */ 479 | B8DFF19C1B8D904D00707959 /* Debug */ = { 480 | isa = XCBuildConfiguration; 481 | buildSettings = { 482 | ALWAYS_SEARCH_USER_PATHS = NO; 483 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 484 | CLANG_CXX_LIBRARY = "libc++"; 485 | CLANG_ENABLE_MODULES = YES; 486 | CLANG_ENABLE_OBJC_ARC = YES; 487 | CLANG_WARN_BOOL_CONVERSION = YES; 488 | CLANG_WARN_CONSTANT_CONVERSION = YES; 489 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 490 | CLANG_WARN_EMPTY_BODY = YES; 491 | CLANG_WARN_ENUM_CONVERSION = YES; 492 | CLANG_WARN_INT_CONVERSION = YES; 493 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 494 | CLANG_WARN_UNREACHABLE_CODE = YES; 495 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 496 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 497 | COPY_PHASE_STRIP = NO; 498 | DEBUG_INFORMATION_FORMAT = dwarf; 499 | ENABLE_STRICT_OBJC_MSGSEND = YES; 500 | ENABLE_TESTABILITY = YES; 501 | GCC_C_LANGUAGE_STANDARD = gnu99; 502 | GCC_DYNAMIC_NO_PIC = NO; 503 | GCC_NO_COMMON_BLOCKS = YES; 504 | GCC_OPTIMIZATION_LEVEL = 0; 505 | GCC_PREPROCESSOR_DEFINITIONS = ( 506 | "DEBUG=1", 507 | "$(inherited)", 508 | ); 509 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 510 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 511 | GCC_WARN_UNDECLARED_SELECTOR = YES; 512 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 513 | GCC_WARN_UNUSED_FUNCTION = YES; 514 | GCC_WARN_UNUSED_VARIABLE = YES; 515 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 516 | MTL_ENABLE_DEBUG_INFO = YES; 517 | ONLY_ACTIVE_ARCH = YES; 518 | SDKROOT = iphoneos; 519 | }; 520 | name = Debug; 521 | }; 522 | B8DFF19D1B8D904D00707959 /* Release */ = { 523 | isa = XCBuildConfiguration; 524 | buildSettings = { 525 | ALWAYS_SEARCH_USER_PATHS = NO; 526 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 527 | CLANG_CXX_LIBRARY = "libc++"; 528 | CLANG_ENABLE_MODULES = YES; 529 | CLANG_ENABLE_OBJC_ARC = YES; 530 | CLANG_WARN_BOOL_CONVERSION = YES; 531 | CLANG_WARN_CONSTANT_CONVERSION = YES; 532 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 533 | CLANG_WARN_EMPTY_BODY = YES; 534 | CLANG_WARN_ENUM_CONVERSION = YES; 535 | CLANG_WARN_INT_CONVERSION = YES; 536 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 537 | CLANG_WARN_UNREACHABLE_CODE = YES; 538 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 539 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 540 | COPY_PHASE_STRIP = NO; 541 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 542 | ENABLE_NS_ASSERTIONS = NO; 543 | ENABLE_STRICT_OBJC_MSGSEND = YES; 544 | GCC_C_LANGUAGE_STANDARD = gnu99; 545 | GCC_NO_COMMON_BLOCKS = YES; 546 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 547 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 548 | GCC_WARN_UNDECLARED_SELECTOR = YES; 549 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 550 | GCC_WARN_UNUSED_FUNCTION = YES; 551 | GCC_WARN_UNUSED_VARIABLE = YES; 552 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 553 | MTL_ENABLE_DEBUG_INFO = NO; 554 | SDKROOT = iphoneos; 555 | VALIDATE_PRODUCT = YES; 556 | }; 557 | name = Release; 558 | }; 559 | B8DFF19F1B8D904D00707959 /* Debug */ = { 560 | isa = XCBuildConfiguration; 561 | buildSettings = { 562 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 563 | INFOPLIST_FILE = WappyBird/Info.plist; 564 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 565 | PRODUCT_BUNDLE_IDENTIFIER = watch.develop.WappyBird; 566 | PRODUCT_NAME = "$(TARGET_NAME)"; 567 | }; 568 | name = Debug; 569 | }; 570 | B8DFF1A01B8D904D00707959 /* Release */ = { 571 | isa = XCBuildConfiguration; 572 | buildSettings = { 573 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 574 | INFOPLIST_FILE = WappyBird/Info.plist; 575 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 576 | PRODUCT_BUNDLE_IDENTIFIER = watch.develop.WappyBird; 577 | PRODUCT_NAME = "$(TARGET_NAME)"; 578 | }; 579 | name = Release; 580 | }; 581 | B8DFF1C11B8D907500707959 /* Debug */ = { 582 | isa = XCBuildConfiguration; 583 | buildSettings = { 584 | INFOPLIST_FILE = "WappyBird@Watch Extension/Info.plist"; 585 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; 586 | PRODUCT_BUNDLE_IDENTIFIER = watch.develop.WappyBird.watchkitapp.watchkitextension; 587 | PRODUCT_NAME = "${TARGET_NAME}"; 588 | SDKROOT = watchos; 589 | SKIP_INSTALL = YES; 590 | TARGETED_DEVICE_FAMILY = 4; 591 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 592 | }; 593 | name = Debug; 594 | }; 595 | B8DFF1C21B8D907500707959 /* Release */ = { 596 | isa = XCBuildConfiguration; 597 | buildSettings = { 598 | INFOPLIST_FILE = "WappyBird@Watch Extension/Info.plist"; 599 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; 600 | PRODUCT_BUNDLE_IDENTIFIER = watch.develop.WappyBird.watchkitapp.watchkitextension; 601 | PRODUCT_NAME = "${TARGET_NAME}"; 602 | SDKROOT = watchos; 603 | SKIP_INSTALL = YES; 604 | TARGETED_DEVICE_FAMILY = 4; 605 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 606 | }; 607 | name = Release; 608 | }; 609 | B8DFF1C51B8D907500707959 /* Debug */ = { 610 | isa = XCBuildConfiguration; 611 | buildSettings = { 612 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 613 | IBSC_MODULE = WappyBird_Watch_Extension; 614 | INFOPLIST_FILE = "WappyBird@Watch/Info.plist"; 615 | PRODUCT_BUNDLE_IDENTIFIER = watch.develop.WappyBird.watchkitapp; 616 | PRODUCT_NAME = "$(TARGET_NAME)"; 617 | SDKROOT = watchos; 618 | SKIP_INSTALL = YES; 619 | TARGETED_DEVICE_FAMILY = 4; 620 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 621 | }; 622 | name = Debug; 623 | }; 624 | B8DFF1C61B8D907500707959 /* Release */ = { 625 | isa = XCBuildConfiguration; 626 | buildSettings = { 627 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 628 | IBSC_MODULE = WappyBird_Watch_Extension; 629 | INFOPLIST_FILE = "WappyBird@Watch/Info.plist"; 630 | PRODUCT_BUNDLE_IDENTIFIER = watch.develop.WappyBird.watchkitapp; 631 | PRODUCT_NAME = "$(TARGET_NAME)"; 632 | SDKROOT = watchos; 633 | SKIP_INSTALL = YES; 634 | TARGETED_DEVICE_FAMILY = 4; 635 | WATCHOS_DEPLOYMENT_TARGET = 2.0; 636 | }; 637 | name = Release; 638 | }; 639 | /* End XCBuildConfiguration section */ 640 | 641 | /* Begin XCConfigurationList section */ 642 | B8DFF1821B8D904D00707959 /* Build configuration list for PBXProject "WappyBird" */ = { 643 | isa = XCConfigurationList; 644 | buildConfigurations = ( 645 | B8DFF19C1B8D904D00707959 /* Debug */, 646 | B8DFF19D1B8D904D00707959 /* Release */, 647 | ); 648 | defaultConfigurationIsVisible = 0; 649 | defaultConfigurationName = Release; 650 | }; 651 | B8DFF19E1B8D904D00707959 /* Build configuration list for PBXNativeTarget "WappyBird" */ = { 652 | isa = XCConfigurationList; 653 | buildConfigurations = ( 654 | B8DFF19F1B8D904D00707959 /* Debug */, 655 | B8DFF1A01B8D904D00707959 /* Release */, 656 | ); 657 | defaultConfigurationIsVisible = 0; 658 | defaultConfigurationName = Release; 659 | }; 660 | B8DFF1C01B8D907500707959 /* Build configuration list for PBXNativeTarget "WappyBird@Watch Extension" */ = { 661 | isa = XCConfigurationList; 662 | buildConfigurations = ( 663 | B8DFF1C11B8D907500707959 /* Debug */, 664 | B8DFF1C21B8D907500707959 /* Release */, 665 | ); 666 | defaultConfigurationIsVisible = 0; 667 | defaultConfigurationName = Release; 668 | }; 669 | B8DFF1C41B8D907500707959 /* Build configuration list for PBXNativeTarget "WappyBird@Watch" */ = { 670 | isa = XCConfigurationList; 671 | buildConfigurations = ( 672 | B8DFF1C51B8D907500707959 /* Debug */, 673 | B8DFF1C61B8D907500707959 /* Release */, 674 | ); 675 | defaultConfigurationIsVisible = 0; 676 | defaultConfigurationName = Release; 677 | }; 678 | /* End XCConfigurationList section */ 679 | }; 680 | rootObject = B8DFF17F1B8D904D00707959 /* Project object */; 681 | } 682 | -------------------------------------------------------------------------------- /WappyBird/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // WappyBird 4 | // 5 | // Created by Peng on 8/26/15. 6 | // Copyright © 2015 Peng. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /WappyBird/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // WappyBird 4 | // 5 | // Created by Peng on 8/26/15. 6 | // Copyright © 2015 Peng. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "ViewController.h" 11 | 12 | @interface AppDelegate () 13 | 14 | @end 15 | 16 | @implementation AppDelegate 17 | 18 | 19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 20 | // Override point for customization after application launch. 21 | 22 | 23 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 24 | 25 | ViewController *vc = [[ViewController alloc] init]; 26 | 27 | self.window.rootViewController = vc; 28 | 29 | [self.window makeKeyAndVisible]; 30 | 31 | return YES; 32 | } 33 | 34 | - (void)applicationWillResignActive:(UIApplication *)application { 35 | // 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. 36 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 37 | } 38 | 39 | - (void)applicationDidEnterBackground:(UIApplication *)application { 40 | // 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. 41 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 42 | } 43 | 44 | - (void)applicationWillEnterForeground:(UIApplication *)application { 45 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 46 | } 47 | 48 | - (void)applicationDidBecomeActive:(UIApplication *)application { 49 | // 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. 50 | } 51 | 52 | - (void)applicationWillTerminate:(UIApplication *)application { 53 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /WappyBird/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /WappyBird/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /WappyBird/Constants.h: -------------------------------------------------------------------------------- 1 | // 2 | // Constants.h 3 | 4 | #import "AppDelegate.h" 5 | #import "Macros.h" 6 | 7 | 8 | // Physic collision bitmasks 9 | 10 | static const uint32_t backBitMask = 0x1 << 0; 11 | static const uint32_t birdBitMask = 0x1 << 1; 12 | static const uint32_t floorBitMask = 0x1 << 2; 13 | static const uint32_t blockBitMask = 0x1 << 3; -------------------------------------------------------------------------------- /WappyBird/Helpers/Math.h: -------------------------------------------------------------------------------- 1 | // 2 | // Math.h 3 | // spritybird 4 | // 5 | // Created by Alexis Creuzot on 09/02/2014. 6 | // Copyright (c) 2014 Alexis Creuzot. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface Math : NSObject 12 | 13 | + (void) setRandomSeed:(unsigned int) seed; 14 | + (float) randomFloatBetween:(float) min and:(float) max; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /WappyBird/Helpers/Math.m: -------------------------------------------------------------------------------- 1 | // 2 | // Math.m 3 | // spritybird 4 | // 5 | // Created by Alexis Creuzot on 09/02/2014. 6 | // Copyright (c) 2014 Alexis Creuzot. All rights reserved. 7 | // 8 | 9 | #import "Math.h" 10 | 11 | static unsigned int _seed = 0; 12 | 13 | @implementation Math 14 | 15 | + (void)setRandomSeed:(unsigned int)seed 16 | { 17 | _seed = seed; 18 | srand(_seed); 19 | } 20 | 21 | + (float) randomFloatBetween:(float) min and:(float) max{ 22 | 23 | float random = ((rand()%RAND_MAX)/(RAND_MAX*1.0))*(max-min)+min; 24 | return random; 25 | } 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /WappyBird/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /WappyBird/Macros.h: -------------------------------------------------------------------------------- 1 | // 2 | // Macros.h 3 | 4 | /////////////////////////////////////////// 5 | // Debugging 6 | /////////////////////////////////////////// 7 | #ifdef DEBUG 8 | # define DLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__) 9 | #else 10 | # define DLog(...) 11 | #endif 12 | 13 | /////////////////////////////////////////// 14 | // App 15 | /////////////////////////////////////////// 16 | 17 | #define APP_VERSION [[NSBundle mainBundle] infoDictionary][@"CFBundleShortVersionString"] 18 | 19 | /////////////////////////////////////////// 20 | // Views 21 | /////////////////////////////////////////// 22 | #define WIDTH(view) view.frame.size.width 23 | #define HEIGHT(view) view.frame.size.height 24 | #define X(view) view.frame.origin.x 25 | #define Y(view) view.frame.origin.y 26 | #define LEFT(view) view.frame.origin.x 27 | #define TOP(view) view.frame.origin.y 28 | #define BOTTOM(view) (view.frame.origin.y + view.frame.size.height) 29 | #define RIGHT(view) (view.frame.origin.x + view.frame.size.width) 30 | 31 | /////////////////////////////////////////// 32 | // Device & OS 33 | /////////////////////////////////////////// 34 | 35 | #define IS_IPAD() (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) 36 | #define Is4Inches() ([[UIScreen mainScreen] bounds].size.height == 568) 37 | #define Is3_5Inches() ([[UIScreen mainScreen] bounds].size.height == 480.0f) 38 | #define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame) 39 | #define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending) 40 | #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) 41 | #define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending) 42 | #define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending) 43 | 44 | 45 | /////////////////////////////////////////// 46 | // Random 47 | /////////////////////////////////////////// 48 | #define RANDOM_MINUS_1_TO_1() ((random() / (GLfloat)0x3fffffff )-1.0f) 49 | #define RANDOM_0_TO_1() ((random() / (GLfloat)0x7fffffff )) 50 | 51 | /////////////////////////////////////////// 52 | // Networking 53 | /////////////////////////////////////////// 54 | #define IsConnected() !([[Reachability reachabilityForInternetConnection] currentReachabilityStatus] == NotReachable) 55 | #define ShowNetworkActivityIndicator() [UIApplication sharedApplication].networkActivityIndicatorVisible = YES 56 | #define HideNetworkActivityIndicator() [UIApplication sharedApplication].networkActivityIndicatorVisible = NO 57 | 58 | /////////////////////////////////////////// 59 | // Misc 60 | /////////////////////////////////////////// 61 | #define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI) 62 | #define URLIFY(urlString) [NSURL URLWithString:urlString] 63 | #define F(string, args...) [NSString stringWithFormat:string, args] 64 | #define ALERT(title, msg) [[[UIAlertView alloc] initWithTitle:title message:msg delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show] 65 | -------------------------------------------------------------------------------- /WappyBird/Models/Score.h: -------------------------------------------------------------------------------- 1 | // 2 | // Score.h 3 | // spritybird 4 | // 5 | // Created by Alexis Creuzot on 16/02/2014. 6 | // Copyright (c) 2014 Alexis Creuzot. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #define kBestScoreKey @"BestScore" 12 | 13 | @interface Score : NSObject 14 | 15 | + (void) registerScore:(NSInteger) score; 16 | + (void) setBestScore:(NSInteger) bestScore; 17 | + (NSInteger) bestScore; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /WappyBird/Models/Score.m: -------------------------------------------------------------------------------- 1 | // 2 | // Score.m 3 | // spritybird 4 | // 5 | // Created by Alexis Creuzot on 16/02/2014. 6 | // Copyright (c) 2014 Alexis Creuzot. All rights reserved. 7 | // 8 | 9 | #import "Score.h" 10 | 11 | @implementation Score 12 | 13 | + (void)registerScore:(NSInteger)score 14 | { 15 | if(score > [Score bestScore]){ 16 | [Score setBestScore:score]; 17 | } 18 | } 19 | 20 | + (void) setBestScore:(NSInteger) bestScore 21 | { 22 | [[NSUserDefaults standardUserDefaults] setInteger:bestScore forKey:kBestScoreKey]; 23 | [[NSUserDefaults standardUserDefaults] synchronize]; 24 | } 25 | 26 | + (NSInteger) bestScore 27 | { 28 | return [[NSUserDefaults standardUserDefaults] integerForKey:kBestScoreKey]; 29 | } 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /WappyBird/Scenes/BirdNode.h: -------------------------------------------------------------------------------- 1 | // 2 | // BirdNode.h 3 | // spritybird 4 | // 5 | // Created by Alexis Creuzot on 16/02/2014. 6 | // Copyright (c) 2014 Alexis Creuzot. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BirdNode : SKSpriteNode 12 | - (void) update:(NSUInteger) currentTime; 13 | - (void) startPlaying; 14 | - (void) bounce; 15 | @end 16 | -------------------------------------------------------------------------------- /WappyBird/Scenes/BirdNode.m: -------------------------------------------------------------------------------- 1 | // 2 | // BirdNode.m 3 | // spritybird 4 | // 5 | // Created by Alexis Creuzot on 16/02/2014. 6 | // Copyright (c) 2014 Alexis Creuzot. All rights reserved. 7 | // 8 | 9 | #import "Constants.h" 10 | #import "BirdNode.h" 11 | 12 | #define VERTICAL_SPEED 1 13 | #define VERTICAL_DELTA 5.0 14 | 15 | @interface BirdNode () 16 | @property (strong,nonatomic) SKAction * flap; 17 | @property (strong,nonatomic) SKAction * flapForever; 18 | @end 19 | 20 | @implementation BirdNode 21 | 22 | static CGFloat deltaPosY = 0; 23 | static bool goingUp = false; 24 | 25 | - (id)init 26 | { 27 | if(self = [super init]){ 28 | 29 | // TODO : use texture atlas 30 | SKTexture* birdTexture1 = [SKTexture textureWithImageNamed:@"bird_1"]; 31 | birdTexture1.filteringMode = SKTextureFilteringNearest; 32 | SKTexture* birdTexture2 = [SKTexture textureWithImageNamed:@"bird_2"]; 33 | birdTexture2.filteringMode = SKTextureFilteringNearest; 34 | SKTexture* birdTexture3 = [SKTexture textureWithImageNamed:@"bird_3"]; 35 | birdTexture3.filteringMode = SKTextureFilteringNearest; 36 | 37 | self = [BirdNode spriteNodeWithTexture:birdTexture1]; 38 | 39 | self.flap = [SKAction animateWithTextures:@[birdTexture1, birdTexture2,birdTexture3] timePerFrame:0.2]; 40 | self.flapForever = [SKAction repeatActionForever:self.flap]; 41 | 42 | [self setTexture:birdTexture1]; 43 | [self runAction:self.flapForever withKey:@"flapForever"]; 44 | } 45 | return self; 46 | } 47 | 48 | - (void) update:(NSUInteger) currentTime 49 | { 50 | if(!self.physicsBody){ 51 | if(deltaPosY > VERTICAL_DELTA){ 52 | goingUp = false; 53 | } 54 | if(deltaPosY < -VERTICAL_DELTA){ 55 | goingUp = true; 56 | } 57 | 58 | float displacement = (goingUp)? VERTICAL_SPEED : -VERTICAL_SPEED; 59 | self.position = CGPointMake(self.position.x, self.position.y + displacement); 60 | deltaPosY += displacement; 61 | } 62 | 63 | // Rotate body based on Y velocity (front toward direction) 64 | self.zRotation = M_PI * self.physicsBody.velocity.dy * 0.0005; 65 | 66 | } 67 | 68 | - (void) startPlaying 69 | { 70 | deltaPosY = 0; 71 | [self setPhysicsBody:[SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(26, 18)]]; 72 | self.physicsBody.categoryBitMask = birdBitMask; 73 | self.physicsBody.mass = 0.1; 74 | [self removeActionForKey:@"flapForever"]; 75 | } 76 | 77 | - (void) bounce 78 | { 79 | [self.physicsBody setVelocity:CGVectorMake(0, 0)]; 80 | [self.physicsBody applyImpulse:CGVectorMake(0, 40)]; 81 | [self runAction:self.flap]; 82 | } 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /WappyBird/Scenes/SKScrollingNode.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKScrollingNode.h 3 | // spritybird 4 | // 5 | // Created by Alexis Creuzot on 09/02/2014. 6 | // Copyright (c) 2014 Alexis Creuzot. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface SKScrollingNode : SKSpriteNode 13 | 14 | @property (nonatomic) CGFloat scrollingSpeed; 15 | 16 | + (id) scrollingNodeWithImageNamed:(NSString *)name inContainerWidth:(float) width; 17 | - (void) update:(NSTimeInterval)currentTime; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /WappyBird/Scenes/SKScrollingNode.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKScrollingNode.m 3 | // spritybird 4 | // 5 | // Created by Alexis Creuzot on 09/02/2014. 6 | // Copyright (c) 2014 Alexis Creuzot. All rights reserved. 7 | // 8 | 9 | #import "SKScrollingNode.h" 10 | 11 | @implementation SKScrollingNode 12 | 13 | 14 | + (id) scrollingNodeWithImageNamed:(NSString *)name inContainerWidth:(float) width 15 | { 16 | UIImage * image = [UIImage imageNamed:name]; 17 | 18 | SKScrollingNode * realNode = [SKScrollingNode spriteNodeWithColor:[UIColor clearColor] size:CGSizeMake(width, image.size.height)]; 19 | realNode.scrollingSpeed = 1; 20 | 21 | float total = 0; 22 | while(total<(width + image.size.width)){ 23 | SKSpriteNode * child = [SKSpriteNode spriteNodeWithImageNamed:name ]; 24 | [child setAnchorPoint:CGPointZero]; 25 | [child setPosition:CGPointMake(total, 0)]; 26 | [realNode addChild:child]; 27 | total+=child.size.width; 28 | } 29 | 30 | return realNode; 31 | } 32 | 33 | 34 | - (void) update:(NSTimeInterval)currentTime 35 | { 36 | [self.children enumerateObjectsUsingBlock:^(SKNode * child, NSUInteger idx, BOOL *stop) { 37 | 38 | SKSpriteNode *spriteChild = (SKSpriteNode *)child; 39 | 40 | spriteChild.position = CGPointMake(spriteChild.position.x-self.scrollingSpeed, spriteChild.position.y); 41 | if (spriteChild.position.x <= -spriteChild.size.width){ 42 | float delta = spriteChild.position.x+spriteChild.size.width; 43 | spriteChild.position = CGPointMake(spriteChild.size.width*(self.children.count-1)+delta, child.position.y); 44 | } 45 | }]; 46 | } 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /WappyBird/Scenes/Scene.h: -------------------------------------------------------------------------------- 1 | // 2 | // BouncingScene.h 3 | // Bouncing 4 | // 5 | // Created by Seung Kyun Nam on 13. 7. 24.. 6 | // Copyright (c) 2013년 Seung Kyun Nam. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @protocol SceneDelegate 13 | - (void) eventStart; 14 | - (void) eventPlay; 15 | - (void) eventWasted; 16 | @end 17 | 18 | @interface Scene : SKScene 19 | 20 | @property (unsafe_unretained,nonatomic) id delegate; 21 | @property (nonatomic) NSInteger score; 22 | 23 | - (void) startGame; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /WappyBird/Scenes/Scene.m: -------------------------------------------------------------------------------- 1 | // 2 | // BouncingScene.m 3 | // Bouncing 4 | // 5 | // Created by Seung Kyun Nam on 13. 7. 24.. 6 | // Copyright (c) 2013년 Seung Kyun Nam. All rights reserved. 7 | // 8 | // Changed by Peng Guo on 15. 8. 28.. 9 | // To support controlling by Apple Watch 10 | 11 | #import 12 | #import "Scene.h" 13 | #import "SKScrollingNode.h" 14 | #import "BirdNode.h" 15 | #import "Score.h" 16 | #import "Constants.h" 17 | #import "Math.h" 18 | 19 | #define BACK_SCROLLING_SPEED .5 20 | #define FLOOR_SCROLLING_SPEED 3 21 | 22 | // Obstacles 23 | #define VERTICAL_GAP_SIZE 120 24 | #define FIRST_OBSTACLE_PADDING 100 25 | #define OBSTACLE_MIN_HEIGHT 60 26 | #define OBSTACLE_INTERVAL_SPACE 130 27 | 28 | @interface Scene () 29 | 30 | @end 31 | 32 | @implementation Scene{ 33 | SKScrollingNode * floor; 34 | SKScrollingNode * back; 35 | SKLabelNode * scoreLabel; 36 | BirdNode * bird; 37 | 38 | int nbObstacles; 39 | NSMutableArray * topPipes; 40 | NSMutableArray * bottomPipes; 41 | } 42 | 43 | static bool wasted = NO; 44 | 45 | - (id)initWithSize:(CGSize)size { 46 | if (self = [super initWithSize:size]) { 47 | 48 | if ([WCSession isSupported]) { 49 | WCSession *session = [WCSession defaultSession]; 50 | session.delegate = self; 51 | [session activateSession]; 52 | } 53 | 54 | self.physicsWorld.contactDelegate = self; 55 | [self startGame]; 56 | } 57 | return self; 58 | } 59 | 60 | - (void) startGame 61 | { 62 | // Reinit 63 | wasted = NO; 64 | 65 | [self removeAllChildren]; 66 | 67 | [self createBackground]; 68 | [self createFloor]; 69 | [self createScore]; 70 | [self createObstacles]; 71 | [self createBird]; 72 | 73 | // Floor needs to be in front of tubes 74 | floor.zPosition = bird.zPosition + 1; 75 | 76 | if([self.delegate respondsToSelector:@selector(eventStart)]){ 77 | [self.delegate eventStart]; 78 | } 79 | } 80 | 81 | #pragma mark - Creations 82 | 83 | - (void) createBackground 84 | { 85 | back = [SKScrollingNode scrollingNodeWithImageNamed:@"back" inContainerWidth:WIDTH(self)]; 86 | [back setScrollingSpeed:BACK_SCROLLING_SPEED]; 87 | [back setAnchorPoint:CGPointZero]; 88 | [back setPhysicsBody:[SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame]]; 89 | back.physicsBody.categoryBitMask = backBitMask; 90 | back.physicsBody.contactTestBitMask = birdBitMask; 91 | [self addChild:back]; 92 | } 93 | 94 | - (void) createScore 95 | { 96 | self.score = 0; 97 | scoreLabel = [SKLabelNode labelNodeWithFontNamed:@"Helvetica-Bold"]; 98 | scoreLabel.text = @"0"; 99 | scoreLabel.fontSize = 500; 100 | scoreLabel.position = CGPointMake(CGRectGetMidX(self.frame), 100); 101 | scoreLabel.alpha = 0.2; 102 | [self addChild:scoreLabel]; 103 | } 104 | 105 | 106 | - (void)createFloor 107 | { 108 | floor = [SKScrollingNode scrollingNodeWithImageNamed:@"floor" inContainerWidth:WIDTH(self)]; 109 | [floor setScrollingSpeed:FLOOR_SCROLLING_SPEED]; 110 | [floor setAnchorPoint:CGPointZero]; 111 | [floor setName:@"floor"]; 112 | [floor setPhysicsBody:[SKPhysicsBody bodyWithEdgeLoopFromRect:floor.frame]]; 113 | floor.physicsBody.categoryBitMask = floorBitMask; 114 | floor.physicsBody.contactTestBitMask = birdBitMask; 115 | [self addChild:floor]; 116 | } 117 | 118 | - (void)createBird 119 | { 120 | bird = [BirdNode new]; 121 | [bird setPosition:CGPointMake(100, CGRectGetMidY(self.frame))]; 122 | [bird setName:@"bird"]; 123 | [self addChild:bird]; 124 | } 125 | 126 | - (void) createObstacles 127 | { 128 | // Calculate how many obstacles we need, the less the better 129 | nbObstacles = ceil(WIDTH(self)/(OBSTACLE_INTERVAL_SPACE)); 130 | 131 | CGFloat lastBlockPos = 0; 132 | bottomPipes = @[].mutableCopy; 133 | topPipes = @[].mutableCopy; 134 | for(int i=0;i bird.position.x && 250 | X(topPipe) + WIDTH(topPipe)/2 < bird.position.x + FLOOR_SCROLLING_SPEED){ 251 | self.score +=1; 252 | scoreLabel.text = [NSString stringWithFormat:@"%lu",self.score]; 253 | if(self.score>=10){ 254 | scoreLabel.fontSize = 340; 255 | scoreLabel.position = CGPointMake(CGRectGetMidX(self.frame), 120); 256 | } 257 | } 258 | } 259 | } 260 | 261 | #pragma mark - Physic 262 | 263 | - (void)didBeginContact:(SKPhysicsContact *)contact 264 | { 265 | if(wasted){ return; } 266 | 267 | wasted = true; 268 | [Score registerScore:self.score]; 269 | 270 | if([self.delegate respondsToSelector:@selector(eventWasted)]){ 271 | [self.delegate eventWasted]; 272 | } 273 | 274 | } 275 | 276 | #pragma 277 | 278 | - (void)session:(WCSession *)session didReceiveMessage:(NSDictionary *)message replyHandler:(void (^)(NSDictionary * _Nonnull))replyHandler 279 | { 280 | NSLog(@"didReceiveMessage: %@", message); 281 | NSString *operation = [message objectForKey:@"Operation"]; 282 | if ([operation isEqualToString:@"bounce"]) 283 | { 284 | NSMutableDictionary *replyMessage = [NSMutableDictionary dictionary]; 285 | 286 | Scene __weak *weakSelf = self; 287 | 288 | dispatch_async(dispatch_get_main_queue(), ^{ 289 | 290 | Scene *strongSelf = weakSelf; 291 | 292 | if(wasted){ 293 | [strongSelf startGame]; 294 | [replyMessage setObject:@"started" forKey:@"Reply"]; 295 | }else{ 296 | if (!bird.physicsBody) { 297 | [bird startPlaying]; 298 | if([strongSelf.delegate respondsToSelector:@selector(eventPlay)]){ 299 | [strongSelf.delegate eventPlay]; 300 | } 301 | } 302 | [bird bounce]; 303 | [replyMessage setObject:@"bounced" forKey:@"Reply"]; 304 | } 305 | 306 | replyHandler(replyMessage); 307 | 308 | }); 309 | } 310 | 311 | } 312 | 313 | 314 | @end 315 | -------------------------------------------------------------------------------- /WappyBird/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // WappyBird 4 | // 5 | // Created by Peng on 8/26/15. 6 | // Copyright © 2015 Peng. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "Scene.h" 11 | 12 | @interface ViewController : UIViewController 13 | 14 | 15 | @end 16 | 17 | -------------------------------------------------------------------------------- /WappyBird/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // WappyBird 4 | // 5 | // Created by Peng on 8/26/15. 6 | // Copyright © 2015 Peng. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ViewController.h" 11 | #import "Score.h" 12 | #import "Macros.h" 13 | 14 | @interface ViewController () 15 | 16 | @property (strong,nonatomic) SKView *gameView; 17 | @property (strong,nonatomic) UIView *getReadyView; 18 | 19 | @property (strong,nonatomic) UIView *gameOverView; 20 | @property (strong,nonatomic) UIImageView *medalImageView; 21 | @property (strong,nonatomic) UILabel *currentScore; 22 | @property (strong,nonatomic) UILabel *bestScore; 23 | 24 | 25 | @end 26 | 27 | @implementation ViewController 28 | { 29 | Scene * scene; 30 | UIView * flash; 31 | } 32 | 33 | 34 | - (void)viewDidLoad { 35 | [super viewDidLoad]; 36 | // Do any additional setup after loading the view, typically from a nib. 37 | 38 | self.gameView = [[SKView alloc] initWithFrame:self.view.bounds]; 39 | 40 | self.getReadyView = [[UIView alloc] initWithFrame:CGRectMake(0, 188.0f, 320.0f, 192.0f)]; 41 | 42 | UIImageView *getReadyImageView = [[UIImageView alloc] initWithFrame:CGRectMake(30.0f, 0.0f, 260.0f, 45.0f)]; 43 | getReadyImageView.image = [UIImage imageNamed:@"get_ready.png"]; 44 | UIImageView *taptapImageView = [[UIImageView alloc] initWithFrame:CGRectMake(40.0f, 62.0f, 240.0f, 110.0f)]; 45 | taptapImageView.image = [UIImage imageNamed:@"taptap.png"]; 46 | [self.getReadyView addSubview:getReadyImageView]; 47 | [self.getReadyView addSubview:taptapImageView]; 48 | [self.gameView addSubview:self.getReadyView]; 49 | 50 | self.gameOverView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 188.0f, 320.0f, 220.0f)]; 51 | UIImageView *gameOverImageView = [[UIImageView alloc] initWithFrame:CGRectMake(30.0f, 0.0f, 260.0f, 45.0f)]; 52 | gameOverImageView.image = [UIImage imageNamed:@"game_over.png"]; 53 | UIImageView *medalPlateImageView = [[UIImageView alloc] initWithFrame:CGRectMake(47.0f, 62.0f, 226.0f, 116.0f)]; 54 | medalPlateImageView.image = [UIImage imageNamed:@"medal_plate.png"]; 55 | UIImageView *medalImageView = [[UIImageView alloc] initWithFrame:CGRectMake(73.0f, 104.0f, 44.0f, 44.0f)]; 56 | medalImageView.image = [UIImage imageNamed:@"medal_bronze.png"]; 57 | self.currentScore = [[UILabel alloc] initWithFrame:CGRectMake(199.0f, 94.0f, 50.0f, 21.0f)]; 58 | self.currentScore.text = @"5"; 59 | self.bestScore = [[UILabel alloc] initWithFrame:CGRectMake(199.0f, 135.0f, 50.0f, 21.0f)]; 60 | self.bestScore.text = @"32"; 61 | [self.gameOverView addSubview:gameOverImageView]; 62 | [self.gameOverView addSubview:medalPlateImageView]; 63 | [self.gameOverView addSubview:medalImageView]; 64 | [self.gameOverView addSubview:self.currentScore]; 65 | [self.gameOverView addSubview:self.bestScore]; 66 | [self.gameView addSubview:self.gameOverView]; 67 | 68 | [self.view addSubview:self.gameView]; 69 | 70 | 71 | // Configure the view. 72 | //self.gameView.showsFPS = YES; 73 | //self.gameView.showsNodeCount = YES; 74 | 75 | // Create and configure the scene. 76 | scene = [Scene sceneWithSize:self.gameView.bounds.size]; 77 | scene.scaleMode = SKSceneScaleModeAspectFill; 78 | scene.delegate = self; 79 | 80 | // Present the scene 81 | self.gameOverView.alpha = 0; 82 | self.gameOverView.transform = CGAffineTransformMakeScale(.9, .9); 83 | [self.gameView presentScene:scene]; 84 | } 85 | 86 | - (BOOL)prefersStatusBarHidden 87 | { 88 | return YES; 89 | } 90 | 91 | #pragma mark - Bouncing scene delegate 92 | 93 | - (void)eventStart 94 | { 95 | [UIView animateWithDuration:.2 animations:^{ 96 | self.gameOverView.alpha = 0; 97 | self.gameOverView.transform = CGAffineTransformMakeScale(.8, .8); 98 | flash.alpha = 0; 99 | self.getReadyView.alpha = 1; 100 | } completion:^(BOOL finished) { 101 | [flash removeFromSuperview]; 102 | 103 | }]; 104 | } 105 | 106 | - (void)eventPlay 107 | { 108 | NSLog(@"eventPlay"); 109 | [UIView animateWithDuration:.5 animations:^{ 110 | self.getReadyView.alpha = 0; 111 | }]; 112 | } 113 | 114 | - (void)eventWasted 115 | { 116 | flash = [[UIView alloc] initWithFrame:self.view.frame]; 117 | flash.backgroundColor = [UIColor whiteColor]; 118 | flash.alpha = .9; 119 | [self.gameView insertSubview:flash belowSubview:self.getReadyView]; 120 | 121 | [self shakeFrame]; 122 | 123 | [UIView animateWithDuration:.6 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{ 124 | 125 | // Display game over 126 | flash.alpha = .4; 127 | self.gameOverView.alpha = 1; 128 | self.gameOverView.transform = CGAffineTransformMakeScale(1, 1); 129 | 130 | // Set medal 131 | if(scene.score >= 40){ 132 | self.medalImageView.image = [UIImage imageNamed:@"medal_platinum"]; 133 | }else if (scene.score >= 30){ 134 | self.medalImageView.image = [UIImage imageNamed:@"medal_gold"]; 135 | }else if (scene.score >= 20){ 136 | self.medalImageView.image = [UIImage imageNamed:@"medal_silver"]; 137 | }else if (scene.score >= 10){ 138 | self.medalImageView.image = [UIImage imageNamed:@"medal_bronze"]; 139 | }else{ 140 | self.medalImageView.image = nil; 141 | } 142 | 143 | // Set scores 144 | self.currentScore.text = F(@"%li",scene.score); 145 | self.bestScore.text = F(@"%li",(long)[Score bestScore]); 146 | 147 | } completion:^(BOOL finished) { 148 | flash.userInteractionEnabled = NO; 149 | }]; 150 | 151 | } 152 | 153 | - (void) shakeFrame 154 | { 155 | CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"]; 156 | [animation setDuration:0.05]; 157 | [animation setRepeatCount:4]; 158 | [animation setAutoreverses:YES]; 159 | [animation setFromValue:[NSValue valueWithCGPoint: 160 | CGPointMake([self.view center].x - 4.0f, [self.view center].y)]]; 161 | [animation setToValue:[NSValue valueWithCGPoint: 162 | CGPointMake([self.view center].x + 4.0f, [self.view center].y)]]; 163 | [[self.view layer] addAnimation:animation forKey:@"position"]; 164 | } 165 | 166 | @end 167 | -------------------------------------------------------------------------------- /WappyBird/images/back@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NilStack/WappyBird/f2a70320028f9ed2fc49eb2b265b83bcb5c446a9/WappyBird/images/back@2x.png -------------------------------------------------------------------------------- /WappyBird/images/bird_1@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NilStack/WappyBird/f2a70320028f9ed2fc49eb2b265b83bcb5c446a9/WappyBird/images/bird_1@2x.png -------------------------------------------------------------------------------- /WappyBird/images/bird_2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NilStack/WappyBird/f2a70320028f9ed2fc49eb2b265b83bcb5c446a9/WappyBird/images/bird_2@2x.png -------------------------------------------------------------------------------- /WappyBird/images/bird_3@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NilStack/WappyBird/f2a70320028f9ed2fc49eb2b265b83bcb5c446a9/WappyBird/images/bird_3@2x.png -------------------------------------------------------------------------------- /WappyBird/images/floor@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NilStack/WappyBird/f2a70320028f9ed2fc49eb2b265b83bcb5c446a9/WappyBird/images/floor@2x.png -------------------------------------------------------------------------------- /WappyBird/images/game_over@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NilStack/WappyBird/f2a70320028f9ed2fc49eb2b265b83bcb5c446a9/WappyBird/images/game_over@2x.png -------------------------------------------------------------------------------- /WappyBird/images/get_ready@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NilStack/WappyBird/f2a70320028f9ed2fc49eb2b265b83bcb5c446a9/WappyBird/images/get_ready@2x.png -------------------------------------------------------------------------------- /WappyBird/images/medal_bronze@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NilStack/WappyBird/f2a70320028f9ed2fc49eb2b265b83bcb5c446a9/WappyBird/images/medal_bronze@2x.png -------------------------------------------------------------------------------- /WappyBird/images/medal_gold@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NilStack/WappyBird/f2a70320028f9ed2fc49eb2b265b83bcb5c446a9/WappyBird/images/medal_gold@2x.png -------------------------------------------------------------------------------- /WappyBird/images/medal_plate@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NilStack/WappyBird/f2a70320028f9ed2fc49eb2b265b83bcb5c446a9/WappyBird/images/medal_plate@2x.png -------------------------------------------------------------------------------- /WappyBird/images/medal_platinum@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NilStack/WappyBird/f2a70320028f9ed2fc49eb2b265b83bcb5c446a9/WappyBird/images/medal_platinum@2x.png -------------------------------------------------------------------------------- /WappyBird/images/medal_silver@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NilStack/WappyBird/f2a70320028f9ed2fc49eb2b265b83bcb5c446a9/WappyBird/images/medal_silver@2x.png -------------------------------------------------------------------------------- /WappyBird/images/pipe_bottom@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NilStack/WappyBird/f2a70320028f9ed2fc49eb2b265b83bcb5c446a9/WappyBird/images/pipe_bottom@2x.png -------------------------------------------------------------------------------- /WappyBird/images/pipe_top@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NilStack/WappyBird/f2a70320028f9ed2fc49eb2b265b83bcb5c446a9/WappyBird/images/pipe_top@2x.png -------------------------------------------------------------------------------- /WappyBird/images/taptap@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NilStack/WappyBird/f2a70320028f9ed2fc49eb2b265b83bcb5c446a9/WappyBird/images/taptap@2x.png -------------------------------------------------------------------------------- /WappyBird/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // WappyBird 4 | // 5 | // Created by Peng on 8/26/15. 6 | // Copyright © 2015 Peng. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /WappyBird@Watch Extension/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /WappyBird@Watch Extension/Assets.xcassets/README__ignoredByTemplate__: -------------------------------------------------------------------------------- 1 | Did you know that git does not support storing empty directories? 2 | -------------------------------------------------------------------------------- /WappyBird@Watch Extension/ExtensionDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // ExtensionDelegate.h 3 | // WappyBird@Watch Extension 4 | // 5 | // Created by Peng on 8/26/15. 6 | // Copyright © 2015 Peng. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ExtensionDelegate : NSObject 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /WappyBird@Watch Extension/ExtensionDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // ExtensionDelegate.m 3 | // WappyBird@Watch Extension 4 | // 5 | // Created by Peng on 8/26/15. 6 | // Copyright © 2015 Peng. All rights reserved. 7 | // 8 | 9 | #import "ExtensionDelegate.h" 10 | 11 | @implementation ExtensionDelegate 12 | 13 | - (void)applicationDidFinishLaunching { 14 | // Perform any final initialization of your application. 15 | } 16 | 17 | - (void)applicationDidBecomeActive { 18 | // 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. 19 | } 20 | 21 | - (void)applicationWillResignActive { 22 | // 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. 23 | // Use this method to pause ongoing tasks, disable timers, etc. 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /WappyBird@Watch Extension/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | WappyBird@Watch Extension 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | NSExtension 26 | 27 | NSExtensionAttributes 28 | 29 | WKAppBundleIdentifier 30 | watch.develop.WappyBird.watchkitapp 31 | 32 | NSExtensionPointIdentifier 33 | com.apple.watchkit 34 | 35 | RemoteInterfacePrincipalClass 36 | InterfaceController 37 | WKExtensionDelegateClassName 38 | ExtensionDelegate 39 | 40 | 41 | -------------------------------------------------------------------------------- /WappyBird@Watch Extension/InterfaceController.h: -------------------------------------------------------------------------------- 1 | // 2 | // InterfaceController.h 3 | // WappyBird@Watch Extension 4 | // 5 | // Created by Peng on 8/26/15. 6 | // Copyright © 2015 Peng. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface InterfaceController : WKInterfaceController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /WappyBird@Watch Extension/InterfaceController.m: -------------------------------------------------------------------------------- 1 | // 2 | // InterfaceController.m 3 | // WappyBird@Watch Extension 4 | // 5 | // Created by Peng on 8/26/15. 6 | // Copyright © 2015 Peng. All rights reserved. 7 | // 8 | 9 | #import "InterfaceController.h" 10 | #import 11 | 12 | 13 | @interface InterfaceController() 14 | 15 | @property (unsafe_unretained, nonatomic) IBOutlet WKInterfaceButton *operationButton; 16 | 17 | @property (assign, nonatomic) BOOL playing; 18 | 19 | @end 20 | 21 | 22 | @implementation InterfaceController 23 | 24 | - (void)awakeWithContext:(id)context { 25 | [super awakeWithContext:context]; 26 | 27 | // Configure interface objects here. 28 | 29 | 30 | if ([WCSession isSupported]) { 31 | WCSession *session = [WCSession defaultSession]; 32 | session.delegate = self; 33 | [session activateSession]; 34 | } 35 | } 36 | 37 | - (void)willActivate { 38 | // This method is called when watch view controller is about to be visible to user 39 | [super willActivate]; 40 | 41 | [self.operationButton setTitle:@"Tap Me!"]; 42 | } 43 | 44 | - (void)didDeactivate { 45 | // This method is called when watch view controller is no longer visible 46 | [super didDeactivate]; 47 | 48 | 49 | } 50 | - (IBAction)operate { 51 | WCSession *session = [WCSession defaultSession]; 52 | if ([session isReachable]) { 53 | 54 | NSDictionary *message = @{@"Operation":@"bounce"}; 55 | 56 | 57 | [session sendMessage:message replyHandler:^(NSDictionary * _Nonnull replyMessage) { 58 | 59 | NSString *result = [replyMessage objectForKey:@"Reply"]; 60 | 61 | NSLog(@"result is : %@", result); 62 | 63 | } errorHandler:^(NSError * _Nonnull error) { 64 | 65 | if (error) { 66 | NSLog(@"when send message : %@, error is : %@", message, error); 67 | } 68 | 69 | }]; 70 | 71 | 72 | } else { 73 | 74 | NSLog(@"not reachable to iPhone"); 75 | 76 | } 77 | 78 | } 79 | 80 | @end 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /WappyBird@Watch/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "24x24", 5 | "idiom" : "watch", 6 | "scale" : "2x", 7 | "role" : "notificationCenter", 8 | "subtype" : "38mm" 9 | }, 10 | { 11 | "size" : "27.5x27.5", 12 | "idiom" : "watch", 13 | "scale" : "2x", 14 | "role" : "notificationCenter", 15 | "subtype" : "42mm" 16 | }, 17 | { 18 | "size" : "29x29", 19 | "idiom" : "watch", 20 | "role" : "companionSettings", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "size" : "29x29", 25 | "idiom" : "watch", 26 | "role" : "companionSettings", 27 | "scale" : "3x" 28 | }, 29 | { 30 | "size" : "40x40", 31 | "idiom" : "watch", 32 | "scale" : "2x", 33 | "role" : "appLauncher", 34 | "subtype" : "38mm" 35 | }, 36 | { 37 | "size" : "44x44", 38 | "idiom" : "watch", 39 | "scale" : "2x", 40 | "role" : "longLook", 41 | "subtype" : "42mm" 42 | }, 43 | { 44 | "size" : "86x86", 45 | "idiom" : "watch", 46 | "scale" : "2x", 47 | "role" : "quickLook", 48 | "subtype" : "38mm" 49 | }, 50 | { 51 | "size" : "98x98", 52 | "idiom" : "watch", 53 | "scale" : "2x", 54 | "role" : "quickLook", 55 | "subtype" : "42mm" 56 | } 57 | ], 58 | "info" : { 59 | "version" : 1, 60 | "author" : "xcode" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /WappyBird@Watch/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /WappyBird@Watch/Assets.xcassets/bird.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "bird_1@2x.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "bird_2@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "bird_3@2x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /WappyBird@Watch/Assets.xcassets/bird.imageset/bird_1@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NilStack/WappyBird/f2a70320028f9ed2fc49eb2b265b83bcb5c446a9/WappyBird@Watch/Assets.xcassets/bird.imageset/bird_1@2x.png -------------------------------------------------------------------------------- /WappyBird@Watch/Assets.xcassets/bird.imageset/bird_2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NilStack/WappyBird/f2a70320028f9ed2fc49eb2b265b83bcb5c446a9/WappyBird@Watch/Assets.xcassets/bird.imageset/bird_2@2x.png -------------------------------------------------------------------------------- /WappyBird@Watch/Assets.xcassets/bird.imageset/bird_3@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NilStack/WappyBird/f2a70320028f9ed2fc49eb2b265b83bcb5c446a9/WappyBird@Watch/Assets.xcassets/bird.imageset/bird_3@2x.png -------------------------------------------------------------------------------- /WappyBird@Watch/Base.lproj/Interface.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /WappyBird@Watch/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | WappyBird 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | UISupportedInterfaceOrientations 26 | 27 | UIInterfaceOrientationPortrait 28 | UIInterfaceOrientationPortraitUpsideDown 29 | 30 | WKCompanionAppBundleIdentifier 31 | watch.develop.WappyBird 32 | WKWatchKitApp 33 | 34 | 35 | 36 | --------------------------------------------------------------------------------