iOS动画中的物理知识应用之愤怒的小鸟-重力加速度

平抛运动

还记得初次玩愤怒的小鸟的时候,弹出小鸟那一瞬间,小鸟在空中划出的优美弧线么?还记得小鸟在地上弹起又落下的场景么?这里就介绍一下如何实现平抛运动。

1.平抛运动的物理知识

这里写图片描述
从图中我们可以看出物体在抛出之后,在X轴方向上速度不变。但是随着时间的变化Y轴方向的速度在变大(红色箭头的长度)。
由基本的物理知识我们知道:

  • Vx = Vx
  • Vy = Vy + at

在计算机中进行模拟的时候,我们可以认为t是一个单位时间,所以在Y轴方向上Vy = Vy + a。这里我们可以给a取一个常量,表示加速度值。现实生活中a = 9.8(或者10)。

在这个例子中:小鸟将具有水平方向的初速度,且受到向下的重力,即小鸟具有向下的加速度,若碰到地面就会进行反弹,速度反向。

2.代码实现

1.设置初始量
- (void)setUpStartValue
{
    //在屏幕上的初始位置
    self.birdX = 0;
    self.birdY = 0;
    //x,y轴上的初始速度
    self.birdSpeedX = 10;
    self.birdSpeedY = 0;
    //重力加速度
    self.gBirdSpeed = 9.8;
}
2.模拟重力环境的核心代码
//在x轴上速度不变,每次刷新的时候,x轴上的位置等于速度,加上前一个位置
    self.birdX += self.birdSpeedX;

    //在y轴上每次刷新,小鸟的速度增加一个重力加速度
    self.birdSpeedY += self.gBirdSpeed;
    //y轴上的位置等于y轴上增加后的速度,加上前一个位置
    self.birdY += self.birdSpeedY;

    //碰到x轴屏幕边缘,在x轴上的位置不在发生变化
    if (self.birdX >= SCREENWIDTH - IMAGEWIDTH) {
        self.birdX = SCREENWIDTH - IMAGEWIDTH;

    }
    //判断是否触地,如果触碰到窗口边界,Vy调整为相反方向
    if(self.birdY >= SCREENHEIGHT - IMAGEHEIGHT)
    {
        self.birdY = SCREENHEIGHT - IMAGEHEIGHT;
        self.birdSpeedY = -self.birdSpeedY;
    }
3.项目的完整代码
#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 *imageBackgound;
@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;

@property (nonatomic,assign) CGFloat gBirdSpeed;



@end

@implementation MRView
- (void)awakeFromNib
{
    self.contentMode = UIViewContentModeRedraw;
    self.backgroundColor = [UIColor blackColor];

    [self setUpStartValue];
}

- (instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]) {
        [self setUpStartValue];
    }

    return self;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{

    [self setUpStartValue];

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

- (void)setUpStartValue
{
    self.imageBackgound = [UIImage imageNamed:@"IMG_0465.jpg"];
    self.imageBird = [UIImage imageNamed:@"QQ20150714-1"];

    self.birdX = 0;
    self.birdY = 0;

    self.birdSpeedX = 10;
    self.birdSpeedY = 0;

    self.gBirdSpeed = 9;
}

- (void)drawRect:(CGRect)rect
{
    [self.imageBird drawInRect:CGRectMake(self.birdX, self.birdY, IMAGEWIDTH,IMAGEHEIGHT)];

    //在x轴上速度不变,每次刷新的时候,x轴上的位置等于速度,加上前一个位置
    self.birdX += self.birdSpeedX;

    //在y轴上每次刷新,小鸟的速度增加一个重力加速度
    self.birdSpeedY += self.gBirdSpeed;
    //y轴上的位置等于y轴上增加后的速度,加上前一个位置
    self.birdY += self.birdSpeedY;

    //碰到x轴屏幕边缘,在x轴上的位置不在发生变化
    if (self.birdX >= SCREENWIDTH - IMAGEWIDTH) {
        self.birdX = SCREENWIDTH - IMAGEWIDTH;

    }
    //判断是否触地,如果触碰到窗口边界,Vy调整为相反方向
    if(self.birdY >= SCREENHEIGHT - IMAGEHEIGHT)
    {
        self.birdY = SCREENHEIGHT - IMAGEHEIGHT;
        self.birdSpeedY = -self.birdSpeedY;
    }
}

@end
4.运行结果

这里写图片描述

这里写图片描述

这里写图片描述

5.Demo

https://github.com/Esdeath/Gravity

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值