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

flyppyBird----用UIKit框架仿写的经典小游戏_第1张图片

在学习了 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 ()
@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 *)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)item withBoundaryIdentifier:(id)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框架仿写的经典小游戏)