• iOS动画中的物理知识应用之愤慨的小鸟-碰撞检測


    碰撞检測


    源码:https://github.com/Esdeath/collsion


    我相信搞iOS得人。多多少少都知道 弹球这个小游戏。

    撞击不同的点,就能改变其运动的轨迹。对于非常多人来说,假设不知道思路可能认为小球在屏幕中撞来撞去,碰到墙壁就改变运动方向似乎非常难实现。
    事实上这个仅仅须要一点点iOS画图基础和动画基础,还要一点点物理知识就OK了。


    这里写图片描写叙述

    1.速度和位移都是矢量

    在2D坐标系中,速度和位移都能分解成在x轴和y轴上的分量
    这里写图片描写叙述
    所以能够依据速度在Vx 和 Vy来描写叙述物体的运动情况。

    界面每次刷新单位时间。利用物体速度分量Vx与Vy的值来计算下次物体出现的位置:

    • 下次X轴坐标=Vx + 当前X轴坐标
    • 下次Y轴坐标=Vy + 当前Y轴坐标

    2.碰撞的速度模型

    这里写图片描写叙述
    假设物体撞到屏幕的底边,这时候物体在X轴上的方向不变。y轴方向上速度取反,同理撞到屏幕顶边也是。
    物理模型:

    • Vx = Vx
    • Vy = - Vy

    同理,假设物体撞到左边或者右边:

    • Vx = - Vx
    • Vy = Vy

    3.代码实现

    1.新建一个MRView加入到根View上。

    这里写图片描写叙述

    CADisplayLink是一个能让我们以和屏幕刷新率同样的频率将内容画到屏幕上的定时器。

    我们在应用中创建一个新的 CADisplayLink 对象,把它加入到一个runloop中,并给它提供一个 target 和selector 在屏幕刷新的时候调用。

    CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)];
    [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

    3.设置成员属性

    //小鸟图片
    @property (nonatomic,strong) UIImage *imageBird;
    //小鸟的位置
    @property (nonatomic,assign) CGFloat birdX;
    @property (nonatomic,assign) CGFloat birdY;
    //小鸟的速度
    @property (nonatomic,assign) CGFloat birdSpeedX;
    @property (nonatomic,assign) CGFloat birdSpeedY;

    4.初始化

    这里要注意,要设置从xib,storyboard,还有代码中初始化都必须引用到。

    CADisplayLink中调用setNeedsDisplay用来不停的重绘。

    //从xib或者storyboard初始化调用
    - (void)awakeFromNib
    {
        [self setUpBird];
    }
    //从代码初始化调用这个
    - (instancetype)initWithFrame:(CGRect)frame
    {
        if (self = [super initWithFrame:frame]) {
            [self setUpBird];
        }
    
        return self;
    }
    
    -(void)setUpBird
    {
        self.backgroundColor = [UIColor blackColor];
    
        CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)];
        [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    
        self.imageBird = [UIImage imageNamed:@"QQ20150714-1"];
        //设置初始位置
        self.birdX = 1;
        self.birdY = 1;
        //设置初始速度
        self.birdSpeedX = 5;
        self.birdSpeedY = 5;
    }

    5.画图

    主要是推断好。小鸟碰撞四周的时候速度反向

    - (void)drawRect:(CGRect)rect
    {
        [self.imageBird drawInRect:CGRectMake(self.birdX , self.birdY, IMAGEWIDTH, IMAGEHEIGHT)];
    
        if (self.birdX < 0 || (self.birdX > SCREENWIDTH - IMAGEWIDTH) )
        {
            self.birdSpeedX = -self.birdSpeedX;
        }
    
        if (self.birdY < 0 || (self.birdY > SCREENHEIGHT - IMAGEHEIGHT) )
        {
            self.birdSpeedY = -self.birdSpeedY;
        }
    
        self.birdX += self.birdSpeedX;
        self.birdY += self.birdSpeedY;
    }

    6.完整的代码

    这里MRView是self.view的子控件。

    全然覆盖self.view

    #import "MRView.h"
    
    #define SCREENHEIGHT   [UIScreen mainScreen].bounds.size.height
    #define SCREENWIDTH    [UIScreen mainScreen].bounds.size.width
    
    #define IMAGEWIDTH  50
    #define IMAGEHEIGHT 50
    
    @interface MRView()
    
    @property (nonatomic,strong) UIImage *imageBird;
    //小鸟的位置
    @property (nonatomic,assign) CGFloat birdX;
    @property (nonatomic,assign) CGFloat birdY;
    //小鸟的速度
    @property (nonatomic,assign) CGFloat birdSpeedX;
    @property (nonatomic,assign) CGFloat birdSpeedY;
    
    @end
    
    @implementation MRView
    - (void)awakeFromNib
    {
        [self setUpBird];
    }
    
    - (instancetype)initWithFrame:(CGRect)frame
    {
        if (self = [super initWithFrame:frame]) {
            [self setUpBird];
        }
    
        return self;
    }
    
    -(void)setUpBird
    {
        self.backgroundColor = [UIColor blackColor];
    
        CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)];
        [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    
        self.imageBird = [UIImage imageNamed:@"QQ20150714-1"];
        //设置初始位置
        self.birdX = 1;
        self.birdY = 1;
        //设置初始速度
        self.birdSpeedX = 5;
        self.birdSpeedY = 5;
    }
    
    - (void)drawRect:(CGRect)rect
    {
        [self.imageBird drawInRect:CGRectMake(self.birdX , self.birdY, IMAGEWIDTH, IMAGEHEIGHT)];
    
        if (self.birdX < 0 || (self.birdX > SCREENWIDTH - IMAGEWIDTH) )
        {
            self.birdSpeedX = -self.birdSpeedX;
        }
    
        if (self.birdY < 0 || (self.birdY > SCREENHEIGHT - IMAGEHEIGHT) )
        {
            self.birdSpeedY = -self.birdSpeedY;
        }
    
        self.birdX += self.birdSpeedX;
        self.birdY += self.birdSpeedY;
    }
    
    @end

    7.结果展示

    这里写图片描写叙述

    这里写图片描写叙述

    这里写图片描写叙述

    这里写图片描写叙述

    这里写图片描写叙述

  • 相关阅读:
    苹果和Google应该如何把二维码变成主流 | 36氪
    成绩换offer,中国版的Smarterer“一问一答”网站帮你把简历推荐给你想去的公司 | 36氪
    读过的一些书
    扫描QR码即可完成移动支付的LevelUp推出集合NFC、QR码等技术的移动支付终端,供商家免费使用 | 36氪
    “消息速递”团队推出“有声照片”,让照片同时拥有拍摄时的现场录音 | 36氪
    css3ps—ps直接生成css3 使用方法
    Google收购的Nik Software将会发力“服务器端图片处理”领域 | 36氪
    收藏本站
    让屏幕抖动一阵
    全中文日期显示
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/6762410.html
Copyright © 2020-2023  润新知