美文网首页
flyppyBird----用UIKit框架仿写的经典小游戏

flyppyBird----用UIKit框架仿写的经典小游戏

作者: 指尖书法 | 来源:发表于2017-03-12 17:57 被阅读55次

    在学习了 UIDynamic之后突发奇想,能不能在iOS UIKit框架下,利用物理仿真API写出一个小游戏,于是尝试着写了一下,虽然还存在一些问题,但游戏整体已经实现,并且可以玩耍,步骤详解以后贴出,现将代码贴在这里,方便记录.
    //  ViewController.m
    //  FlayppyBird
    //
    //  Created by wsh on 2017/1/26.
    //  Copyright © 2017年 wsh. All rights reserved.
    //
    
    #import "ViewController.h"
    #import "AppDelegate.h"
    
    #define KScreenWidth [UIScreen mainScreen].bounds.size.width
    #define KScreenHeight [UIScreen mainScreen].bounds.size.height
    #define KWidth bounds.size.width
    #define KHeight bounds.size.height
    
    @interface ViewController ()<UICollisionBehaviorDelegate>
    @property (weak, nonatomic)  UIImageView *bird;
    @property (weak, nonatomic) IBOutlet UIImageView *cloud;
    @property (weak, nonatomic) IBOutlet UIImageView *bottom;
    
    /** <#注释#> */
    @property (nonatomic, strong)  NSTimer *timer1;
    @property (nonatomic, strong)  NSTimer *timer2;
    @property (nonatomic, strong)  NSTimer *timer3;
    /** <#注释#> */
    @property (nonatomic, weak)  UILabel *label;
    /** <#注释#> */
    @property (nonatomic, strong)  UIImageView *imageView2;
    /** <#注释#> */
    @property (nonatomic, strong)  UIImageView *imageView;
    
    /** <#注释#> */
    @property (nonatomic, strong)  UIImageView *huishou1;
    
    
    /** <#注释#> */
    @property (nonatomic, strong)  UIImageView *huishou2;
    /** bottom */
    @property (nonatomic, strong)  UIImageView *bottom1;
    
    /** cloud */
    @property (nonatomic, strong)  UIImageView *cloud1;
    /** 上部管子 */
    @property (nonatomic, strong)  UIImageView *topPiller;
    
    /** 物理仿真器 */
    @property (nonatomic, strong)  UIDynamicAnimator *animater;
    /** 记录点击的时间 */
    @property (nonatomic, strong)  NSDate *firstDate;
    
    @property (nonatomic, strong)  UIDynamicBehavior *beh;
    
    /** <#注释#> */
    @property (nonatomic, strong)  CALayer *layer;
    @end
    
    static CGFloat pillerWidth = 100;
    static NSInteger score = 0;
    //难度,也就是两个水管中间距离
    static NSInteger distance = 200;
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.navigationController.navigationBarHidden = YES;
        self.cloud1 = self.cloud;
        self.bottom1 = self.bottom;
        [self setupBird];
        [self setupPillers];
        [self setupBg];
        [self setupCloud];
        [self setupScoreLabel];
    }
    
    
    #pragma mark -
    #pragma mark - 小鸟
    -(void)setupBird {
        UIImageView *birdView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 68 * 0.8, 48 * 0.8)];
        birdView.center = self.view.center;
        //播放动画图片
        UIImage *b1 = [UIImage imageNamed:@"bird-1"];
        UIImage *b2 = [UIImage imageNamed:@"bird-2"];
        UIImage *b3 = [UIImage imageNamed:@"bird-3"];
        UIImage *b4 = [UIImage imageNamed:@"bird-4"];
        
        birdView.animationImages = @[b1,b2,b3,b4];
        
        //动画间隔
        birdView.animationDuration = 1;
        birdView.animationRepeatCount = MAXFLOAT;
        
        //开始动画
        [birdView startAnimating];
        
        //添加
        [self.view addSubview:birdView];
        self.bird = birdView;
    }
    
    
    #pragma mark -
    #pragma mark - 给小鸟加重力/推力
    
    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        
        //记录两次点击间隔
        NSDate *currentTime = [NSDate date];
        NSTimeInterval timeInterval = [currentTime timeIntervalSinceDate:self.firstDate];
        //NSLog(@"%f",timeInterval);
        self.firstDate = currentTime;
        
        
        //创建物理仿真器
        self.animater = [[UIDynamicAnimator alloc]initWithReferenceView:self.view];
        
        //推动行为(持续推动)
        UIPushBehavior *push = [[UIPushBehavior alloc]initWithItems:@[self.bird] mode:UIPushBehaviorModeInstantaneous];
        
        //设置推动的方向和推力的大小
        push.angle = - M_PI_2 ;
       // push.magnitude = 10;
        if (timeInterval) {
            push.magnitude = 1.8 - timeInterval;
            if (push.magnitude < 0 ) {
                push.magnitude = 0;
            }
        }
        
        //重力行为
        UIGravityBehavior * gravity = [[UIGravityBehavior alloc]initWithItems:@[self.bird]];
        gravity.magnitude = 1.5;
        //碰撞行为
        
        UICollisionBehavior *collision = [[UICollisionBehavior alloc]initWithItems:@[self.bird]];
        //collision.translatesReferenceBoundsIntoBoundary = YES;
        collision.collisionMode = UICollisionBehaviorModeEverything;
        
        //添加一条直线作为碰撞边界
        CGFloat x = KScreenWidth;
        CGFloat y = 480;
        
        //NSLog(@"%f,%f",x,y);
        [collision addBoundaryWithIdentifier:@"bottomID" fromPoint:CGPointMake(0, y) toPoint:CGPointMake(x, y)];
        
        
        
        //动力行为项
        UIDynamicItemBehavior *item = [[UIDynamicItemBehavior alloc]initWithItems:@[self.bird]];
        item.elasticity = 0.5;
        //item.friction = 0.5;
        
        //添加行为
        [self.animater addBehavior:push];
        [self.animater addBehavior:collision];
        [self.animater addBehavior:gravity];
        [self.animater addBehavior:item];
        collision.collisionDelegate = self;
    
        //小鸡旋转
        [UIView animateWithDuration:1 animations:^{
            [self.bird setTransform:CGAffineTransformMakeRotation(M_PI_4)];
        } completion:^(BOOL finished) {
            
            [UIView animateWithDuration:1 animations:^{
                [self.bird setTransform:CGAffineTransformMakeRotation(- M_PI_4)];;
                
            }];
        }];
    }
    
    #pragma mark --
    #pragma mark - 设置水管 以及动画
    
    -(void)setupPillers{
        
        
    //        NSTimer *timer = [NSTimer timerWithTimeInterval:10 repeats:YES block:^(NSTimer * _Nonnull timer) {
    //    
    //            [self creatPiller];
    //            
    //            
    //            
    //        UICollisionBehavior *collision = [[UICollisionBehavior alloc]initWithItems:@[self.bird,self.imageView]];
    //            UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.imageView.frame];
    //        [collision addBoundaryWithIdentifier:@"b1" forPath:path];
    //        [self.animater addBehavior:collision];
    //            
    //            
    //            
    //            
    //            
    //            [UIView animateKeyframesWithDuration:9 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeLinear  animations:^{
    //                [self.imageView setTransform:CGAffineTransformMakeTranslation(-KScreenWidth - 100 , 0)];
    //                self.layer = self.imageView.layer;
    //                
    //            } completion:^(BOOL finished) {
    //                
    //                nil;
    //            }];
    //           
    //        }];
    //        [[NSRunLoop mainRunLoop]addTimer:timer forMode:NSDefaultRunLoopMode];
    //        [timer fire];
    //    
    //    
    //
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
    //    
    //    [self creatPiller];
    //    
    //    
    //    NSTimer *timer1 = [NSTimer scheduledTimerWithTimeInterval:2 repeats:YES block:^(NSTimer * _Nonnull timer) {
    //        
    //        CALayer *layer1 = [CALayer layer];
    //        layer1.frame = self.imageView.frame;
    //        NSLog(@"%f",layer1.frame.size.width);
    //        [self.view.layer addSublayer:layer1];
    //        
    //        CABasicAnimation *animation = [CABasicAnimation animation];
    //        
    //        animation.keyPath = @"position";
    //        animation.toValue = [NSValue valueWithCGPoint:CGPointMake(-pillerWidth, self.imageView.center.y)];
    //        animation.duration = 4;
    //        animation.repeatCount = MAXFLOAT;
    //        [layer1 addAnimation:animation forKey:nil];
    //    }];
    //    [[NSRunLoop mainRunLoop]addTimer:timer1 forMode:NSDefaultRunLoopMode];
    //    [timer1 fire];
        
        
    //    //使用核心动画
    //    CALayer *layer = self.imageView.layer;
    //    CALayer *layer2 = self.imageView2.layer;
    //    CABasicAnimation *animation = [CABasicAnimation animation];
    //
    //    animation.keyPath = @"position";
    //    animation.toValue = [NSValue valueWithCGPoint:CGPointMake(-pillerWidth, self.imageView.center.y)];
    //    animation.duration = 4;
    //    animation.repeatCount = MAXFLOAT;
    //    [layer addAnimation:animation forKey:nil];
    //
    //    
    //    CABasicAnimation *animation2 = [CABasicAnimation animation];
    //    animation2.keyPath = @"position";
    //    animation2.toValue = [NSValue valueWithCGPoint:CGPointMake(-pillerWidth, self.imageView2.center.y)];
    //    animation2.duration = 4;
    //    animation2.repeatCount = MAXFLOAT;
    //    [layer2 addAnimation:animation2 forKey:nil];
    //    
    //    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    //        [layer2 addAnimation:animation2 forKey:nil];
    //        [layer addAnimation:animation forKey:nil];
    //    });
    //    
    //    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.1 repeats:YES block:^(NSTimer * _Nonnull timer) {
    //        
    //        
    //        NSLog(@"%f",layer.presentationLayer.frame.origin.x);
    //        UICollisionBehavior *collision = [[UICollisionBehavior alloc]initWithItems:@[self.bird]];
    //                        UIBezierPath *path = [UIBezierPath bezierPathWithRect:layer.presentationLayer.frame];
    //        UIBezierPath *path2 = [UIBezierPath bezierPathWithRect:layer2.presentationLayer.frame];
    //        [collision addBoundaryWithIdentifier:@"b1" forPath:path];
    //        [collision addBoundaryWithIdentifier:@"b2" forPath:path2];
    //        
    //        collision.collisionDelegate = self;
    //        [self.animater addBehavior:collision];
    //        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    //            [self.animater removeBehavior:collision];
    //        });
    //    }];
    //    
    //    [[NSRunLoop mainRunLoop]addTimer:timer forMode:NSDefaultRunLoopMode];
    //    [timer fire];
        
        
        
        
        
    
    //    //
    //    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    //        for (UIImageView *pile in self.view.subviews) {
    //            if ((pile.bounds.size.width == pillerWidth) &&  pile.frame.origin.x < 0  ) {
    //                [pile removeFromSuperview];
    //            }
    //        }
    //        
    //    });
    
        
        
        
        
        
        
        [self creatPiller];
        
        NSTimer *timer2 = [NSTimer timerWithTimeInterval:0.1 repeats:YES block:^(NSTimer * _Nonnull timer) {
            
            CGRect frame = self.imageView.frame;
            CGRect frame2 = self.imageView2.frame;
            frame.origin.x -= 1.5 ;
            frame2.origin.x -= 1.5 ;
            self.imageView.frame = frame;
            self.imageView2.frame = frame2;
            if (self.imageView.center.x  < self.view.center.x) {
                self.huishou1 = self.imageView;
                self.huishou2 = self.imageView2;
                self.label.text = [NSString stringWithFormat:@"%ld",++score];
                [UIView animateWithDuration:(KScreenWidth / (2 * 1.5)) * 0.1 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
                    [self.imageView setTransform:CGAffineTransformMakeTranslation(-(KScreenWidth / 2 + pillerWidth/2 ), 0)];
                    [self.imageView2 setTransform:CGAffineTransformMakeTranslation(-(KScreenWidth / 2 + pillerWidth/2 ), 0)];
                    
                } completion:^(BOOL finished) {
                    
    //                [self.huishou2 removeFromSuperview];
    //                [self.huishou1 removeFromSuperview];
                }];
                
                [self creatPiller];
            }
    
            UICollisionBehavior *collision = [[UICollisionBehavior alloc]initWithItems:@[self.bird]];
                    UIBezierPath *path = [UIBezierPath bezierPathWithRect:self.imageView.frame];
            [collision addBoundaryWithIdentifier:@"b1" forPath:path];
            UIBezierPath *path2 = [UIBezierPath bezierPathWithRect:self.imageView2.frame];
            [collision addBoundaryWithIdentifier:@"b2" forPath:path2];
            collision.collisionDelegate = self;
            [self.animater addBehavior:collision];
            self.beh = collision;
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [self.animater removeBehavior:collision];
            });
            
    }];
        
        [[NSRunLoop mainRunLoop]addTimer:timer2 forMode:NSDefaultRunLoopMode];
        [timer2 fire];
        
        self.timer2 = timer2;
    //
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            for (UIImageView *pile in self.view.subviews) {
                if ((pile.bounds.size.width == pillerWidth) &&  pile.frame.origin.x < 0  ) {
                    [pile removeFromSuperview];
                }
            }
    
        });
        
    }
    
    #pragma mark --
    #pragma mark - 创建得分Label
    
    -(void)setupScoreLabel {
        UILabel *label = [[UILabel alloc]init];
        label.text = [NSString stringWithFormat:@"%ld",score];
        label.textColor = [UIColor redColor];
        label.font = [UIFont systemFontOfSize:50];
        label.center = CGPointMake(self.view.center.x, self.view.center.y - 200) ;
        label.bounds = CGRectMake(0, 0, KScreenWidth, KScreenHeight);
        label.textAlignment = NSTextAlignmentCenter;
        [self.view addSubview:label];
        self.label = label;
    }
    
    #pragma mark --
    #pragma mark - 创建水管
    
    -(void)creatPiller {
        
       //添加图片在最右边
        UIImageView * topPiller = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"PipeDown"]];
        
        UIImageView * bottomPiller = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"PipeUp"]];
        
        
        
        
        CGFloat TopPillerHeight = arc4random_uniform(200)+ 100;
        topPiller.frame = CGRectMake(KScreenWidth, 0, pillerWidth, TopPillerHeight);
        //
        CGFloat downY = TopPillerHeight + distance;
        CGFloat downH = 480 - downY;
        bottomPiller.frame = CGRectMake(KScreenWidth, downY, pillerWidth, downH);
        [self.view addSubview:bottomPiller];
        [self.view addSubview:topPiller];
        self.imageView = bottomPiller;
        self.imageView2 = topPiller;
    }
    
    -(void)setupBg{
        
        
        
        
        //self.bottom.hidden = YES;
    
            
            UIImageView *bottom1 = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"land"]];
            bottom1.frame = CGRectMake(KScreenWidth, 480, KScreenWidth, 187);
            [self.view addSubview:bottom1];
        
            //平移动画
            [UIView animateWithDuration:8 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
            [self.bottom1  setTransform:CGAffineTransformTranslate(self.bottom1.transform, -KScreenWidth, 0)];
            [bottom1  setTransform:CGAffineTransformMakeTranslation(-  KScreenWidth, 0)];
            
            } completion:^(BOOL finished) {
                
                [self.bottom1 removeFromSuperview];
                self.bottom1 = bottom1;
                UIImageView *bottom2 = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"land"]];
                bottom2.frame = CGRectMake(KScreenWidth, 480, KScreenWidth, 187);
                [self.view addSubview:bottom2];
                [UIView animateWithDuration:8 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
                    [self.bottom1  setTransform:CGAffineTransformTranslate(self.bottom1.transform, -KScreenWidth, 0)];
                    [bottom2  setTransform:CGAffineTransformMakeTranslation(- KScreenWidth, 0)];
                    
                    
                } completion:^(BOOL finished) {
                    
                   [self.bottom1 removeFromSuperview];
                    self.bottom1 = bottom2;
                    [self setupBg];
                }];
            }];
        
        
        
        
    }
    
    
    -(void)setupCloud{
        
        
        
        
        
        
        
        UIImageView *cloud = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"sky"]];
        cloud.frame = CGRectMake(KScreenWidth, 265, KScreenWidth, 215);
        [self.view insertSubview:cloud belowSubview:self.bird];
        
        //平移动画
        [UIView animateWithDuration:8 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
            [self.cloud1  setTransform:CGAffineTransformTranslate(self.cloud1.transform, -KScreenWidth, 0)];
            [cloud  setTransform:CGAffineTransformMakeTranslation(-  KScreenWidth, 0)];
            
        } completion:^(BOOL finished) {
            [self.cloud1 removeFromSuperview];
            self.cloud1 = cloud;
            UIImageView *cloud2 = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"sky"]];
            cloud2.frame = CGRectMake(KScreenWidth, 265, KScreenWidth, 215);
            [self.view insertSubview:cloud2 belowSubview:self.bird];
            [UIView animateWithDuration:8 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
                [self.cloud1  setTransform:CGAffineTransformTranslate(self.cloud1.transform, -KScreenWidth, 0)];
                [cloud2  setTransform:CGAffineTransformMakeTranslation(- KScreenWidth, 0)];
                
                
            } completion:^(BOOL finished) {
                
                [self.cloud1 removeFromSuperview];
                self.cloud1 = cloud2;
                [self setupCloud];
            }];
        }];
        
        
        
        
    }
    
    
    #pragma mark --
    #pragma mark - 碰撞检测
    -(void)collisionBehavior:(UICollisionBehavior *)behavior beganContactForItem:(id<UIDynamicItem>)item withBoundaryIdentifier:(id<NSCopying>)identifier atPoint:(CGPoint)p {
        
        //self.bird.backgroundColor = [UIColor redColor];
        
        self.label.text = [NSString stringWithFormat:@"0"];
        
        [self.timer2 invalidate];
        self.timer2  = nil;
        for (UIImageView *pill in self.view.subviews) {
            if (pill.bounds.size.width == pillerWidth) {
                [pill performSelector:@selector(removeFromSuperview)];
            }
        }
    //    [self.animater removeAllBehaviors];
    //    self.animater = nil;
    
        
        
        NSString *lala = [NSString stringWithFormat:@"您一共得了 %lu 分 ,再接再厉哦!",score];
        UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"失败" message:lala preferredStyle:UIAlertControllerStyleAlert];
        
        UIAlertAction *act1 = [UIAlertAction actionWithTitle:@"再来一局" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            score = 0 ;
            [self.bird removeFromSuperview];
            [self setupBird];
            [self setupPillers];
                    //[self.animater removeBehavior:self.beh];
            //self.animater = nil;
            
        } ];
       // [act1 setValue:green forKey:@"_titleTextColor"];
        UIAlertAction *act2 = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
           
            [self exitApplication];
        } ];
    
        
        [alert addAction:act1];
        [alert addAction:act2];
        [self presentViewController:alert animated:YES completion:nil];
    
        
        
    //    UIViewController *vc = [[UIViewController alloc]init];
    //    UINavigationController *nac = [[UINavigationController alloc]initWithRootViewController:vc];
    //    vc.view.backgroundColor = [UIColor whiteColor];
    //    UILabel *label = [[UILabel alloc]init];
    //    label.text = [NSString stringWithFormat:@"您一共得了 %lu 分 ,再接再厉哦!",score];
    //    label.numberOfLines = 0;
    //    label.textColor = [UIColor redColor];
    //    label.font = [UIFont systemFontOfSize:50];
    //    label.center = CGPointMake(self.view.center.x, self.view.center.y - 200) ;
    //    label.bounds = CGRectMake(0, 0, KScreenWidth, KScreenHeight);
    //    label.textAlignment = NSTextAlignmentCenter;
    //    [vc.view addSubview:label];
    //    [self.navigationController pushViewController:vc animated:YES];
        
        
        
    }
    
    -(void)dealloc {
        NSLog(@"销毁");
    }
    - (void)exitApplication {
        
        AppDelegate *app = [UIApplication sharedApplication].delegate;
        UIWindow *window = app.window;
        
        [UIView animateWithDuration:1.0f animations:^{
            window.alpha = 0;
            window.frame = CGRectMake(0, window.bounds.size.width, 0, 0);
        } completion:^(BOOL finished) {
            exit(0);
        }];
        //exit(0);
        
    }
    @end
    
    

    相关文章

      网友评论

          本文标题:flyppyBird----用UIKit框架仿写的经典小游戏

          本文链接:https://www.haomeiwen.com/subject/ipjobttx.html