2011-11-06 19 views
5

así que mi versión actual es el siguiente: Animation Moviepunto animado varias veces y de forma más natural

soy bastante nuevo en centrales animaciones, así que lo que intento conseguir es que hay varios puntos como la actual, moviéndose desde la caja izquierda en varios ángulos, alturas y velocidades, como una máquina de pelota de tenis.

enter image description here

el primer problema es, que mi "bola" no parece que se agarró de la gravedad y también la velocidad en un principio no es lo suficientemente rápido.

también, cómo hacer esta animación varias veces con distancias variables entre el principio.

si algo no está claro, POR FAVOR deje un comentario.

mi código actual:

- (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

me gustaría sugerir que nos fijamos en el uso de [cocos2d/box2d] (http://www.cocos2d-iphone.org/) para hacer funcionar su "animación "como una simulación de física. Eso es lo que se supone que debería ser, si quieres movimientos de gravedad y partículas realistas. – aroth

+0

Creo que no necesito esa dependencia. es solo para una sola vista (y no muy importante) en mi aplicación. – choise

+0

Dado que intenta incorporar física básica al balón, ¿sería aceptable usar CADisplayLink y animar el balón cambiando repetidamente su posición? ¿Alguien tiene algo en contra de esta solución? –

Respuesta

1

La forma más fácil de modelar la gravedad es con las ecuaciones parabólicas que aprendes en física básica. En resumen, la función siguiente toma una posición inicial, una velocidad y un ángulo (EN RADIANES, donde 0 está a la derecha). un CALayer aparece en posición y recibe un disparo a esa velocidad y ángulo.

Estoy usando un CADisplayLink (que efectivamente es un temporizador que se sincroniza con su velocidad de cuadro) para llamar a una función muy rápidamente. Cada vez que se llama a la función, el punto se mueve. La velocidad horizontal es constante y la velocidad vertical aumenta hacia la parte inferior de cada cuadro para emular la gravedad (`vy - = 0.5f;). Si quieres más/menos gravedad, simplemente juega con este valor 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]; 
    } 
} 

y la interfaz:

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

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

@end 
1

creo que puede haber un par de cosas que se pueden hacer aquí.
- Una es usar kCAMediaTimingFunctionLinear en lugar de kCAMediaTimingFunctionEaseOut.
- La otra es establecer su punto de control en el centro de la caída de la bola, donde sea que esté. Pruebe esto:

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"]; 

Debería ser capaz de mover el punto de control por diferentes caminos.

+0

esto crea una línea recta – choise

+0

¡Exactamente! Entonces, lo que debes hacer es jugar con la variable del punto de control para obtener curvas. Por ejemplo, mueva el valor de x a, digamos 200, para una curva. –

Cuestiones relacionadas