├── logo-sprite_liquids.jpeg ├── sprite-liquids-ios-app ├── Assets.xcassets │ ├── Contents.json │ ├── AppIcon.appiconset │ │ ├── icon_20@1x.png │ │ ├── icon_20@2x.png │ │ ├── icon_20@3x.png │ │ ├── icon_29@1x.png │ │ ├── icon_29@2x.png │ │ ├── icon_29@3x.png │ │ ├── icon_40@1x.png │ │ ├── icon_40@2x.png │ │ ├── icon_40@3x.png │ │ ├── icon_60@2x.png │ │ ├── icon_60@3x.png │ │ ├── icon_76@1x.png │ │ ├── icon_76@2x.png │ │ ├── icon_1024@1x.png │ │ ├── icon_83.5@2x.png │ │ └── Contents.json │ ├── Clean.imageset │ │ ├── icons8-broom-128.png │ │ └── Contents.json │ └── MainIcon.imageset │ │ ├── icons8-water-2048.png │ │ └── Contents.json ├── SpriteKit Assets │ ├── Actions.sks │ ├── GameScene.sks │ └── RotationAction.sks ├── SpriteLiquids-Prefix.pch ├── Common │ ├── LQKImageUtils.m │ ├── LiquidNode.h │ ├── LQKLiquidEffect.h │ ├── LiquidParticleFactory.h │ ├── SolidColorEffect.h │ ├── LQKImageUtils.h │ ├── LiquidFilter.h │ ├── LiquidNode.m │ ├── LiquidParticleFactory.m │ ├── SolidColorEffect.m │ └── LiquidFilter.m ├── AppDelegate.h ├── Scenes │ ├── GameScene.h │ └── GameScene.m ├── iOS │ ├── LQKImageUtils+iOSUtils.h │ └── LQKImageUtils+iOSUtils.m ├── SpriteLiquids.h ├── main.m ├── Controller │ ├── GameViewController.h │ └── GameViewController.m ├── Info.plist ├── AppDelegate.m └── View │ └── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── sprite-liquids-ios-app.xcodeproj ├── project.xcworkspace │ └── contents.xcworkspacedata ├── xcuserdata │ └── astemireleev.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist └── project.pbxproj ├── .gitignore ├── sprite-liquids-ios-app-tests ├── Info.plist └── LiquidDemoTests.m ├── sprite-liquids-ios-app-UI-tests ├── Info.plist └── LiquidDemoUITests.m ├── LICENSE └── README.md /logo-sprite_liquids.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eleev/sprite-liquids-ios-app/HEAD/logo-sprite_liquids.jpeg -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /sprite-liquids-ios-app/SpriteKit Assets/Actions.sks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eleev/sprite-liquids-ios-app/HEAD/sprite-liquids-ios-app/SpriteKit Assets/Actions.sks -------------------------------------------------------------------------------- /sprite-liquids-ios-app/SpriteKit Assets/GameScene.sks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eleev/sprite-liquids-ios-app/HEAD/sprite-liquids-ios-app/SpriteKit Assets/GameScene.sks -------------------------------------------------------------------------------- /sprite-liquids-ios-app/SpriteKit Assets/RotationAction.sks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eleev/sprite-liquids-ios-app/HEAD/sprite-liquids-ios-app/SpriteKit Assets/RotationAction.sks -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eleev/sprite-liquids-ios-app/HEAD/sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_20@1x.png -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eleev/sprite-liquids-ios-app/HEAD/sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_20@2x.png -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eleev/sprite-liquids-ios-app/HEAD/sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_20@3x.png -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eleev/sprite-liquids-ios-app/HEAD/sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_29@1x.png -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eleev/sprite-liquids-ios-app/HEAD/sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_29@2x.png -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eleev/sprite-liquids-ios-app/HEAD/sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_29@3x.png -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eleev/sprite-liquids-ios-app/HEAD/sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_40@1x.png -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eleev/sprite-liquids-ios-app/HEAD/sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_40@2x.png -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eleev/sprite-liquids-ios-app/HEAD/sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_40@3x.png -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eleev/sprite-liquids-ios-app/HEAD/sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_60@2x.png -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eleev/sprite-liquids-ios-app/HEAD/sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_60@3x.png -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eleev/sprite-liquids-ios-app/HEAD/sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_76@1x.png -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eleev/sprite-liquids-ios-app/HEAD/sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_76@2x.png -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eleev/sprite-liquids-ios-app/HEAD/sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_1024@1x.png -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eleev/sprite-liquids-ios-app/HEAD/sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/icon_83.5@2x.png -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Assets.xcassets/Clean.imageset/icons8-broom-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eleev/sprite-liquids-ios-app/HEAD/sprite-liquids-ios-app/Assets.xcassets/Clean.imageset/icons8-broom-128.png -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Assets.xcassets/MainIcon.imageset/icons8-water-2048.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eleev/sprite-liquids-ios-app/HEAD/sprite-liquids-ios-app/Assets.xcassets/MainIcon.imageset/icons8-water-2048.png -------------------------------------------------------------------------------- /sprite-liquids-ios-app/SpriteLiquids-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #ifdef __OBJC__ 8 | #import 9 | #endif 10 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Common/LQKImageUtils.m: -------------------------------------------------------------------------------- 1 | // 2 | // LQKImageUtils.m 3 | // Sprite Liquids 4 | // 5 | // Created by Astemir Eleev on 21/10/2017. 6 | // Copyright (c) 2017 Astemir Eleev 7 | // 8 | 9 | #import "LQKImageUtils.h" 10 | 11 | @implementation LQKImageUtils 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // Sprite Liquids 4 | // 5 | // Created by Astemir Eleev on 21/10/2017. 6 | // Copyright © 2017 Astemir Eleev. 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 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Scenes/GameScene.h: -------------------------------------------------------------------------------- 1 | // 2 | // GameScene.h 3 | // Sprite Liquids 4 | // 5 | // Created by Astemir Eleev on 21/10/2017. 6 | // Copyright © 2017 Astemir Eleev. All rights reserved. 7 | // 8 | 9 | 10 | #import 11 | 12 | @interface GameScene : SKScene 13 | 14 | - (void) createaLiquid:(int) particlesCount; 15 | - (void) removeLiquid; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Common/LiquidNode.h: -------------------------------------------------------------------------------- 1 | // 2 | // LQKLiquidNode.h 3 | // Sprite Liquids 4 | // 5 | // Created by Astemir Eleev on 21/10/2017. 6 | // Copyright (c) 2017 Astemir Eleev 7 | // 8 | 9 | #import 10 | #import "LQKImageUtils.h" 11 | 12 | @interface LiquidNode : SKEffectNode 13 | 14 | - (id) initWithBlurRadius:(NSInteger)radius withLiquidFilter:(CIFilter *)filter; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app/iOS/LQKImageUtils+iOSUtils.h: -------------------------------------------------------------------------------- 1 | // 2 | // LQKImageUtils+iOSUtils.h 3 | // Sprite Liquids 4 | // 5 | // Created by Astemir Eleev on 21/10/2017. 6 | // Copyright (c) 2017 Astemir Eleev 7 | // 8 | 9 | #import "LQKImageUtils.h" 10 | 11 | @interface LQKImageUtils (iOSUtils) 12 | 13 | + (UIImage *) imageWithSize:(CGSize)size fromContextDrawBlock:(void (^) (CGContextRef))drawBlock; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app/SpriteLiquids.h: -------------------------------------------------------------------------------- 1 | // 2 | // LQKSolidColorEffect.m 3 | // Sprite Liquids 4 | // 5 | // Created by Astemir Eleev on 2/8/14. 6 | // Copyright (c) 2017 Astemir Eleev 7 | // 8 | 9 | #import "LQKCILiquidFilter.h" 10 | #import "LQKLiquidNode.h" 11 | #import "LQKLiquidParticleFactory.h" 12 | #import "LQKLiquidEffect.h" 13 | #import "LQKSolidColorEffect.h" 14 | 15 | @interface LiquidKit : NSObject 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Common/LQKLiquidEffect.h: -------------------------------------------------------------------------------- 1 | // 2 | // LQKLiquidEffect.h 3 | // Sprite Liquids 4 | // 5 | // Created by Astemir Eleev on 21/10/2017. 6 | // Copyright (c) 2017 Astemir Eleev 7 | // 8 | 9 | #import 10 | 11 | #import "LQKImageUtils.h" 12 | 13 | @protocol LQKLiquidEffect 14 | 15 | - (CIImage *) thresholdGradient; 16 | - (CIImage *) postProcessedFrameFrom:(CIImage *)input; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Spreite Liquids 4 | // 5 | // Created by Astemir Eleev on 21/10/2017. 6 | // Copyright © 2017 Astemir Eleev. 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 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Assets.xcassets/Clean.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "icons8-broom-128.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Assets.xcassets/MainIcon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "idiom" : "universal", 9 | "filename" : "icons8-water-2048.png", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Controller/GameViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // GameViewController.h 3 | // Sprite Liquids 4 | // 5 | // Created by Astemir Eleev on 21/10/2017. 6 | // Copyright © 2017 Astemir Eleev. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | #import "GameScene.h" 13 | 14 | @interface GameViewController : UIViewController 15 | 16 | @property(nonatomic) GameScene *scene; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## OS X Finder 2 | .DS_Store 3 | 4 | ## Build generated 5 | build/ 6 | DerivedData 7 | 8 | ## Various settings 9 | *.pbxuser 10 | !default.pbxuser 11 | *.mode1v3 12 | !default.mode1v3 13 | *.mode2v3 14 | !default.mode2v3 15 | *.perspectivev3 16 | !default.perspectivev3 17 | xcuserdata 18 | 19 | ## Other 20 | *.xccheckout 21 | *.moved-aside 22 | *.xcuserstate 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | 29 | # Swift Package Manager 30 | .build/ 31 | 32 | # Carthage 33 | Carthage/Build 34 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Common/LiquidParticleFactory.h: -------------------------------------------------------------------------------- 1 | // 2 | // LQKLiquidParticleFactory.h 3 | // Sprite Liquids 4 | // 5 | // Created by Astemir Eleev on 21/10/2017. 6 | // Copyright (c) 2017 Astemir Eleev 7 | // 8 | 9 | #import 10 | 11 | @interface LiquidParticleFactory : NSObject 12 | 13 | /* Constants */ 14 | extern const CGFloat CIRCLE_COLOR[]; 15 | 16 | /* Properties */ 17 | @property CGFloat circleRadius; 18 | @property SKTexture *circleTexture; 19 | 20 | /* Instance methods */ 21 | - (id) initWithRadius:(CGFloat)radius; 22 | 23 | - (SKNode*) createLiquidParticle; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app.xcodeproj/xcuserdata/astemireleev.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | LiquidDemo.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | sprite-liquids-ios-app.xcscheme 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Common/SolidColorEffect.h: -------------------------------------------------------------------------------- 1 | // 2 | // LQKSolidColorEffect.h 3 | // Sprite Liquids 4 | // 5 | // Created by Astemir Eleev on 21/10/2017. 6 | // Copyright (c) 2017 Astemir Eleev 7 | // 8 | 9 | #import 10 | 11 | #import "LQKLiquidEffect.h" 12 | 13 | @interface SolidColorEffect : NSObject 14 | 15 | /* Properties */ 16 | @property XXColor* color; 17 | @property CGFloat index; 18 | @property CGFloat width; 19 | 20 | - (id) initWithColor:(XXColor*)color withIndex:(CGFloat)index withWidth:(CGFloat)width; 21 | 22 | - (CIImage *) thresholdGradient; 23 | 24 | - (CIImage *) postProcessedFrameFrom:(CIImage *)input; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app/iOS/LQKImageUtils+iOSUtils.m: -------------------------------------------------------------------------------- 1 | // 2 | // LQKImageUtils+iOSUtils.m 3 | // Sprite Liquids 4 | // 5 | // Created by Astemir Eleev on 21/10/2017. 6 | // Copyright (c) 2017 Astemir Eleev 7 | // 8 | 9 | #import "LQKImageUtils+iOSUtils.h" 10 | 11 | @implementation LQKImageUtils (iOSUtils) 12 | 13 | + (UIImage *) imageWithSize:(CGSize)size fromContextDrawBlock:(void (^) (CGContextRef))drawBlock { 14 | 15 | UIGraphicsBeginImageContextWithOptions(size, NO, 0); 16 | 17 | CGContextRef context = UIGraphicsGetCurrentContext(); 18 | 19 | drawBlock(context); 20 | 21 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 22 | 23 | UIGraphicsEndImageContext(); 24 | 25 | return image; 26 | } 27 | 28 | @end 29 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Common/LQKImageUtils.h: -------------------------------------------------------------------------------- 1 | // 2 | // LQKImageUtils.h 3 | // Sprite Liquids 4 | // 5 | // Created by Astemir Eleev on 21/10/2017. 6 | // Copyright (c) 2017 Astemir Eleev 7 | // 8 | 9 | //#if TARGET_OS_IPHONE 10 | #import 11 | //#else 12 | ////#import 13 | //#endif 14 | 15 | /* define common util functions here */ 16 | @interface LQKImageUtils : NSObject 17 | 18 | @end 19 | 20 | /* Attach platform specific utilities */ 21 | //#if TARGET_OS_IPHONE 22 | #import 23 | #import "LQKImageUtils+iOSUtils.h" 24 | typedef UIImage XXImage; 25 | typedef UIColor XXColor; 26 | //#else 27 | //#import 28 | //#import "LQKImageUtils+OSXUtils.h" 29 | //typedef NSImage XXImage; 30 | //typedef NSColor XXColor; 31 | //#endif 32 | 33 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app-tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app-UI-tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Common/LiquidFilter.h: -------------------------------------------------------------------------------- 1 | // 2 | // LQKLiquidEffect.h 3 | // Sprite Liquids 4 | // 5 | // Created by Astemir Eleev on 21/10/2017. 6 | // Copyright (c) 2017 Astemir Eleev 7 | // 8 | 9 | //#if TARGET_OS_IPHONE 10 | #import 11 | //#else 12 | //#import 13 | //#endif 14 | 15 | #import "LQKLiquidEffect.h" 16 | 17 | @interface LiquidFilter: CIFilter { 18 | CIImage *inputImage; 19 | } 20 | 21 | @property (retain, nonatomic) CIImage *inputImage; 22 | 23 | @property CIFilter *threshFilter; 24 | @property CIFilter *compositeFilter; 25 | @property CIFilter *blurFilter; 26 | @property CIImage *backgroundColor; 27 | 28 | @property CGFloat blurRadius; 29 | @property NSObject *liquidEffect; 30 | 31 | - (id) initWithBlurRadius:(CGFloat)blurRadius withLiquidEffect:(NSObject*)liquidEffect; 32 | 33 | @end 34 | 35 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Common/LiquidNode.m: -------------------------------------------------------------------------------- 1 | // 2 | // LQKLiquidNode.m 3 | // Sprite Liquids 4 | // 5 | // Created by Astemir Eleev on 21/10/2017. 6 | // Copyright (c) 2017 Astemir Eleev 7 | // 8 | 9 | #import "LiquidNode.h" 10 | #import "LiquidFilter.h" 11 | 12 | @implementation LiquidNode 13 | 14 | - (id) initWithBlurRadius:(NSInteger)radius withLiquidFilter:(CIFilter *)filter { 15 | 16 | if (self = [super init]) { 17 | 18 | // TODO: This class will contain the logic associated with grouping child nodes 19 | // together and rasterizing those groups individually for opimization 20 | 21 | /* effect node properties */ 22 | self.filter = filter; 23 | self.shouldRasterize = NO; 24 | self.shouldEnableEffects = YES; 25 | self.physicsBody.usesPreciseCollisionDetection= NO; 26 | self.shouldCenterFilter = YES; 27 | 28 | } 29 | return self; 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app-tests/LiquidDemoTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // LiquidDemoTests.m 3 | // LiquidDemoTests 4 | // 5 | // Created by Astemir Eleev on 21/10/2017. 6 | // Copyright © 2017 Astemir Eleev. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface LiquidDemoTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation LiquidDemoTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Astemir Eleev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app-UI-tests/LiquidDemoUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // LiquidDemoUITests.m 3 | // LiquidDemoUITests 4 | // 5 | // Created by Astemir Eleev on 21/10/2017. 6 | // Copyright © 2017 Astemir Eleev. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface LiquidDemoUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation LiquidDemoUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sprite-liquids-ios-app [![Awesome](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/sindresorhus/awesome) 2 | 3 | [![Platform](https://img.shields.io/badge/platform-iOS-yellow.svg)]() 4 | [![Language](https://img.shields.io/badge/language-objective%20c-blue.svg)]() 5 | [![Framework](https://img.shields.io/badge/framework-core%20image-red.svg)]() 6 | [![Framework](https://img.shields.io/badge/frameworks-SpriteKit-ff69b4.svg)]() 7 | [![License](https://img.shields.io/badge/license-MIT-blue.svg)]() 8 | 9 | **Last Update: 20/December/2018.** 10 | 11 | ![](logo-sprite_liquids.jpeg) 12 | 13 | ### If you like the project, please give it a star ⭐ It will show the creator your appreciation and help others to discover the repo. 14 | 15 | # ✍️ About 16 | Demonstrates a practical approach for liquid visualization using SpriteKit and CoreImage frameworks 💧. Feel free to use this development in your `games`, as part of your `UI` or to `visualize` something. `Swift` version is planned and will be added as well `optimization` and creation of more `conscious API`. 17 | 18 | # 📺 Demo 19 | 20 | 21 | # 👨‍💻 Author 22 | [Astemir Eleev](https://github.com/jVirus) 23 | 24 | # 🔖 Licence 25 | The project is available under [MIT Licence](https://github.com/jVirus/sprite-liquids-ios-app/blob/master/LICENSE). 26 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Sprite Liquids 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.1 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UIRequiresFullScreen 34 | 35 | UIStatusBarHidden 36 | 37 | UISupportedInterfaceOrientations 38 | 39 | UIInterfaceOrientationPortrait 40 | 41 | UISupportedInterfaceOrientations~ipad 42 | 43 | UIInterfaceOrientationPortrait 44 | UIInterfaceOrientationPortraitUpsideDown 45 | UIInterfaceOrientationLandscapeLeft 46 | UIInterfaceOrientationLandscapeRight 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Controller/GameViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // GameViewController.m 3 | // Sprite Liquids 4 | // 5 | // Created by Astemir Eleev on 21/10/2017. 6 | // Copyright © 2017 Astemir Eleev. All rights reserved. 7 | // 8 | 9 | #import "GameViewController.h" 10 | #import "GameScene.h" 11 | 12 | @implementation GameViewController 13 | 14 | - (void)viewDidLoad { 15 | [super viewDidLoad]; 16 | 17 | // Load the SKScene from 'GameScene.sks' 18 | _scene = (GameScene *)[SKScene nodeWithFileNamed:@"GameScene"]; 19 | 20 | // Set the scale mode to scale to fit the window 21 | _scene.scaleMode = SKSceneScaleModeAspectFit; 22 | 23 | SKView *skView = (SKView *)self.view; 24 | 25 | // Present the scene 26 | [skView presentScene: _scene]; 27 | 28 | skView.showsFPS = YES; 29 | skView.showsNodeCount = YES; 30 | } 31 | 32 | - (BOOL)shouldAutorotate { 33 | return NO; 34 | } 35 | 36 | - (UIInterfaceOrientationMask)supportedInterfaceOrientations { 37 | return UIInterfaceOrientationMaskAllButUpsideDown; 38 | 39 | /* 40 | if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { 41 | return UIInterfaceOrientationMaskAllButUpsideDown; 42 | } else { 43 | return UIInterfaceOrientationMaskAll; 44 | } 45 | */ 46 | } 47 | 48 | - (void)didReceiveMemoryWarning { 49 | [super didReceiveMemoryWarning]; 50 | // Release any cached data, images, etc that aren't in use. 51 | } 52 | 53 | - (BOOL)prefersStatusBarHidden { 54 | return YES; 55 | } 56 | 57 | #pragma MARK: - Actions 58 | 59 | - (IBAction)cleanAction:(UIButton *)sender { 60 | [_scene removeLiquid]; 61 | [_scene createaLiquid:90]; 62 | } 63 | 64 | @end 65 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // Sprite Liquids 4 | // 5 | // Created by Astemir Eleev on 21/10/2017. 6 | // Copyright © 2017 Astemir Eleev. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // 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. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // 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. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // 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. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Common/LiquidParticleFactory.m: -------------------------------------------------------------------------------- 1 | // 2 | // LQKLiquidParticleFactory.m 3 | // Sprite Liquids 4 | // 5 | // Created by Astemir Eleev on 21/10/2017. 6 | // Copyright (c) 2017 Astemir Eleev 7 | // 8 | 9 | #import "LiquidParticleFactory.h" 10 | #import "LQKImageUtils.h" 11 | 12 | @implementation LiquidParticleFactory 13 | 14 | /* Constants */ 15 | 16 | /* The current CI liquid filter algorithm uses a white circle and colors */ 17 | /* the parent liquid by mapping white to the liquid's desired color. */ 18 | const CGFloat CIRCLE_COLOR[] = { 1.0f, 1.0f, 1.0f, 1.0f }; 19 | 20 | - (id) initWithRadius:(CGFloat)radius { 21 | 22 | if (self = [super init]) { 23 | 24 | XXImage *image = [LQKImageUtils imageWithSize:CGSizeMake(radius * 2, radius * 2) fromContextDrawBlock:^(CGContextRef context){ 25 | 26 | CGMutablePathRef circlePath = CGPathCreateMutable(); 27 | CGPathAddArc(circlePath, NULL, radius, radius, radius, 0, M_PI*2, NO); 28 | 29 | CGContextSetFillColor(context, CIRCLE_COLOR); 30 | CGContextAddPath(context, circlePath); 31 | CGContextFillPath(context); 32 | CGPathRelease(circlePath); 33 | 34 | }]; 35 | 36 | self.circleRadius = radius; 37 | self.circleTexture = [SKTexture textureWithImage:image]; 38 | 39 | } 40 | return self; 41 | } 42 | 43 | - (SKNode*) createLiquidParticle { 44 | 45 | SKSpriteNode *circleNode = [[SKSpriteNode alloc] init]; 46 | 47 | /* Attach sprite */ 48 | circleNode.texture = self.circleTexture; 49 | circleNode.size = CGSizeMake(self.circleRadius * 2, self.circleRadius * 2); 50 | circleNode.anchorPoint = CGPointMake(0.5,0.5); 51 | 52 | /* Attach physics body */ 53 | circleNode.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:self.circleRadius]; 54 | circleNode.physicsBody.dynamic = YES; 55 | circleNode.physicsBody.categoryBitMask = 3; 56 | circleNode.physicsBody.contactTestBitMask = 4; 57 | circleNode.physicsBody.collisionBitMask = -1; 58 | circleNode.physicsBody.usesPreciseCollisionDetection = NO; 59 | circleNode.physicsBody.mass = 10; 60 | circleNode.physicsBody.friction = 0; 61 | circleNode.physicsBody.restitution = 0.1; 62 | 63 | 64 | return circleNode; 65 | } 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Common/SolidColorEffect.m: -------------------------------------------------------------------------------- 1 | // 2 | // LQKSolidColorEffect.m 3 | // Sprite Liquids 4 | // 5 | // Created by Astemir Eleev on 21/10/2017. 6 | // Copyright (c) 2017 Astemir Eleev 7 | // 8 | 9 | #import "SolidColorEffect.h" 10 | 11 | @implementation SolidColorEffect 12 | 13 | - (id) initWithColor:(XXColor*)color withIndex:(CGFloat)index withWidth:(CGFloat)width { 14 | if (self = [super init]) { 15 | 16 | if (!color) { 17 | return nil; 18 | } 19 | 20 | self.color = color; 21 | self.index = index; 22 | self.width = width; 23 | } 24 | 25 | return self; 26 | } 27 | 28 | - (CIImage *) thresholdGradient { 29 | 30 | /* Create index-length opaque strip */ 31 | CIFilter *backgroundColorFilter = [CIFilter filterWithName:@"CIConstantColorGenerator"]; 32 | [backgroundColorFilter setValue:[CIColor colorWithRed:0 green:0 blue:0 alpha:1] forKey:@"inputColor"]; 33 | 34 | CIImage *infiniteBackgroundImage = [backgroundColorFilter valueForKey: kCIOutputImageKey]; 35 | CIImage *backgroundImage = [infiniteBackgroundImage imageByCroppingToRect:CGRectMake(0, 0, self.index, 1)]; 36 | 37 | /* Create width-length white strip */ 38 | CIFilter *foregroundColorFilter = [CIFilter filterWithName:@"CIConstantColorGenerator"]; 39 | [foregroundColorFilter setValue:[CIColor colorWithRed:1 green:1 blue:1 alpha:1] forKey:@"inputColor"]; 40 | 41 | CIImage *infiniteForegroundFImage = [foregroundColorFilter valueForKey: kCIOutputImageKey]; 42 | CIImage *foregroundImage = [infiniteForegroundFImage imageByCroppingToRect:CGRectMake(0, 0, self.width, 1)]; 43 | 44 | /* Source out composite opaque strip from white-strip, resulting in 0 to index-length transparency */ 45 | CIFilter *compositeFilter = [CIFilter filterWithName:@"CISourceOutCompositing"]; 46 | [compositeFilter setValue:backgroundImage forKey:@"inputBackgroundImage"]; 47 | [compositeFilter setValue: foregroundImage forKey: kCIInputImageKey]; 48 | 49 | CIImage *baseGradient = [compositeFilter valueForKey: kCIOutputImageKey]; 50 | 51 | /* Adjust a transparent and white gradient to be transparent and */ 52 | CIFilter *gradientColorAdjust = [CIFilter filterWithName:@"CIWhitePointAdjust"]; 53 | [gradientColorAdjust setValue:baseGradient forKey:kCIInputImageKey]; 54 | [gradientColorAdjust setValue:[CIColor colorWithCGColor:self.color.CGColor] forKey:@"inputColor"]; 55 | 56 | CIImage *coloredGradientImage = [gradientColorAdjust valueForKey: kCIOutputImageKey]; 57 | 58 | return coloredGradientImage; 59 | 60 | } 61 | 62 | - (CIImage *) postProcessedFrameFrom:(CIImage *)input { 63 | return input; 64 | } 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "icon_20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "icon_20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "icon_29@2x.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "icon_29@3x.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "40x40", 29 | "idiom" : "iphone", 30 | "filename" : "icon_40@2x.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "icon_40@3x.png", 37 | "scale" : "3x" 38 | }, 39 | { 40 | "size" : "60x60", 41 | "idiom" : "iphone", 42 | "filename" : "icon_60@2x.png", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "icon_60@3x.png", 49 | "scale" : "3x" 50 | }, 51 | { 52 | "size" : "20x20", 53 | "idiom" : "ipad", 54 | "filename" : "icon_20@1x.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "icon_20@2x.png", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "size" : "29x29", 65 | "idiom" : "ipad", 66 | "filename" : "icon_29@1x.png", 67 | "scale" : "1x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "icon_29@2x.png", 73 | "scale" : "2x" 74 | }, 75 | { 76 | "size" : "40x40", 77 | "idiom" : "ipad", 78 | "filename" : "icon_40@1x.png", 79 | "scale" : "1x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "icon_40@2x.png", 85 | "scale" : "2x" 86 | }, 87 | { 88 | "size" : "76x76", 89 | "idiom" : "ipad", 90 | "filename" : "icon_76@1x.png", 91 | "scale" : "1x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "icon_76@2x.png", 97 | "scale" : "2x" 98 | }, 99 | { 100 | "size" : "83.5x83.5", 101 | "idiom" : "ipad", 102 | "filename" : "icon_83.5@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "1024x1024", 107 | "idiom" : "ios-marketing", 108 | "filename" : "icon_1024@1x.png", 109 | "scale" : "1x" 110 | } 111 | ], 112 | "info" : { 113 | "version" : 1, 114 | "author" : "xcode" 115 | } 116 | } -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Common/LiquidFilter.m: -------------------------------------------------------------------------------- 1 | // 2 | // LQKCILiquidFilter.m 3 | // Sprite Liquids 4 | // 5 | // Created by Astemir Eleev on 21/10/2017. 6 | // Copyright (c) 2017 Astemir Eleev 7 | // 8 | 9 | #import "LiquidFilter.h" 10 | 11 | #define GEN_COLOR_PADDING 12 12 | 13 | @implementation LiquidFilter 14 | 15 | @synthesize inputImage; 16 | 17 | 18 | - (id) initWithBlurRadius:(CGFloat)blurRadius withLiquidEffect:(NSObject*)liquidEffect { 19 | if (self = [super init]) { 20 | 21 | CIImage *inputGradientImage = nil; 22 | 23 | if (!(inputGradientImage = [liquidEffect thresholdGradient])) { 24 | return nil; 25 | } 26 | 27 | self.blurRadius = blurRadius; 28 | self.liquidEffect = liquidEffect; 29 | 30 | self.threshFilter = [CIFilter filterWithName:@"CIColorMap" keysAndValues:@"inputGradientImage", inputGradientImage, nil]; 31 | 32 | /* Create background filter */ 33 | CIFilter *backgroundColorFilter = [CIFilter filterWithName:@"CIConstantColorGenerator"]; 34 | [backgroundColorFilter setValue:[CIColor colorWithRed:0 green:0 blue:0 alpha:1] forKey:@"inputColor"]; 35 | 36 | /* Create image from background filter */ 37 | self.backgroundColor = [backgroundColorFilter valueForKey: kCIOutputImageKey]; 38 | 39 | /* Create composite filter */ 40 | self.compositeFilter = [CIFilter filterWithName:@"CISourceOverCompositing"]; 41 | 42 | /* Create blur */ 43 | self.blurFilter = [CIFilter filterWithName:@"CIGaussianBlur"]; 44 | [self.blurFilter setDefaults]; 45 | [self.blurFilter setValue:[NSNumber numberWithInteger:self.blurRadius] forKey:@"inputRadius"]; 46 | 47 | } 48 | 49 | return self; 50 | } 51 | 52 | - (CIImage *) outputImage { 53 | 54 | /* ColorMap only maps non-alpha colors, so a background is needed */ 55 | /* The color is padded to be a bit larger than the source image */ 56 | /* so that the gaussian blur has data to blur at the very edges of the source image */ 57 | CIImage *croppedColor = [self.backgroundColor 58 | imageByCroppingToRect:CGRectMake( 59 | self.inputImage.extent.origin.x - GEN_COLOR_PADDING - self.blurRadius, 60 | self.inputImage.extent.origin.y - GEN_COLOR_PADDING - self.blurRadius, 61 | self.inputImage.extent.size.width + ((GEN_COLOR_PADDING + self.blurRadius) * 2), 62 | self.inputImage.extent.size.height + ((GEN_COLOR_PADDING + self.blurRadius) * 2) 63 | ) 64 | ]; 65 | 66 | [self.compositeFilter setValue:croppedColor forKey:@"inputBackgroundImage"]; 67 | 68 | /* Composite input with background */ 69 | [self.compositeFilter setValue: self.inputImage forKey: kCIInputImageKey]; 70 | CIImage *backgroundedImage = [self.compositeFilter valueForKey: kCIOutputImageKey]; 71 | 72 | 73 | // TODO: allow blur radius to be passed in 74 | [self.blurFilter setValue:backgroundedImage forKey:kCIInputImageKey]; 75 | 76 | CIImage *blurredImage = [self.blurFilter valueForKey: kCIOutputImageKey]; 77 | 78 | /* Apply threshold */ 79 | [self.threshFilter setValue:blurredImage forKey:kCIInputImageKey]; 80 | 81 | CIImage *liquidImage = [self.threshFilter valueForKey: kCIOutputImageKey]; 82 | 83 | return [self.liquidEffect postProcessedFrameFrom:liquidImage]; 84 | } 85 | 86 | @end 87 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app/Scenes/GameScene.m: -------------------------------------------------------------------------------- 1 | // 2 | // GameScene.m 3 | // Sprite Liquids 4 | // 5 | // Created by Astemir Eleev on 21/10/2017. 6 | // Copyright © 2017 Astemir Eleev. All rights reserved. 7 | // 8 | 9 | #import "GameScene.h" 10 | 11 | #import "SolidColorEffect.h" 12 | #import "LiquidFilter.h" 13 | #import "LiquidParticleFactory.h" 14 | #import "LiquidNode.h" 15 | 16 | @import CoreMotion; 17 | 18 | @implementation GameScene { 19 | SKFieldNode* fieldNode; 20 | CMMotionManager* motionManager; 21 | } 22 | 23 | -(instancetype)initWithCoder:(NSCoder *)coder { 24 | self = [super initWithCoder:coder]; 25 | if (self) { 26 | 27 | fieldNode = [SKFieldNode magneticField]; 28 | fieldNode.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:60]; 29 | fieldNode.strength = 3.0; 30 | 31 | int particles = 90; 32 | [self createaLiquid:particles]; 33 | } 34 | return self; 35 | } 36 | 37 | -(void)didMoveToView:(SKView *)view { 38 | // Setup your scene here 39 | 40 | motionManager = [CMMotionManager new]; 41 | [motionManager startAccelerometerUpdates]; 42 | } 43 | 44 | -(void)createaLiquid:(int) particlesCount { 45 | // TODO: The following function requires refactoring: 46 | // 1. Eliminate magical numbers 47 | // 2. Make it more weakly-coupled and provide possibility to change physical and visual properties of liquid particles 48 | 49 | int blurRadius = 60; 50 | int particleRadius = 18; 51 | 52 | /* Create a texturing strategy for the liquid -- built-in, or on your own */ 53 | SolidColorEffect *solidEffect = [[SolidColorEffect alloc] initWithColor:[UIColor colorWithRed:0.2 green:0.2 blue:1.0 alpha:0.6] withIndex:100 withWidth:256]; 54 | 55 | /* Create a liquid filter with the liquid texturing effect */ 56 | LiquidFilter *filter = [[LiquidFilter alloc] initWithBlurRadius:blurRadius withLiquidEffect:solidEffect]; 57 | 58 | /* Create a liquid node with the liquid filter */ 59 | SKNode *liquidNode = [[LiquidNode alloc] initWithBlurRadius:blurRadius withLiquidFilter:filter]; 60 | liquidNode.name = @"liquid-node"; 61 | 62 | /* Create a particle factory that can produce optimized particles of a given size */ 63 | LiquidParticleFactory *liquidParticleFactory = [[LiquidParticleFactory alloc] initWithRadius:particleRadius]; 64 | 65 | CGFloat midX = CGRectGetMidX(self.view.bounds) / 2; 66 | CGFloat midY = CGRectGetMidY(self.view.bounds); 67 | midY = midY + 300; 68 | 69 | for (int p = 0; p < particlesCount; p++) { 70 | dispatch_async(dispatch_get_main_queue(), ^{ 71 | /* Spawn a single bead of liquid */ 72 | SKNode *particleNode = [liquidParticleFactory createLiquidParticle]; 73 | CGPoint position = CGPointMake(midX + p / 2, midY); 74 | particleNode.position = position; 75 | particleNode.physicsBody.density = 50.0; 76 | particleNode.physicsBody.mass = 0.5; 77 | particleNode.physicsBody.restitution = 0.1; 78 | 79 | /* Add the particle to the liquid so it will adopt its visual properties */ 80 | [liquidNode addChild:particleNode]; 81 | }); 82 | } 83 | [self addChild:liquidNode]; 84 | } 85 | 86 | -(void) removeLiquid { 87 | SKNode *liquidNode = [self childNodeWithName:@"liquid-node"]; 88 | [liquidNode removeAllChildren]; 89 | [liquidNode removeAllActions]; 90 | [liquidNode removeFromParent]; 91 | } 92 | 93 | -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 94 | [self addChild:fieldNode]; 95 | } 96 | 97 | -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{ 98 | 99 | for (UITouch *t in touches) { 100 | CGPoint location = [t locationInNode:self]; 101 | fieldNode.position = location; 102 | } 103 | } 104 | 105 | -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 106 | [fieldNode removeFromParent]; 107 | } 108 | 109 | -(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { 110 | [fieldNode removeFromParent]; 111 | } 112 | 113 | 114 | -(void)update:(CFTimeInterval)currentTime { 115 | // Called before each frame is rendered 116 | 117 | /* 118 | CMAccelerometerData* data = [motionManager accelerometerData]; 119 | 120 | if (data != nil) { 121 | self.physicsWorld.gravity = CGVectorMake(data.acceleration.y * -1, data.acceleration.x * -1); 122 | } 123 | */ 124 | } 125 | 126 | @end 127 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app/View/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | AvenirNext-Regular 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 41 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app/View/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 64 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /sprite-liquids-ios-app.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | A92286481F9B807D0012FD44 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A92286471F9B807D0012FD44 /* AppDelegate.m */; }; 11 | A922864A1F9B807D0012FD44 /* GameScene.sks in Resources */ = {isa = PBXBuildFile; fileRef = A92286491F9B807D0012FD44 /* GameScene.sks */; }; 12 | A922864C1F9B807D0012FD44 /* Actions.sks in Resources */ = {isa = PBXBuildFile; fileRef = A922864B1F9B807D0012FD44 /* Actions.sks */; }; 13 | A922864F1F9B807D0012FD44 /* GameScene.m in Sources */ = {isa = PBXBuildFile; fileRef = A922864E1F9B807D0012FD44 /* GameScene.m */; }; 14 | A92286521F9B807D0012FD44 /* GameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A92286511F9B807D0012FD44 /* GameViewController.m */; }; 15 | A92286551F9B807D0012FD44 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A92286531F9B807D0012FD44 /* Main.storyboard */; }; 16 | A92286571F9B807D0012FD44 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A92286561F9B807D0012FD44 /* Assets.xcassets */; }; 17 | A922865A1F9B807D0012FD44 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A92286581F9B807D0012FD44 /* LaunchScreen.storyboard */; }; 18 | A922865D1F9B807D0012FD44 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = A922865C1F9B807D0012FD44 /* main.m */; }; 19 | A92286671F9B807D0012FD44 /* LiquidDemoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = A92286661F9B807D0012FD44 /* LiquidDemoTests.m */; }; 20 | A92286721F9B807D0012FD44 /* LiquidDemoUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = A92286711F9B807D0012FD44 /* LiquidDemoUITests.m */; }; 21 | A92286921F9B80B80012FD44 /* SpriteKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A92286911F9B80B80012FD44 /* SpriteKit.framework */; }; 22 | A92286931F9B80C80012FD44 /* SolidColorEffect.m in Sources */ = {isa = PBXBuildFile; fileRef = A92286801F9B80AC0012FD44 /* SolidColorEffect.m */; }; 23 | A92286951F9B80C80012FD44 /* LiquidNode.m in Sources */ = {isa = PBXBuildFile; fileRef = A92286821F9B80AD0012FD44 /* LiquidNode.m */; }; 24 | A92286971F9B80C80012FD44 /* LQKImageUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = A92286841F9B80AD0012FD44 /* LQKImageUtils.m */; }; 25 | A92286981F9B80C80012FD44 /* LiquidFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = A92286851F9B80AD0012FD44 /* LiquidFilter.m */; }; 26 | A922869C1F9B80C80012FD44 /* LiquidParticleFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = A92286891F9B80AD0012FD44 /* LiquidParticleFactory.m */; }; 27 | A922869E1F9B80C80012FD44 /* LQKImageUtils+iOSUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = A922868C1F9B80AD0012FD44 /* LQKImageUtils+iOSUtils.m */; }; 28 | A94A50761F9BA2A6003AF86C /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A94A50751F9BA2A6003AF86C /* CoreMotion.framework */; }; 29 | A94A50781F9BA780003AF86C /* RotationAction.sks in Resources */ = {isa = PBXBuildFile; fileRef = A94A50771F9BA780003AF86C /* RotationAction.sks */; }; 30 | A9DF00CF2065201A004BFBF2 /* .gitignore in Resources */ = {isa = PBXBuildFile; fileRef = A9DF00CE2065201A004BFBF2 /* .gitignore */; }; 31 | /* End PBXBuildFile section */ 32 | 33 | /* Begin PBXContainerItemProxy section */ 34 | A92286631F9B807D0012FD44 /* PBXContainerItemProxy */ = { 35 | isa = PBXContainerItemProxy; 36 | containerPortal = A922863B1F9B807D0012FD44 /* Project object */; 37 | proxyType = 1; 38 | remoteGlobalIDString = A92286421F9B807D0012FD44; 39 | remoteInfo = LiquidDemo; 40 | }; 41 | A922866E1F9B807D0012FD44 /* PBXContainerItemProxy */ = { 42 | isa = PBXContainerItemProxy; 43 | containerPortal = A922863B1F9B807D0012FD44 /* Project object */; 44 | proxyType = 1; 45 | remoteGlobalIDString = A92286421F9B807D0012FD44; 46 | remoteInfo = LiquidDemo; 47 | }; 48 | /* End PBXContainerItemProxy section */ 49 | 50 | /* Begin PBXFileReference section */ 51 | A92286431F9B807D0012FD44 /* sprite-liquids-ios-app.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "sprite-liquids-ios-app.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | A92286461F9B807D0012FD44 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 53 | A92286471F9B807D0012FD44 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 54 | A92286491F9B807D0012FD44 /* GameScene.sks */ = {isa = PBXFileReference; lastKnownFileType = file.sks; path = GameScene.sks; sourceTree = ""; }; 55 | A922864B1F9B807D0012FD44 /* Actions.sks */ = {isa = PBXFileReference; lastKnownFileType = file.sks; path = Actions.sks; sourceTree = ""; }; 56 | A922864D1F9B807D0012FD44 /* GameScene.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameScene.h; sourceTree = ""; }; 57 | A922864E1F9B807D0012FD44 /* GameScene.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameScene.m; sourceTree = ""; }; 58 | A92286501F9B807D0012FD44 /* GameViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GameViewController.h; sourceTree = ""; }; 59 | A92286511F9B807D0012FD44 /* GameViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GameViewController.m; sourceTree = ""; }; 60 | A92286541F9B807D0012FD44 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 61 | A92286561F9B807D0012FD44 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 62 | A92286591F9B807D0012FD44 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 63 | A922865B1F9B807D0012FD44 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 64 | A922865C1F9B807D0012FD44 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 65 | A92286621F9B807D0012FD44 /* sprite-liquids-ios-appTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "sprite-liquids-ios-appTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 66 | A92286661F9B807D0012FD44 /* LiquidDemoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LiquidDemoTests.m; sourceTree = ""; }; 67 | A92286681F9B807D0012FD44 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 68 | A922866D1F9B807D0012FD44 /* sprite-liquids-ios-appUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "sprite-liquids-ios-appUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 69 | A92286711F9B807D0012FD44 /* LiquidDemoUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LiquidDemoUITests.m; sourceTree = ""; }; 70 | A92286731F9B807D0012FD44 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 71 | A92286801F9B80AC0012FD44 /* SolidColorEffect.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SolidColorEffect.m; sourceTree = ""; }; 72 | A92286811F9B80AC0012FD44 /* LiquidFilter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LiquidFilter.h; sourceTree = ""; }; 73 | A92286821F9B80AD0012FD44 /* LiquidNode.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LiquidNode.m; sourceTree = ""; }; 74 | A92286831F9B80AD0012FD44 /* LiquidParticleFactory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LiquidParticleFactory.h; sourceTree = ""; }; 75 | A92286841F9B80AD0012FD44 /* LQKImageUtils.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LQKImageUtils.m; sourceTree = ""; }; 76 | A92286851F9B80AD0012FD44 /* LiquidFilter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LiquidFilter.m; sourceTree = ""; }; 77 | A92286861F9B80AD0012FD44 /* SolidColorEffect.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SolidColorEffect.h; sourceTree = ""; }; 78 | A92286871F9B80AD0012FD44 /* LiquidNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LiquidNode.h; sourceTree = ""; }; 79 | A92286881F9B80AD0012FD44 /* LQKLiquidEffect.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LQKLiquidEffect.h; sourceTree = ""; }; 80 | A92286891F9B80AD0012FD44 /* LiquidParticleFactory.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LiquidParticleFactory.m; sourceTree = ""; }; 81 | A922868A1F9B80AD0012FD44 /* LQKImageUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LQKImageUtils.h; sourceTree = ""; }; 82 | A922868C1F9B80AD0012FD44 /* LQKImageUtils+iOSUtils.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "LQKImageUtils+iOSUtils.m"; sourceTree = ""; }; 83 | A922868D1F9B80AD0012FD44 /* LQKImageUtils+iOSUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "LQKImageUtils+iOSUtils.h"; sourceTree = ""; }; 84 | A922868E1F9B80AD0012FD44 /* SpriteLiquids-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SpriteLiquids-Prefix.pch"; sourceTree = ""; }; 85 | A922868F1F9B80AD0012FD44 /* SpriteLiquids.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SpriteLiquids.h; sourceTree = ""; }; 86 | A92286911F9B80B80012FD44 /* SpriteKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SpriteKit.framework; path = System/Library/Frameworks/SpriteKit.framework; sourceTree = SDKROOT; }; 87 | A94A50751F9BA2A6003AF86C /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = System/Library/Frameworks/CoreMotion.framework; sourceTree = SDKROOT; }; 88 | A94A50771F9BA780003AF86C /* RotationAction.sks */ = {isa = PBXFileReference; lastKnownFileType = file.sks; path = RotationAction.sks; sourceTree = ""; }; 89 | A9DF00CE2065201A004BFBF2 /* .gitignore */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitignore; sourceTree = ""; }; 90 | /* End PBXFileReference section */ 91 | 92 | /* Begin PBXFrameworksBuildPhase section */ 93 | A92286401F9B807D0012FD44 /* Frameworks */ = { 94 | isa = PBXFrameworksBuildPhase; 95 | buildActionMask = 2147483647; 96 | files = ( 97 | A94A50761F9BA2A6003AF86C /* CoreMotion.framework in Frameworks */, 98 | A92286921F9B80B80012FD44 /* SpriteKit.framework in Frameworks */, 99 | ); 100 | runOnlyForDeploymentPostprocessing = 0; 101 | }; 102 | A922865F1F9B807D0012FD44 /* Frameworks */ = { 103 | isa = PBXFrameworksBuildPhase; 104 | buildActionMask = 2147483647; 105 | files = ( 106 | ); 107 | runOnlyForDeploymentPostprocessing = 0; 108 | }; 109 | A922866A1F9B807D0012FD44 /* Frameworks */ = { 110 | isa = PBXFrameworksBuildPhase; 111 | buildActionMask = 2147483647; 112 | files = ( 113 | ); 114 | runOnlyForDeploymentPostprocessing = 0; 115 | }; 116 | /* End PBXFrameworksBuildPhase section */ 117 | 118 | /* Begin PBXGroup section */ 119 | A922863A1F9B807D0012FD44 = { 120 | isa = PBXGroup; 121 | children = ( 122 | A9DF00CE2065201A004BFBF2 /* .gitignore */, 123 | A92286451F9B807D0012FD44 /* sprite-liquids-ios-app */, 124 | A92286651F9B807D0012FD44 /* sprite-liquids-ios-app-tests */, 125 | A92286701F9B807D0012FD44 /* sprite-liquids-ios-app-UI-tests */, 126 | A92286441F9B807D0012FD44 /* Products */, 127 | A92286901F9B80B80012FD44 /* Frameworks */, 128 | ); 129 | sourceTree = ""; 130 | }; 131 | A92286441F9B807D0012FD44 /* Products */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | A92286431F9B807D0012FD44 /* sprite-liquids-ios-app.app */, 135 | A92286621F9B807D0012FD44 /* sprite-liquids-ios-appTests.xctest */, 136 | A922866D1F9B807D0012FD44 /* sprite-liquids-ios-appUITests.xctest */, 137 | ); 138 | name = Products; 139 | sourceTree = ""; 140 | }; 141 | A92286451F9B807D0012FD44 /* sprite-liquids-ios-app */ = { 142 | isa = PBXGroup; 143 | children = ( 144 | A92286461F9B807D0012FD44 /* AppDelegate.h */, 145 | A92286471F9B807D0012FD44 /* AppDelegate.m */, 146 | A922868E1F9B80AD0012FD44 /* SpriteLiquids-Prefix.pch */, 147 | A922868F1F9B80AD0012FD44 /* SpriteLiquids.h */, 148 | A92286561F9B807D0012FD44 /* Assets.xcassets */, 149 | A922865B1F9B807D0012FD44 /* Info.plist */, 150 | A922865C1F9B807D0012FD44 /* main.m */, 151 | A9DF00CD20651A67004BFBF2 /* View */, 152 | A9DF00CC206518E5004BFBF2 /* Scenes */, 153 | A9DF00CB206518DB004BFBF2 /* Controller */, 154 | A9DF00CA206518CB004BFBF2 /* SpriteKit Assets */, 155 | A922867F1F9B80AC0012FD44 /* Common */, 156 | A922868B1F9B80AD0012FD44 /* iOS */, 157 | ); 158 | path = "sprite-liquids-ios-app"; 159 | sourceTree = ""; 160 | }; 161 | A92286651F9B807D0012FD44 /* sprite-liquids-ios-app-tests */ = { 162 | isa = PBXGroup; 163 | children = ( 164 | A92286661F9B807D0012FD44 /* LiquidDemoTests.m */, 165 | A92286681F9B807D0012FD44 /* Info.plist */, 166 | ); 167 | path = "sprite-liquids-ios-app-tests"; 168 | sourceTree = ""; 169 | }; 170 | A92286701F9B807D0012FD44 /* sprite-liquids-ios-app-UI-tests */ = { 171 | isa = PBXGroup; 172 | children = ( 173 | A92286711F9B807D0012FD44 /* LiquidDemoUITests.m */, 174 | A92286731F9B807D0012FD44 /* Info.plist */, 175 | ); 176 | path = "sprite-liquids-ios-app-UI-tests"; 177 | sourceTree = ""; 178 | }; 179 | A922867F1F9B80AC0012FD44 /* Common */ = { 180 | isa = PBXGroup; 181 | children = ( 182 | A92286811F9B80AC0012FD44 /* LiquidFilter.h */, 183 | A92286851F9B80AD0012FD44 /* LiquidFilter.m */, 184 | A92286871F9B80AD0012FD44 /* LiquidNode.h */, 185 | A92286821F9B80AD0012FD44 /* LiquidNode.m */, 186 | A92286831F9B80AD0012FD44 /* LiquidParticleFactory.h */, 187 | A92286891F9B80AD0012FD44 /* LiquidParticleFactory.m */, 188 | A92286861F9B80AD0012FD44 /* SolidColorEffect.h */, 189 | A92286801F9B80AC0012FD44 /* SolidColorEffect.m */, 190 | A922868A1F9B80AD0012FD44 /* LQKImageUtils.h */, 191 | A92286841F9B80AD0012FD44 /* LQKImageUtils.m */, 192 | A92286881F9B80AD0012FD44 /* LQKLiquidEffect.h */, 193 | ); 194 | path = Common; 195 | sourceTree = ""; 196 | }; 197 | A922868B1F9B80AD0012FD44 /* iOS */ = { 198 | isa = PBXGroup; 199 | children = ( 200 | A922868D1F9B80AD0012FD44 /* LQKImageUtils+iOSUtils.h */, 201 | A922868C1F9B80AD0012FD44 /* LQKImageUtils+iOSUtils.m */, 202 | ); 203 | path = iOS; 204 | sourceTree = ""; 205 | }; 206 | A92286901F9B80B80012FD44 /* Frameworks */ = { 207 | isa = PBXGroup; 208 | children = ( 209 | A94A50751F9BA2A6003AF86C /* CoreMotion.framework */, 210 | A92286911F9B80B80012FD44 /* SpriteKit.framework */, 211 | ); 212 | name = Frameworks; 213 | sourceTree = ""; 214 | }; 215 | A9DF00CA206518CB004BFBF2 /* SpriteKit Assets */ = { 216 | isa = PBXGroup; 217 | children = ( 218 | A92286491F9B807D0012FD44 /* GameScene.sks */, 219 | A922864B1F9B807D0012FD44 /* Actions.sks */, 220 | A94A50771F9BA780003AF86C /* RotationAction.sks */, 221 | ); 222 | path = "SpriteKit Assets"; 223 | sourceTree = ""; 224 | }; 225 | A9DF00CB206518DB004BFBF2 /* Controller */ = { 226 | isa = PBXGroup; 227 | children = ( 228 | A92286501F9B807D0012FD44 /* GameViewController.h */, 229 | A92286511F9B807D0012FD44 /* GameViewController.m */, 230 | ); 231 | path = Controller; 232 | sourceTree = ""; 233 | }; 234 | A9DF00CC206518E5004BFBF2 /* Scenes */ = { 235 | isa = PBXGroup; 236 | children = ( 237 | A922864D1F9B807D0012FD44 /* GameScene.h */, 238 | A922864E1F9B807D0012FD44 /* GameScene.m */, 239 | ); 240 | path = Scenes; 241 | sourceTree = ""; 242 | }; 243 | A9DF00CD20651A67004BFBF2 /* View */ = { 244 | isa = PBXGroup; 245 | children = ( 246 | A92286531F9B807D0012FD44 /* Main.storyboard */, 247 | A92286581F9B807D0012FD44 /* LaunchScreen.storyboard */, 248 | ); 249 | path = View; 250 | sourceTree = ""; 251 | }; 252 | /* End PBXGroup section */ 253 | 254 | /* Begin PBXNativeTarget section */ 255 | A92286421F9B807D0012FD44 /* sprite-liquids-ios-app */ = { 256 | isa = PBXNativeTarget; 257 | buildConfigurationList = A92286761F9B807D0012FD44 /* Build configuration list for PBXNativeTarget "sprite-liquids-ios-app" */; 258 | buildPhases = ( 259 | A922863F1F9B807D0012FD44 /* Sources */, 260 | A92286401F9B807D0012FD44 /* Frameworks */, 261 | A92286411F9B807D0012FD44 /* Resources */, 262 | ); 263 | buildRules = ( 264 | ); 265 | dependencies = ( 266 | ); 267 | name = "sprite-liquids-ios-app"; 268 | productName = LiquidDemo; 269 | productReference = A92286431F9B807D0012FD44 /* sprite-liquids-ios-app.app */; 270 | productType = "com.apple.product-type.application"; 271 | }; 272 | A92286611F9B807D0012FD44 /* sprite-liquids-ios-appTests */ = { 273 | isa = PBXNativeTarget; 274 | buildConfigurationList = A92286791F9B807D0012FD44 /* Build configuration list for PBXNativeTarget "sprite-liquids-ios-appTests" */; 275 | buildPhases = ( 276 | A922865E1F9B807D0012FD44 /* Sources */, 277 | A922865F1F9B807D0012FD44 /* Frameworks */, 278 | A92286601F9B807D0012FD44 /* Resources */, 279 | ); 280 | buildRules = ( 281 | ); 282 | dependencies = ( 283 | A92286641F9B807D0012FD44 /* PBXTargetDependency */, 284 | ); 285 | name = "sprite-liquids-ios-appTests"; 286 | productName = LiquidDemoTests; 287 | productReference = A92286621F9B807D0012FD44 /* sprite-liquids-ios-appTests.xctest */; 288 | productType = "com.apple.product-type.bundle.unit-test"; 289 | }; 290 | A922866C1F9B807D0012FD44 /* sprite-liquids-ios-appUITests */ = { 291 | isa = PBXNativeTarget; 292 | buildConfigurationList = A922867C1F9B807D0012FD44 /* Build configuration list for PBXNativeTarget "sprite-liquids-ios-appUITests" */; 293 | buildPhases = ( 294 | A92286691F9B807D0012FD44 /* Sources */, 295 | A922866A1F9B807D0012FD44 /* Frameworks */, 296 | A922866B1F9B807D0012FD44 /* Resources */, 297 | ); 298 | buildRules = ( 299 | ); 300 | dependencies = ( 301 | A922866F1F9B807D0012FD44 /* PBXTargetDependency */, 302 | ); 303 | name = "sprite-liquids-ios-appUITests"; 304 | productName = LiquidDemoUITests; 305 | productReference = A922866D1F9B807D0012FD44 /* sprite-liquids-ios-appUITests.xctest */; 306 | productType = "com.apple.product-type.bundle.ui-testing"; 307 | }; 308 | /* End PBXNativeTarget section */ 309 | 310 | /* Begin PBXProject section */ 311 | A922863B1F9B807D0012FD44 /* Project object */ = { 312 | isa = PBXProject; 313 | attributes = { 314 | LastUpgradeCheck = 0940; 315 | ORGANIZATIONNAME = "Astemir Eleev"; 316 | TargetAttributes = { 317 | A92286421F9B807D0012FD44 = { 318 | CreatedOnToolsVersion = 9.0; 319 | ProvisioningStyle = Automatic; 320 | }; 321 | A92286611F9B807D0012FD44 = { 322 | CreatedOnToolsVersion = 9.0; 323 | ProvisioningStyle = Automatic; 324 | TestTargetID = A92286421F9B807D0012FD44; 325 | }; 326 | A922866C1F9B807D0012FD44 = { 327 | CreatedOnToolsVersion = 9.0; 328 | ProvisioningStyle = Automatic; 329 | TestTargetID = A92286421F9B807D0012FD44; 330 | }; 331 | }; 332 | }; 333 | buildConfigurationList = A922863E1F9B807D0012FD44 /* Build configuration list for PBXProject "sprite-liquids-ios-app" */; 334 | compatibilityVersion = "Xcode 8.0"; 335 | developmentRegion = en; 336 | hasScannedForEncodings = 0; 337 | knownRegions = ( 338 | en, 339 | Base, 340 | ); 341 | mainGroup = A922863A1F9B807D0012FD44; 342 | productRefGroup = A92286441F9B807D0012FD44 /* Products */; 343 | projectDirPath = ""; 344 | projectRoot = ""; 345 | targets = ( 346 | A92286421F9B807D0012FD44 /* sprite-liquids-ios-app */, 347 | A92286611F9B807D0012FD44 /* sprite-liquids-ios-appTests */, 348 | A922866C1F9B807D0012FD44 /* sprite-liquids-ios-appUITests */, 349 | ); 350 | }; 351 | /* End PBXProject section */ 352 | 353 | /* Begin PBXResourcesBuildPhase section */ 354 | A92286411F9B807D0012FD44 /* Resources */ = { 355 | isa = PBXResourcesBuildPhase; 356 | buildActionMask = 2147483647; 357 | files = ( 358 | A92286551F9B807D0012FD44 /* Main.storyboard in Resources */, 359 | A9DF00CF2065201A004BFBF2 /* .gitignore in Resources */, 360 | A922864A1F9B807D0012FD44 /* GameScene.sks in Resources */, 361 | A92286571F9B807D0012FD44 /* Assets.xcassets in Resources */, 362 | A922865A1F9B807D0012FD44 /* LaunchScreen.storyboard in Resources */, 363 | A922864C1F9B807D0012FD44 /* Actions.sks in Resources */, 364 | A94A50781F9BA780003AF86C /* RotationAction.sks in Resources */, 365 | ); 366 | runOnlyForDeploymentPostprocessing = 0; 367 | }; 368 | A92286601F9B807D0012FD44 /* Resources */ = { 369 | isa = PBXResourcesBuildPhase; 370 | buildActionMask = 2147483647; 371 | files = ( 372 | ); 373 | runOnlyForDeploymentPostprocessing = 0; 374 | }; 375 | A922866B1F9B807D0012FD44 /* Resources */ = { 376 | isa = PBXResourcesBuildPhase; 377 | buildActionMask = 2147483647; 378 | files = ( 379 | ); 380 | runOnlyForDeploymentPostprocessing = 0; 381 | }; 382 | /* End PBXResourcesBuildPhase section */ 383 | 384 | /* Begin PBXSourcesBuildPhase section */ 385 | A922863F1F9B807D0012FD44 /* Sources */ = { 386 | isa = PBXSourcesBuildPhase; 387 | buildActionMask = 2147483647; 388 | files = ( 389 | A92286931F9B80C80012FD44 /* SolidColorEffect.m in Sources */, 390 | A92286951F9B80C80012FD44 /* LiquidNode.m in Sources */, 391 | A92286971F9B80C80012FD44 /* LQKImageUtils.m in Sources */, 392 | A92286981F9B80C80012FD44 /* LiquidFilter.m in Sources */, 393 | A922869C1F9B80C80012FD44 /* LiquidParticleFactory.m in Sources */, 394 | A922869E1F9B80C80012FD44 /* LQKImageUtils+iOSUtils.m in Sources */, 395 | A922864F1F9B807D0012FD44 /* GameScene.m in Sources */, 396 | A92286521F9B807D0012FD44 /* GameViewController.m in Sources */, 397 | A922865D1F9B807D0012FD44 /* main.m in Sources */, 398 | A92286481F9B807D0012FD44 /* AppDelegate.m in Sources */, 399 | ); 400 | runOnlyForDeploymentPostprocessing = 0; 401 | }; 402 | A922865E1F9B807D0012FD44 /* Sources */ = { 403 | isa = PBXSourcesBuildPhase; 404 | buildActionMask = 2147483647; 405 | files = ( 406 | A92286671F9B807D0012FD44 /* LiquidDemoTests.m in Sources */, 407 | ); 408 | runOnlyForDeploymentPostprocessing = 0; 409 | }; 410 | A92286691F9B807D0012FD44 /* Sources */ = { 411 | isa = PBXSourcesBuildPhase; 412 | buildActionMask = 2147483647; 413 | files = ( 414 | A92286721F9B807D0012FD44 /* LiquidDemoUITests.m in Sources */, 415 | ); 416 | runOnlyForDeploymentPostprocessing = 0; 417 | }; 418 | /* End PBXSourcesBuildPhase section */ 419 | 420 | /* Begin PBXTargetDependency section */ 421 | A92286641F9B807D0012FD44 /* PBXTargetDependency */ = { 422 | isa = PBXTargetDependency; 423 | target = A92286421F9B807D0012FD44 /* sprite-liquids-ios-app */; 424 | targetProxy = A92286631F9B807D0012FD44 /* PBXContainerItemProxy */; 425 | }; 426 | A922866F1F9B807D0012FD44 /* PBXTargetDependency */ = { 427 | isa = PBXTargetDependency; 428 | target = A92286421F9B807D0012FD44 /* sprite-liquids-ios-app */; 429 | targetProxy = A922866E1F9B807D0012FD44 /* PBXContainerItemProxy */; 430 | }; 431 | /* End PBXTargetDependency section */ 432 | 433 | /* Begin PBXVariantGroup section */ 434 | A92286531F9B807D0012FD44 /* Main.storyboard */ = { 435 | isa = PBXVariantGroup; 436 | children = ( 437 | A92286541F9B807D0012FD44 /* Base */, 438 | ); 439 | name = Main.storyboard; 440 | sourceTree = ""; 441 | }; 442 | A92286581F9B807D0012FD44 /* LaunchScreen.storyboard */ = { 443 | isa = PBXVariantGroup; 444 | children = ( 445 | A92286591F9B807D0012FD44 /* Base */, 446 | ); 447 | name = LaunchScreen.storyboard; 448 | sourceTree = ""; 449 | }; 450 | /* End PBXVariantGroup section */ 451 | 452 | /* Begin XCBuildConfiguration section */ 453 | A92286741F9B807D0012FD44 /* Debug */ = { 454 | isa = XCBuildConfiguration; 455 | buildSettings = { 456 | ALWAYS_SEARCH_USER_PATHS = NO; 457 | CLANG_ANALYZER_NONNULL = YES; 458 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 459 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 460 | CLANG_CXX_LIBRARY = "libc++"; 461 | CLANG_ENABLE_MODULES = YES; 462 | CLANG_ENABLE_OBJC_ARC = YES; 463 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 464 | CLANG_WARN_BOOL_CONVERSION = YES; 465 | CLANG_WARN_COMMA = YES; 466 | CLANG_WARN_CONSTANT_CONVERSION = YES; 467 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 468 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 469 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 470 | CLANG_WARN_EMPTY_BODY = YES; 471 | CLANG_WARN_ENUM_CONVERSION = YES; 472 | CLANG_WARN_INFINITE_RECURSION = YES; 473 | CLANG_WARN_INT_CONVERSION = YES; 474 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 475 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 476 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 477 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 478 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 479 | CLANG_WARN_STRICT_PROTOTYPES = YES; 480 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 481 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 482 | CLANG_WARN_UNREACHABLE_CODE = YES; 483 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 484 | CODE_SIGN_IDENTITY = "iPhone Developer"; 485 | COPY_PHASE_STRIP = NO; 486 | DEBUG_INFORMATION_FORMAT = dwarf; 487 | ENABLE_STRICT_OBJC_MSGSEND = YES; 488 | ENABLE_TESTABILITY = YES; 489 | GCC_C_LANGUAGE_STANDARD = gnu11; 490 | GCC_DYNAMIC_NO_PIC = NO; 491 | GCC_NO_COMMON_BLOCKS = YES; 492 | GCC_OPTIMIZATION_LEVEL = 0; 493 | GCC_PREPROCESSOR_DEFINITIONS = ( 494 | "DEBUG=1", 495 | "$(inherited)", 496 | ); 497 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 498 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 499 | GCC_WARN_UNDECLARED_SELECTOR = YES; 500 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 501 | GCC_WARN_UNUSED_FUNCTION = YES; 502 | GCC_WARN_UNUSED_VARIABLE = YES; 503 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 504 | MTL_ENABLE_DEBUG_INFO = YES; 505 | ONLY_ACTIVE_ARCH = YES; 506 | SDKROOT = iphoneos; 507 | }; 508 | name = Debug; 509 | }; 510 | A92286751F9B807D0012FD44 /* Release */ = { 511 | isa = XCBuildConfiguration; 512 | buildSettings = { 513 | ALWAYS_SEARCH_USER_PATHS = NO; 514 | CLANG_ANALYZER_NONNULL = YES; 515 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 516 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 517 | CLANG_CXX_LIBRARY = "libc++"; 518 | CLANG_ENABLE_MODULES = YES; 519 | CLANG_ENABLE_OBJC_ARC = YES; 520 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 521 | CLANG_WARN_BOOL_CONVERSION = YES; 522 | CLANG_WARN_COMMA = YES; 523 | CLANG_WARN_CONSTANT_CONVERSION = YES; 524 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 525 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 526 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 527 | CLANG_WARN_EMPTY_BODY = YES; 528 | CLANG_WARN_ENUM_CONVERSION = YES; 529 | CLANG_WARN_INFINITE_RECURSION = YES; 530 | CLANG_WARN_INT_CONVERSION = YES; 531 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 532 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 533 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 534 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 535 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 536 | CLANG_WARN_STRICT_PROTOTYPES = YES; 537 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 538 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 539 | CLANG_WARN_UNREACHABLE_CODE = YES; 540 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 541 | CODE_SIGN_IDENTITY = "iPhone Developer"; 542 | COPY_PHASE_STRIP = NO; 543 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 544 | ENABLE_NS_ASSERTIONS = NO; 545 | ENABLE_STRICT_OBJC_MSGSEND = YES; 546 | GCC_C_LANGUAGE_STANDARD = gnu11; 547 | GCC_NO_COMMON_BLOCKS = YES; 548 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 549 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 550 | GCC_WARN_UNDECLARED_SELECTOR = YES; 551 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 552 | GCC_WARN_UNUSED_FUNCTION = YES; 553 | GCC_WARN_UNUSED_VARIABLE = YES; 554 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 555 | MTL_ENABLE_DEBUG_INFO = NO; 556 | SDKROOT = iphoneos; 557 | VALIDATE_PRODUCT = YES; 558 | }; 559 | name = Release; 560 | }; 561 | A92286771F9B807D0012FD44 /* Debug */ = { 562 | isa = XCBuildConfiguration; 563 | buildSettings = { 564 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 565 | CODE_SIGN_STYLE = Automatic; 566 | DEVELOPMENT_TEAM = T3K58FE38R; 567 | INFOPLIST_FILE = "$(SRCROOT)/sprite-liquids-ios-app/Info.plist"; 568 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 569 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 570 | PRODUCT_BUNDLE_IDENTIFIER = "eleev.astemir.io.sprite-liquids"; 571 | PRODUCT_NAME = "$(TARGET_NAME)"; 572 | TARGETED_DEVICE_FAMILY = "1,2"; 573 | }; 574 | name = Debug; 575 | }; 576 | A92286781F9B807D0012FD44 /* Release */ = { 577 | isa = XCBuildConfiguration; 578 | buildSettings = { 579 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 580 | CODE_SIGN_STYLE = Automatic; 581 | DEVELOPMENT_TEAM = T3K58FE38R; 582 | INFOPLIST_FILE = "$(SRCROOT)/sprite-liquids-ios-app/Info.plist"; 583 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 584 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 585 | PRODUCT_BUNDLE_IDENTIFIER = "eleev.astemir.io.sprite-liquids"; 586 | PRODUCT_NAME = "$(TARGET_NAME)"; 587 | TARGETED_DEVICE_FAMILY = "1,2"; 588 | }; 589 | name = Release; 590 | }; 591 | A922867A1F9B807D0012FD44 /* Debug */ = { 592 | isa = XCBuildConfiguration; 593 | buildSettings = { 594 | BUNDLE_LOADER = "$(TEST_HOST)"; 595 | CODE_SIGN_STYLE = Automatic; 596 | DEVELOPMENT_TEAM = T3K58FE38R; 597 | INFOPLIST_FILE = LiquidDemoTests/Info.plist; 598 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 599 | PRODUCT_BUNDLE_IDENTIFIER = projectk.io.LiquidDemoTests; 600 | PRODUCT_NAME = "$(TARGET_NAME)"; 601 | TARGETED_DEVICE_FAMILY = "1,2"; 602 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/sprite-liquids-ios-app.app/sprite-liquids-ios-app"; 603 | }; 604 | name = Debug; 605 | }; 606 | A922867B1F9B807D0012FD44 /* Release */ = { 607 | isa = XCBuildConfiguration; 608 | buildSettings = { 609 | BUNDLE_LOADER = "$(TEST_HOST)"; 610 | CODE_SIGN_STYLE = Automatic; 611 | DEVELOPMENT_TEAM = T3K58FE38R; 612 | INFOPLIST_FILE = LiquidDemoTests/Info.plist; 613 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 614 | PRODUCT_BUNDLE_IDENTIFIER = projectk.io.LiquidDemoTests; 615 | PRODUCT_NAME = "$(TARGET_NAME)"; 616 | TARGETED_DEVICE_FAMILY = "1,2"; 617 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/sprite-liquids-ios-app.app/sprite-liquids-ios-app"; 618 | }; 619 | name = Release; 620 | }; 621 | A922867D1F9B807D0012FD44 /* Debug */ = { 622 | isa = XCBuildConfiguration; 623 | buildSettings = { 624 | CODE_SIGN_STYLE = Automatic; 625 | DEVELOPMENT_TEAM = EK3QDL7K69; 626 | INFOPLIST_FILE = LiquidDemoUITests/Info.plist; 627 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 628 | PRODUCT_BUNDLE_IDENTIFIER = projectk.io.LiquidDemoUITests; 629 | PRODUCT_NAME = "$(TARGET_NAME)"; 630 | TARGETED_DEVICE_FAMILY = "1,2"; 631 | TEST_TARGET_NAME = LiquidDemo; 632 | }; 633 | name = Debug; 634 | }; 635 | A922867E1F9B807D0012FD44 /* Release */ = { 636 | isa = XCBuildConfiguration; 637 | buildSettings = { 638 | CODE_SIGN_STYLE = Automatic; 639 | DEVELOPMENT_TEAM = EK3QDL7K69; 640 | INFOPLIST_FILE = LiquidDemoUITests/Info.plist; 641 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 642 | PRODUCT_BUNDLE_IDENTIFIER = projectk.io.LiquidDemoUITests; 643 | PRODUCT_NAME = "$(TARGET_NAME)"; 644 | TARGETED_DEVICE_FAMILY = "1,2"; 645 | TEST_TARGET_NAME = LiquidDemo; 646 | }; 647 | name = Release; 648 | }; 649 | /* End XCBuildConfiguration section */ 650 | 651 | /* Begin XCConfigurationList section */ 652 | A922863E1F9B807D0012FD44 /* Build configuration list for PBXProject "sprite-liquids-ios-app" */ = { 653 | isa = XCConfigurationList; 654 | buildConfigurations = ( 655 | A92286741F9B807D0012FD44 /* Debug */, 656 | A92286751F9B807D0012FD44 /* Release */, 657 | ); 658 | defaultConfigurationIsVisible = 0; 659 | defaultConfigurationName = Release; 660 | }; 661 | A92286761F9B807D0012FD44 /* Build configuration list for PBXNativeTarget "sprite-liquids-ios-app" */ = { 662 | isa = XCConfigurationList; 663 | buildConfigurations = ( 664 | A92286771F9B807D0012FD44 /* Debug */, 665 | A92286781F9B807D0012FD44 /* Release */, 666 | ); 667 | defaultConfigurationIsVisible = 0; 668 | defaultConfigurationName = Release; 669 | }; 670 | A92286791F9B807D0012FD44 /* Build configuration list for PBXNativeTarget "sprite-liquids-ios-appTests" */ = { 671 | isa = XCConfigurationList; 672 | buildConfigurations = ( 673 | A922867A1F9B807D0012FD44 /* Debug */, 674 | A922867B1F9B807D0012FD44 /* Release */, 675 | ); 676 | defaultConfigurationIsVisible = 0; 677 | defaultConfigurationName = Release; 678 | }; 679 | A922867C1F9B807D0012FD44 /* Build configuration list for PBXNativeTarget "sprite-liquids-ios-appUITests" */ = { 680 | isa = XCConfigurationList; 681 | buildConfigurations = ( 682 | A922867D1F9B807D0012FD44 /* Debug */, 683 | A922867E1F9B807D0012FD44 /* Release */, 684 | ); 685 | defaultConfigurationIsVisible = 0; 686 | defaultConfigurationName = Release; 687 | }; 688 | /* End XCConfigurationList section */ 689 | }; 690 | rootObject = A922863B1F9B807D0012FD44 /* Project object */; 691 | } 692 | --------------------------------------------------------------------------------