оживить точку несколько раз и более естественно - PullRequest
5 голосов
/ 07 ноября 2011

, поэтому моя текущая версия выглядит так: Анимационный фильм

Я довольно новичок в основной анимации, поэтому я пытаюсь добиться того, чтобы было несколько точек, подобных текущей, которые перемещаются из левого окна под разными углами, высотами и скоростями, как в теннисе. мяч машина.

enter image description here

Первая проблема в том, что мой «мяч» не выглядит так, как будто его схватили под действием силы тяжести, а скорость сначала не достаточно высока.

также, как сделать эту анимацию несколько раз с переменным расстоянием между началом.

если что-то неясно, ПОЖАЛУЙСТА, оставьте комментарий.

мой текущий код:

- (void)loadView {
    [super loadView];

    self.view.backgroundColor = [UIColor lightGrayColor];   

    CGPoint startPoint = CGPointMake(20, 300);
    CGPoint endPoint = CGPointMake(300, 500);

    UIBezierPath *trackPath = [UIBezierPath bezierPath];
    [trackPath moveToPoint:startPoint];
    [trackPath addQuadCurveToPoint:endPoint controlPoint:CGPointMake(endPoint.x, startPoint.y)];

    CALayer *point = [CALayer layer];
    point.bounds = CGRectMake(0, 0, 20.0, 20.0);
    point.position = startPoint;
    point.contents = (id)([UIImage imageNamed:@"point.png"].CGImage);
    [self.view.layer addSublayer:point];

    CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    anim.path = trackPath.CGPath;
    anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
    anim.repeatCount = HUGE_VALF;
    anim.duration = 2.0;
    [point addAnimation:anim forKey:@"movepoint"];

    CALayer *caseLayer = [CALayer layer];
    caseLayer.bounds = CGRectMake(0, 0, 140.0, 150.0);
    caseLayer.position = startPoint;
    caseLayer.contents = (id)([UIImage imageNamed:@"case.png"].CGImage);
    [self.view.layer addSublayer:caseLayer];

}

Ответы [ 2 ]

1 голос
/ 16 ноября 2011

Самый простой способ моделировать гравитацию - это те параболические уравнения, которые вы изучаете в базовой физике. Вкратце, нижеприведенная функция принимает начальную позицию, скорость и угол (IN RADIANS, где 0 - справа). CALayer появляется в позиции и получает выстрел с этой скоростью и углом.

Я использую CADisplayLink (который фактически является таймером, который синхронизируется с вашей частотой кадров), чтобы вызывать функцию очень быстро. Каждый раз, когда вызывается функция, точка перемещается. Горизонтальная скорость постоянна, и вертикальная скорость увеличивается к нижней части каждого кадра, чтобы имитировать гравитацию (`vy - = 0.5f;). Если вы хотите больше / меньше гравитации, просто возитесь с этим значением 0.5f.

- (id)initWithFrame:(CGRect)frame {

    self = [super initWithFrame:frame];
    if (self) {
      point = [[CALayer alloc] init];
      point.bounds = CGRectMake(0.0f, 0.0f, 10.0f, 10.0f);
      point.backgroundColor = [UIColor redColor].CGColor;
      point.position = CGPointMake(-10.0f, -10.0f);
      [self.layer addSublayer:point];
      [point release];
    }
    return self;
}

-(void)animateBallFrom:(CGPoint)start withSpeed:(CGFloat)speed andAngle:(CGFloat)angle       
  vx = speed*cos(angle);
  vy = speed*sin(angle);


  [CATransaction begin];
  [CATransaction setDisableActions:YES];
  point.position = start;
  [CATransaction commit];

  displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(animate)];
  [displayLink setFrameInterval:2];
  [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}

-(void)animate {
  if (point.position.x + point.bounds.size.width/2.0f < 0.0f || point.position.x > self.bounds.size.width + point.bounds.size.width/2.0f ||
    point.position.y + point.bounds.size.height/2.0f < 0.0f || point.position.y > self.bounds.size.height + point.bounds.size.height/2.0f) {
    [displayLink invalidate];
  } else {
    [CATransaction begin];
    [CATransaction setDisableActions:YES];
    point.position = CGPointMake(point.position.x+vx, point.position.y-vy);
    vy -= 0.5f;
    [CATransaction commit];
  }
}

и интерфейс:

@interface Bounce : UIView {
  CALayer *point;
  CADisplayLink *displayLink;
  CGFloat vx, vy;
}

-(void)animateBallFrom:(CGPoint)start withSpeed:(CGFloat)speed andAngle:(CGFloat)angle;

@end
1 голос
/ 10 ноября 2011

Я думаю, что здесь можно сделать несколько вещей.
- Один из них - использовать kCAMediaTimingFunctionLinear вместо kCAMediaTimingFunctionEaseOut.
- Другой - установить контрольную точку в центре падения шара,где бы это ни было.Попробуйте это:

CGPoint startPoint = CGPointMake(20, 300);
CGPoint controlPoint = CGPointMake(160, 400);
CGPoint endPoint = CGPointMake(300, 500);

UIBezierPath *trackPath = [UIBezierPath bezierPath];
[trackPath moveToPoint:startPoint];
[trackPath addQuadCurveToPoint:endPoint controlPoint:controlPoint];

CALayer *point = [CALayer layer];
point.bounds = CGRectMake(0, 0, 20.0, 20.0);
point.position = startPoint;
point.contents = (id)([UIImage imageNamed:@"point.png"].CGImage);
[self.view.layer addSublayer:point];

CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
anim.path = trackPath.CGPath;
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
anim.repeatCount = HUGE_VALF;
anim.duration = 2.0;
[point addAnimation:anim forKey:@"movepoint"];

После этого вы сможете перемещать контрольную точку для разных путей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...