2011-11-06 8 views
5

così la mia versione attuale si presenta così: Animation Movieanimato punto più volte e in modo più naturale

io sono abbastanza nuovo per core-animazioni, quindi quello che cerco di realizzare è che ci sono più punti, come quello attuale, muovendo dalla scatola di sinistra in vari angoli, altezze e velocità fuori di esso, proprio come una macchina da palla da tennis.

enter image description here

il primo problema è, che il mio "palla" non sembra che venga afferrato dalla gravità e anche la velocità in un primo momento non è abbastanza veloce.

anche, come fare questa animazione più volte con variando le distanze tra l'inizio.

se qualcosa non è chiaro, si prega di lasciare un commento.

il mio codice corrente:

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

Suggerirei che si guarda utilizzando [cocos2d/box2d] (http://www.cocos2d-iphone.org/) per eseguire il "animazione "come una simulazione fisica. Questo è quello che sembra che dovrebbe essere, se vuoi la gravità e il movimento delle particelle realistici. – aroth

+0

penso di non aver bisogno di una tale dipendenza. è solo per una vista singola (e non molto importante) nella mia applicazione. – choise

+0

Dato che stai cercando di incorporare la fisica di base alla palla, l'utilizzo di CADisplayLink e l'animazione della palla cambieranno ripetutamente la sua posizione in modo accettabile? Qualcuno ha qualcosa contro questa soluzione? –

risposta

1

Il modo più semplice per modellare la gravità è con quelle equazioni paraboliche che si impara in fisica di base. In breve, la funzione seguente assume una posizione iniziale, una velocità e un angolo (IN RADIANI, dove 0 è a destra). un CALayer appare in posizione e viene colpito a tale velocità e angolazione.

sto usando un CADisplayLink (che è effettivamente un timer che si sincronizza con il vostro frame rate) per chiamare una funzione molto rapidamente. Ogni volta che viene chiamata la funzione, il punto viene spostato. La velocità orizzontale è costante e la velocità verticale aumenta verso il basso ogni fotogramma per emulare la gravità (`vy = 0.5f;). Se vuoi più/meno gravità, gira solo con questo valore 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]; 
    } 
} 

e l'interfaccia:

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

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

@end 
1

penso che ci possa essere un paio di cose che si possono fare qui.
- Uno è quello di utilizzare al posto di kCAMediaTimingFunctionLinear kCAMediaTimingFunctionEaseOut.
- L'altro è quello di impostare il punto di controllo nel centro di caduta della palla, ovunque esso sia. Prova questo:

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

Dovresti quindi essere in grado di spostare il punto di controllo intorno per percorsi diversi.

+0

crea una linea retta – choise

+0

Esattamente! Quindi quello che dovresti fare è giocare con la variabile del punto di controllo per ottenere le curve. Ad esempio, sposta il valore x su, diciamo 200, per una curva. –

Problemi correlati