├── .gitignore ├── GoBangGraduationProject.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── GoBangGraduationProject ├── Class │ ├── AI │ │ ├── AIViewController.h │ │ └── AIViewController.m │ ├── Chooes │ │ ├── ViewController.h │ │ └── ViewController.m │ ├── Launch │ │ ├── DHLaunchVC.h │ │ └── DHLaunchVC.m │ ├── Menu │ │ ├── DHMenuVC.h │ │ └── DHMenuVC.m │ └── Person │ │ ├── PersonViewController.h │ │ └── PersonViewController.m ├── CustomModel │ ├── DHAI.h │ ├── DHAI.m │ ├── DHPoint.h │ └── DHPoint.m ├── CustomVC │ ├── DHNavgationController.h │ └── DHNavgationController.m ├── CustomView │ ├── ChessBoardView.h │ ├── ChessBoardView.m │ ├── DHPPChessBoardView.h │ └── DHPPChessBoardView.m ├── Info.plist ├── Lib │ ├── LLSwitch │ │ ├── LLAnimationManager.h │ │ ├── LLAnimationManager.m │ │ ├── LLEyesLayer.h │ │ ├── LLEyesLayer.m │ │ ├── LLSwitch.h │ │ └── LLSwitch.m │ └── SFDraggableDialogView │ │ ├── Resources │ │ ├── icArrow.png │ │ ├── icArrow@2x.png │ │ ├── icArrow@3x.png │ │ ├── icArrowTop.png │ │ ├── icArrowTop@2x.png │ │ ├── icArrowTop@3x.png │ │ └── icCross@2x.png │ │ ├── SFDraggableDialogView.h │ │ ├── SFDraggableDialogView.m │ │ ├── SFDraggableDialogView.xib │ │ ├── UIImage+ImageEffects.h │ │ └── UIImage+ImageEffects.m ├── Main │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-20@3x.png │ │ │ ├── Icon-60@2x.png │ │ │ ├── Icon-60@3x.png │ │ │ ├── Icon-Small@2x.png │ │ │ ├── Icon-Small@3x.png │ │ │ ├── Icon-Spotlight-20@2x.png │ │ │ ├── Icon-Spotlight-40@2x.png │ │ │ └── Icon-Spotlight-40@3x.png │ │ ├── Contents.json │ │ ├── backMusic.imageset │ │ │ ├── Contents.json │ │ │ └── backMusic.png │ │ ├── backNoMusic.imageset │ │ │ ├── Contents.json │ │ │ └── backNoMusic.png │ │ ├── bk1.imageset │ │ │ ├── Contents.json │ │ │ └── bk1.png │ │ ├── bk2.imageset │ │ │ ├── Contents.json │ │ │ └── bk2.png │ │ ├── bottom.imageset │ │ │ ├── Contents.json │ │ │ └── bottom.jpg │ │ ├── classicalBG1.imageset │ │ │ ├── Contents.json │ │ │ └── classicalBG1.jpg │ │ ├── classicalBG2.imageset │ │ │ ├── Contents.json │ │ │ └── classicalBG2.jpg │ │ ├── classicalBG3.imageset │ │ │ ├── Contents.json │ │ │ └── classicalBG3.jpg │ │ ├── gaide │ │ │ ├── 1.imageset │ │ │ │ ├── 1.jpg │ │ │ │ └── Contents.json │ │ │ ├── 10.imageset │ │ │ │ ├── 10.jpg │ │ │ │ └── Contents.json │ │ │ ├── 2.imageset │ │ │ │ ├── 2.jpg │ │ │ │ └── Contents.json │ │ │ ├── 3.imageset │ │ │ │ ├── 3.jpg │ │ │ │ └── Contents.json │ │ │ ├── 4.imageset │ │ │ │ ├── 4.jpg │ │ │ │ └── Contents.json │ │ │ ├── 5.imageset │ │ │ │ ├── 5.jpg │ │ │ │ └── Contents.json │ │ │ ├── 6.imageset │ │ │ │ ├── 6.jpg │ │ │ │ └── Contents.json │ │ │ ├── 7.imageset │ │ │ │ ├── 7.jpg │ │ │ │ └── Contents.json │ │ │ ├── 8.imageset │ │ │ │ ├── 8.jpg │ │ │ │ └── Contents.json │ │ │ ├── 9.imageset │ │ │ │ ├── 9.jpg │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ └── lappover.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── lappover.png │ │ ├── launch │ │ │ ├── Contents.json │ │ │ ├── Default-Portrait.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── Default-Portrait.png │ │ │ │ └── Default-Portrait@2x.png │ │ │ └── DefaultLaunchPicture.imageset │ │ │ │ ├── Contents.json │ │ │ │ ├── Default-568h@2x.png │ │ │ │ ├── Default.png │ │ │ │ └── Default@2x.png │ │ ├── lostPic.imageset │ │ │ ├── Contents.json │ │ │ └── lostPic.jpg │ │ ├── playbackground.imageset │ │ │ ├── Contents.json │ │ │ └── playbackground.png │ │ ├── stone_black.imageset │ │ │ ├── Contents.json │ │ │ └── stone_black.png │ │ ├── stone_white.imageset │ │ │ ├── Contents.json │ │ │ └── stone_white.png │ │ ├── winPic.imageset │ │ │ ├── Contents.json │ │ │ └── winPic.png │ │ ├── wuziqiIcon-1.imageset │ │ │ ├── Contents.json │ │ │ └── wuziqiIcon.png │ │ └── wuziqiIcon.imageset │ │ │ ├── Contents.json │ │ │ └── wuziqiIcon.png │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Config.h │ └── Gobang.pch ├── Resource │ └── sound │ │ ├── BgMusic.mp3 │ │ ├── au_gameover.wav │ │ ├── au_victory.wav │ │ ├── check.wav │ │ ├── down.wav │ │ ├── lost.wav │ │ ├── marking.wav │ │ ├── mode.wav │ │ ├── pipa.mp3 │ │ ├── quikly.wav │ │ ├── regret.wav │ │ ├── start.wav │ │ └── win.wav ├── Tool │ ├── DHGobangTool.h │ ├── DHGobangTool.m │ ├── DHMCTool.h │ ├── DHMCTool.m │ ├── DHNSUserdefault.h │ ├── DHNSUserdefault.m │ ├── HBPlaySoundUtil.h │ └── HBPlaySoundUtil.m └── main.m ├── GoBangGraduationProjectTests ├── GoBangGraduationProjectTests.m └── Info.plist ├── GoBangGraduationProjectUITests ├── GoBangGraduationProjectUITests.m └── Info.plist ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xcuserstate 23 | 24 | ## Obj-C/Swift specific 25 | *.hmap 26 | *.ipa 27 | *.dSYM.zip 28 | *.dSYM 29 | 30 | # CocoaPods 31 | # 32 | # We recommend against adding the Pods directory to your .gitignore. However 33 | # you should judge for yourself, the pros and cons are mentioned at: 34 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 35 | # 36 | # Pods/ 37 | 38 | # Carthage 39 | # 40 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 41 | # Carthage/Checkouts 42 | 43 | Carthage/Build 44 | 45 | # fastlane 46 | # 47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 48 | # screenshots whenever they are needed. 49 | # For more information about the recommended setup visit: 50 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 51 | 52 | fastlane/report.xml 53 | fastlane/screenshots 54 | 55 | #Code Injection 56 | # 57 | # After new code Injection tools there's a generated folder /iOSInjectionProject 58 | # https://github.com/johnno1962/injectionforxcode 59 | 60 | iOSInjectionProject/ 61 | -------------------------------------------------------------------------------- /GoBangGraduationProject.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Class/AI/AIViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // AIViewController.h 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/5/30. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AIViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Class/AI/AIViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // AIViewController.m 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/5/30. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import "AIViewController.h" 10 | #import "HBPlaySoundUtil.h" 11 | #import "ChessBoardView.h" 12 | #import "SFDraggableDialogView.h" 13 | #import "DHNSUserdefault.h" 14 | 15 | @interface AIViewController () { 16 | 17 | __weak IBOutlet UIImageView *backgroundImgView; 18 | ChessBoardView *boardView; 19 | __weak IBOutlet UIButton *soundBtn; 20 | } 21 | 22 | @end 23 | 24 | @implementation AIViewController 25 | 26 | - (void)dealloc { 27 | 28 | [[NSNotificationCenter defaultCenter] removeObserver:self name:AIWhoWinNotify object:nil]; 29 | } 30 | 31 | - (void)viewDidLoad { 32 | [super viewDidLoad]; 33 | /** 34 | 通知 35 | */ 36 | soundBtn.selected = ![DHNSUserdefault getTheIsSounds]; 37 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(whoWin:) name:AIWhoWinNotify object:nil]; 38 | boardView = [[ChessBoardView alloc] initWithFrame:CGRectMake(0, 50, SCREEN_W, SCREEN_W)]; 39 | backgroundImgView.userInteractionEnabled = YES; 40 | [backgroundImgView addSubview:boardView]; 41 | } 42 | - (IBAction)startAgainClick:(UIButton *)sender { 43 | 44 | [[HBPlaySoundUtil shareForPlayingSoundEffectWith:@"start.wav"] play]; 45 | [boardView reset]; 46 | } 47 | - (IBAction)undoClick:(UIButton *)sender { 48 | 49 | [[HBPlaySoundUtil shareForPlayingSoundEffectWith:@"regret.wav"] play]; 50 | [boardView undo]; 51 | } 52 | - (IBAction)soundClick:(UIButton *)sender { 53 | 54 | sender.selected = !sender.selected; 55 | [DHNSUserdefault setupIsSounds:!sender.isSelected]; 56 | } 57 | 58 | - (void)whoWin:(NSNotification *)notify { 59 | 60 | OccupyType type = [notify.userInfo[@"type"] integerValue]; 61 | SFDraggableDialogView *v = [[SFDraggableDialogView alloc] init]; 62 | if (type == OccupyTypeAI) { 63 | NSLog(@"收到通知,AI赢了"); 64 | v = [SFDraggableDialogView drgViewWith:self titleText:@"游戏结束了" photo:[UIImage imageNamed:@"lostPic.jpg"] message:@"电脑都搞不赢"]; 65 | v.delegate = self; 66 | } else if (type == OccupyTypeUser) { 67 | NSLog(@"收到通知,你赢了"); 68 | v = [SFDraggableDialogView drgViewWith:self titleText:@"游戏结束了" photo:[UIImage imageNamed:@"winPic.png"] message:@"诶吆,不错了"]; 69 | v.delegate = self; 70 | } 71 | 72 | [self.view addSubview:v]; 73 | } 74 | 75 | - (void)draggableDialogView:(SFDraggableDialogView *)dialogView didPressFirstButton:(UIButton *)firstButton { 76 | 77 | [boardView reset]; 78 | [dialogView dismissWithDrop:YES]; 79 | } 80 | @end 81 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Class/Chooes/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/5/10. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Class/Chooes/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/5/10. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "ChessBoardView.h" 11 | #import "DHMCTool.h" 12 | #import "PersonViewController.h" 13 | 14 | @interface ViewController () { 15 | 16 | 17 | } 18 | @property (nonatomic, strong) DHMCTool *mcTool; 19 | 20 | @end 21 | 22 | @implementation ViewController 23 | 24 | - (DHMCTool *)mcTool { 25 | 26 | if (!_mcTool) { 27 | _mcTool = [DHMCTool tool]; 28 | } 29 | return _mcTool; 30 | } 31 | 32 | - (void)viewDidLoad { 33 | [super viewDidLoad]; 34 | /** 35 | * 测试 36 | */ 37 | for (int i = 0; i < -1; i ++) { 38 | NSLog(@"i == %d",i); 39 | } 40 | self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:self action:nil]; 41 | } 42 | 43 | - (IBAction)twoPersonClick:(UIButton *)sender { 44 | 45 | _mcTool.delegate = self; 46 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"请选择以下场景" message:@"蓝牙对战要先打开蓝牙,或者同一局域网内" delegate:sender cancelButtonTitle:@"稳一手" otherButtonTitles:@"同屏对战",@"蓝牙对战", nil]; 47 | alert.delegate = self; 48 | [alert show]; 49 | } 50 | 51 | - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { 52 | 53 | if (buttonIndex == 1) { 54 | [self performSegueWithIdentifier:@"ppSegue" sender:@1]; 55 | } else if (buttonIndex == 2) { 56 | 57 | self.mcTool.browser = [self.mcTool browser]; 58 | [self presentViewController:self.mcTool.browser animated:YES completion:^{ 59 | 60 | }]; 61 | } 62 | } 63 | 64 | #pragma mark - DHMCToolDelegate 65 | - (void)browserControllerCancleAndDone { 66 | 67 | [self performSegueWithIdentifier:@"ppSegue" sender:@2]; 68 | } 69 | 70 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 71 | 72 | if ([segue.identifier isEqualToString:@"ppSegue"]) { 73 | PersonViewController *p = segue.destinationViewController; 74 | p.isBlueTooth = ([sender integerValue] == 1 ? NO:YES); 75 | } 76 | } 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Class/Launch/DHLaunchVC.h: -------------------------------------------------------------------------------- 1 | // 2 | // DHLaunchVC.h 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/6/3. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DHLaunchVC : UIViewController 12 | /** 13 | * 回到主界面 14 | */ 15 | - (void)getBackToHomeView; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Class/Launch/DHLaunchVC.m: -------------------------------------------------------------------------------- 1 | // 2 | // DHLaunchVC.m 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/6/3. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import "DHLaunchVC.h" 10 | #import "DHNavgationController.h" 11 | 12 | @interface DHLaunchVC () { 13 | 14 | UIScrollView *scrollView; // 滚动试图 15 | UIPageControl *pageControl; // 分页控制器 16 | NSInteger pages; 17 | } 18 | 19 | @end 20 | 21 | @implementation DHLaunchVC 22 | - (BOOL)prefersStatusBarHidden { 23 | 24 | return YES; 25 | } 26 | 27 | 28 | - (void)viewDidLoad { 29 | [super viewDidLoad]; 30 | self.view.backgroundColor = [UIColor whiteColor]; 31 | pages = 10; // 页面数 32 | [self createUI]; 33 | } 34 | /** 35 | * 创建UI 36 | */ 37 | - (void)createUI { 38 | 39 | scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_W, SCREEN_H)]; 40 | scrollView.contentSize = CGSizeMake(SCREEN_W * pages, 0); 41 | scrollView.showsVerticalScrollIndicator = NO; 42 | scrollView.showsHorizontalScrollIndicator = NO; 43 | scrollView.pagingEnabled = YES; 44 | scrollView.bounces = NO; // 关闭弹性滑动; 45 | scrollView.delegate = self; 46 | 47 | 48 | // 添加图片 49 | for (NSInteger i = 0; i < pages; i ++) { 50 | UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(SCREEN_W * i, 0, SCREEN_W, SCREEN_H)]; 51 | UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; 52 | btn.frame = CGRectMake(SCREEN_W * (i + 1) - 55, 5, 50, 25); 53 | [btn addTarget:self action:@selector(getBackToHomeView) forControlEvents:UIControlEventTouchUpInside]; 54 | [btn setBackgroundImage:[UIImage imageNamed:@"lappover"] forState:UIControlStateNormal]; 55 | NSString *imgStr = [NSString stringWithFormat:@"%d.jpg",i + 1]; 56 | imgView.image = [UIImage imageNamed:imgStr]; 57 | [scrollView addSubview:imgView]; 58 | [scrollView addSubview:btn]; 59 | } 60 | 61 | // 添加退出btn 62 | UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; 63 | btn.center = CGPointMake(SCREEN_W * (pages - 1) + SCREEN_W / 2, SCREEN_H / 6.0 * 5.5); 64 | btn.bounds = CGRectMake(0, 0, 80, 30); 65 | [btn setTitle:@"进入游戏" forState:UIControlStateNormal]; 66 | btn.backgroundColor = [UIColor lightGrayColor]; 67 | btn.layer.borderColor = [UIColor whiteColor].CGColor; 68 | btn.layer.borderWidth = 2; 69 | btn.layer.cornerRadius = 5; 70 | [btn addTarget:self action:@selector(getBackToHomeView) forControlEvents:UIControlEventTouchUpInside]; 71 | 72 | // 创建分页器 73 | pageControl = [[UIPageControl alloc] init]; 74 | pageControl.center = CGPointMake(SCREEN_W / 2, SCREEN_H / 6.0 * 5.2); 75 | pageControl.bounds = CGRectMake(0, 0, 80, 37); 76 | pageControl.numberOfPages = pages; 77 | pageControl.currentPageIndicatorTintColor = [UIColor yellowColor]; 78 | 79 | [scrollView addSubview:btn]; 80 | [self.view addSubview:scrollView]; 81 | [self.view addSubview:pageControl]; 82 | } 83 | #pragma mark 按钮点击 84 | /** 85 | * 回到主界面 86 | */ 87 | - (void)getBackToHomeView { 88 | 89 | // 让登陆界面成为根控制器 90 | UIWindow *window = [UIApplication sharedApplication].keyWindow; 91 | UIStoryboard *loginStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; 92 | DHNavgationController *loginVC = [loginStoryboard instantiateViewControllerWithIdentifier:@"DHNavgationController"]; 93 | [[NSUserDefaults standardUserDefaults] setBool:YES forKey:IsHaveUsed]; 94 | [[NSUserDefaults standardUserDefaults] synchronize]; 95 | [window setRootViewController:loginVC]; 96 | [window makeKeyAndVisible]; 97 | 98 | } 99 | /** 100 | * scrollView代理 101 | */ 102 | - (void)scrollViewDidScroll:(UIScrollView *)scrollViewss { 103 | 104 | /** 105 | round():如果参数是小数,则对自身四舍五入 106 | ceil():如果参数是小数,则求最大整数 107 | floor():如果参数是小数,则求最小整数 108 | */ 109 | NSInteger index = round(scrollViewss.contentOffset.x / SCREEN_W); 110 | pageControl.currentPage = index; 111 | } 112 | 113 | 114 | 115 | @end 116 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Class/Menu/DHMenuVC.h: -------------------------------------------------------------------------------- 1 | // 2 | // DHMenuVC.h 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/5/30. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DHMenuVC : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Class/Menu/DHMenuVC.m: -------------------------------------------------------------------------------- 1 | // 2 | // DHMenuVC.m 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/5/30. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import "DHMenuVC.h" 10 | #import "LLSwitch.h" 11 | #import "DHNSUserdefault.h" 12 | 13 | @interface DHMenuVC () 14 | 15 | @end 16 | 17 | @implementation DHMenuVC 18 | 19 | 20 | - (void)viewDidLoad { 21 | [super viewDidLoad]; 22 | [self.view addSubview:({ 23 | UIImageView *imagView = [[UIImageView alloc] initWithFrame:self.view.frame]; 24 | imagView.image = [UIImage imageNamed:@"bottom.jpg"]; 25 | imagView; 26 | 27 | })]; 28 | for (int i = 0; i < 3; i ++) { 29 | [self.view addSubview:({ 30 | UILabel *lab = [[UILabel alloc] init]; 31 | lab.textAlignment = NSTextAlignmentCenter; 32 | lab.backgroundColor = [UIColor brownColor]; 33 | lab.layer.cornerRadius = 5; 34 | lab.layer.masksToBounds = YES; 35 | lab.frame = CGRectMake(SCREEN_W / 2.0 - 100, 80 + 60 * i, 80, 40); 36 | lab.text = (i == 0 ? @"白旗先手":(i == 1 ? @"玩家先手":@"开关声音")); 37 | lab; 38 | })]; 39 | [self.view addSubview:({ 40 | CGRect frame = CGRectMake(SCREEN_W / 2.0 + 20, 85 + i * 60, 60, 30); 41 | LLSwitch *swith = [[LLSwitch alloc] initWithFrame:frame]; 42 | swith.delegate = self; 43 | swith.tag = 100 + i; 44 | swith.on = (i == 0 ? [DHNSUserdefault getTheIsWhiteSente]: 45 | (i == 1 ? [DHNSUserdefault getTheIsPlayerSente]: 46 | [DHNSUserdefault getTheIsSounds])); 47 | swith.onColor = [UIColor brownColor]; 48 | swith; 49 | })]; 50 | } 51 | } 52 | 53 | 54 | - (void)didTapLLSwitch:(LLSwitch *)llSwitch { 55 | 56 | // NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 57 | // LLSwitch *whiteSwith = [self.view viewWithTag:100]; 58 | // LLSwitch *AISwith = [self.view viewWithTag:101]; 59 | // if (llSwitch == whiteSwith) { 60 | // [defaults setBool:YES forKey:IsWhiteSente]; 61 | // } else if (llSwitch == AISwith) { 62 | // [defaults setBool:YES forKey:IsPlayerSente]; 63 | // } else { 64 | // [defaults setBool:YES forKey:IsSounds]; 65 | // } 66 | } 67 | 68 | 69 | - (void)animationDidStopForLLSwitch:(LLSwitch *)llSwitch { 70 | 71 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 72 | LLSwitch *whiteSwith = [self.view viewWithTag:100]; 73 | LLSwitch *AISwith = [self.view viewWithTag:101]; 74 | if (llSwitch == whiteSwith) { 75 | [defaults setBool:llSwitch.on forKey:IsWhiteSente]; 76 | } else if (llSwitch == AISwith) { 77 | [defaults setBool:llSwitch.on forKey:IsPlayerSente]; 78 | } else { 79 | [defaults setBool:llSwitch.on forKey:IsSounds]; 80 | } 81 | } 82 | 83 | @end 84 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Class/Person/PersonViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // PersonViewController.h 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/5/30. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PersonViewController : UIViewController 12 | 13 | @property (nonatomic, assign) BOOL isBlueTooth; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Class/Person/PersonViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // PersonViewController.m 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/5/30. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import "PersonViewController.h" 10 | #import "DHPPChessBoardView.h" 11 | #import "DHMCTool.h" 12 | #import "HBPlaySoundUtil.h" 13 | #import "DHNSUserdefault.h" 14 | #import "SFDraggableDialogView.h" 15 | 16 | @interface PersonViewController (){ 17 | 18 | __weak IBOutlet UIImageView *bgImgView; 19 | __weak IBOutlet UIButton *soundBtn; 20 | } 21 | 22 | @property (nonatomic, strong) DHPPChessBoardView *chessView; 23 | @property (nonatomic, strong) DHMCTool *mcTool; 24 | 25 | @end 26 | 27 | @implementation PersonViewController 28 | 29 | - (void)dealloc { 30 | 31 | [[NSNotificationCenter defaultCenter] removeObserver:self name:PPWhoWinNotify object:nil]; 32 | } 33 | 34 | - (DHMCTool *)mcTool { 35 | 36 | if (!_mcTool) { 37 | _mcTool = [DHMCTool tool]; 38 | _mcTool.delegate = self; 39 | } 40 | return _mcTool; 41 | } 42 | 43 | - (void)viewWillAppear:(BOOL)animated { 44 | 45 | [super viewWillAppear:animated]; 46 | if (self.isBlueTooth) { 47 | self.mcTool.delegate = self; 48 | } 49 | } 50 | 51 | - (void)viewDidLoad { 52 | [super viewDidLoad]; 53 | [bgImgView addSubview:({ 54 | self.chessView = [[DHPPChessBoardView alloc] initWithFrame:CGRectMake(0, 50, SCREEN_W, SCREEN_W)]; 55 | self.chessView.isBlueTooth = self.isBlueTooth; 56 | self.chessView.delegate = self; 57 | self.chessView.isAbleClick = YES; 58 | self.chessView; 59 | })]; 60 | [self.view sendSubviewToBack:bgImgView]; 61 | bgImgView.userInteractionEnabled = YES; 62 | soundBtn.selected = ![DHNSUserdefault getTheIsSounds]; 63 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(whoWinWith:) name:PPWhoWinNotify object:nil]; 64 | } 65 | - (IBAction)resetClick:(UIButton *)sender { 66 | // if (!self.isBlueTooth) { 67 | [self.chessView reset]; 68 | // } 69 | } 70 | - (IBAction)undoClick:(UIButton *)sender { 71 | 72 | if (!self.isBlueTooth) { 73 | [self.chessView undo]; 74 | } else { 75 | /** 76 | * 你下完了后 77 | */ 78 | if (!self.chessView.isAbleClick) { 79 | [self.mcTool sendMessage:@"undo" error:nil]; 80 | } else if (self.chessView.isAbleClick) { 81 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"温馨提示" message:@"你下棋了后才能马上点击悔棋 " delegate:nil cancelButtonTitle:@"明白" otherButtonTitles: nil]; 82 | [alert show]; 83 | } 84 | } 85 | } 86 | - (IBAction)soundsClick:(UIButton *)sender { 87 | sender.selected = !sender.selected; 88 | [DHNSUserdefault setupIsSounds:!sender.isSelected]; 89 | } 90 | - (IBAction)quiklyClick:(UIButton *)sender { 91 | 92 | if (self.isBlueTooth) { 93 | [self.mcTool sendMessage:@"quikly" error:nil]; 94 | } else { 95 | [[HBPlaySoundUtil shareForPlayingSoundEffectWith:@"quikly.wav"] play]; 96 | } 97 | } 98 | 99 | #pragma mark - DHMCToolDelegate 100 | - (void)session:(MCSession *)session didReceiveString:(NSString *)str fromPeer:(MCPeerID *)peer { 101 | 102 | NSLog(@"我收到的数据是:%@",str); 103 | /** 104 | * 棋子 105 | */ 106 | if (str.length == 9 && ([[str substringToIndex:5] isEqualToString:@"black"] || [[str substringToIndex:5] isEqualToString:@"white"])) { 107 | // 1.判断黑白棋 108 | BOOL isBlack; 109 | NSInteger x,y; 110 | isBlack = [[str substringToIndex:5] isEqualToString:@"black"] ? YES : NO; 111 | x = [[str substringWithRange:NSMakeRange(5, 2)] integerValue]; 112 | y = [[str substringWithRange:NSMakeRange(7, 2)] integerValue]; 113 | [self.chessView addChessWithX:x y:y isBlack:isBlack type:OccupyTypeAI]; 114 | self.chessView.isAbleClick = YES; 115 | } 116 | if ([str isEqualToString:@"quikly"]) { 117 | [[HBPlaySoundUtil shareForPlayingSoundEffectWith:@"quikly.wav"] play]; 118 | } 119 | if ([str isEqualToString:@"undo"]) { 120 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"温馨提示" message:@"对方想悔棋,是否同意" delegate:self cancelButtonTitle:@"没门" otherButtonTitles:@"同意", nil]; 121 | [alert show]; 122 | self.chessView.isAbleClick = NO; 123 | } 124 | if ([str isEqualToString:@"sureUndo"]) { 125 | [self.chessView undo]; 126 | self.chessView.isAbleClick = YES; 127 | } 128 | if ([str isEqualToString:@"dontUndo"]) { 129 | self.chessView.isAbleClick = NO; 130 | } 131 | 132 | 133 | } 134 | - (void)session:(MCSession *)session didChangeState:(MCSessionState)state fromPeer:(MCPeerID *)peer { 135 | 136 | 137 | } 138 | 139 | #pragma mark - DHPPChessDelegate 140 | - (void)touchThePoint:(DHPoint *)point isWhite:(BOOL)isWhiteChess { 141 | 142 | if (!self.isBlueTooth) { 143 | return; 144 | } 145 | NSString *chessType = isWhiteChess ? @"white" : @"black"; 146 | NSMutableString *dataString = [NSMutableString stringWithFormat:@"%@%02ld%02ld",chessType,point.x,point.y]; 147 | NSError *error; 148 | [self.mcTool sendMessage:dataString error:error]; 149 | self.chessView.isAbleClick = NO; 150 | if (error) { 151 | NSLog(@"发送消息错误%@",[error localizedDescription]); 152 | } 153 | } 154 | 155 | #pragma mark notify 156 | - (void)whoWinWith:(NSNotification *)notify { 157 | 158 | OccupyType type = [notify.userInfo[@"type"] integerValue]; 159 | switch (type) { 160 | case OccupyTypeUser: 161 | { 162 | SFDraggableDialogView *v = [SFDraggableDialogView drgViewWith:self titleText:@"你赢了" photo:[UIImage imageNamed:@"winPic.jpg"] message:@"路还长,莫骄傲"]; 163 | v.delegate = self; 164 | [self.view addSubview:v]; 165 | } 166 | break; 167 | case OccupyTypeAI: 168 | { 169 | SFDraggableDialogView *v = [SFDraggableDialogView drgViewWith:self titleText:@"你输了" photo:[UIImage imageNamed:@"lostPic.jpg"] message:@"哪里跌倒那里爬起"]; 170 | v.delegate = self; 171 | [self.view addSubview:v]; 172 | 173 | } 174 | break; 175 | case OccupyTypeWhite: 176 | { 177 | SFDraggableDialogView *v = [SFDraggableDialogView drgViewWith:self titleText:@"白棋赢了" photo:[UIImage imageNamed:@"winPic.jpg"] message:@"路还长,莫骄傲"]; 178 | v.delegate = self; 179 | [self.view addSubview:v]; 180 | } 181 | break; 182 | case OccupyTypeBlack: 183 | { 184 | SFDraggableDialogView *v = [SFDraggableDialogView drgViewWith:self titleText:@"黑棋赢了" photo:[UIImage imageNamed:@"winPic.jpg"] message:@"路还长,莫骄傲"]; 185 | v.delegate = self; 186 | [self.view addSubview:v]; 187 | } 188 | break; 189 | 190 | default: 191 | break; 192 | } 193 | } 194 | 195 | - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { 196 | 197 | if (buttonIndex == 0) { 198 | [self.mcTool sendMessage:@"dontUndo" error:nil]; 199 | self.chessView.isAbleClick = YES; 200 | } else { 201 | [self.chessView undo]; 202 | [self.mcTool sendMessage:@"sureUndo" error:nil]; 203 | self.chessView.isAbleClick = NO; 204 | } 205 | } 206 | 207 | - (void)draggableDialogView:(SFDraggableDialogView *)dialogView didPressFirstButton:(UIButton *)firstButton { 208 | 209 | self.view.userInteractionEnabled = YES; 210 | self.chessView.isAbleClick = YES; 211 | [self.chessView reset]; 212 | [dialogView dismissWithDrop:YES]; 213 | } 214 | @end 215 | -------------------------------------------------------------------------------- /GoBangGraduationProject/CustomModel/DHAI.h: -------------------------------------------------------------------------------- 1 | // 2 | // DHAI.h 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/5/18. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DHPoint.h" 11 | 12 | 13 | 14 | 15 | 16 | /** 17 | * 记录所有点的数据 18 | */ 19 | @interface DHPointData : NSObject 20 | 21 | @property (nonatomic, strong) DHPoint *p; 22 | @property (nonatomic, assign) int count; 23 | 24 | - (instancetype)initWithPoint:(DHPoint *)point count:(int)count; 25 | 26 | @end 27 | 28 | 29 | 30 | /** 31 | * 电脑下棋 32 | */ 33 | @interface DHOmni : NSObject 34 | 35 | @property (nonatomic, strong) NSMutableArray *totalChesses; 36 | @property (nonatomic, assign) OccupyType userType; 37 | @property (nonatomic, assign) OccupyType aiType; 38 | 39 | - (id)initWithArr:(NSMutableArray *)ar user:(OccupyType)user ai:(OccupyType)ai; 40 | - (BOOL)isStepEmergent:(DHPoint *)point num:(int)num type:(OccupyType)type; 41 | 42 | @end 43 | 44 | 45 | 46 | /** 47 | * 电脑找点 48 | */ 49 | @interface DHAI : NSObject 50 | 51 | + (DHPoint *)SearchTheGreat:(NSMutableArray *)board type:(OccupyType)type; 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /GoBangGraduationProject/CustomModel/DHAI.m: -------------------------------------------------------------------------------- 1 | // 2 | // DHAI.m 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/5/18. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import "DHAI.h" 10 | 11 | @implementation DHPointData 12 | 13 | - (instancetype)init { 14 | 15 | if (self = [super init]) { 16 | self.p = [[DHPoint alloc] initPointWith:0 y:0]; 17 | self.count = 0; 18 | } 19 | return self; 20 | } 21 | 22 | - (instancetype)initWithPoint:(DHPoint *)point count:(int)count { 23 | 24 | self = [self init]; 25 | if (self) { 26 | self.p = point; 27 | self.count = count; 28 | } 29 | return self; 30 | } 31 | 32 | @end 33 | 34 | 35 | 36 | @implementation DHOmni 37 | 38 | - (instancetype)init { 39 | 40 | if (self = [super init]) { 41 | self.userType = OccupyTypeEmpty; 42 | self.aiType = OccupyTypeEmpty; 43 | } 44 | return self; 45 | } 46 | 47 | - (id)initWithArr:(NSMutableArray *)ar user:(OccupyType)user ai:(OccupyType)ai { 48 | 49 | if (self = [self init]) { 50 | self.totalChesses = ar; 51 | self.userType = user; 52 | self.aiType = ai; 53 | } 54 | return self; 55 | } 56 | 57 | /** 58 | * 改点的四个方向 59 | * 60 | * @param point <#point description#> 61 | * @param num <#num description#> 62 | * @param type <#type description#> 63 | * 64 | * @return <#return value description#> 65 | */ 66 | - (BOOL)isStepEmergent:(DHPoint *)point num:(int)num type:(OccupyType)type { 67 | 68 | if ([self isUsefulPonint:point]) { // 判断改点是否超出边界 69 | 70 | DHPoint *originalPoint = [[DHPoint alloc] initPointWith:point.x y:point.y]; 71 | 72 | 73 | DHPoint *textLeft = [[DHPoint alloc] initPointWith:point.x y:point.y]; 74 | DHPoint *textRight = [[DHPoint alloc] initPointWith:point.x y:point.y]; 75 | for (int i = 1; originalPoint.x - i >= 1 && [self.totalChesses[originalPoint.x - i - 1][originalPoint.y - 1] integerValue] == type; i ++) { 76 | textLeft = [[DHPoint alloc] initPointWith:textLeft.x - 1 y:textLeft.y]; 77 | } 78 | for (int i = 1; originalPoint.x + i <= DHBoardSize && [self.totalChesses[originalPoint.x + i - 1][originalPoint.y - 1] integerValue] == type; i ++) { 79 | textRight = [[DHPoint alloc] initPointWith:textRight.x + 1 y:textRight.y]; 80 | } 81 | if ([self isStepEmergentWithStart:textLeft end:textRight direction:DirectionTypeRight num:num]) { 82 | return YES; 83 | }; 84 | 85 | 86 | DHPoint *textTop = [[DHPoint alloc] initPointWith:point.x y:point.y]; 87 | DHPoint *textDown = [[DHPoint alloc] initPointWith:point.x y:point.y]; 88 | for (int i = 1; originalPoint.y - i >= 1 && [self.totalChesses[point.x - 1][point.y - 1 - i] integerValue] == type; i ++) { 89 | textTop = [[DHPoint alloc] initPointWith:textTop.x y:textTop.y - 1]; 90 | } 91 | for (int i = 1; originalPoint.y + i <= DHBoardSize && [self.totalChesses[point.x - 1][point.y + i - 1] integerValue] == type; i ++) { 92 | textDown = [[DHPoint alloc] initPointWith:textDown.x y:textDown.y + 1]; 93 | } 94 | if ([self isStepEmergentWithStart:textTop end:textDown direction:DirectionTypeTop num:num]) { 95 | return YES; 96 | } 97 | 98 | 99 | DHPoint *textEN = [[DHPoint alloc] initPointWith:point.x y:point.y]; //东北 100 | DHPoint *textWS = [[DHPoint alloc] initPointWith:point.x y:point.y]; //西南 101 | for (int i = 1; originalPoint.y + i <= DHBoardSize && originalPoint.x - i > 0 && [self.totalChesses[point.x - i - 1][point.y + i - 1] integerValue] == type; i ++) { 102 | textWS = [[DHPoint alloc] initPointWith:textWS.x - 1 y:textWS.y + 1]; 103 | } 104 | for (int i = 1; originalPoint.y - i > 0 && originalPoint.x + i <= DHBoardSize && [self.totalChesses[point.x + i - 1][point.y - i - 1] integerValue] == type; i ++) { 105 | textEN = [[DHPoint alloc] initPointWith:textEN.x + 1 y:textEN.y - 1]; 106 | } 107 | if ([self isStepEmergentWithStart:textWS end:textEN direction:DirectionTypeRightTop num:num]) { 108 | return YES; 109 | } 110 | 111 | 112 | DHPoint *textWN = [[DHPoint alloc] initPointWith:point.x y:point.y]; //西北 113 | DHPoint *textES = [[DHPoint alloc] initPointWith:point.x y:point.y]; //东南 114 | for (int i = 1; originalPoint.y - i > 0 && originalPoint.x - i > 0 && [self.totalChesses[point.x - i - 1][point.y - i - 1] integerValue] == type; i ++) { 115 | textWN = [[DHPoint alloc] initPointWith:textWN.x - i y:textWN.y - i]; 116 | } 117 | for (int i = 1; originalPoint.y + i <= DHBoardSize && originalPoint.x + i <= DHBoardSize && [self.totalChesses[point.x + i - 1][point.y + i - 1] integerValue] == type; i ++) { 118 | textES = [[DHPoint alloc] initPointWith:textES.x + 1 y:textES.y + 1]; 119 | } 120 | if ([self isStepEmergentWithStart:textWN end:textES direction:DirectionTypeRightDown num:num]) { 121 | return YES; 122 | } 123 | 124 | // DHPoint *textLeft = [[DHPoint alloc] initPointWith:point.x y:point.y]; 125 | // DHPoint *textRight = [[DHPoint alloc] initPointWith:point.x y:point.y]; 126 | // 127 | // for (int i = 1; textLeft.x - i >= 1 && [self.totalChesses[textLeft.x - 1][textLeft.y - 1] integerValue] == type; i ++) { 128 | // textLeft = [[DHPoint alloc] initPointWith:textLeft.x - i y:textLeft.y]; 129 | // } 130 | // for (int i = 1; textRight.x + i <= DHBoardSize && [self.totalChesses[textRight.x - 1][textRight.y - 1] integerValue] == type; i ++) { 131 | // textRight = [[DHPoint alloc] initPointWith:textRight.x + i y:textRight.y]; 132 | // } 133 | // if (textRight.x - textLeft.x > num) { 134 | // if ([self isUsefulPonint:textLeft] && [self isUsefulPonint:textRight]) { 135 | // if ([self.totalChesses[textRight.x - 1][textRight.y - 1] integerValue] == OccupyTypeEmpty && [self.totalChesses[textLeft.x - 1][textLeft.y - 1] integerValue] == OccupyTypeEmpty) { 136 | // return YES; 137 | // } 138 | // } 139 | // } 140 | 141 | 142 | } 143 | return NO; 144 | } 145 | 146 | /** 147 | * 判断两个点是否是满足条件的 148 | */ 149 | - (BOOL)isStepEmergentWithStart:(DHPoint *)startPoint end:(DHPoint *)endPoint direction:(DirectionType)direction num:(NSInteger)num { 150 | 151 | /** 152 | 找到传进来的点的上一个点 153 | 154 | - eg: ¥***¥,找到*之前的¥ 155 | */ 156 | DHPoint *start = [[DHPoint alloc] initPointWith:startPoint.x y:startPoint.y]; 157 | DHPoint *end = [[DHPoint alloc] initPointWith:endPoint.x y:endPoint.y]; 158 | switch (direction) { 159 | case DirectionTypeTop: 160 | { 161 | start.y --; 162 | end.y ++; 163 | } 164 | break; 165 | case DirectionTypeRightTop: 166 | { 167 | start.x --,start.y ++; 168 | end.x ++,end.y --; 169 | } 170 | break; 171 | case DirectionTypeRight: 172 | { 173 | start.x --,end.x ++; 174 | } 175 | break; 176 | case DirectionTypeRightDown: 177 | { 178 | start.x --,start.y --; 179 | end.x ++,end.y ++; 180 | } 181 | break; 182 | 183 | default: 184 | break; 185 | } 186 | 187 | if ([self isUsefulPonint:start] && [self isUsefulPonint:end]) { 188 | if ([self.totalChesses[start.x - 1][start.y - 1] integerValue] == OccupyTypeEmpty && [self.totalChesses[end.x - 1][end.y - 1] integerValue] == OccupyTypeEmpty) { 189 | switch (direction) { 190 | case DirectionTypeTop: 191 | { 192 | if (end.y - start.y >= num) { 193 | return YES; 194 | } 195 | } 196 | break; 197 | case DirectionTypeRightTop: 198 | { 199 | if (end.x - start.x >= num && start.y - end.y >= num) { 200 | return YES; 201 | } 202 | } 203 | break; 204 | case DirectionTypeRight: 205 | { 206 | if (end.x - start.x >= num) { 207 | return YES; 208 | } 209 | } 210 | break; 211 | case DirectionTypeRightDown: 212 | { 213 | if (end.y - start.y >= num && end.x - start.x >= num) { 214 | return YES; 215 | } 216 | } 217 | break; 218 | 219 | default: 220 | break; 221 | } 222 | 223 | // return YES; 224 | } 225 | } 226 | return NO; 227 | } 228 | 229 | /** 230 | * 检查改点是否可以用 231 | */ 232 | - (BOOL)isUsefulPonint:(DHPoint *)point { 233 | 234 | if (point.x <= 15 && point.y <= 15 && point.x >0 && point.y > 0) { 235 | return YES; 236 | } 237 | return NO; 238 | } 239 | 240 | #pragma mark - 下一步 241 | /** 242 | * 在某个方向上找到threshold的连珠,并且有可能成为num的连珠 243 | * 244 | * @param direction 方向 245 | * @param point 原始点 246 | * @param type 类型 247 | * @param num 可能成为num的连珠 248 | * @param threshold 已经有threshold的连珠 249 | */ 250 | - (DHPoint *)direction:(DirectionType)direction 251 | originalPoint:(DHPoint *)point 252 | type:(OccupyType)type 253 | num:(int)num 254 | threshold:(int)threshold { 255 | 256 | if (![self isUsefulPonint:point]) { 257 | return point; 258 | } 259 | DHPoint *resultPoint = [[DHPoint alloc] init]; 260 | int count = 0; 261 | NSInteger x = 0,y = 0; 262 | for (int i = 0; i < num; i ++) { 263 | switch (direction) { 264 | case DirectionTypeTop: 265 | { 266 | x = point.x; 267 | y = point.y + i; 268 | } 269 | break; 270 | case DirectionTypeRightTop: 271 | { 272 | x = point.x + i; 273 | y = point.y - i; 274 | } 275 | break; 276 | case DirectionTypeRight: 277 | { 278 | x = point.x + i; 279 | y = point.y; 280 | } 281 | break; 282 | case DirectionTypeRightDown: 283 | { 284 | x = point.x + i; 285 | y = point.y + i; 286 | } 287 | break; 288 | 289 | default: 290 | break; 291 | } 292 | if (y > 0 && x > 0 && y <= DHBoardSize && x <= DHBoardSize) { 293 | if ([self.totalChesses[x - 1][y - 1] integerValue] == type) { 294 | count ++; 295 | } 296 | if ([self.totalChesses[x - 1][y - 1] integerValue] == OccupyTypeEmpty) { 297 | resultPoint.x = x; 298 | resultPoint.y = y; 299 | } 300 | } 301 | } 302 | if (count >= threshold && [self isUsefulPonint:resultPoint]) { 303 | return resultPoint; 304 | } 305 | return [self direction:direction originalPoint:[self nextPoint:point] type:type num:num threshold:threshold]; 306 | } 307 | 308 | - (DHPoint *)nextPoint:(DHPoint *)point { 309 | 310 | DHPoint *resultPoint = [[DHPoint alloc] initPointWith:point.x y:point.y]; 311 | if (point.x >=DHBoardSize) { 312 | resultPoint.x = 1,resultPoint.y ++; 313 | } else { 314 | resultPoint.x ++; 315 | } 316 | return resultPoint; 317 | } 318 | 319 | /** 320 | * 从(x,y)点开始便利四周有threshold连珠并且即将形成num连珠的位置 321 | */ 322 | - (DHPoint *)nextStep:(OccupyType)type num:(int)num threshold:(int)threshold x:(int)startX y:(int)startY { 323 | 324 | DHPoint *search = [[DHPoint alloc] initPointWith:startX y:startY]; 325 | DHPoint *topPoint; 326 | DHPoint *rightTopPoint; 327 | DHPoint *rightPoint; 328 | DHPoint *rightDownPoint; 329 | /** 330 | * 在竖直方向上便利是否有threshold连珠并且即将形成num连珠的点 331 | */ 332 | topPoint = [self direction:DirectionTypeTop originalPoint:search type:type num:num threshold:threshold]; 333 | /** 334 | * 在东北方向上便利是否有threshold连珠并且即将形成num连珠的点 335 | */ 336 | rightTopPoint = [self direction:DirectionTypeRightTop originalPoint:search type:type num:num threshold:threshold]; 337 | /** 338 | * 在纵向方向上便利是否有threshold连珠并且即将形成num连珠的点 339 | */ 340 | rightPoint = [self direction:DirectionTypeRight originalPoint:search type:type num:num threshold:threshold]; 341 | /** 342 | * 在东南方向上便利是否有threshold连珠并且即将形成num连珠的点 343 | */ 344 | rightDownPoint = [self direction:DirectionTypeRightDown originalPoint:search type:type num:num threshold:threshold]; 345 | if (num == 5) { //找到胜利的棋子 346 | if ([self isUsefulPonint:topPoint]) return topPoint; 347 | if ([self isUsefulPonint:rightTopPoint]) return rightTopPoint; 348 | if ([self isUsefulPonint:rightPoint]) return rightPoint; 349 | if ([self isUsefulPonint:rightDownPoint]) return rightDownPoint; 350 | } else { 351 | 352 | // while ([self isUsefulPonint:topPoint] && ![self isStepEmergent:topPoint num:num type:type]) { 353 | // // 在顶部寻找threshold连续且可以形成num连续的点 354 | // topPoint = [self direction:DirectionTypeTop 355 | // originalPoint:[self nextPoint:topPoint] 356 | // type:type 357 | // num:num 358 | // threshold:threshold]; 359 | // } 360 | if ([self isStepEmergent:topPoint num:num type:type]) return topPoint; 361 | 362 | 363 | // while ([self isUsefulPonint:rightTopPoint] && ![self isStepEmergent:rightTopPoint num:num type:type]) { 364 | // // 在东北寻找threshold连续且可以形成num连续的点 365 | // rightTopPoint = [self direction:DirectionTypeRightTop 366 | // originalPoint:[self nextPoint:rightTopPoint] 367 | // type:type 368 | // num:num 369 | // threshold:threshold]; 370 | // } 371 | if ([self isStepEmergent:rightTopPoint num:num type:type]) return rightTopPoint; 372 | 373 | 374 | // while ([self isUsefulPonint:rightDownPoint] && ![self isStepEmergent:rightDownPoint num:num type:type]) { 375 | // // 在顶部寻找threshold连续且可以形成num连续的点 376 | // rightDownPoint = [self direction:DirectionTypeRightDown 377 | // originalPoint:[self nextPoint:rightDownPoint] 378 | // type:type 379 | // num:num 380 | // threshold:threshold]; 381 | // } 382 | if ([self isStepEmergent:rightDownPoint num:num type:type]) return rightDownPoint; 383 | 384 | 385 | // while ([self isUsefulPonint:rightPoint] && ![self isStepEmergent:rightPoint num:num type:type]) { 386 | // // 在顶部寻找threshold连续且可以形成num连续的点 387 | // rightPoint = [self direction:DirectionTypeRight 388 | // originalPoint:[self nextPoint:rightPoint] 389 | // type:type 390 | // num:num 391 | // threshold:threshold]; 392 | // } 393 | if ([self isStepEmergent:rightPoint num:num type:type]) return rightPoint; 394 | } 395 | DHPoint *invalid = [[DHPoint alloc] init]; 396 | return invalid; 397 | } 398 | 399 | @end 400 | 401 | 402 | 403 | @implementation DHAI 404 | 405 | + (DHPoint *)SearchTheGreat:(NSMutableArray *)board type:(OccupyType)type { 406 | 407 | DHOmni *omni = [[DHOmni alloc] init]; 408 | if (type == OccupyTypeUser) { 409 | omni = [[DHOmni alloc] initWithArr:board user:OccupyTypeAI ai:OccupyTypeUser]; 410 | } else { 411 | omni = [[DHOmni alloc] initWithArr:board user:OccupyTypeUser ai:OccupyTypeAI]; 412 | } 413 | 414 | DHPoint *luck = [[DHPoint alloc] init]; 415 | for (int i = 5; i > 1; i --) { 416 | // AI以自己的角度观察场上形势,从(1, 1)点开始遍历,寻找用户棋子排放是否有(i - 1)子连珠并且可以形成i子连珠的点 417 | luck = [omni nextStep:omni.aiType num:i threshold:i - 1 x:1 y:1]; 418 | if ([omni isUsefulPonint:luck]) return luck; 419 | 420 | // AI以用户的角度观察场上形势,从(0, 0)点开始遍历,寻找用户棋子排放是否有(i - 1)子连珠并且可以形成i子连珠的点 421 | luck = [omni nextStep:omni.userType num:i threshold:i - 1 x:1 y:1]; 422 | if ([omni isUsefulPonint:luck]) return luck; 423 | } 424 | 425 | DHPoint *sad = [[DHPoint alloc] initPointWith:(DHBoardSize + 1) / 2 y:(DHBoardSize + 1) / 2]; 426 | return sad; 427 | 428 | } 429 | 430 | @end 431 | -------------------------------------------------------------------------------- /GoBangGraduationProject/CustomModel/DHPoint.h: -------------------------------------------------------------------------------- 1 | // 2 | // DHPoint.h 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/5/18. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DHPoint : NSObject 12 | 13 | @property (nonatomic, assign) NSInteger x; 14 | @property (nonatomic, assign) NSInteger y; 15 | 16 | - (instancetype)initPointWith:(NSInteger)X y:(NSInteger)Y; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /GoBangGraduationProject/CustomModel/DHPoint.m: -------------------------------------------------------------------------------- 1 | // 2 | // DHPoint.m 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/5/18. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import "DHPoint.h" 10 | 11 | @implementation DHPoint 12 | 13 | - (instancetype)init { 14 | 15 | if (self = [super init]) { 16 | self.x = -1; 17 | self.y = -1; 18 | } 19 | return self; 20 | } 21 | 22 | - (instancetype)initPointWith:(NSInteger)X y:(NSInteger)Y { 23 | 24 | if (self = [self init]) { 25 | self.x = X; 26 | self.y = Y; 27 | } 28 | return self; 29 | } 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /GoBangGraduationProject/CustomVC/DHNavgationController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DHNavgationController.h 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/5/30. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DHNavgationController : UINavigationController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /GoBangGraduationProject/CustomVC/DHNavgationController.m: -------------------------------------------------------------------------------- 1 | // 2 | // DHNavgationController.m 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/5/30. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import "DHNavgationController.h" 10 | 11 | @interface DHNavgationController () 12 | 13 | @end 14 | 15 | @implementation DHNavgationController 16 | 17 | - (void)viewDidLoad { 18 | [super viewDidLoad]; 19 | self.navigationBar.barTintColor = [UIColor brownColor]; 20 | self.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName:[UIColor whiteColor]}; 21 | self.navigationBar.tintColor = [UIColor whiteColor]; 22 | self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:self action:nil]; 23 | 24 | } 25 | @end 26 | -------------------------------------------------------------------------------- /GoBangGraduationProject/CustomView/ChessBoardView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ChessBoardView.h 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/5/10. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @protocol DHAIChessBoardDelegate 12 | 13 | @end 14 | 15 | @interface ChessBoardView : UIView 16 | 17 | 18 | 19 | - (instancetype)initWithFrame:(CGRect)frame; 20 | - (void)reset; 21 | - (void)undo; 22 | 23 | /** 24 | * 添加棋子 25 | * 26 | * @param x x坐标 27 | * @param y y坐标 28 | * @param isBlack 是否黑白 29 | */ 30 | - (void)addChessWithX:(NSInteger)x y:(NSInteger)y isBlack:(BOOL)isBlack type:(OccupyType)type; 31 | 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /GoBangGraduationProject/CustomView/ChessBoardView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ChessBoardView.m 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/5/10. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import "ChessBoardView.h" 10 | #import "DHAI.h" 11 | #import "DHGobangTool.h" 12 | #import "DHNSUserdefault.h" 13 | #import "HBPlaySoundUtil.h" 14 | 15 | @interface ChessBoardView () { 16 | 17 | void(^xyBlock)(NSInteger x,NSInteger y); 18 | BOOL isMePlay; 19 | } 20 | @property (nonatomic, strong) NSMutableArray *places; //记录所有位置的棋盘 21 | @property (nonatomic, strong) NSMutableArray *totalChess; //记录所有棋子 22 | 23 | @end 24 | 25 | @implementation ChessBoardView 26 | 27 | 28 | - (instancetype)initWithFrame:(CGRect)frame { 29 | 30 | if (self = [super initWithFrame:frame]) { 31 | self.backgroundColor = [UIColor clearColor]; 32 | [self addLines]; 33 | [self initilizeData]; 34 | [self isPlayerSente]; 35 | } 36 | return self; 37 | } 38 | 39 | - (void)addLines { 40 | 41 | for (int i = 0; i < DHBoardSize + 2; i ++) { 42 | CALayer *hLayer = [CALayer layer]; 43 | hLayer.frame = CGRectMake(0, i * SCREEN_W / (DHBoardSize + 1), SCREEN_W, 0.5); 44 | hLayer.backgroundColor = [UIColor blackColor].CGColor; 45 | 46 | CALayer *vLayer = [CALayer layer]; 47 | vLayer.frame = CGRectMake(i * SCREEN_W / (DHBoardSize + 1), 0, 0.5, SCREEN_W); 48 | vLayer.backgroundColor = [UIColor blackColor].CGColor; 49 | 50 | [self.layer addSublayer:hLayer]; 51 | [self.layer addSublayer:vLayer]; 52 | } 53 | } 54 | 55 | - (void)initilizeData { 56 | 57 | self.places = [NSMutableArray array]; 58 | self.totalChess = [NSMutableArray array]; 59 | 60 | for (int i = 0; i < DHBoardSize; i ++) { 61 | NSMutableArray *horArr = [NSMutableArray array]; //横向 62 | for (int j = 0; j < DHBoardSize; j ++) { 63 | [horArr addObject:@(OccupyTypeEmpty)]; //竖向 64 | } 65 | [self.places addObject:horArr]; 66 | } 67 | } 68 | 69 | - (void)isPlayerSente { 70 | 71 | BOOL isPlayerSente = [DHNSUserdefault getTheIsPlayerSente]; 72 | BOOL isWhite = [DHNSUserdefault getTheIsWhiteSente]; 73 | if (!isPlayerSente) { 74 | DHPoint *aiPoint = [[DHPoint alloc] init]; 75 | aiPoint = [DHAI SearchTheGreat:self.places type:OccupyTypeAI]; 76 | [self addChessWithX:aiPoint.x y:aiPoint.y isBlack:!isWhite type:OccupyTypeAI]; 77 | } 78 | } 79 | 80 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 81 | 82 | UITouch *touch = [touches anyObject]; 83 | CGPoint point = [touch locationInView:self]; 84 | DHPoint *puppetPoint = [DHGobangTool getTouchPointWith:point]; 85 | NSInteger h,v; 86 | h = puppetPoint.x; 87 | v = puppetPoint.y; 88 | /** 89 | * 如果不是空的话就不准下棋 90 | */ 91 | if ([DHGobangTool getType:puppetPoint array:self.places] != OccupyTypeEmpty) { 92 | return; 93 | } 94 | BOOL isPlayerSente = [DHNSUserdefault getTheIsPlayerSente]; 95 | BOOL isWhite = [DHNSUserdefault getTheIsWhiteSente]; 96 | [self addChessWithX:h y:v isBlack:isPlayerSente ? !isWhite : isWhite type:OccupyTypeUser]; 97 | DHPoint *aiPoint = [[DHPoint alloc] init]; 98 | aiPoint = [DHAI SearchTheGreat:self.places type:OccupyTypeAI]; 99 | [self addChessWithX:aiPoint.x y:aiPoint.y isBlack:isPlayerSente ? isWhite : !isWhite type:OccupyTypeAI]; 100 | } 101 | 102 | - (void)winWithPoint:(DHPoint *)point { 103 | 104 | NSInteger type = [self.places[point.x - 1][point.y - 1] integerValue]; 105 | OccupyType myType; 106 | if (type == OccupyTypeAI) { 107 | NSLog(@"电脑赢了"); 108 | [[HBPlaySoundUtil shareForPlayingSoundEffectWith:@"lost.wav"] play]; 109 | myType = OccupyTypeAI; 110 | } else if (type == OccupyTypeUser) { 111 | NSLog(@"你赢了"); 112 | [[HBPlaySoundUtil shareForPlayingSoundEffectWith:@"win.wav"] play]; 113 | myType = OccupyTypeUser; 114 | } 115 | [[NSNotificationCenter defaultCenter] postNotificationName:AIWhoWinNotify object:nil userInfo:@{@"type":@(myType)}]; 116 | } 117 | 118 | /** 119 | * 在h,v这个点添加个棋子 120 | */ 121 | - (void)addChessWithX:(NSInteger)x y:(NSInteger)y isBlack:(BOOL)isBlack type:(OccupyType)type{ 122 | 123 | [[HBPlaySoundUtil shareForPlayingSoundEffectWith:@"down.wav"] play]; 124 | CGFloat boardWidth = SCREEN_W / (DHBoardSize + 1); 125 | if ([self.places[x - 1][y - 1] integerValue] == OccupyTypeEmpty) { 126 | UIImageView *chessImg = [UIImageView new]; 127 | chessImg.image = [UIImage imageNamed:isBlack?@"stone_black":@"stone_white"]; 128 | chessImg.bounds = CGRectMake(0, 0, boardWidth, boardWidth); 129 | CGFloat centerX = x * boardWidth; 130 | CGFloat centerY = y * boardWidth; 131 | chessImg.center = CGPointMake(centerX, centerY); 132 | [self addSubview:chessImg]; 133 | 134 | /** 135 | * 棋子添加成功后做的操作 136 | */ 137 | // 0.添加到数组里面 138 | NSMutableArray *puppetArr = self.places[x - 1]; 139 | [puppetArr replaceObjectAtIndex:y - 1 withObject:@(type)]; 140 | 141 | // 1.判断是否胜利 142 | DHPoint *resultPoint = [[DHPoint alloc] initPointWith:x y:y]; 143 | if ([DHGobangTool isVictory:resultPoint array:self.places]) { 144 | [self winWithPoint:resultPoint]; 145 | } 146 | 147 | // 2.加到记录棋子的数组 148 | [self.totalChess addObject:[[DHPoint alloc] initPointWith:x y:y]]; 149 | } 150 | } 151 | 152 | #pragma mark - public 153 | - (void)reset { 154 | 155 | for (UIImageView *imgView in self.subviews) { 156 | [imgView removeFromSuperview]; 157 | } 158 | [self initilizeData]; 159 | } 160 | 161 | - (void)undo { 162 | 163 | if (self.totalChess.count >= 2) { 164 | DHPoint *lastPoint = [self.totalChess objectAtIndex:self.totalChess.count - 1]; 165 | DHPoint *lastTwoPoint = [self.totalChess objectAtIndex:self.totalChess.count - 2]; 166 | UIImageView *lastChess = [DHGobangTool foundChessWithPoint:lastPoint superView:self]; 167 | UIImageView *lastTwoChess = [DHGobangTool foundChessWithPoint:lastTwoPoint superView:self]; 168 | if (lastChess) { 169 | [lastChess removeFromSuperview]; 170 | [self.totalChess removeObject:lastPoint]; 171 | [self.places[lastPoint.x - 1] replaceObjectAtIndex:lastPoint.y - 1 withObject:@0]; 172 | } 173 | if (lastTwoPoint) { 174 | [lastTwoChess removeFromSuperview]; 175 | [self.totalChess removeObject:lastTwoPoint]; 176 | [self.places[lastTwoPoint.x - 1] replaceObjectAtIndex:lastTwoPoint.y - 1 withObject:@0]; 177 | } 178 | } 179 | } 180 | 181 | 182 | @end 183 | -------------------------------------------------------------------------------- /GoBangGraduationProject/CustomView/DHPPChessBoardView.h: -------------------------------------------------------------------------------- 1 | // 2 | // DHPPChessBoardView.h 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/6/1. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DHPoint.h" 11 | 12 | @protocol DHPPChessDelegate 13 | 14 | - (void)touchThePoint:(DHPoint *)point isWhite:(BOOL)isWhiteChess; 15 | 16 | @end 17 | 18 | @interface DHPPChessBoardView : UIView 19 | 20 | @property (nonatomic, assign) id delegate; 21 | @property (nonatomic, assign) BOOL isBlueTooth; 22 | @property (nonatomic, assign) BOOL isAbleClick; 23 | 24 | - (instancetype)initWithFrame:(CGRect)frame; 25 | - (void)reset; 26 | - (void)undo; 27 | 28 | /** 29 | * 添加棋子 30 | * 31 | * @param x x坐标 32 | * @param y y坐标 33 | * @param isBlack 是否黑白 34 | */ 35 | - (void)addChessWithX:(NSInteger)x y:(NSInteger)y isBlack:(BOOL)isBlack type:(OccupyType)type; 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /GoBangGraduationProject/CustomView/DHPPChessBoardView.m: -------------------------------------------------------------------------------- 1 | // 2 | // DHPPChessBoardView.m 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/6/1. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import "DHPPChessBoardView.h" 10 | #import "DHGobangTool.h" 11 | #import "DHNSUserdefault.h" 12 | #import "HBPlaySoundUtil.h" 13 | 14 | 15 | @interface DHPPChessBoardView () { 16 | 17 | 18 | } 19 | @property (nonatomic, strong) NSMutableArray *places; //记录所有位置的棋盘 20 | @property (nonatomic, strong) NSMutableArray *totalChess; //记录所有棋子 21 | @property (nonatomic, assign) BOOL isWhiteChess; //是否该白旗落子 22 | 23 | @end 24 | 25 | @implementation DHPPChessBoardView 26 | 27 | - (instancetype)initWithFrame:(CGRect)frame { 28 | 29 | if (self = [super initWithFrame:frame]) { 30 | self.backgroundColor = [UIColor clearColor]; 31 | [self addLines]; 32 | [self initilizeData]; 33 | } 34 | return self; 35 | } 36 | 37 | - (void)addLines { 38 | 39 | for (int i = 0; i < DHBoardSize + 2; i ++) { 40 | CALayer *hLayer = [CALayer layer]; 41 | hLayer.frame = CGRectMake(0, i * SCREEN_W / (DHBoardSize + 1), SCREEN_W, 0.5); 42 | hLayer.backgroundColor = [UIColor blackColor].CGColor; 43 | 44 | CALayer *vLayer = [CALayer layer]; 45 | vLayer.frame = CGRectMake(i * SCREEN_W / (DHBoardSize + 1), 0, 0.5, SCREEN_W); 46 | vLayer.backgroundColor = [UIColor blackColor].CGColor; 47 | 48 | [self.layer addSublayer:hLayer]; 49 | [self.layer addSublayer:vLayer]; 50 | } 51 | } 52 | 53 | - (void)initilizeData { 54 | 55 | self.places = [NSMutableArray array]; 56 | self.totalChess = [NSMutableArray array]; 57 | 58 | for (int i = 0; i < DHBoardSize; i ++) { 59 | NSMutableArray *horArr = [NSMutableArray array]; //横向 60 | for (int j = 0; j < DHBoardSize; j ++) { 61 | [horArr addObject:@(OccupyTypeEmpty)]; //竖向 62 | } 63 | [self.places addObject:horArr]; 64 | } 65 | } 66 | 67 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 68 | 69 | UITouch *touch = [touches anyObject]; 70 | CGPoint point = [touch locationInView:self]; 71 | DHPoint *puppetPoint = [DHGobangTool getTouchPointWith:point]; 72 | NSInteger h,v; 73 | h = puppetPoint.x; 74 | v = puppetPoint.y; 75 | 76 | // 1.如果不是空的话就不准下棋 77 | if ([DHGobangTool getType:puppetPoint array:self.places] != OccupyTypeEmpty) { 78 | return; 79 | } 80 | 81 | // 2.如果是蓝牙的话,在点击下棋后没收到对手落子前是不能点击棋盘的 82 | if (self.isBlueTooth && !self.isAbleClick) { 83 | return; 84 | } 85 | 86 | // 3.判断是否是白色棋子 87 | _isWhiteChess = (self.totalChess.count % 2 == 0 ? YES:NO); 88 | _isWhiteChess = [DHNSUserdefault getTheIsWhiteSente] ? _isWhiteChess : !_isWhiteChess; 89 | 90 | // 4.代理出去 91 | if (self.delegate && [self.delegate respondsToSelector:@selector(touchThePoint:isWhite:)]) { 92 | [self.delegate touchThePoint:puppetPoint isWhite:_isWhiteChess]; 93 | } 94 | if (self.isBlueTooth) { 95 | [self addChessWithX:h y:v isBlack:!_isWhiteChess type:OccupyTypeUser]; 96 | } else { 97 | OccupyType type; 98 | /** 99 | * 玩家先手,ai后手 100 | */ 101 | type = (self.totalChess.count % 2 == 0 ? OccupyTypeUser:OccupyTypeAI); 102 | [self addChessWithX:h y:v isBlack:!_isWhiteChess type:type]; 103 | } 104 | } 105 | 106 | - (void)winWithPoint:(DHPoint *)point { 107 | 108 | OccupyType myType; 109 | NSInteger type = [self.places[point.x - 1][point.y - 1] integerValue]; 110 | if (self.isBlueTooth) { 111 | 112 | if (type == OccupyTypeAI) { 113 | NSLog(@"你输了"); 114 | [[HBPlaySoundUtil shareForPlayingSoundEffectWith:@"lost.wav"] play]; 115 | myType = OccupyTypeAI; 116 | } else if (type == OccupyTypeUser) { 117 | NSLog(@"你赢了"); 118 | [[HBPlaySoundUtil shareForPlayingSoundEffectWith:@"win.wav"] play]; 119 | myType = OccupyTypeUser; 120 | } 121 | } else { 122 | 123 | [[HBPlaySoundUtil shareForPlayingSoundEffectWith:@"win.wav"] play]; 124 | if (type == OccupyTypeAI) { 125 | myType = [DHNSUserdefault getTheIsWhiteSente] ? OccupyTypeBlack:OccupyTypeWhite; 126 | } else if (type == OccupyTypeUser) { 127 | myType = [DHNSUserdefault getTheIsWhiteSente] ? OccupyTypeWhite:OccupyTypeBlack; 128 | } 129 | } 130 | [[NSNotificationCenter defaultCenter] postNotificationName:PPWhoWinNotify object:nil userInfo:@{@"type":@(myType)}]; 131 | } 132 | 133 | 134 | /** 135 | * 在h,v这个点添加个棋子 136 | */ 137 | - (void)addChessWithX:(NSInteger)x y:(NSInteger)y isBlack:(BOOL)isBlack type:(OccupyType)type{ 138 | 139 | [[HBPlaySoundUtil shareForPlayingSoundEffectWith:@"down.wav"] play]; 140 | CGFloat boardWidth = SCREEN_W / (DHBoardSize + 1); 141 | if ([self.places[x - 1][y - 1] integerValue] == OccupyTypeEmpty) { 142 | UIImageView *chessImg = [UIImageView new]; 143 | chessImg.image = [UIImage imageNamed:isBlack?@"stone_black":@"stone_white"]; 144 | chessImg.bounds = CGRectMake(0, 0, boardWidth, boardWidth); 145 | CGFloat centerX = x * boardWidth; 146 | CGFloat centerY = y * boardWidth; 147 | chessImg.center = CGPointMake(centerX, centerY); 148 | [self addSubview:chessImg]; 149 | 150 | /** 151 | * 棋子添加成功后做的操作 152 | */ 153 | // 0.添加到数组里面 154 | NSMutableArray *puppetArr = self.places[x - 1]; 155 | [puppetArr replaceObjectAtIndex:y - 1 withObject:@(type)]; 156 | 157 | // 1.判断是否胜利 158 | DHPoint *resultPoint = [[DHPoint alloc] initPointWith:x y:y]; 159 | if ([DHGobangTool isVictory:resultPoint array:self.places]) { 160 | [self winWithPoint:resultPoint]; 161 | } 162 | 163 | // 2.加到记录棋子的数组 164 | [self.totalChess addObject:[[DHPoint alloc] initPointWith:x y:y]]; 165 | } 166 | } 167 | 168 | #pragma mark - public 169 | - (void)reset { 170 | 171 | [[HBPlaySoundUtil shareForPlayingSoundEffectWith:@"start.wav"] play]; 172 | for (UIImageView *imgView in self.subviews) { 173 | [imgView removeFromSuperview]; 174 | } 175 | [self initilizeData]; 176 | } 177 | 178 | - (void)undo { 179 | 180 | [[HBPlaySoundUtil shareForPlayingSoundEffectWith:@"regret.wav"] play]; 181 | if (self.totalChess.count > 1) { 182 | DHPoint *lastPoint = [self.totalChess objectAtIndex:self.totalChess.count - 1]; 183 | UIImageView *lastChess = [DHGobangTool foundChessWithPoint:lastPoint superView:self]; 184 | if (lastChess) { 185 | [lastChess removeFromSuperview]; 186 | [self.totalChess removeObject:lastPoint]; 187 | [self.places[lastPoint.x - 1] replaceObjectAtIndex:lastPoint.y - 1 withObject:@0]; 188 | } 189 | } 190 | } 191 | 192 | 193 | 194 | @end 195 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | zh_CN 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | 大华五子棋 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.3 23 | LSRequiresIPhoneOS 24 | 25 | NSAppleMusicUsageDescription 26 | App需要您的同意,才能访问媒体资料库 27 | NSBluetoothPeripheralUsageDescription 28 | App需要您的同意,才能访问蓝牙 29 | NSCalendarsUsageDescription 30 | App需要您的同意,才能访问日历 31 | NSCameraUsageDescription 32 | App需要您的同意,才能访问相机 33 | NSHealthShareUsageDescription 34 | App需要您的同意,才能访问健康分享 35 | NSHealthUpdateUsageDescription 36 | App需要您的同意,才能访问健康更新 37 | NSLocationAlwaysUsageDescription 38 | App需要您的同意,才能始终访问位置 39 | NSLocationUsageDescription 40 | App需要您的同意,才能访问位置 41 | NSLocationWhenInUseUsageDescription 42 | App需要您的同意,才能在使用期间访问位置 43 | NSMicrophoneUsageDescription 44 | App需要您的同意,才能访问麦克风 45 | NSMotionUsageDescription 46 | App需要您的同意,才能访问运动与健身 47 | NSPhotoLibraryUsageDescription 48 | App需要您的同意,才能访问相册 49 | NSRemindersUsageDescription 50 | App需要您的同意,才能访问提醒事项 51 | UILaunchStoryboardName 52 | LaunchScreen 53 | UIMainStoryboardFile 54 | Main 55 | UIRequiredDeviceCapabilities 56 | 57 | armv7 58 | 59 | UIStatusBarHidden 60 | 61 | UISupportedInterfaceOrientations 62 | 63 | UIInterfaceOrientationPortrait 64 | 65 | UISupportedInterfaceOrientations~ipad 66 | 67 | UIInterfaceOrientationPortrait 68 | UIInterfaceOrientationPortraitUpsideDown 69 | UIInterfaceOrientationLandscapeLeft 70 | UIInterfaceOrientationLandscapeRight 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Lib/LLSwitch/LLAnimationManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // LLAnimationManager.h 3 | // LLSwitch 4 | // 5 | // Created by admin on 16/5/12. 6 | // Copyright © 2016年 LiLei. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | 13 | @interface LLAnimationManager : NSObject 14 | 15 | 16 | /** 17 | * init 18 | */ 19 | - (instancetype)initWithAnimationDuration:(CGFloat)animationDuration; 20 | 21 | 22 | /** 23 | * the face layer move position 24 | */ 25 | - (CABasicAnimation *)moveAnimationWithFromPosition:(CGPoint)fromPosition toPosition:(CGPoint)toPosition; 26 | 27 | /** 28 | * the layer background color animation 29 | */ 30 | - (CABasicAnimation *)backgroundColorAnimationFromValue:(NSValue *)fromValue toValue:(NSValue *)toValue; 31 | 32 | /** 33 | * the eye layer move position 34 | */ 35 | - (CABasicAnimation *)eyeMoveAnimationFromValue:(NSValue *)fromValue toValue:(NSValue *)toValue; 36 | 37 | /** 38 | * mouth key frame animation 39 | */ 40 | - (CAKeyframeAnimation *)mouthKeyFrameAnimationWidthOffSet:(CGFloat)offSet on:(BOOL)on; 41 | 42 | /** 43 | * eyes close and open key frame animation 44 | */ 45 | - (CAKeyframeAnimation *)eyesCloseAndOpenAnimationWithRect:(CGRect)rect; 46 | 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Lib/LLSwitch/LLAnimationManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // LLAnimationManager.m 3 | // LLSwitch 4 | // 5 | // Created by admin on 16/5/12. 6 | // Copyright © 2016年 LiLei. All rights reserved. 7 | // 8 | 9 | #import "LLAnimationManager.h" 10 | #import 11 | 12 | @interface LLAnimationManager() 13 | 14 | /** 15 | * the duration is the face moving time not include spring animation 16 | */ 17 | @property (nonatomic, assign) CGFloat animationDuration; 18 | 19 | @end 20 | 21 | 22 | 23 | @implementation LLAnimationManager 24 | 25 | 26 | /** 27 | * init 28 | */ 29 | - (instancetype)initWithAnimationDuration:(CGFloat)animationDuration { 30 | self = [super init]; 31 | if (self) { 32 | _animationDuration = animationDuration; 33 | } 34 | return self; 35 | } 36 | 37 | /** 38 | * faceLayer move animation 39 | */ 40 | - (CABasicAnimation *)moveAnimationWithFromPosition:(CGPoint)fromPosition toPosition:(CGPoint)toPosition { 41 | CABasicAnimation *moveAnimation = [CABasicAnimation animationWithKeyPath:@"position"]; 42 | moveAnimation.fromValue = [NSValue valueWithCGPoint:fromPosition]; 43 | moveAnimation.toValue = [NSValue valueWithCGPoint:toPosition]; 44 | moveAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 45 | moveAnimation.duration = _animationDuration * 2 /3; 46 | moveAnimation.removedOnCompletion = NO; 47 | moveAnimation.fillMode = kCAFillModeForwards; 48 | return moveAnimation; 49 | } 50 | 51 | /** 52 | * layer background color animation 53 | */ 54 | - (CABasicAnimation *)backgroundColorAnimationFromValue:(NSValue *)fromValue toValue:(NSValue *)toValue { 55 | CABasicAnimation *colorAnimation = [CABasicAnimation animationWithKeyPath:@"backgroundColor"]; 56 | colorAnimation.fromValue = fromValue; 57 | colorAnimation.toValue = toValue; 58 | colorAnimation.duration = _animationDuration * 2 /3; 59 | colorAnimation.removedOnCompletion = NO; 60 | colorAnimation.fillMode = kCAFillModeForwards; 61 | return colorAnimation; 62 | 63 | } 64 | 65 | /** 66 | * the eyes layer move 67 | */ 68 | - (CABasicAnimation *)eyeMoveAnimationFromValue:(NSValue *)fromValue toValue:(NSValue *)toValue{ 69 | CABasicAnimation *moveAnimation = [CABasicAnimation animationWithKeyPath:@"transform.translation.x"]; 70 | moveAnimation.fromValue = fromValue; 71 | moveAnimation.toValue = toValue; 72 | moveAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 73 | moveAnimation.duration = _animationDuration / 3; 74 | moveAnimation.removedOnCompletion = NO; 75 | moveAnimation.fillMode = kCAFillModeForwards; 76 | return moveAnimation; 77 | } 78 | 79 | 80 | /** 81 | * mouth key frame animation 82 | */ 83 | - (CAKeyframeAnimation *)mouthKeyFrameAnimationWidthOffSet:(CGFloat)offSet on:(BOOL)on{ 84 | CGFloat frameNumber = _animationDuration * 60 / 3; 85 | CGFloat frameValue = on ? offSet : 0; 86 | NSMutableArray *arrayFrame = [NSMutableArray array]; 87 | for (int i = 0; i < frameNumber; i++) { 88 | if (on) { 89 | frameValue = frameValue - offSet / frameNumber; 90 | } else { 91 | frameValue = frameValue + offSet / frameNumber; 92 | } 93 | [arrayFrame addObject:@(frameValue)]; 94 | } 95 | CAKeyframeAnimation *keyAnimation = [CAKeyframeAnimation animationWithKeyPath:@"mouthOffSet"]; 96 | keyAnimation.values = arrayFrame; 97 | keyAnimation.duration = _animationDuration / 4; 98 | if (!on && _animationDuration >= 1.f) { 99 | keyAnimation.beginTime = CACurrentMediaTime() + _animationDuration / 12; 100 | } 101 | keyAnimation.removedOnCompletion = NO; 102 | keyAnimation.fillMode = kCAFillModeForwards; 103 | return keyAnimation; 104 | } 105 | 106 | /** 107 | * eyes close and open key frame animation 108 | */ 109 | - (CAKeyframeAnimation *)eyesCloseAndOpenAnimationWithRect:(CGRect)rect { 110 | CGFloat frameNumber = _animationDuration * 180 / 9; // 180 frame erver second 111 | CGFloat eyesX = rect.origin.x; 112 | CGFloat eyesY = rect.origin.y; 113 | CGFloat eyesWidth = rect.size.width; 114 | CGFloat eyesHeight = rect.size.height; 115 | NSMutableArray *arrayFrame = [NSMutableArray array]; 116 | for (int i = 0; i < frameNumber; i++) { 117 | if (i < frameNumber / 3) { 118 | // close 119 | eyesHeight = eyesHeight - rect.size.height / (frameNumber / 3); 120 | } else if (i >= frameNumber / 3 && i < frameNumber * 2 / 3) { 121 | // zero 122 | eyesHeight = 0; 123 | } else { 124 | // open 125 | eyesHeight = eyesHeight + rect.size.height / (frameNumber / 3); 126 | } 127 | eyesY = (rect.size.height - eyesHeight) / 2; 128 | [arrayFrame addObject:[NSValue valueWithCGRect:CGRectMake(eyesX, eyesY, eyesWidth, eyesHeight)]]; 129 | } 130 | CAKeyframeAnimation *keyAnimation = [CAKeyframeAnimation animationWithKeyPath:@"eyeRect"]; 131 | keyAnimation.values = arrayFrame; 132 | keyAnimation.duration = _animationDuration / 3; 133 | keyAnimation.removedOnCompletion = NO; 134 | keyAnimation.fillMode = kCAFillModeForwards; 135 | return keyAnimation; 136 | } 137 | 138 | @end 139 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Lib/LLSwitch/LLEyesLayer.h: -------------------------------------------------------------------------------- 1 | // 2 | // LLLeftEyeLayer.h 3 | // LLSwitch 4 | // 5 | // Created by admin on 16/5/13. 6 | // Copyright © 2016年 LiLei. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface LLEyesLayer : CALayer 13 | 14 | /** 15 | * eye property 16 | */ 17 | @property (nonatomic, assign) CGRect eyeRect; 18 | 19 | @property (nonatomic, assign) CGFloat eyeDistance; 20 | 21 | @property (nonatomic, strong) UIColor *eyeColor; 22 | 23 | @property (nonatomic, assign) BOOL isLiking; 24 | 25 | @property (nonatomic, assign) CGFloat mouthOffSet; 26 | 27 | @property (nonatomic, assign) CGFloat mouthY; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Lib/LLSwitch/LLEyesLayer.m: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // LLLeftEyeLayer.m 4 | // LLSwitch 5 | // 6 | // Created by admin on 16/5/13. 7 | // Copyright © 2016年 LiLei. All rights reserved. 8 | // 9 | 10 | #import "LLEyesLayer.h" 11 | 12 | @implementation LLEyesLayer 13 | 14 | /** 15 | * init layer 16 | * 17 | * @return self 18 | */ 19 | - (instancetype)init { 20 | if (self = [super init]) { 21 | // 默认属性 22 | _eyeRect = CGRectMake(0, 0, 0, 0); 23 | _mouthOffSet = 0.f; 24 | } 25 | return self; 26 | } 27 | 28 | - (instancetype)initWithLayer:(LLEyesLayer *)layer { 29 | self = [super initWithLayer:layer]; 30 | if (self) { 31 | self.eyeRect = layer.eyeRect; 32 | self.eyeDistance = layer.eyeDistance; 33 | self.eyeColor = layer.eyeColor; 34 | self.isLiking = layer.isLiking; 35 | self.mouthOffSet = layer.mouthOffSet; 36 | self.mouthY = layer.mouthY; 37 | } 38 | return self; 39 | } 40 | 41 | /** 42 | * draw 43 | */ 44 | - (void)drawInContext:(CGContextRef)ctx { 45 | UIBezierPath *bezierLeft = [UIBezierPath bezierPathWithOvalInRect:_eyeRect]; 46 | UIBezierPath *bezierRight = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(_eyeDistance, _eyeRect.origin.y, _eyeRect.size.width, _eyeRect.size.height)]; 47 | 48 | 49 | UIBezierPath *bezierMouth = [UIBezierPath bezierPath]; 50 | CGFloat mouthWidth = _eyeRect.size.width + _eyeDistance; 51 | if (_isLiking) { 52 | // funny mouth 53 | [bezierMouth moveToPoint:CGPointMake(0, _mouthY)]; 54 | [bezierMouth addCurveToPoint:CGPointMake(mouthWidth, _mouthY) controlPoint1:CGPointMake(mouthWidth - _mouthOffSet * 3 / 4, _mouthY + _mouthOffSet / 2) controlPoint2:CGPointMake(mouthWidth - _mouthOffSet / 4, _mouthY + _mouthOffSet / 2)]; 55 | } else { 56 | // boring mouth 57 | bezierMouth = [UIBezierPath bezierPathWithRect:CGRectMake(0, _mouthY, mouthWidth, _eyeRect.size.height / 4)]; 58 | } 59 | 60 | [bezierMouth closePath]; 61 | CGContextAddPath(ctx, bezierLeft.CGPath); 62 | CGContextAddPath(ctx, bezierRight.CGPath); 63 | CGContextAddPath(ctx, bezierMouth.CGPath); 64 | CGContextSetFillColorWithColor(ctx, _eyeColor.CGColor); 65 | CGContextSetStrokeColorWithColor(ctx, [UIColor redColor].CGColor); 66 | CGContextFillPath(ctx); 67 | } 68 | 69 | 70 | /** 71 | * key animation 72 | */ 73 | +(BOOL)needsDisplayForKey:(NSString *)key{ 74 | if ([key isEqual:@"mouthOffSet"]) { 75 | return YES; 76 | } 77 | if ([key isEqual:@"eyeRect"]) { 78 | return YES; 79 | } 80 | return [super needsDisplayForKey:key]; 81 | } 82 | 83 | @end 84 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Lib/LLSwitch/LLSwitch.h: -------------------------------------------------------------------------------- 1 | // 2 | // LLSwitch.h 3 | // LLSwitch 4 | // 5 | // Created by admin on 16/5/12. 6 | // Copyright © 2016年 LiLei. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @protocol LLSwitchDelegate; 12 | 13 | IB_DESIGNABLE @interface LLSwitch : UIView 14 | 15 | 16 | /** 17 | * switch on color 18 | */ 19 | @property (nonatomic, strong) IBInspectable UIColor *onColor; 20 | 21 | /** 22 | * switch off color 23 | */ 24 | @property (nonatomic, strong) IBInspectable UIColor *offColor; 25 | 26 | /** 27 | * face on and off color 28 | */ 29 | @property (nonatomic, strong) IBInspectable UIColor *faceColor; 30 | 31 | /** 32 | * the duration is the face moving time 33 | */ 34 | @property (nonatomic, assign) IBInspectable CGFloat animationDuration; 35 | 36 | 37 | /** 38 | * the switch status is or isn't on 39 | */ 40 | @property (nonatomic, assign) IBInspectable BOOL on; 41 | 42 | @property (nonatomic, weak) IBOutlet id delegate; 43 | 44 | @end 45 | 46 | 47 | #pragma mark LLSwitch delegate 48 | @protocol LLSwitchDelegate 49 | 50 | @optional 51 | 52 | 53 | - (void)didTapLLSwitch:(LLSwitch *)llSwitch; 54 | 55 | 56 | - (void)animationDidStopForLLSwitch:(LLSwitch *)llSwitch; 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Lib/LLSwitch/LLSwitch.m: -------------------------------------------------------------------------------- 1 | // 2 | // LLSwitch.m 3 | // LLSwitch 4 | // 5 | // Created by admin on 16/5/12. 6 | // Copyright © 2016年 LiLei. All rights reserved. 7 | // 8 | 9 | #import "LLSwitch.h" 10 | #import "LLAnimationManager.h" 11 | #import "LLEyesLayer.h" 12 | 13 | 14 | NSString * const FaceMoveAnimationKey = @"FaceMoveAnimationKey"; 15 | NSString * const BackgroundColorAnimationKey = @"BackgroundColorAnimationKey"; 16 | NSString * const EyesMoveStartAnimationKey = @"EyesMoveStartAnimationKey"; 17 | NSString * const EyesMoveEndAnimationKey = @"EyesMoveEndAnimationKey"; 18 | NSString * const EyesMoveBackAnimationKey = @"EyesMoveBackAnimationKey"; 19 | NSString * const MouthFrameAnimationKey = @"MouthFrameAnimationKey"; 20 | NSString * const EyesCloseAndOpenAnimationKey = @"EyesCloseAndOpenAnimationKey"; 21 | 22 | @interface LLSwitch() 23 | 24 | /** 25 | * switch background view 26 | */ 27 | @property (nonatomic, strong) UIView *backgroundView; 28 | 29 | /** 30 | * face layer 31 | */ 32 | @property (nonatomic, strong) CAShapeLayer *circleFaceLayer; 33 | 34 | /** 35 | * paddingWidth 36 | */ 37 | @property (nonatomic, assign) CGFloat paddingWidth; 38 | 39 | /** 40 | * eyes layer 41 | */ 42 | @property (nonatomic, strong) LLEyesLayer *eyesLayer; 43 | 44 | /** 45 | * face radius 46 | */ 47 | @property (nonatomic, assign) CGFloat circleFaceRadius; 48 | 49 | /** 50 | * the faceLayer move distance 51 | */ 52 | @property (nonatomic, assign) CGFloat moveDistance; 53 | 54 | /** 55 | * handler layer animation manager 56 | */ 57 | @property (nonatomic, strong) LLAnimationManager *animationManager; 58 | 59 | 60 | /** 61 | * whether is animated 62 | */ 63 | @property (nonatomic, assign) BOOL isAnimating; 64 | 65 | @property (nonatomic, assign) CGFloat faceLayerWidth; 66 | 67 | 68 | 69 | @end 70 | 71 | 72 | @implementation LLSwitch 73 | 74 | - (instancetype)initWithFrame:(CGRect)frame { 75 | self = [super initWithFrame:frame]; 76 | if (self) { 77 | [self initSetUpView]; 78 | } 79 | return self; 80 | } 81 | 82 | - (instancetype)initWithCoder:(NSCoder *)aDecoder { 83 | self = [super initWithCoder:aDecoder]; 84 | if (self) { 85 | [self initSetUpView]; 86 | } 87 | return self; 88 | } 89 | 90 | 91 | - (void)initSetUpView { 92 | 93 | /** 94 | * check the switch width and height 95 | */ 96 | NSAssert(self.frame.size.width >= self.frame.size.height, @"switch width must be tall!"); 97 | 98 | /** 99 | * init property 100 | */ 101 | _onColor = [UIColor colorWithRed:73/255.0 green:182/255.0 blue:235/255.0 alpha:1.f]; 102 | _offColor = [UIColor colorWithRed:211/255.0 green:207/255.0 blue:207/255.0 alpha:1.f]; 103 | _faceColor = [UIColor whiteColor]; 104 | _paddingWidth = self.frame.size.height * 0.1; 105 | _circleFaceRadius = (self.frame.size.height - 2 * _paddingWidth) / 2; 106 | _animationDuration = 1.2f; 107 | _animationManager = [[LLAnimationManager alloc] initWithAnimationDuration:_animationDuration]; 108 | _moveDistance = self.frame.size.width - _paddingWidth * 2 - _circleFaceRadius * 2; 109 | _on = NO; 110 | _isAnimating = NO; 111 | 112 | /** 113 | * setting init property 114 | */ 115 | self.backgroundView.backgroundColor = _offColor; 116 | self.circleFaceLayer.fillColor = _faceColor.CGColor; 117 | self.faceLayerWidth = self.circleFaceLayer.frame.size.width; 118 | [self.eyesLayer setNeedsDisplay]; 119 | 120 | [self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapSwitch)]]; 121 | } 122 | 123 | 124 | #pragma mark set property 125 | 126 | - (void)setBackgroundColor:(UIColor *)backgroundColor { 127 | return; 128 | } 129 | 130 | - (void)setOffColor:(UIColor *)offColor { 131 | _offColor = offColor; 132 | if (!_on) { 133 | _backgroundView.backgroundColor = offColor; 134 | _eyesLayer.eyeColor = offColor; 135 | [self.eyesLayer setNeedsDisplay]; 136 | } 137 | } 138 | 139 | - (void)setOnColor:(UIColor *)onColor { 140 | _onColor = onColor; 141 | if (_on) { 142 | _backgroundView.backgroundColor = onColor; 143 | _eyesLayer.eyeColor = onColor; 144 | [self.eyesLayer setNeedsDisplay]; 145 | } 146 | } 147 | 148 | - (void)setFaceColor:(UIColor *)faceColor { 149 | _faceColor = faceColor; 150 | _circleFaceLayer.fillColor = faceColor.CGColor; 151 | } 152 | 153 | - (void)setAnimationDuration:(CGFloat)animationDuration { 154 | _animationDuration = animationDuration; 155 | _animationManager = [[LLAnimationManager alloc] initWithAnimationDuration:_animationDuration]; 156 | } 157 | 158 | - (void)setOn:(BOOL)on { 159 | _on = on; 160 | if (on) { 161 | self.backgroundView.backgroundColor = _onColor; 162 | self.circleFaceLayer.position = CGPointMake(self.circleFaceLayer.position.x + _moveDistance, self.circleFaceLayer.position.y); 163 | self.eyesLayer.eyeColor = _onColor; 164 | self.eyesLayer.isLiking = YES; 165 | self.eyesLayer.mouthOffSet = _eyesLayer.frame.size.width; 166 | [self.eyesLayer needsDisplay]; 167 | } 168 | } 169 | 170 | 171 | #pragma mark GestureRecognizer 172 | - (void)handleTapSwitch { 173 | if (_isAnimating) { 174 | return; 175 | } 176 | _isAnimating = YES; 177 | // faceLayer 178 | CABasicAnimation *moveAnimation = [_animationManager moveAnimationWithFromPosition:_circleFaceLayer.position toPosition:_on ? CGPointMake(_circleFaceLayer.position.x - _moveDistance, _circleFaceLayer.position.y) : CGPointMake(_circleFaceLayer.position.x + _moveDistance, _circleFaceLayer.position.y)]; 179 | moveAnimation.delegate = self; 180 | [_circleFaceLayer addAnimation:moveAnimation forKey:FaceMoveAnimationKey]; 181 | 182 | // backfroundView 183 | CABasicAnimation *colorAnimation = [_animationManager backgroundColorAnimationFromValue:(id)(_on ? _onColor : _offColor).CGColor toValue:(id)(_on ? _offColor : _onColor).CGColor]; 184 | [_backgroundView.layer addAnimation:colorAnimation forKey:BackgroundColorAnimationKey]; 185 | 186 | // eyesLayer 187 | CABasicAnimation *rotationAnimation = [_animationManager eyeMoveAnimationFromValue:@(0) toValue:@(_on ? -_faceLayerWidth : _faceLayerWidth)]; 188 | rotationAnimation.delegate = self; 189 | [_eyesLayer addAnimation:rotationAnimation forKey:EyesMoveStartAnimationKey]; 190 | _circleFaceLayer.masksToBounds = YES; 191 | if (_on) { 192 | [self eyesKeyFrameAnimationStart]; 193 | } 194 | 195 | 196 | // start delegate 197 | if ([self.delegate respondsToSelector:@selector(didTapLLSwitch:)]) { 198 | [self.delegate didTapLLSwitch:self]; 199 | } 200 | 201 | } 202 | 203 | 204 | 205 | #pragma mark Init 206 | 207 | /** 208 | * init backgroundView 209 | * 210 | * @return backgroundView 211 | */ 212 | - (UIView *)backgroundView { 213 | if (!_backgroundView) { 214 | _backgroundView = [[UIView alloc] init]; 215 | _backgroundView.frame = self.bounds; 216 | _backgroundView.layer.cornerRadius = self.frame.size.height / 2; 217 | _backgroundView.layer.masksToBounds = YES; 218 | [self addSubview:_backgroundView]; 219 | } 220 | return _backgroundView; 221 | } 222 | 223 | 224 | /** 225 | * init circleFaceLayer 226 | * 227 | * @return circleFaceLayer 228 | */ 229 | - (CAShapeLayer *)circleFaceLayer { 230 | if (!_circleFaceLayer) { 231 | _circleFaceLayer = [CAShapeLayer layer]; 232 | [_circleFaceLayer setFrame:CGRectMake(_paddingWidth, _paddingWidth, _circleFaceRadius * 2, _circleFaceRadius *2)]; 233 | UIBezierPath *circlePath = [UIBezierPath bezierPathWithOvalInRect:_circleFaceLayer.bounds]; 234 | _circleFaceLayer.path = circlePath.CGPath; 235 | [self.backgroundView.layer addSublayer:_circleFaceLayer]; 236 | } 237 | return _circleFaceLayer; 238 | } 239 | 240 | 241 | /** 242 | * eyes and mouth layer 243 | * 244 | * @return eyesLayer 245 | */ 246 | - (LLEyesLayer *)eyesLayer { 247 | if (!_eyesLayer) { 248 | _eyesLayer = [LLEyesLayer layer]; 249 | _eyesLayer.eyeRect = CGRectMake(0, 0, _faceLayerWidth / 6, _circleFaceLayer.frame.size.height * 0.22); 250 | _eyesLayer.eyeDistance = _faceLayerWidth / 3; 251 | _eyesLayer.eyeColor = _offColor; 252 | _eyesLayer.isLiking = NO; 253 | _eyesLayer.mouthY = _eyesLayer.eyeRect.size.height * 7 / 4; 254 | _eyesLayer.frame = CGRectMake(_faceLayerWidth / 4, _circleFaceLayer.frame.size.height * 0.28, _faceLayerWidth / 2, _circleFaceLayer.frame.size.height * 0.72); 255 | // _eyesLayer.backgroundColor = [UIColor redColor].CGColor; 256 | [self.circleFaceLayer addSublayer:_eyesLayer]; 257 | 258 | } 259 | return _eyesLayer; 260 | } 261 | 262 | #pragma mark AnimationDelegate 263 | - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { 264 | if (flag) { 265 | 266 | // start eyes ending animation 267 | if (anim == [_eyesLayer animationForKey:EyesMoveStartAnimationKey]) { 268 | _eyesLayer.eyeColor = _on ? _offColor: _onColor; 269 | _eyesLayer.isLiking = !_on; 270 | [_eyesLayer setNeedsDisplay]; 271 | CABasicAnimation *rotationAnimation = [_animationManager eyeMoveAnimationFromValue:@(_on ? _faceLayerWidth : -_faceLayerWidth) toValue:@(_on ? -_faceLayerWidth / 6 : _faceLayerWidth / 6)]; 272 | rotationAnimation.delegate = self; 273 | [_eyesLayer addAnimation:rotationAnimation forKey:EyesMoveEndAnimationKey]; 274 | 275 | if (!_on) { 276 | [self eyesKeyFrameAnimationStart]; 277 | } 278 | } 279 | 280 | // start eyes back animation 281 | if (anim == [_eyesLayer animationForKey:EyesMoveEndAnimationKey]) { 282 | CABasicAnimation *rotationAnimation = [_animationManager eyeMoveAnimationFromValue:@(_on ? -_faceLayerWidth / 6 : _faceLayerWidth / 6) toValue:@(0)]; 283 | rotationAnimation.delegate = self; 284 | [_eyesLayer addAnimation:rotationAnimation forKey:EyesMoveBackAnimationKey]; 285 | 286 | if (!_on) { 287 | CAKeyframeAnimation *eyesKeyFrameAnimation = [_animationManager eyesCloseAndOpenAnimationWithRect:_eyesLayer.eyeRect]; 288 | [_eyesLayer addAnimation:eyesKeyFrameAnimation forKey:EyesCloseAndOpenAnimationKey]; 289 | } 290 | } 291 | 292 | // eyes back animation end 293 | if (anim == [_eyesLayer animationForKey:EyesMoveBackAnimationKey]) { 294 | [_eyesLayer removeAllAnimations]; 295 | _eyesLayer.mouthOffSet = _on ? 0 : _eyesLayer.frame.size.width; 296 | 297 | if (_on) { 298 | _circleFaceLayer.position = CGPointMake(_circleFaceLayer.position.x - _moveDistance, _circleFaceLayer.position.y); 299 | _on = NO; 300 | } else { 301 | _circleFaceLayer.position = CGPointMake(_circleFaceLayer.position.x + _moveDistance, _circleFaceLayer.position.y); 302 | _on = YES; 303 | } 304 | _isAnimating = NO; 305 | 306 | 307 | // stop delegate 308 | if ([self.delegate respondsToSelector:@selector(animationDidStopForLLSwitch:)]) { 309 | [self.delegate animationDidStopForLLSwitch:self]; 310 | } 311 | } 312 | } 313 | } 314 | 315 | /** 316 | * add mouth keyFrameAnimation 317 | */ 318 | - (void)eyesKeyFrameAnimationStart { 319 | CAKeyframeAnimation *keyAnimation = [_animationManager mouthKeyFrameAnimationWidthOffSet:_eyesLayer.frame.size.width on:_on]; 320 | [_eyesLayer addAnimation:keyAnimation forKey:MouthFrameAnimationKey]; 321 | } 322 | 323 | - (void)dealloc { 324 | self.delegate = nil; 325 | } 326 | 327 | 328 | @end 329 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Lib/SFDraggableDialogView/Resources/icArrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Lib/SFDraggableDialogView/Resources/icArrow.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Lib/SFDraggableDialogView/Resources/icArrow@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Lib/SFDraggableDialogView/Resources/icArrow@2x.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Lib/SFDraggableDialogView/Resources/icArrow@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Lib/SFDraggableDialogView/Resources/icArrow@3x.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Lib/SFDraggableDialogView/Resources/icArrowTop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Lib/SFDraggableDialogView/Resources/icArrowTop.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Lib/SFDraggableDialogView/Resources/icArrowTop@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Lib/SFDraggableDialogView/Resources/icArrowTop@2x.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Lib/SFDraggableDialogView/Resources/icArrowTop@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Lib/SFDraggableDialogView/Resources/icArrowTop@3x.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Lib/SFDraggableDialogView/Resources/icCross@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Lib/SFDraggableDialogView/Resources/icCross@2x.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Lib/SFDraggableDialogView/SFDraggableDialogView.h: -------------------------------------------------------------------------------- 1 | // 2 | // SFDraggableDialogView.h 3 | // 4 | // Created by Jakub Truhlar on 10.12.15. 5 | // Copyright © 2015 Jakub Truhlar. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | @class SFDraggableDialogView; 11 | 12 | @protocol SFDraggableDialogViewDelegate 13 | 14 | @optional 15 | 16 | /** 17 | * The bottom first button was pressed. 18 | * 19 | * @param dialogView Dialog view within the button was pressed. 20 | * @param closeButton Reference of the pressed button. 21 | */ 22 | - (void)draggableDialogView:(SFDraggableDialogView *)dialogView didPressFirstButton:(UIButton *)firstButton; 23 | 24 | /** 25 | * The bottom second button was pressed. 26 | * 27 | * @param dialogView Dialog view within the button was pressed. 28 | * @param closeButton Reference of the pressed button. 29 | */ 30 | - (void)draggableDialogView:(SFDraggableDialogView *)dialogView didPressSecondButton:(UIButton *)secondButton; 31 | 32 | /** 33 | * Dialog view interactive dragging did begin. 34 | * 35 | * @param dialogView Dialog view within the dialog did begin moving. 36 | */ 37 | - (void)draggingDidBegin:(SFDraggableDialogView *)dialogView; 38 | 39 | /** 40 | * Dialog view interactive dragging did end. 41 | * 42 | * @param dialogView Dialog view within the dialog did end moving. 43 | */ 44 | - (void)draggingDidEnd:(SFDraggableDialogView *)dialogView; 45 | 46 | /** 47 | * Dialog view was dismissed by dragging out of the screen or by pressed close button. 48 | * 49 | * @param dialogView Dialog view within the dialog was dismissed. 50 | */ 51 | - (void)draggableDialogViewDismissed:(SFDraggableDialogView *)dialogView; 52 | 53 | /** 54 | * Dialog view will be dismissed by dragging out of the screen or by pressed close button. 55 | * 56 | * @param dialogView Dialog view within the dialog will be dismissed. 57 | */ 58 | - (void)draggableDialogViewWillDismiss:(SFDraggableDialogView *)dialogView; 59 | 60 | @end 61 | 62 | typedef NS_ENUM(NSInteger, SFContentViewType) { 63 | SFContentViewTypeDefault = 0, 64 | SFContentViewTypeCustom 65 | }; 66 | 67 | @interface SFDraggableDialogView : UIView 68 | 69 | /** 70 | * Dialog is centered within the background superview. DEFAULT is (270.0, 350.0). 71 | */ 72 | @property (nonatomic, assign) CGSize size; 73 | 74 | /** 75 | * Dialog's corner radius. DEFAULT is 5.0. 76 | */ 77 | @property (nonatomic, assign) CGFloat cornerRadius; 78 | 79 | /** 80 | * Opacity (between 0.0 and 1.0) of the dialog's shadow. DEFAULT is 0.3 81 | */ 82 | @property (nonatomic, assign) CGFloat backgroundShadowOpacity; 83 | 84 | /** 85 | * Background color of the dialog. DEFAULT is White. 86 | */ 87 | @property (nonatomic, strong) UIColor *dialogBackgroundColor; 88 | 89 | /** 90 | * Background color of the first button. DEFAULT is a kind of green. 91 | * MUST BE set, otherwise the button's highlight WILL NOT be working. 92 | */ 93 | @property (nonatomic, strong) UIColor *firstBtnBackgroundColor; 94 | 95 | /** 96 | * The first button's text color. DEFAULT is white. 97 | */ 98 | @property (nonatomic, strong) UIColor *firstBtnTextColor; 99 | 100 | /** 101 | * The first button's font. DEFAULT is Helvetica Neue 15.0 Bold. 102 | */ 103 | @property (nonatomic, strong) UIFont *firstBtnFont; 104 | 105 | /** 106 | * Background color of the second button. DEFAULT is a kind of green. 107 | * MUST BE set, otherwise the button's highlight WILL NOT be working. 108 | */ 109 | @property (nonatomic, strong) UIColor *secondBtnBackgroundColor; 110 | 111 | /** 112 | * Second button's text color. DEFAULT is white. 113 | */ 114 | @property (nonatomic, strong) UIColor *secondBtnTextColor; 115 | 116 | /** 117 | * Second button's font. DEFAULT is Helvetica Neue 15.0 Bold. 118 | */ 119 | @property (nonatomic, strong) UIFont *secondBtnFont; 120 | 121 | /** 122 | * Image for the dismissal button. 123 | */ 124 | @property (nonatomic, strong) UIImage *closeBtnImage; 125 | 126 | /** 127 | * Image for the circular image view. 128 | */ 129 | @property (nonatomic, strong) UIImage *photo; 130 | 131 | /** 132 | * Title text. Title label is suppose to have one line. 133 | */ 134 | @property (nonatomic, strong) NSMutableAttributedString *titleText; 135 | 136 | /** 137 | * Message text. Message label is suppose to have two lines. 138 | */ 139 | @property (nonatomic, strong) NSMutableAttributedString *messageText; 140 | 141 | /** 142 | * Default button's text. DEFAULT is Accept. 143 | */ 144 | @property (nonatomic, strong) NSString *firstBtnText; 145 | 146 | /** 147 | * Second button's text. DEFAULT is Cancel. 148 | */ 149 | @property (nonatomic, strong) NSString *secondBtnText; 150 | 151 | /** 152 | * Text of the cancel arrow. Empty value will make it hidden and draggable dismissing will be disabled. DEFAULT is @"Cancel". 153 | */ 154 | @property (nonatomic, strong) NSMutableAttributedString *cancelArrowText; 155 | 156 | /** 157 | * The image of the cancel view. Default is arrow 158 | */ 159 | @property (nonatomic, strong) UIImage *cancelArrowImage; 160 | 161 | /** 162 | * The visible content view. Custom is blank, default has image and two labels. DEFAULT is Default. 163 | */ 164 | @property (nonatomic, assign) SFContentViewType contentViewType; 165 | 166 | /** 167 | * Should hide close button. DEFAULT is NO. 168 | */ 169 | @property (nonatomic, assign) bool hideCloseButton; 170 | 171 | /** 172 | * Should show the second button. DEFAULT is NO. 173 | */ 174 | @property (nonatomic, assign) bool showSecondBtn; 175 | 176 | /** 177 | * Dialog view is draggable. DEFAULT is YES. 178 | */ 179 | @property (nonatomic, assign, getter=isDraggable) bool draggable; 180 | 181 | /** 182 | * The custom content view of the contentViewTypeCustom type. Add any subview here. 183 | */ 184 | @property (weak, nonatomic) IBOutlet UIView *customView; 185 | 186 | @property (nonatomic, assign) id delegate; 187 | 188 | /** 189 | * Background image button view reference. Should be use only for a subview adding. 190 | */ 191 | @property (weak, nonatomic) IBOutlet UIButton *backgroundImageBtn; 192 | 193 | /** 194 | * Dismiss the dialog view. 195 | * 196 | * @param drop Drop down movement 197 | */ 198 | - (void)dismissWithDrop:(bool)drop; 199 | 200 | /** 201 | * Dismiss the dialog view. 202 | * 203 | * @param drop Drop down movement 204 | * @param completion Completion block. 205 | */ 206 | - (void)dismissWithDrop:(bool)drop completion:(void (^)())completion; 207 | 208 | /** 209 | * Create the background image view that will be placed behind the dialog view. 210 | * 211 | * @param backgroundImage Blurred image. 212 | * @param tintColor Tint color of the blurred image view. 213 | * @param blurRadius Blur radius of the blurred image view. 214 | */ 215 | - (void)createBlurBackgroundWithImage:(UIImage *)backgroundImage tintColor:(UIColor *)tintColor blurRadius:(CGFloat)blurRadius; 216 | 217 | /** 218 | * SFDraggableDialogView *dialogView = [[[NSBundle mainBundle] loadNibNamed:@"SFDraggableDialogView" owner:self options:nil] firstObject]; 219 | dialogView.frame = self.view.bounds; 220 | * 221 | * @param owner <#owner description#> 222 | * 223 | * @return <#return value description#> 224 | */ 225 | 226 | + (instancetype)drgViewWith:(UIViewController *)owner titleText:(NSString *)titleText photo:(UIImage *)photo message:(NSString *)messageText; 227 | @end -------------------------------------------------------------------------------- /GoBangGraduationProject/Lib/SFDraggableDialogView/SFDraggableDialogView.m: -------------------------------------------------------------------------------- 1 | // 2 | // SFDraggableDialogView.m 3 | // 4 | // Created by Jakub Truhlar on 10.12.15. 5 | // Copyright © 2015 Jakub Truhlar. All rights reserved. 6 | // 7 | 8 | #import "SFDraggableDialogView.h" 9 | #import "UIImage+ImageEffects.h" 10 | 11 | typedef NS_ENUM(NSInteger, SFPanDirection) { 12 | SFPanDirectionTop = 0, 13 | SFPanDirectionBottom, 14 | SFPanDirectionOthers 15 | }; 16 | 17 | @interface SFDraggableDialogView() 18 | 19 | @property (weak, nonatomic) IBOutlet UIView *dialogView; 20 | @property (weak, nonatomic) IBOutlet UIView *shadowView; 21 | @property (weak, nonatomic) IBOutlet UIView *cancelViewBottom; 22 | 23 | // Content 24 | @property (weak, nonatomic) IBOutlet UIImageView *photoImageView; 25 | @property (weak, nonatomic) IBOutlet UILabel *messageLbl; 26 | @property (weak, nonatomic) IBOutlet UILabel *titleLbl; 27 | @property (weak, nonatomic) IBOutlet UIButton *cancelArrowBtnBottom; 28 | @property (weak, nonatomic) IBOutlet UIImageView *cancelArrowImageViewTop; 29 | @property (weak, nonatomic) IBOutlet UIImageView *cancelArrowImageViewBottom; 30 | @property (weak, nonatomic) IBOutlet UIView *defaultView; 31 | 32 | // Buttons 33 | @property (weak, nonatomic) IBOutlet UIButton *firstBtn; 34 | @property (weak, nonatomic) IBOutlet UIButton *secondBtn; 35 | @property (weak, nonatomic) IBOutlet UIButton *closeBtn; 36 | 37 | // UIDynamics 38 | @property (nonatomic, strong) UIGestureRecognizer *gestureRecognizer; 39 | @property (nonatomic, strong) UIDynamicAnimator *animator; 40 | @property (nonatomic, assign) SFPanDirection *panDirection; 41 | 42 | // Constraints 43 | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *dialogViewHeightCns; 44 | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *dialogViewWidthCns; 45 | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *dialogViewBottomCns; 46 | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *infoCustomViewViewVerticalOffsetCns; 47 | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *gameOverCustomViewVerticalOffsetCns; 48 | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *pauseCustomViewVerticalOffsetCns; 49 | @property (weak, nonatomic) IBOutlet NSLayoutConstraint *defaultViewVerticalOffsetCns; 50 | 51 | // The first button highlight handle 52 | - (IBAction)firstBtnTouchDownEvent:(id)sender; 53 | 54 | // Second button highlight handle 55 | - (IBAction)secondBtnTouchDownEvent:(id)sender; 56 | 57 | @end 58 | 59 | @implementation SFDraggableDialogView 60 | 61 | + (instancetype)drgViewWith:(UIViewController *)owner titleText:(NSString *)titleText photo:(UIImage *)photo message:(NSString *)messageText { 62 | 63 | SFDraggableDialogView *dialogView = [[[NSBundle mainBundle] loadNibNamed:@"SFDraggableDialogView" owner:owner options:nil] firstObject]; 64 | dialogView.frame = [UIScreen mainScreen].bounds; 65 | dialogView.photo = photo; 66 | dialogView.titleText = [[NSMutableAttributedString alloc] initWithString:titleText]; 67 | dialogView.messageText = [SFDraggableDialogView exampleAttributeString:messageText]; 68 | dialogView.firstBtnText = [@"重新开始" uppercaseString]; 69 | dialogView.dialogBackgroundColor = [UIColor whiteColor]; 70 | dialogView.cornerRadius = 8.0; 71 | dialogView.backgroundShadowOpacity = 0.2; 72 | dialogView.hideCloseButton = true; 73 | dialogView.showSecondBtn = false; 74 | dialogView.contentViewType = SFContentViewTypeDefault; 75 | dialogView.firstBtnBackgroundColor = [UIColor colorWithRed:0.230 green:0.777 blue:0.316 alpha:1.000]; 76 | [dialogView createBlurBackgroundWithImage:[SFDraggableDialogView jt_imageWithView:owner.view] tintColor:[[UIColor blackColor] colorWithAlphaComponent:0.35] blurRadius:60.0]; 77 | return dialogView; 78 | } 79 | + (UIImage *)jt_imageWithView:(UIView *)view { 80 | CGFloat scale = [[UIScreen mainScreen] scale]; 81 | UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, scale); 82 | [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:true]; 83 | UIImage * image = UIGraphicsGetImageFromCurrentImageContext(); 84 | UIGraphicsEndImageContext(); 85 | 86 | return image; 87 | } 88 | 89 | + (NSMutableAttributedString *)exampleAttributeString:(NSString *)messageText { 90 | 91 | NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:messageText]; 92 | [attributedString addAttribute:NSFontAttributeName value:[UIFont boldSystemFontOfSize:21.0] range:NSMakeRange(0, messageText.length)]; 93 | [attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor colorWithRed:0.230 green:0.777 blue:0.316 alpha:1.000] range:NSMakeRange(0, messageText.length)]; 94 | return attributedString;} 95 | 96 | - (void)awakeFromNib { 97 | [super awakeFromNib]; 98 | 99 | // Gesture recognizer for dragging 100 | [self addGestureRecognizer]; 101 | 102 | // Create engine 103 | self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self]; 104 | 105 | // Default initialization 106 | [self defaultSetup]; 107 | } 108 | 109 | - (void)drawRect:(CGRect)rect { 110 | [super drawRect:rect]; 111 | 112 | // Blur 113 | [self showBlurView:true]; 114 | 115 | // Show animation 116 | [self dropToCenter]; 117 | 118 | // Cancel arror 119 | [self showCancelArrow:true]; 120 | 121 | // Layout if needed 122 | self.photo = _photo; 123 | } 124 | 125 | - (void)defaultSetup { 126 | self.cornerRadius = 5.0; 127 | self.dialogBackgroundColor = [UIColor whiteColor]; 128 | self.draggable = true; 129 | self.backgroundShadowOpacity = 0.3; 130 | self.hideCloseButton = false; 131 | self.cancelArrowText = [[NSMutableAttributedString alloc] initWithString:@"取消"]; 132 | self.firstBtnText = [@"接受" uppercaseString]; 133 | self.firstBtnTextColor = [UIColor whiteColor]; 134 | self.secondBtnText = [@"取消" uppercaseString]; 135 | self.showSecondBtn = false; 136 | self.secondBtnTextColor = [UIColor whiteColor]; 137 | self.contentViewType = SFContentViewTypeDefault; 138 | self.customView.hidden = true; 139 | self.defaultView.hidden = false; 140 | 141 | self.size = CGSizeMake(270.0, 350.0); 142 | 143 | // Cancel arrow button resizing 144 | [self.cancelArrowBtnBottom.titleLabel setAdjustsFontSizeToFitWidth:true]; 145 | [self.cancelArrowBtnBottom.titleLabel setLineBreakMode:NSLineBreakByClipping]; 146 | 147 | // Initial close button image 148 | NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"SFDraggableDialogView" ofType:@"bundle"]; 149 | [_closeBtn setImage:[UIImage imageWithContentsOfFile:[[NSBundle bundleWithPath:bundlePath] pathForResource:@"icCross" ofType:@"png"]] forState:UIControlStateNormal]; 150 | } 151 | 152 | - (void)dealloc { 153 | [self.dialogView removeGestureRecognizer:self.gestureRecognizer]; 154 | } 155 | 156 | - (void)showCancelArrow:(bool)show { 157 | __weak typeof(self)weakSelf = self; 158 | if (show) { 159 | [UIView animateWithDuration:0.2 animations:^{ 160 | [weakSelf cancelViewAlpha:1.0]; 161 | }]; 162 | 163 | } else { 164 | [UIView animateWithDuration:0.2 animations:^{ 165 | [weakSelf cancelViewAlpha:0.0]; 166 | }]; 167 | } 168 | } 169 | 170 | - (void)cancelViewAlpha:(CGFloat)alpha { 171 | _cancelArrowImageViewTop.alpha = alpha; 172 | _cancelViewBottom.alpha = alpha; 173 | } 174 | 175 | - (void)dismissWithDrop:(bool)drop { 176 | [self dismissWithDrop:drop completion:nil]; 177 | } 178 | 179 | - (void)dismissWithDrop:(bool)drop completion:(void (^)())completion { 180 | if (drop) { 181 | [self dropDown]; 182 | } 183 | 184 | [self showCancelArrow:false]; 185 | [self showBlurView:false]; 186 | 187 | __weak typeof(self)weakSelf = self; 188 | [UIView animateWithDuration:0.15 delay:0.45 options:UIViewAnimationOptionCurveEaseInOut animations:^{ 189 | weakSelf.alpha = 0.0; 190 | 191 | } completion:^(BOOL finished) { 192 | [weakSelf removeFromSuperview]; 193 | }]; 194 | 195 | if ([weakSelf.delegate respondsToSelector:@selector(draggableDialogViewWillDismiss:)]) { 196 | [weakSelf.delegate draggableDialogViewWillDismiss:weakSelf]; 197 | } 198 | 199 | dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC); 200 | dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 201 | if ([weakSelf.delegate respondsToSelector:@selector(draggableDialogViewDismissed:)]) { 202 | [weakSelf.delegate draggableDialogViewDismissed:self]; 203 | } 204 | 205 | completion ? completion() : nil; 206 | }); 207 | } 208 | 209 | - (void)showBlurView:(bool)show { 210 | if (show) { 211 | [UIView animateWithDuration:0.1 animations:^{ 212 | self.backgroundImageBtn.alpha = 1.0; 213 | }]; 214 | 215 | } else { 216 | [UIView animateWithDuration:0.4 animations:^{ 217 | self.backgroundImageBtn.alpha = 0.0; 218 | }]; 219 | } 220 | } 221 | 222 | - (void)highlight:(bool)highlight btn:(UIButton *)button { 223 | UIColor *btnDefaultColor = button.backgroundColor; 224 | if ([button isEqual:self.firstBtn]) { 225 | btnDefaultColor = self.firstBtnBackgroundColor; 226 | 227 | } else if ([button isEqual:self.secondBtn]) { 228 | btnDefaultColor = self.secondBtnBackgroundColor; 229 | } 230 | 231 | if (highlight) { 232 | CGFloat r, g, b, a; 233 | if ([btnDefaultColor getRed:&r green:&g blue:&b alpha:&a]) { 234 | button.backgroundColor = [UIColor colorWithRed:MAX(r - 0.05, 0.0) green:MAX(g - 0.05, 0.0) blue:MAX(b - 0.05, 0.0) alpha:a]; 235 | } 236 | 237 | } else { 238 | CGFloat r, g, b, a; 239 | if ([btnDefaultColor getRed:&r green:&g blue:&b alpha:&a]) { 240 | button.backgroundColor = [UIColor colorWithRed:MIN(r + 0.05, 1.0) green:MIN(g + 0.05, 1.0) blue:MIN(b + 0.05, 1.0) alpha:a]; 241 | } 242 | } 243 | } 244 | 245 | #pragma mark - Gesture recognizer and UIDynamics 246 | - (void)addGestureRecognizer { 247 | self.gestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; 248 | [self.shadowView addGestureRecognizer:self.gestureRecognizer]; 249 | } 250 | 251 | - (void)handlePan:(UIPanGestureRecognizer *)gesture { 252 | if (!_draggable) { 253 | return; 254 | } 255 | 256 | [self highlight:false btn:self.firstBtn]; 257 | [self highlight:false btn:self.secondBtn]; 258 | 259 | static UIAttachmentBehavior *attachment; 260 | static CGPoint startCenter; 261 | 262 | // Variables for calculating angular velocity 263 | static CFAbsoluteTime lastTime; 264 | static CGFloat lastAngle; 265 | static CGFloat angularVelocity; 266 | 267 | if (gesture.state == UIGestureRecognizerStateBegan) { 268 | 269 | if ([self.delegate respondsToSelector:@selector(draggingDidBegin:)]) { 270 | [self.delegate draggingDidBegin:self]; 271 | } 272 | 273 | [self showCancelArrow:false]; 274 | 275 | // UIDynamics handle 276 | [self.animator removeAllBehaviors]; 277 | 278 | startCenter = gesture.view.center; 279 | 280 | // Calculate the center offset and anchor point 281 | CGPoint pointWithinAnimatedView = [gesture locationInView:gesture.view]; 282 | UIOffset offset = UIOffsetMake(pointWithinAnimatedView.x - gesture.view.bounds.size.width / 2.0, pointWithinAnimatedView.y - gesture.view.bounds.size.height / 2.0); 283 | CGPoint anchor = [gesture locationInView:gesture.view.superview]; 284 | 285 | // Create attachment behavior 286 | attachment = [[UIAttachmentBehavior alloc] initWithItem:gesture.view offsetFromCenter:offset attachedToAnchor:anchor]; 287 | 288 | // Code to calculate angular velocity 289 | lastTime = CFAbsoluteTimeGetCurrent(); 290 | lastAngle = [self angleOfView:gesture.view]; 291 | typeof(self) __weak weakSelf = self; 292 | 293 | attachment.action = ^{ 294 | CFAbsoluteTime time = CFAbsoluteTimeGetCurrent(); 295 | CGFloat angle = [weakSelf angleOfView:gesture.view]; 296 | if (time > lastTime) { 297 | angularVelocity = (angle - lastAngle) / (time - lastTime); 298 | lastTime = time; 299 | lastAngle = angle; 300 | } 301 | }; 302 | 303 | // Add attachment behavior 304 | [self.animator addBehavior:attachment]; 305 | 306 | } else if (gesture.state == UIGestureRecognizerStateChanged) { 307 | // As user makes gesture, update attachment behavior's anchor point, achieving drag and rotate 308 | CGPoint anchor = [gesture locationInView:gesture.view.superview]; 309 | attachment.anchorPoint = anchor; 310 | 311 | } else if (gesture.state == UIGestureRecognizerStateEnded || gesture.state == UIGestureRecognizerStateCancelled) { 312 | 313 | if ([self.delegate respondsToSelector:@selector(draggingDidEnd:)]) { 314 | [self.delegate draggingDidEnd:self]; 315 | } 316 | 317 | // UIDynamics handle 318 | [self.animator removeAllBehaviors]; 319 | 320 | CGPoint velocity = [gesture velocityInView:gesture.view.superview]; 321 | 322 | // If we aren't dragging it allowed way, just snap it back and quit 323 | if (!_cancelArrowText || _cancelArrowText.length == 0) { 324 | [self showCancelArrow:true]; 325 | UISnapBehavior *snap = [[UISnapBehavior alloc] initWithItem:gesture.view snapToPoint:startCenter]; 326 | [self.animator addBehavior:snap]; 327 | return; 328 | 329 | } 330 | 331 | if ([self calculateDirectionFromVelocity:velocity] != 0 && [self calculateDirectionFromVelocity:velocity] != 1) { 332 | [self showCancelArrow:true]; 333 | UISnapBehavior *snap = [[UISnapBehavior alloc] initWithItem:gesture.view snapToPoint:startCenter]; 334 | [self.animator addBehavior:snap]; 335 | return; 336 | } 337 | 338 | // Start dismissing 339 | self.shadowView.userInteractionEnabled = false; 340 | [self dismissWithDrop:false]; 341 | 342 | // Otherwise, create UIDynamicItemBehavior that carries on animation from where the gesture left off (notably linear and angular velocity) 343 | UIDynamicItemBehavior *dynamic = [[UIDynamicItemBehavior alloc] initWithItems:@[gesture.view]]; 344 | [dynamic addLinearVelocity:velocity forItem:gesture.view]; 345 | [dynamic addAngularVelocity:angularVelocity forItem:gesture.view]; 346 | [dynamic setAngularResistance:1.25]; 347 | 348 | // When the view no longer intersects with its superview, go ahead and remove it 349 | typeof(self) __weak weakSelf = self; 350 | 351 | dynamic.action = ^{ 352 | if (!CGRectIntersectsRect(gesture.view.superview.bounds, gesture.view.frame)) { 353 | [weakSelf.animator removeAllBehaviors]; 354 | [gesture.view removeFromSuperview]; 355 | } 356 | }; 357 | [self.animator addBehavior:dynamic]; 358 | 359 | // Add a little gravity so it accelerates off the screen (in case user gesture was slow) 360 | UIGravityBehavior *gravity = [[UIGravityBehavior alloc] initWithItems:@[gesture.view]]; 361 | 362 | gravity.magnitude = 1.0; 363 | // Push it down with vertical gravity 364 | // gravity.gravityDirection = CGVectorMake(0.0, 20.0); 365 | [self.animator addBehavior:gravity]; 366 | 367 | // Slower throw 368 | UIDynamicItemBehavior *dynamicItemBehavior = [[UIDynamicItemBehavior alloc] initWithItems:@[self.shadowView]]; 369 | dynamicItemBehavior.resistance = 2; 370 | [self.animator addBehavior:dynamicItemBehavior]; 371 | } 372 | } 373 | 374 | - (CGFloat)angleOfView:(UIView *)view { 375 | return atan2(view.transform.b, view.transform.a); 376 | } 377 | 378 | - (SFPanDirection)calculateDirectionFromVelocity:(CGPoint)velocity { 379 | CGFloat arctangent = atan2(velocity.y, velocity.x) - M_PI_2; 380 | CGFloat absoluteValue = fabs(arctangent); 381 | 382 | if (absoluteValue <= M_PI_4) { 383 | return SFPanDirectionBottom; 384 | 385 | } else if (absoluteValue <= (M_PI + M_PI_4) && absoluteValue > (M_PI_2 + M_PI_4)) { 386 | return SFPanDirectionTop; 387 | 388 | } else { 389 | return SFPanDirectionOthers; 390 | } 391 | } 392 | 393 | #pragma mark - Animations 394 | - (void)dropToCenter { 395 | if (!self.shadowView) { 396 | return; 397 | } 398 | 399 | // Starts at the top 400 | self.dialogViewBottomCns.constant = self.frame.size.height; 401 | [self layoutIfNeeded]; 402 | 403 | self.shadowView.transform = CGAffineTransformMakeScale(1.1, 1.1); 404 | [UIView animateWithDuration:0.75 delay:0.0 usingSpringWithDamping:0.5 initialSpringVelocity:1.0 options:UIViewAnimationOptionCurveEaseOut animations:^{ 405 | self.shadowView.transform = CGAffineTransformMakeScale(1.0, 1.0); 406 | } completion:nil]; 407 | 408 | [self.animator removeAllBehaviors]; 409 | UISnapBehavior *snapBehaviour = [[UISnapBehavior alloc] initWithItem:self.shadowView snapToPoint:self.superview.center]; 410 | snapBehaviour.damping = 0.65; 411 | [self.animator addBehavior:snapBehaviour]; 412 | } 413 | 414 | - (void)dropDown { 415 | if (!self.shadowView) { 416 | return; 417 | } 418 | 419 | [self.animator removeAllBehaviors]; 420 | CGFloat offsetY = 300.0; 421 | UISnapBehavior *snapBehaviour = [[UISnapBehavior alloc] initWithItem:self.shadowView snapToPoint:CGPointMake(self.superview.center.x, self.superview.frame.size.height + (self.shadowView.frame.size.height / 2.0) + offsetY)]; 422 | [self.animator addBehavior:snapBehaviour]; 423 | 424 | UIDynamicItemBehavior *dynamicItemBehavior = [[UIDynamicItemBehavior alloc] initWithItems:@[self.shadowView]]; 425 | dynamicItemBehavior.resistance = 100000; 426 | [self.animator addBehavior:dynamicItemBehavior]; 427 | } 428 | 429 | #pragma mark - Setters 430 | - (void)setSize:(CGSize)size { 431 | _size = size; 432 | self.dialogViewWidthCns.constant = size.width; 433 | self.dialogViewHeightCns.constant = size.height; 434 | } 435 | 436 | - (void)setCloseBtnImage:(UIImage *)closeBtnImage { 437 | _closeBtnImage = closeBtnImage; 438 | [_closeBtn setImage:closeBtnImage forState:UIControlStateNormal]; 439 | } 440 | 441 | - (void)setCornerRadius:(CGFloat)cornerRadius { 442 | _cornerRadius = cornerRadius; 443 | self.dialogView.layer.cornerRadius = _cornerRadius; 444 | self.dialogView.layer.masksToBounds = true; 445 | } 446 | 447 | - (void)setDialogBackgroundColor:(UIColor *)dialogBackgroundColor { 448 | _dialogBackgroundColor = dialogBackgroundColor; 449 | self.dialogView.backgroundColor = dialogBackgroundColor; 450 | } 451 | 452 | - (void)setPhoto:(UIImage *)photo { 453 | _photo = photo; 454 | self.photoImageView.image = photo; 455 | self.photoImageView.layer.cornerRadius = self.photoImageView.frame.size.width / 2.0; 456 | self.photoImageView.layer.masksToBounds = true; 457 | } 458 | 459 | - (void)setTitleText:(NSMutableAttributedString *)titleText { 460 | _titleText = titleText; 461 | _titleLbl.attributedText = titleText; 462 | } 463 | 464 | - (void)setMessageText:(NSMutableAttributedString *)messageText { 465 | _messageText = messageText; 466 | _messageLbl.attributedText = messageText; 467 | } 468 | 469 | - (void)setHideCloseButton:(bool)hideCloseButton { 470 | _hideCloseButton = hideCloseButton; 471 | self.closeBtn.hidden = hideCloseButton; 472 | } 473 | 474 | - (void)setBackgroundShadowOpacity:(CGFloat)backgroundShadowOpacity { 475 | _backgroundShadowOpacity = backgroundShadowOpacity; 476 | 477 | self.shadowView.layer.shadowColor = [[UIColor blackColor] CGColor]; 478 | self.shadowView.layer.shadowOpacity = _backgroundShadowOpacity; 479 | self.shadowView.layer.shadowRadius = 10.0; 480 | self.shadowView.layer.shadowOffset = CGSizeZero; 481 | self.shadowView.layer.shouldRasterize = true; 482 | self.shadowView.layer.rasterizationScale = [UIScreen mainScreen].scale; 483 | } 484 | 485 | - (void)setFirstBtnText:(NSString *)firstBtnText { 486 | _firstBtnText = firstBtnText; 487 | [self.firstBtn setTitle:_firstBtnText forState:UIControlStateNormal]; 488 | } 489 | 490 | - (void)setFirstBtnTextColor:(UIColor *)firstBtnTextColor { 491 | _firstBtnTextColor = firstBtnTextColor; 492 | [self.firstBtn setTitleColor:_firstBtnTextColor forState:UIControlStateNormal]; 493 | } 494 | 495 | - (void)setFirstBtnFont:(UIFont *)firstBtnFont { 496 | _firstBtnFont = firstBtnFont; 497 | self.firstBtn.titleLabel.font = _firstBtnFont; 498 | } 499 | 500 | - (void)setFirstBtnBackgroundColor:(UIColor *)firstBtnBackgroundColor { 501 | _firstBtnBackgroundColor = firstBtnBackgroundColor; 502 | self.firstBtn.backgroundColor = _firstBtnBackgroundColor; 503 | } 504 | 505 | - (void)setSecondBtnText:(NSString *)secondBtnText { 506 | _secondBtnText = secondBtnText; 507 | [self.secondBtn setTitle:_secondBtnText forState:UIControlStateNormal]; 508 | } 509 | 510 | - (void)setSecondBtnBackgroundColor:(UIColor *)secondBtnBackgroundColor { 511 | _secondBtnBackgroundColor = secondBtnBackgroundColor; 512 | self.secondBtn.backgroundColor = _secondBtnBackgroundColor; 513 | } 514 | 515 | - (void)setSecondBtnFont:(UIFont *)secondBtnFont { 516 | _secondBtnFont = secondBtnFont; 517 | self.secondBtn.titleLabel.font = _secondBtnFont; 518 | } 519 | 520 | - (void)setSecondBtnTextColor:(UIColor *)secondBtnTextColor { 521 | _secondBtnTextColor = secondBtnTextColor; 522 | [self.secondBtn setTitleColor:_secondBtnTextColor forState:UIControlStateNormal]; 523 | } 524 | 525 | - (void)setContentViewType:(SFContentViewType)contentViewType { 526 | _contentViewType = contentViewType; 527 | if (_contentViewType == SFContentViewTypeCustom) { 528 | self.defaultView.hidden = true; 529 | self.customView.hidden = false; 530 | 531 | } else { 532 | self.defaultView.hidden = false; 533 | self.customView.hidden = true; 534 | } 535 | } 536 | 537 | - (void)setCancelArrowText:(NSMutableAttributedString *)cancelArrowText { 538 | _cancelArrowText = cancelArrowText; 539 | 540 | if (!cancelArrowText || cancelArrowText.length == 0) { 541 | _cancelArrowImageViewTop.hidden = true; 542 | _cancelViewBottom.hidden = true; 543 | 544 | } else { 545 | NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"SFDraggableDialogView" ofType:@"bundle"]; 546 | _cancelArrowImageViewTop.image = [UIImage imageWithContentsOfFile:[[NSBundle bundleWithPath:bundlePath] pathForResource:@"icArrowTop" ofType:@"png"]]; 547 | _cancelArrowImageViewBottom.image = [UIImage imageWithContentsOfFile:[[NSBundle bundleWithPath:bundlePath] pathForResource:@"icArrow" ofType:@"png"]]; 548 | _cancelArrowImageViewTop.hidden = false; 549 | _cancelViewBottom.hidden = false; 550 | 551 | [self cancelViewAlpha:1.0]; 552 | 553 | // Do not let system UIButton's title flicker 554 | [UIView setAnimationsEnabled:false]; 555 | [_cancelArrowBtnBottom layoutIfNeeded]; 556 | [_cancelArrowBtnBottom setAttributedTitle:_cancelArrowText forState:UIControlStateNormal]; 557 | [UIView setAnimationsEnabled:true]; 558 | } 559 | } 560 | 561 | - (void)setCancelArrowImage:(UIImage *)cancelArrowImage { 562 | _cancelArrowImage = cancelArrowImage; 563 | _cancelArrowImageViewBottom.image = _cancelArrowImage; 564 | _cancelArrowImageViewTop.image = _cancelArrowImage; 565 | } 566 | 567 | - (void)createBlurBackgroundWithImage:(UIImage *)backgroundImage tintColor:(UIColor *)tintColor blurRadius:(CGFloat)blurRadius { 568 | [self.backgroundImageBtn setImage:[backgroundImage applyBlurWithRadius:blurRadius tintColor:tintColor saturationDeltaFactor:0.5 maskImage:nil] forState:UIControlStateNormal]; 569 | } 570 | 571 | - (void)setShowSecondBtn:(bool)showSecondBtn { 572 | _showSecondBtn = showSecondBtn; 573 | 574 | if (showSecondBtn) { 575 | self.infoCustomViewViewVerticalOffsetCns.constant = self.firstBtn.frame.size.height; 576 | self.gameOverCustomViewVerticalOffsetCns.constant = self.firstBtn.frame.size.height; 577 | self.pauseCustomViewVerticalOffsetCns.constant = self.firstBtn.frame.size.height; 578 | self.defaultViewVerticalOffsetCns.constant = self.firstBtn.frame.size.height; 579 | self.secondBtn.hidden = false; 580 | 581 | } else { 582 | self.infoCustomViewViewVerticalOffsetCns.constant = 0.0; 583 | self.gameOverCustomViewVerticalOffsetCns.constant = 0.0; 584 | self.pauseCustomViewVerticalOffsetCns.constant = 0.0; 585 | self.defaultViewVerticalOffsetCns.constant = 0.0; 586 | self.secondBtn.hidden = true; 587 | } 588 | 589 | [self layoutIfNeeded]; 590 | } 591 | 592 | #pragma mark - Actions 593 | - (IBAction)firstBtnPressed:(id)sender { 594 | [self highlight:false btn:self.firstBtn]; 595 | if ([self.delegate respondsToSelector:@selector(draggableDialogView:didPressFirstButton:)]) { 596 | [self.delegate draggableDialogView:self didPressFirstButton:self.firstBtn]; 597 | } 598 | } 599 | 600 | - (IBAction)secondBtnPressed:(id)sender { 601 | [self highlight:false btn:self.secondBtn]; 602 | if ([self.delegate respondsToSelector:@selector(draggableDialogView:didPressSecondButton:)]) { 603 | [self.delegate draggableDialogView:self didPressSecondButton:self.secondBtn]; 604 | } 605 | } 606 | 607 | - (IBAction)closeBtnPressed:(id)sender { 608 | [self showCancelArrow:false]; 609 | [self dismissWithDrop:true]; 610 | } 611 | 612 | - (IBAction)backgroundImageBtnPressed:(id)sender { 613 | [self dismissWithDrop:true]; 614 | } 615 | 616 | - (IBAction)firstBtnTouchDownEvent:(id)sender { 617 | [self highlight:true btn:self.firstBtn]; 618 | } 619 | 620 | - (IBAction)secondBtnTouchDownEvent:(id)sender { 621 | [self highlight:true btn:self.secondBtn]; 622 | } 623 | 624 | - (IBAction)arrowBtnPressed:(id)sender { 625 | [self dismissWithDrop:true]; 626 | } 627 | 628 | - (IBAction)arrowBtnTouchDown:(id)sender { 629 | self.cancelArrowImageViewBottom.alpha = 0.2; 630 | self.cancelArrowImageViewTop.alpha = 0.2; 631 | } 632 | 633 | - (IBAction)arrowBtnTouchCanceled:(id)sender { 634 | __weak typeof(self)weakSelf = self; 635 | [UIView animateWithDuration:0.2 animations:^{ 636 | weakSelf.cancelArrowImageViewBottom.alpha = 1.0; 637 | weakSelf.cancelArrowImageViewTop.alpha = 1.0; 638 | }]; 639 | } 640 | 641 | - (IBAction)arrowBtnTouchDragInside:(id)sender { 642 | __weak typeof(self)weakSelf = self; 643 | [UIView animateWithDuration:0.2 animations:^{ 644 | weakSelf.cancelArrowImageViewBottom.alpha = 0.2; 645 | weakSelf.cancelArrowImageViewTop.alpha = 0.2; 646 | }]; 647 | } 648 | 649 | - (IBAction)arrowBtnTouchDragOutside:(id)sender { 650 | __weak typeof(self)weakSelf = self; 651 | [UIView animateWithDuration:0.2 animations:^{ 652 | weakSelf.cancelArrowImageViewBottom.alpha = 1.0; 653 | weakSelf.cancelArrowImageViewTop.alpha = 1.0; 654 | }]; 655 | } 656 | 657 | @end -------------------------------------------------------------------------------- /GoBangGraduationProject/Lib/SFDraggableDialogView/UIImage+ImageEffects.h: -------------------------------------------------------------------------------- 1 | /* 2 | File: UIImage+ImageEffects.h 3 | Abstract: This is a category of UIImage that adds methods to apply blur and tint effects to an image. This is the code you’ll want to look out to find out how to use vImage to efficiently calculate a blur. 4 | Version: 1.0 5 | 6 | Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple 7 | Inc. ("Apple") in consideration of your agreement to the following 8 | terms, and your use, installation, modification or redistribution of 9 | this Apple software constitutes acceptance of these terms. If you do 10 | not agree with these terms, please do not use, install, modify or 11 | redistribute this Apple software. 12 | 13 | In consideration of your agreement to abide by the following terms, and 14 | subject to these terms, Apple grants you a personal, non-exclusive 15 | license, under Apple's copyrights in this original Apple software (the 16 | "Apple Software"), to use, reproduce, modify and redistribute the Apple 17 | Software, with or without modifications, in source and/or binary forms; 18 | provided that if you redistribute the Apple Software in its entirety and 19 | without modifications, you must retain this notice and the following 20 | text and disclaimers in all such redistributions of the Apple Software. 21 | Neither the name, trademarks, service marks or logos of Apple Inc. may 22 | be used to endorse or promote products derived from the Apple Software 23 | without specific prior written permission from Apple. Except as 24 | expressly stated in this notice, no other rights or licenses, express or 25 | implied, are granted by Apple herein, including but not limited to any 26 | patent rights that may be infringed by your derivative works or by other 27 | works in which the Apple Software may be incorporated. 28 | 29 | The Apple Software is provided by Apple on an "AS IS" basis. APPLE 30 | MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 31 | THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 32 | FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 33 | OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 34 | 35 | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 36 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 37 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 38 | INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 39 | MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 40 | AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 41 | STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 42 | POSSIBILITY OF SUCH DAMAGE. 43 | 44 | Copyright (C) 2013 Apple Inc. All Rights Reserved. 45 | 46 | 47 | Copyright © 2013 Apple Inc. All rights reserved. 48 | WWDC 2013 License 49 | 50 | NOTE: This Apple Software was supplied by Apple as part of a WWDC 2013 51 | Session. Please refer to the applicable WWDC 2013 Session for further 52 | information. 53 | 54 | IMPORTANT: This Apple software is supplied to you by Apple Inc. 55 | ("Apple") in consideration of your agreement to the following terms, and 56 | your use, installation, modification or redistribution of this Apple 57 | software constitutes acceptance of these terms. If you do not agree with 58 | these terms, please do not use, install, modify or redistribute this 59 | Apple software. 60 | 61 | In consideration of your agreement to abide by the following terms, and 62 | subject to these terms, Apple grants you a non-exclusive license, under 63 | Apple's copyrights in this original Apple software (the "Apple 64 | Software"), to use, reproduce, modify and redistribute the Apple 65 | Software, with or without modifications, in source and/or binary forms; 66 | provided that if you redistribute the Apple Software in its entirety and 67 | without modifications, you must retain this notice and the following 68 | text and disclaimers in all such redistributions of the Apple Software. 69 | Neither the name, trademarks, service marks or logos of Apple Inc. may 70 | be used to endorse or promote products derived from the Apple Software 71 | without specific prior written permission from Apple. Except as 72 | expressly stated in this notice, no other rights or licenses, express or 73 | implied, are granted by Apple herein, including but not limited to any 74 | patent rights that may be infringed by your derivative works or by other 75 | works in which the Apple Software may be incorporated. 76 | 77 | The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES 78 | NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE 79 | IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR 80 | A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 81 | OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 82 | 83 | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 84 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 85 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 86 | INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 87 | MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 88 | AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 89 | STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 90 | POSSIBILITY OF SUCH DAMAGE. 91 | 92 | EA1002 93 | 5/3/2013 94 | */ 95 | 96 | @import UIKit; 97 | 98 | @interface UIImage (ImageEffects) 99 | 100 | - (UIImage *)applyLightEffect; 101 | - (UIImage *)applyExtraLightEffect; 102 | - (UIImage *)applyDarkEffect; 103 | - (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor; 104 | - (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage; 105 | 106 | @end 107 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Lib/SFDraggableDialogView/UIImage+ImageEffects.m: -------------------------------------------------------------------------------- 1 | /* 2 | File: UIImage+ImageEffects.m 3 | Abstract: This is a category of UIImage that adds methods to apply blur and tint effects to an image. This is the code you’ll want to look out to find out how to use vImage to efficiently calculate a blur. 4 | Version: 1.0 5 | 6 | Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple 7 | Inc. ("Apple") in consideration of your agreement to the following 8 | terms, and your use, installation, modification or redistribution of 9 | this Apple software constitutes acceptance of these terms. If you do 10 | not agree with these terms, please do not use, install, modify or 11 | redistribute this Apple software. 12 | 13 | In consideration of your agreement to abide by the following terms, and 14 | subject to these terms, Apple grants you a personal, non-exclusive 15 | license, under Apple's copyrights in this original Apple software (the 16 | "Apple Software"), to use, reproduce, modify and redistribute the Apple 17 | Software, with or without modifications, in source and/or binary forms; 18 | provided that if you redistribute the Apple Software in its entirety and 19 | without modifications, you must retain this notice and the following 20 | text and disclaimers in all such redistributions of the Apple Software. 21 | Neither the name, trademarks, service marks or logos of Apple Inc. may 22 | be used to endorse or promote products derived from the Apple Software 23 | without specific prior written permission from Apple. Except as 24 | expressly stated in this notice, no other rights or licenses, express or 25 | implied, are granted by Apple herein, including but not limited to any 26 | patent rights that may be infringed by your derivative works or by other 27 | works in which the Apple Software may be incorporated. 28 | 29 | The Apple Software is provided by Apple on an "AS IS" basis. APPLE 30 | MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 31 | THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 32 | FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 33 | OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 34 | 35 | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 36 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 37 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 38 | INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 39 | MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 40 | AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 41 | STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 42 | POSSIBILITY OF SUCH DAMAGE. 43 | 44 | Copyright (C) 2013 Apple Inc. All Rights Reserved. 45 | 46 | 47 | Copyright © 2013 Apple Inc. All rights reserved. 48 | WWDC 2013 License 49 | 50 | NOTE: This Apple Software was supplied by Apple as part of a WWDC 2013 51 | Session. Please refer to the applicable WWDC 2013 Session for further 52 | information. 53 | 54 | IMPORTANT: This Apple software is supplied to you by Apple Inc. 55 | ("Apple") in consideration of your agreement to the following terms, and 56 | your use, installation, modification or redistribution of this Apple 57 | software constitutes acceptance of these terms. If you do not agree with 58 | these terms, please do not use, install, modify or redistribute this 59 | Apple software. 60 | 61 | In consideration of your agreement to abide by the following terms, and 62 | subject to these terms, Apple grants you a non-exclusive license, under 63 | Apple's copyrights in this original Apple software (the "Apple 64 | Software"), to use, reproduce, modify and redistribute the Apple 65 | Software, with or without modifications, in source and/or binary forms; 66 | provided that if you redistribute the Apple Software in its entirety and 67 | without modifications, you must retain this notice and the following 68 | text and disclaimers in all such redistributions of the Apple Software. 69 | Neither the name, trademarks, service marks or logos of Apple Inc. may 70 | be used to endorse or promote products derived from the Apple Software 71 | without specific prior written permission from Apple. Except as 72 | expressly stated in this notice, no other rights or licenses, express or 73 | implied, are granted by Apple herein, including but not limited to any 74 | patent rights that may be infringed by your derivative works or by other 75 | works in which the Apple Software may be incorporated. 76 | 77 | The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES 78 | NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE 79 | IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR 80 | A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 81 | OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 82 | 83 | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 84 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 85 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 86 | INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 87 | MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 88 | AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 89 | STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 90 | POSSIBILITY OF SUCH DAMAGE. 91 | 92 | EA1002 93 | 5/3/2013 94 | */ 95 | 96 | #import "UIImage+ImageEffects.h" 97 | 98 | @import Accelerate; 99 | #import 100 | 101 | 102 | @implementation UIImage (ImageEffects) 103 | 104 | 105 | - (UIImage *)applyLightEffect 106 | { 107 | UIColor *tintColor = [UIColor colorWithWhite:1.0 alpha:0.3]; 108 | return [self applyBlurWithRadius:30 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil]; 109 | } 110 | 111 | 112 | - (UIImage *)applyExtraLightEffect 113 | { 114 | UIColor *tintColor = [UIColor colorWithWhite:0.97 alpha:0.82]; 115 | return [self applyBlurWithRadius:20 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil]; 116 | } 117 | 118 | 119 | - (UIImage *)applyDarkEffect 120 | { 121 | UIColor *tintColor = [UIColor colorWithWhite:0.11 alpha:0.73]; 122 | return [self applyBlurWithRadius:20 tintColor:tintColor saturationDeltaFactor:1.8 maskImage:nil]; 123 | } 124 | 125 | 126 | - (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor 127 | { 128 | const CGFloat EffectColorAlpha = 0.6; 129 | UIColor *effectColor = tintColor; 130 | long componentCount = CGColorGetNumberOfComponents(tintColor.CGColor); 131 | if (componentCount == 2) { 132 | CGFloat b; 133 | if ([tintColor getWhite:&b alpha:NULL]) { 134 | effectColor = [UIColor colorWithWhite:b alpha:EffectColorAlpha]; 135 | } 136 | } 137 | else { 138 | CGFloat r, g, b; 139 | if ([tintColor getRed:&r green:&g blue:&b alpha:NULL]) { 140 | effectColor = [UIColor colorWithRed:r green:g blue:b alpha:EffectColorAlpha]; 141 | } 142 | } 143 | return [self applyBlurWithRadius:10 tintColor:effectColor saturationDeltaFactor:-1.0 maskImage:nil]; 144 | } 145 | 146 | 147 | - (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage 148 | { 149 | // Check pre-conditions. 150 | if (self.size.width < 1 || self.size.height < 1) { 151 | NSLog (@"*** error: invalid size: (%.2f x %.2f). Both dimensions must be >= 1: %@", self.size.width, self.size.height, self); 152 | return nil; 153 | } 154 | if (!self.CGImage) { 155 | NSLog (@"*** error: image must be backed by a CGImage: %@", self); 156 | return nil; 157 | } 158 | if (maskImage && !maskImage.CGImage) { 159 | NSLog (@"*** error: maskImage must be backed by a CGImage: %@", maskImage); 160 | return nil; 161 | } 162 | 163 | CGRect imageRect = { CGPointZero, self.size }; 164 | UIImage *effectImage = self; 165 | 166 | BOOL hasBlur = blurRadius > __FLT_EPSILON__; 167 | BOOL hasSaturationChange = fabs(saturationDeltaFactor - 1.) > __FLT_EPSILON__; 168 | if (hasBlur || hasSaturationChange) { 169 | UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]); 170 | CGContextRef effectInContext = UIGraphicsGetCurrentContext(); 171 | CGContextScaleCTM(effectInContext, 1.0, -1.0); 172 | CGContextTranslateCTM(effectInContext, 0, -self.size.height); 173 | CGContextDrawImage(effectInContext, imageRect, self.CGImage); 174 | 175 | vImage_Buffer effectInBuffer; 176 | effectInBuffer.data = CGBitmapContextGetData(effectInContext); 177 | effectInBuffer.width = CGBitmapContextGetWidth(effectInContext); 178 | effectInBuffer.height = CGBitmapContextGetHeight(effectInContext); 179 | effectInBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectInContext); 180 | 181 | UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]); 182 | CGContextRef effectOutContext = UIGraphicsGetCurrentContext(); 183 | vImage_Buffer effectOutBuffer; 184 | effectOutBuffer.data = CGBitmapContextGetData(effectOutContext); 185 | effectOutBuffer.width = CGBitmapContextGetWidth(effectOutContext); 186 | effectOutBuffer.height = CGBitmapContextGetHeight(effectOutContext); 187 | effectOutBuffer.rowBytes = CGBitmapContextGetBytesPerRow(effectOutContext); 188 | 189 | if (hasBlur) { 190 | // A description of how to compute the box kernel width from the Gaussian 191 | // radius (aka standard deviation) appears in the SVG spec: 192 | // http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement 193 | // 194 | // For larger values of 's' (s >= 2.0), an approximation can be used: Three 195 | // successive box-blurs build a piece-wise quadratic convolution kernel, which 196 | // approximates the Gaussian kernel to within roughly 3%. 197 | // 198 | // let d = floor(s * 3*sqrt(2*pi)/4 + 0.5) 199 | // 200 | // ... if d is odd, use three box-blurs of size 'd', centered on the output pixel. 201 | // 202 | CGFloat inputRadius = blurRadius * [[UIScreen mainScreen] scale]; 203 | int radius = (int)floor(inputRadius * 3. * sqrt(2 * M_PI) / 4 + 0.5); 204 | if (radius % 2 != 1) { 205 | radius += 1; // force radius to be odd so that the three box-blur methodology works. 206 | } 207 | vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend); 208 | vImageBoxConvolve_ARGB8888(&effectOutBuffer, &effectInBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend); 209 | vImageBoxConvolve_ARGB8888(&effectInBuffer, &effectOutBuffer, NULL, 0, 0, radius, radius, 0, kvImageEdgeExtend); 210 | } 211 | BOOL effectImageBuffersAreSwapped = NO; 212 | if (hasSaturationChange) { 213 | CGFloat s = saturationDeltaFactor; 214 | CGFloat floatingPointSaturationMatrix[] = { 215 | 0.0722 + 0.9278 * s, 0.0722 - 0.0722 * s, 0.0722 - 0.0722 * s, 0, 216 | 0.7152 - 0.7152 * s, 0.7152 + 0.2848 * s, 0.7152 - 0.7152 * s, 0, 217 | 0.2126 - 0.2126 * s, 0.2126 - 0.2126 * s, 0.2126 + 0.7873 * s, 0, 218 | 0, 0, 0, 1, 219 | }; 220 | const int32_t divisor = 256; 221 | NSUInteger matrixSize = sizeof(floatingPointSaturationMatrix)/sizeof(floatingPointSaturationMatrix[0]); 222 | int16_t saturationMatrix[matrixSize]; 223 | for (NSUInteger i = 0; i < matrixSize; ++i) { 224 | saturationMatrix[i] = (int16_t)roundf(floatingPointSaturationMatrix[i] * divisor); 225 | } 226 | if (hasBlur) { 227 | vImageMatrixMultiply_ARGB8888(&effectOutBuffer, &effectInBuffer, saturationMatrix, divisor, NULL, NULL, kvImageNoFlags); 228 | effectImageBuffersAreSwapped = YES; 229 | } 230 | else { 231 | vImageMatrixMultiply_ARGB8888(&effectInBuffer, &effectOutBuffer, saturationMatrix, divisor, NULL, NULL, kvImageNoFlags); 232 | } 233 | } 234 | if (!effectImageBuffersAreSwapped) 235 | effectImage = UIGraphicsGetImageFromCurrentImageContext(); 236 | UIGraphicsEndImageContext(); 237 | 238 | if (effectImageBuffersAreSwapped) 239 | effectImage = UIGraphicsGetImageFromCurrentImageContext(); 240 | UIGraphicsEndImageContext(); 241 | } 242 | 243 | // Set up output context. 244 | UIGraphicsBeginImageContextWithOptions(self.size, NO, [[UIScreen mainScreen] scale]); 245 | CGContextRef outputContext = UIGraphicsGetCurrentContext(); 246 | CGContextScaleCTM(outputContext, 1.0, -1.0); 247 | CGContextTranslateCTM(outputContext, 0, -self.size.height); 248 | 249 | // Draw base image. 250 | CGContextDrawImage(outputContext, imageRect, self.CGImage); 251 | 252 | // Draw effect image. 253 | if (hasBlur) { 254 | CGContextSaveGState(outputContext); 255 | if (maskImage) { 256 | CGContextClipToMask(outputContext, imageRect, maskImage.CGImage); 257 | } 258 | CGContextDrawImage(outputContext, imageRect, effectImage.CGImage); 259 | CGContextRestoreGState(outputContext); 260 | } 261 | 262 | // Add in color tint. 263 | if (tintColor) { 264 | CGContextSaveGState(outputContext); 265 | CGContextSetFillColorWithColor(outputContext, tintColor.CGColor); 266 | CGContextFillRect(outputContext, imageRect); 267 | CGContextRestoreGState(outputContext); 268 | } 269 | 270 | // Output image is ready. 271 | UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext(); 272 | UIGraphicsEndImageContext(); 273 | 274 | return outputImage; 275 | } 276 | 277 | @end 278 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/5/10. 6 | // Copyright © 2016年 dahua. 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 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/5/10. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "DHLaunchVC.h" 11 | #import "DHNavgationController.h" 12 | 13 | 14 | @interface AppDelegate () 15 | 16 | @end 17 | 18 | @implementation AppDelegate 19 | 20 | 21 | 22 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 23 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 24 | [defaults setBool:YES forKey:IsWhiteSente]; 25 | [defaults setBool:YES forKey:IsSounds]; 26 | [defaults setBool:YES forKey:IsPlayerSente]; 27 | 28 | BOOL isHaveUsed = [defaults boolForKey:IsHaveUsed]; 29 | if (isHaveUsed) { 30 | UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]]; 31 | DHNavgationController *nav = [sb instantiateViewControllerWithIdentifier:@"DHNavgationController"]; 32 | [self.window setRootViewController:nav]; 33 | [self.window makeKeyAndVisible]; 34 | } else { 35 | DHLaunchVC *launch = [[DHLaunchVC alloc] init]; 36 | [self.window setRootViewController:launch]; 37 | [self.window makeKeyAndVisible]; 38 | }; 39 | 40 | return YES; 41 | } 42 | 43 | - (void)applicationWillResignActive:(UIApplication *)application { 44 | // 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. 45 | // 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. 46 | } 47 | 48 | - (void)applicationDidEnterBackground:(UIApplication *)application { 49 | // 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. 50 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 51 | } 52 | 53 | - (void)applicationWillEnterForeground:(UIApplication *)application { 54 | // 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. 55 | } 56 | 57 | - (void)applicationDidBecomeActive:(UIApplication *)application { 58 | // 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. 59 | } 60 | 61 | - (void)applicationWillTerminate:(UIApplication *)application { 62 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 63 | } 64 | 65 | @end 66 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-Spotlight-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-Small@2x.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-Small@3x.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "40x40", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-Spotlight-40@2x.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-Spotlight-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 | "info" : { 53 | "version" : 1, 54 | "author" : "xcode" 55 | } 56 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/AppIcon.appiconset/Icon-20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/AppIcon.appiconset/Icon-20@3x.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/AppIcon.appiconset/Icon-60@2x.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/AppIcon.appiconset/Icon-60@3x.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/AppIcon.appiconset/Icon-Small@2x.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/AppIcon.appiconset/Icon-Small@3x.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-20@2x.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@2x.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/AppIcon.appiconset/Icon-Spotlight-40@3x.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/backMusic.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "backMusic.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/backMusic.imageset/backMusic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/backMusic.imageset/backMusic.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/backNoMusic.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "backNoMusic.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/backNoMusic.imageset/backNoMusic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/backNoMusic.imageset/backNoMusic.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/bk1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "bk1.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/bk1.imageset/bk1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/bk1.imageset/bk1.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/bk2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "bk2.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/bk2.imageset/bk2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/bk2.imageset/bk2.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/bottom.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "bottom.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/bottom.imageset/bottom.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/bottom.imageset/bottom.jpg -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/classicalBG1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "classicalBG1.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/classicalBG1.imageset/classicalBG1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/classicalBG1.imageset/classicalBG1.jpg -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/classicalBG2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "classicalBG2.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/classicalBG2.imageset/classicalBG2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/classicalBG2.imageset/classicalBG2.jpg -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/classicalBG3.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "classicalBG3.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/classicalBG3.imageset/classicalBG3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/classicalBG3.imageset/classicalBG3.jpg -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/gaide/1.imageset/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/gaide/1.imageset/1.jpg -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/gaide/1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "1.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/gaide/10.imageset/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/gaide/10.imageset/10.jpg -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/gaide/10.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "10.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/gaide/2.imageset/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/gaide/2.imageset/2.jpg -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/gaide/2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "2.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/gaide/3.imageset/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/gaide/3.imageset/3.jpg -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/gaide/3.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "3.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/gaide/4.imageset/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/gaide/4.imageset/4.jpg -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/gaide/4.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "4.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/gaide/5.imageset/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/gaide/5.imageset/5.jpg -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/gaide/5.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "5.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/gaide/6.imageset/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/gaide/6.imageset/6.jpg -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/gaide/6.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "6.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/gaide/7.imageset/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/gaide/7.imageset/7.jpg -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/gaide/7.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "7.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/gaide/8.imageset/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/gaide/8.imageset/8.jpg -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/gaide/8.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "8.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/gaide/9.imageset/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/gaide/9.imageset/9.jpg -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/gaide/9.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "9.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/gaide/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/gaide/lappover.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "lappover.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/gaide/lappover.imageset/lappover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/gaide/lappover.imageset/lappover.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/launch/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/launch/Default-Portrait.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Default-Portrait.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Default-Portrait@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/launch/Default-Portrait.imageset/Default-Portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/launch/Default-Portrait.imageset/Default-Portrait.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/launch/Default-Portrait.imageset/Default-Portrait@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/launch/Default-Portrait.imageset/Default-Portrait@2x.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/launch/DefaultLaunchPicture.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Default.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Default@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | }, 17 | { 18 | "idiom" : "universal", 19 | "filename" : "Default-568h@2x.png", 20 | "subtype" : "retina4", 21 | "scale" : "2x" 22 | } 23 | ], 24 | "info" : { 25 | "version" : 1, 26 | "author" : "xcode" 27 | } 28 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/launch/DefaultLaunchPicture.imageset/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/launch/DefaultLaunchPicture.imageset/Default-568h@2x.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/launch/DefaultLaunchPicture.imageset/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/launch/DefaultLaunchPicture.imageset/Default.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/launch/DefaultLaunchPicture.imageset/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/launch/DefaultLaunchPicture.imageset/Default@2x.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/lostPic.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "lostPic.jpg", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/lostPic.imageset/lostPic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/lostPic.imageset/lostPic.jpg -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/playbackground.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "playbackground.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/playbackground.imageset/playbackground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/playbackground.imageset/playbackground.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/stone_black.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "stone_black.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/stone_black.imageset/stone_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/stone_black.imageset/stone_black.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/stone_white.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "stone_white.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/stone_white.imageset/stone_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/stone_white.imageset/stone_white.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/winPic.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "winPic.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/winPic.imageset/winPic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/winPic.imageset/winPic.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/wuziqiIcon-1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "wuziqiIcon.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/wuziqiIcon-1.imageset/wuziqiIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/wuziqiIcon-1.imageset/wuziqiIcon.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/wuziqiIcon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "wuziqiIcon.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Assets.xcassets/wuziqiIcon.imageset/wuziqiIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Main/Assets.xcassets/wuziqiIcon.imageset/wuziqiIcon.png -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/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 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Config.h: -------------------------------------------------------------------------------- 1 | // 2 | // Config.h 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/5/18. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import 10 | typedef NS_ENUM(NSInteger, OccupyType) { 11 | OccupyTypeEmpty = 0, //空 12 | OccupyTypeUser, //用户 13 | OccupyTypeAI, //电脑 14 | OccupyTypeEnemy, //对手 15 | OccupyTypeUnknown, //未知 16 | OccupyTypeWhite, //白旗 17 | OccupyTypeBlack, //黑旗 18 | }; 19 | 20 | typedef NS_ENUM(NSInteger, DirectionType) { 21 | 22 | DirectionTypeTop = 0, 23 | DirectionTypeRightTop, 24 | DirectionTypeRight, 25 | DirectionTypeRightDown, 26 | DirectionTypeDown, 27 | DirectionTypeLeftDown, 28 | DirectionTypeLeft, 29 | DirectionTypeLeftTop, 30 | }; 31 | static NSInteger const DHBoardSize = 15; 32 | static NSString * const ServiceType = @"dh-gobang"; 33 | 34 | /** 35 | * 沙河 36 | */ 37 | #define IsSounds @"isSounds" 38 | #define IsWhiteSente @"isWhiteSente" 39 | #define IsPlayerSente @"isPlayerSente" 40 | #define IsHaveUsed @"isFirstUse" 41 | 42 | /** 43 | * 通知 44 | */ 45 | #define AIWhoWinNotify @"AIWhoWinNotify" 46 | #define PPWhoWinNotify @"PPWhoWinNotify" 47 | 48 | 49 | @interface Config : NSObject 50 | 51 | 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Main/Gobang.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Gobang.pch 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/5/12. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #ifndef Gobang_pch 10 | #define Gobang_pch 11 | 12 | /** 13 | * release不打印 14 | */ 15 | #if (!defined(DEBUG)) 16 | #define NSLog(...) 17 | #endif 18 | 19 | 20 | #define SCREEN_H [UIScreen mainScreen].bounds.size.height 21 | #define SCREEN_W [UIScreen mainScreen].bounds.size.width 22 | #import "Config.h" 23 | 24 | #endif /* Gobang_pch */ 25 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Resource/sound/BgMusic.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Resource/sound/BgMusic.mp3 -------------------------------------------------------------------------------- /GoBangGraduationProject/Resource/sound/au_gameover.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Resource/sound/au_gameover.wav -------------------------------------------------------------------------------- /GoBangGraduationProject/Resource/sound/au_victory.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Resource/sound/au_victory.wav -------------------------------------------------------------------------------- /GoBangGraduationProject/Resource/sound/check.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Resource/sound/check.wav -------------------------------------------------------------------------------- /GoBangGraduationProject/Resource/sound/down.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Resource/sound/down.wav -------------------------------------------------------------------------------- /GoBangGraduationProject/Resource/sound/lost.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Resource/sound/lost.wav -------------------------------------------------------------------------------- /GoBangGraduationProject/Resource/sound/marking.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Resource/sound/marking.wav -------------------------------------------------------------------------------- /GoBangGraduationProject/Resource/sound/mode.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Resource/sound/mode.wav -------------------------------------------------------------------------------- /GoBangGraduationProject/Resource/sound/pipa.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Resource/sound/pipa.mp3 -------------------------------------------------------------------------------- /GoBangGraduationProject/Resource/sound/quikly.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Resource/sound/quikly.wav -------------------------------------------------------------------------------- /GoBangGraduationProject/Resource/sound/regret.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Resource/sound/regret.wav -------------------------------------------------------------------------------- /GoBangGraduationProject/Resource/sound/start.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Resource/sound/start.wav -------------------------------------------------------------------------------- /GoBangGraduationProject/Resource/sound/win.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dadahua/GoBangProject/8e252488da648b97e54571df4ecdc396c011c2bd/GoBangGraduationProject/Resource/sound/win.wav -------------------------------------------------------------------------------- /GoBangGraduationProject/Tool/DHGobangTool.h: -------------------------------------------------------------------------------- 1 | // 2 | // DHGobangTool.h 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/5/30. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "DHPoint.h" 12 | 13 | @interface DHGobangTool : NSObject 14 | 15 | + (BOOL)isVictory:(DHPoint *)point array:(NSArray *)places; 16 | + (OccupyType)getType:(DHPoint *)point array:(NSMutableArray *)places; 17 | + (DHPoint *)getTouchPointWith:(CGPoint)point; 18 | /** 19 | * 根据点和父试图找到相应的棋子。前提:棋子的view是正方形,边长=屏幕宽 20 | */ 21 | + (UIImageView *)foundChessWithPoint:(DHPoint *)point superView:(UIView *)view; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Tool/DHGobangTool.m: -------------------------------------------------------------------------------- 1 | // 2 | // DHGobangTool.m 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/5/30. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import "DHGobangTool.h" 10 | 11 | 12 | @implementation DHGobangTool 13 | 14 | + (BOOL)isVictory:(DHPoint *)point array:(NSArray *)places { 15 | 16 | NSInteger x = point.x; 17 | NSInteger y = point.y; 18 | OccupyType type = [places[x - 1][y - 1] integerValue]; 19 | if (type == OccupyTypeEmpty) return NO; 20 | 21 | // 判断改点是否超出边界 22 | 23 | DHPoint *textLeft = [[DHPoint alloc] initPointWith:point.x y:point.y]; 24 | DHPoint *textRight = [[DHPoint alloc] initPointWith:point.x y:point.y]; 25 | for (int i = 1; point.x - i >= 1 && [places[point.x - i - 1][point.y - 1] integerValue] == type; i ++) { 26 | textLeft = [[DHPoint alloc] initPointWith:point.x - i y:textLeft.y]; 27 | } 28 | for (int i = 1; point.x + i <= DHBoardSize && [places[point.x + i - 1][point.y - 1] integerValue] == type; i ++) { 29 | textRight = [[DHPoint alloc] initPointWith:point.x + i y:textRight.y]; 30 | } 31 | if (textRight.x - textLeft.x >= 4) return YES; 32 | 33 | DHPoint *textTop = [[DHPoint alloc] initPointWith:point.x y:point.y]; 34 | DHPoint *textDown = [[DHPoint alloc] initPointWith:point.x y:point.y]; 35 | for (int i = 1; point.y - i >= 1 && [places[point.x - 1][point.y - i - 1] integerValue] == type; i ++) { 36 | textTop = [[DHPoint alloc] initPointWith:point.x y:point.y - i]; 37 | } 38 | for (int i = 1; point.y + i <= DHBoardSize && [places[point.x - 1][point.y + i - 1] integerValue] == type; i ++) { 39 | textDown = [[DHPoint alloc] initPointWith:point.x y:point.y + i ]; 40 | } 41 | if (textDown.y - textTop.y >= 4) return YES; 42 | 43 | DHPoint *textEN = [[DHPoint alloc] initPointWith:point.x y:point.y]; //东北 44 | DHPoint *textWS = [[DHPoint alloc] initPointWith:point.x y:point.y]; //西南 45 | for (int i = 1; point.y + i <= DHBoardSize && point.x - i > 0 && [places[point.x - i - 1][point.y + i - 1] integerValue] == type; i ++) { 46 | textWS = [[DHPoint alloc] initPointWith:point.x - i y:point.y + i]; 47 | } 48 | for (int i = 1; point.y - i > 0 && point.x + i <= DHBoardSize && [places[point.x + i - 1][point.y - i - 1] integerValue] == type; i ++) { 49 | textEN = [[DHPoint alloc] initPointWith:point.x + i y:point.y - i]; 50 | } 51 | if (textEN.x - textWS.x >= 4 && textWS.y - textEN.y >= 4) return YES; 52 | 53 | DHPoint *textWN = [[DHPoint alloc] initPointWith:point.x y:point.y]; //西北 54 | DHPoint *textES = [[DHPoint alloc] initPointWith:point.x y:point.y]; //东南 55 | for (int i = 1; point.y - i > 0 && point.x - i > 0 && [places[point.x - i - 1][point.y - i - 1] integerValue] == type; i ++) { 56 | textWN = [[DHPoint alloc] initPointWith:point.x - i y:point.y - i]; 57 | } 58 | for (int i = 1; point.y + i <= DHBoardSize && point.x + i <= DHBoardSize && [places[point.x + i - 1][point.y + i - 1] integerValue] == type; i ++) { 59 | textES = [[DHPoint alloc] initPointWith:point.x + i y:point.y + i]; 60 | } 61 | if (textES.x - textWN.x >= 4 && textES.y - textWN.y >= 4) return YES; 62 | return NO; 63 | 64 | } 65 | 66 | /** 67 | * 获取某个点的种类 68 | */ 69 | + (OccupyType)getType:(DHPoint *)point array:(NSMutableArray *)places { 70 | 71 | if (point.x >0 && point.y >0 && point.x <= DHBoardSize && point.y <= DHBoardSize) { 72 | return [places[point.x - 1][point.y - 1] integerValue]; 73 | } 74 | return OccupyTypeEmpty; 75 | } 76 | 77 | + (DHPoint *)getTouchPointWith:(CGPoint)point { 78 | 79 | CGFloat touchX = point.x, touchY = point.y; 80 | CGFloat boardWidth = SCREEN_W / (DHBoardSize + 1); 81 | /** 82 | * h:水平第几个点 83 | * W:垂直第几个点 84 | */ 85 | NSInteger h,v; 86 | h = (NSInteger)(touchX / boardWidth); 87 | v = (NSInteger)(touchY / boardWidth); 88 | /** 89 | * 如果点大于棋格的一半就落下一个点,边界不允许下棋 90 | */ 91 | if (fmod(touchX, boardWidth) > boardWidth / 2.0 || touchX <= boardWidth / 2) { 92 | h ++; 93 | } 94 | if (fmod(touchY, boardWidth) > boardWidth / 2.0 || touchY <= boardWidth / 2) { 95 | v ++; 96 | } 97 | if (touchX >= SCREEN_W - boardWidth / 2) { 98 | h --; 99 | } 100 | if (touchY >= SCREEN_W - boardWidth / 2) { 101 | v --; 102 | } 103 | return [[DHPoint alloc] initPointWith:h y:v]; 104 | 105 | } 106 | 107 | + (UIImageView *)foundChessWithPoint:(DHPoint *)point superView:(UIView *)view { 108 | 109 | NSInteger x = point.x; 110 | NSInteger y = point.y; 111 | CGFloat boardWidth = SCREEN_W / (DHBoardSize + 1); 112 | for (UIImageView *imgView in view.subviews) { 113 | if (imgView.center.x == x * boardWidth && imgView.center.y == y * boardWidth) { 114 | return imgView; 115 | } 116 | } 117 | return nil; 118 | } 119 | 120 | 121 | @end 122 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Tool/DHMCTool.h: -------------------------------------------------------------------------------- 1 | // 2 | // DHMCTool.h 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/5/31. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @protocol DHMCToolDelegate 13 | 14 | @optional 15 | - (void)session:(MCSession *)session didReceiveString:(NSString *)str fromPeer:(MCPeerID *)peer; 16 | - (void)session:(MCSession *)session didChangeState:(MCSessionState)state fromPeer:(MCPeerID *)peer; 17 | - (void)browserControllerCancleAndDone; 18 | 19 | @end 20 | 21 | @interface DHMCTool : NSObject 22 | 23 | @property (nonatomic, strong) MCBrowserViewController *browser; 24 | @property (nonatomic, strong) MCSession *session; 25 | @property (nonatomic, assign) id delegate; 26 | + (instancetype)tool; 27 | 28 | /** 29 | * 开启广播和初始化peer 和 session 和 advertiser 30 | */ 31 | - (void)setupPeerSessionAdvertiser; 32 | 33 | /** 34 | * 关闭广播 35 | */ 36 | - (void)closeAdvertiser; 37 | 38 | /** 39 | * 发送数据 40 | */ 41 | - (void)sendMessage:(NSString *)message error:(NSError *)error; 42 | @end 43 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Tool/DHMCTool.m: -------------------------------------------------------------------------------- 1 | // 2 | // DHMCTool.m 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/5/31. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import "DHMCTool.h" 10 | static DHMCTool *tool = nil; 11 | 12 | @interface DHMCTool (){ 13 | MCPeerID *myPeer; 14 | MCAdvertiserAssistant *advertiser; 15 | // MCBrowserViewController *browser; 16 | } 17 | 18 | @end 19 | 20 | @implementation DHMCTool 21 | 22 | // 初始化 23 | - (instancetype)init { 24 | 25 | if (self = [super init]) { 26 | myPeer = nil; 27 | self.session = nil; 28 | advertiser = nil; 29 | self.browser = nil; 30 | [self setupPeerSessionAdvertiser]; 31 | } 32 | return self; 33 | } 34 | 35 | // 单利获取对象 36 | + (instancetype)tool { 37 | 38 | static dispatch_once_t onceToken; 39 | dispatch_once(&onceToken, ^{ 40 | tool = [[DHMCTool alloc] init]; 41 | }); 42 | return tool; 43 | } 44 | 45 | #pragma mark - public mothed 46 | - (void)setupPeerSessionAdvertiser { 47 | 48 | // 标识设备,通常是设备昵称 49 | myPeer = [[MCPeerID alloc] initWithDisplayName:[UIDevice currentDevice].name]; 50 | // 启用和管理Multipeer连接会话中的所有同行之间的沟通 51 | _session = [[MCSession alloc] initWithPeer:myPeer securityIdentity:nil encryptionPreference:MCEncryptionNone]; 52 | // 发送广播,向用户呈现传入的邀请并处理用户的响应的UI 53 | advertiser = [[MCAdvertiserAssistant alloc] initWithServiceType:ServiceType discoveryInfo:nil session:_session]; 54 | // 开启广播 55 | [advertiser start]; 56 | _session.delegate = self; 57 | advertiser.delegate = self; 58 | } 59 | 60 | // 关闭广播 61 | - (void)closeAdvertiser { 62 | 63 | [advertiser stop]; 64 | advertiser = nil; 65 | } 66 | 67 | // 发送消息 68 | - (void)sendMessage:(NSString *)message error:(NSError *)error{ 69 | 70 | NSError *errors; 71 | NSData *data = [message dataUsingEncoding:NSUTF8StringEncoding]; 72 | [_session sendData:data toPeers:_session.connectedPeers withMode:MCSessionSendDataReliable error:&errors]; 73 | error = errors; 74 | } 75 | 76 | // 查找蓝牙的浏览器控制器 77 | - (MCBrowserViewController *)browser { 78 | 79 | if (!_browser) { 80 | _browser = [[MCBrowserViewController alloc] initWithServiceType:ServiceType session:_session]; 81 | _browser.delegate = self; 82 | } 83 | return _browser; 84 | } 85 | 86 | #pragma mark - MCSessionDelegate 87 | // 状态改变 88 | - (void)session:(MCSession *)session peer:(MCPeerID *)peerID didChangeState:(MCSessionState)state { 89 | 90 | if (self.delegate && [self.delegate respondsToSelector:@selector(session:didChangeState:fromPeer:)]) { 91 | [self.delegate session:session didChangeState:state fromPeer:peerID]; 92 | } 93 | } 94 | 95 | // 收到消息 96 | - (void)session:(MCSession *)session didReceiveData:(NSData *)data fromPeer:(MCPeerID *)peerID { 97 | 98 | dispatch_async(dispatch_get_main_queue(), ^{ 99 | NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 100 | if (str && self.delegate && [self.delegate respondsToSelector:@selector(session:didReceiveString:fromPeer:)]) { 101 | [self.delegate session:session didReceiveString:str fromPeer:peerID]; 102 | } 103 | }); 104 | } 105 | 106 | - (void) session:(MCSession *)session 107 | didReceiveStream:(NSInputStream *)stream 108 | withName:(NSString *)streamName 109 | fromPeer:(MCPeerID *)peerID { 110 | 111 | 112 | } 113 | 114 | - (void) session:(MCSession *)session 115 | didStartReceivingResourceWithName:(NSString *)resourceName 116 | fromPeer:(MCPeerID *)peerID 117 | withProgress:(NSProgress *)progress { 118 | 119 | 120 | } 121 | 122 | - (void) session:(MCSession *)session 123 | didFinishReceivingResourceWithName:(NSString *)resourceName 124 | fromPeer:(MCPeerID *)peerID 125 | atURL:(NSURL *)localURL 126 | withError:(nullable NSError *)error { 127 | 128 | 129 | } 130 | 131 | #pragma mark - MCBrowserViewControllerDelegate 132 | - (void)browserViewControllerDidFinish:(MCBrowserViewController *)browserViewController { 133 | 134 | [_browser dismissViewControllerAnimated:YES completion:^{ 135 | if (self.delegate && [self.delegate respondsToSelector:@selector(browserControllerCancleAndDone)]) { 136 | [self.delegate browserControllerCancleAndDone]; 137 | } 138 | }]; 139 | } 140 | 141 | - (void)browserViewControllerWasCancelled:(MCBrowserViewController *)browserViewController { 142 | 143 | [_browser dismissViewControllerAnimated:YES completion:^{ 144 | if (self.delegate && [self.delegate respondsToSelector:@selector(browserControllerCancleAndDone)]) { 145 | [self.delegate browserControllerCancleAndDone]; 146 | } 147 | }]; 148 | } 149 | 150 | 151 | @end 152 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Tool/DHNSUserdefault.h: -------------------------------------------------------------------------------- 1 | // 2 | // DHNSUserdefault.h 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/6/1. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DHNSUserdefault : NSObject 12 | 13 | + (BOOL)getTheIsWhiteSente; 14 | + (BOOL)getTheIsSounds; 15 | + (BOOL)getTheIsPlayerSente; 16 | 17 | + (void)setupIsWhiteSente:(BOOL)bools; 18 | + (void)setupIsSounds:(BOOL)bools; 19 | + (void)setupIsPlayerSente:(BOOL)bools; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Tool/DHNSUserdefault.m: -------------------------------------------------------------------------------- 1 | // 2 | // DHNSUserdefault.m 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/6/1. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import "DHNSUserdefault.h" 10 | 11 | @implementation DHNSUserdefault 12 | 13 | + (BOOL)getTheIsSounds { 14 | 15 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 16 | return [defaults boolForKey:IsSounds]; 17 | } 18 | 19 | + (BOOL)getTheIsWhiteSente { 20 | 21 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 22 | return [defaults boolForKey:IsWhiteSente]; 23 | } 24 | 25 | + (BOOL)getTheIsPlayerSente { 26 | 27 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 28 | return [defaults boolForKey:IsPlayerSente]; 29 | } 30 | 31 | + (void)setupIsSounds:(BOOL)bools { 32 | 33 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 34 | [defaults setBool:bools forKey:IsSounds]; 35 | } 36 | 37 | + (void)setupIsWhiteSente:(BOOL)bools { 38 | 39 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 40 | [defaults setBool:bools forKey:IsWhiteSente]; 41 | } 42 | 43 | + (void)setupIsPlayerSente:(BOOL)bools { 44 | 45 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 46 | [defaults setBool:bools forKey:IsPlayerSente]; 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Tool/HBPlaySoundUtil.h: -------------------------------------------------------------------------------- 1 | // 2 | // HBPlaySoundUtil.h 3 | // wq8 4 | // 5 | // Created by weqia on 13-10-16. 6 | // Copyright (c) 2013年 Weqia. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | @interface HBPlaySoundUtil : NSObject 12 | { 13 | SystemSoundID soundID; 14 | int _type; 15 | } 16 | -(id)initForPlayingVibrate; //震动 17 | -(id)initForPlayingSystemSoundEffectWith:(NSString *)resourceName ofType:(NSString *)type; //系统声音 18 | -(id)initForPlayingSoundEffectWith:(NSString *)filename; //自定义声音 19 | 20 | -(void)play; 21 | 22 | +(id)shareForPlayingVibrate; 23 | +(id)sharePlayingSystemSoundEffectWith:(NSString *)resourceName ofType:(NSString *)type; 24 | +(id)shareForPlayingSoundEffectWith:(NSString *)filename; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /GoBangGraduationProject/Tool/HBPlaySoundUtil.m: -------------------------------------------------------------------------------- 1 | // 2 | // HBPlaySoundUtil.m 3 | // wq8 4 | // 5 | // Created by weqia on 13-10-16. 6 | // Copyright (c) 2013年 Weqia. All rights reserved. 7 | // 8 | 9 | #import "HBPlaySoundUtil.h" 10 | #import "DHNSUserdefault.h" 11 | 12 | @implementation HBPlaySoundUtil 13 | -(id)initForPlayingVibrate 14 | { 15 | self=[super init]; 16 | if(self){ 17 | soundID = kSystemSoundID_Vibrate; 18 | } 19 | return self; 20 | } 21 | -(id)initForPlayingSystemSoundEffectWith:(NSString *)resourceName ofType:(NSString *)type 22 | { 23 | self=[super init]; 24 | _type=1; 25 | if(self){ 26 | NSString *path = [[NSBundle bundleWithIdentifier:@"com.apple.UIKit"] pathForResource:resourceName ofType:type]; 27 | if (path) { 28 | SystemSoundID theSoundID; 29 | OSStatus error = AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:path], &theSoundID); 30 | if (error == kAudioServicesNoError) { 31 | soundID = theSoundID; 32 | }else { 33 | NSLog(@"Failed to create sound "); 34 | } 35 | } 36 | } 37 | return self; 38 | } 39 | -(id)initForPlayingSoundEffectWith:(NSString *)filename 40 | { 41 | self=[super init]; 42 | _type=2; 43 | if(self){ 44 | NSURL *fileURL = [[NSBundle mainBundle] URLForResource:filename withExtension:nil]; 45 | if (fileURL != nil) 46 | { 47 | SystemSoundID theSoundID; 48 | OSStatus error = AudioServicesCreateSystemSoundID((__bridge CFURLRef)fileURL, &theSoundID); 49 | if (error == kAudioServicesNoError){ 50 | soundID = theSoundID; 51 | }else { 52 | NSLog(@"Failed to create sound "); 53 | } 54 | } 55 | } 56 | return self; 57 | } 58 | 59 | -(void)play 60 | { 61 | if ([DHNSUserdefault getTheIsSounds]) { 62 | AudioServicesPlaySystemSound(soundID); 63 | }; 64 | } 65 | 66 | +(id)shareForPlayingVibrate 67 | { 68 | static HBPlaySoundUtil * util=nil; 69 | static dispatch_once_t onceToken; 70 | dispatch_once(&onceToken, ^{ 71 | util=[[HBPlaySoundUtil alloc]initForPlayingVibrate]; 72 | }); 73 | return util; 74 | } 75 | +(id)sharePlayingSystemSoundEffectWith:(NSString *)resourceName ofType:(NSString *)type 76 | { 77 | static HBPlaySoundUtil * util=nil; 78 | static dispatch_once_t onceToken; 79 | dispatch_once(&onceToken, ^{ 80 | util=[[HBPlaySoundUtil alloc]initForPlayingSystemSoundEffectWith:resourceName ofType:type]; 81 | }); 82 | return util; 83 | } 84 | +(id)shareForPlayingSoundEffectWith:(NSString *)filename; 85 | { 86 | if (filename==nil) { 87 | return nil; 88 | } 89 | static NSMutableDictionary * dic=nil; 90 | static dispatch_once_t onceToken; 91 | dispatch_once(&onceToken, ^{ 92 | dic=[NSMutableDictionary dictionary]; 93 | }); 94 | HBPlaySoundUtil * util=[dic objectForKey:filename]; 95 | if (util==nil) { 96 | util=[[HBPlaySoundUtil alloc]initForPlayingSoundEffectWith:filename]; 97 | [dic setObject:util forKey:filename]; 98 | } 99 | return util; 100 | } 101 | @end 102 | -------------------------------------------------------------------------------- /GoBangGraduationProject/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // GoBangGraduationProject 4 | // 5 | // Created by 刘人华 on 16/5/10. 6 | // Copyright © 2016年 dahua. 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 | -------------------------------------------------------------------------------- /GoBangGraduationProjectTests/GoBangGraduationProjectTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // GoBangGraduationProjectTests.m 3 | // GoBangGraduationProjectTests 4 | // 5 | // Created by 刘人华 on 16/5/10. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface GoBangGraduationProjectTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation GoBangGraduationProjectTests 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 | -------------------------------------------------------------------------------- /GoBangGraduationProjectTests/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 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /GoBangGraduationProjectUITests/GoBangGraduationProjectUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // GoBangGraduationProjectUITests.m 3 | // GoBangGraduationProjectUITests 4 | // 5 | // Created by 刘人华 on 16/5/10. 6 | // Copyright © 2016年 dahua. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface GoBangGraduationProjectUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation GoBangGraduationProjectUITests 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 | -------------------------------------------------------------------------------- /GoBangGraduationProjectUITests/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 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 dadahua 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GoBangProject 2 | 大华五子棋(已上架),该项目主要用到MutipeerConnectivity框架,用蓝牙或者局域网二人近场五子棋对战。 3 | 🚫🚫🚫仅供学习参考,禁止用于商业用途🚫🚫🚫 4 | 5 | ### 一.项目介绍 6 | #### 1.地址: 7 | 8 | github地址:[https://github.com/dadahua/GoBangProject](https://github.com/dadahua/GoBangProject) 9 | 10 | 优酷操作视频:[如何操作](http://v.youku.com/v_show/id_XMjY1OTk5MzMzMg==.html?from=s1.8-1-1.2&spm=a2h0k.8191407.0.0) 11 | 12 | #### 2.效果图: 13 | 14 | ![近场五子棋对战.gif](http://upload-images.jianshu.io/upload_images/1352811-b16aa5446c4964c8.gif?imageMogr2/auto-orient/strip) 15 | 16 | 17 | 18 | #### 3.简介: 19 | 该项目主要用到[MutipeerConnectivity](https://www.oschina.net/translate/intro-multipeer-connectivity-framework-ios-programming)框架,用**蓝牙**或者**局域网**二人近场五子棋对战。 20 | 21 | 22 | ### 二.思路介绍 23 | 大概说下思路,具体看代码实现。 24 | #### 1.画棋盘及落点 25 | 这个可以去慕课网看看这个视频:[五子棋](http://www.imooc.com/learn/646),里面有详细的讲解,我对里面的进行了部分优化。比如怎么判断两点之间到底触摸的哪个点。 26 | 27 | 28 | #### 2.悔棋,重来 29 | 每个点都是一个对象,让后把对象放数组里面,进行删去,或者重置。 30 | 31 | 32 | #### 3.人机模式 33 | ![AI简介.png](http://upload-images.jianshu.io/upload_images/1352811-1d9630f0550e20de.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) 34 | 35 | 这里的AI(人工智能)比较简单,这个算法可深可浅,此项目就是比较浅的,深的可以去看[算法](http://blog.csdn.net/onezeros/article/details/5542379),此项目AI的大体思路是: 36 | 37 | - 先便利棋盘上面的点,找到AI的棋子有活四,死四的点,既下一步能形成5个点的落子点,找到就直接在此点落子。 38 | 39 | - 如果没找到,就遍历玩家活四,或者死四的点,并在此进行落点进行防守,虽然活四没法防守。 40 | 41 | - 然后这两个点都没找到的话,就直接找AI有形成活三,或者死三的点,进行落子进攻。 42 | 43 | - 如果没找到,就找用户能形成活三,死三的点进行防守。就这样简单的进行交互。 44 | 45 | #### 4.人人模式 46 | 人人连机主要用Multipeer Connectivity框架进行近场通讯,现在有黑白玩家想要连接。 47 | 48 | - 那么双方必须打开蓝牙或者连接**同一WiFi**,接着至少要有一个设备作为浏览器(browser),用来搜寻其他设备; 49 | 50 | - 第二个设备必须是可发现的,它要声明它在这里,并且它想要与别的设备连接。换句话说,第二个设备需要宣传自己。 51 | 一般来说,两个设备都要宣传自己,但至少要有一个能浏览其他设备,从而建立连接。 52 | 53 | - 接受邀请后双方建立连接。然后他们就可以基于session会话来传递数据消息数据(包括文本、图像以及可以转换为NSData对象的任何其他数据),流数据,资源数据。 54 | 55 | - 此项目只需要传递消息数据即可。收到数据的代理方法默认会是在子线程上面,所以如果要更新UI等操作要用**GCD线程回调到主线程**上面来,否则会造成线程异常的情况。 56 | 57 | - 传递的数据有棋子位置,棋子颜色,催促信号,语言文字等。为此我制定了简单的协议来区别这些数据。否则没有一套基本的标准,应用没办法判定这串数据是否是语言文字,还是棋子位置或者信号等。通讯协议表如下表所示。 58 | 59 | |数据类型 | 头部| 内容 |例子| 60 | | ------------- |:-------------:| :-------------:|:-------------:| 61 | | 语言文字| ~| 文字 | ~你吃饭了吗?| 62 | | 黑子位置 | black | 棋子x,y坐标 | black0705 63 | | 白子位置 | white | 棋子x,y坐标 | white0705 64 | | 催促| quikly | | quikly 65 | | 悔棋 | undo | | undo 66 | 67 | 68 | #### 三.用到的三方和借鉴 69 | 感谢下面作者 70 | 1.[LLSwitch](https://github.com/lilei644/LLSwitch) 71 | 2.[SFDraggableDialogView](https://github.com/kubatruhlar/SFDraggableDialogView) 72 | 3.[慕课网五子棋](http://www.imooc.com/learn/646) 73 | 74 | #### 四.结语 75 | 如果能对你有帮助,就给个star或赞鼓励下,有什么没明白的欢迎留言交流。 76 | --------------------------------------------------------------------------------