Question

I'm having two issues with the attached code.

First, if I set the animation duration of shape to 1 second so that the shape is always moving then touchesBegan does not fire. When I look through the C4View.m it seems that UIViewAnimationOptionAllowUserInteraction is not set. Is there a way that I could get access to the UIView to set this option? It seems that it would be difficult without rewriting C4View.

http://iphonedevsdk.com/forum/iphone-sdk-development/64569-uiview-animatewithduration-blocks-the-screen-for-touch-input.html

Second, every time the shape is hit I want it to shrink a little bit. The problem I'm having is that after I hit it the first time it stops moving. After some digging it seems that C4Shape loses its shapeness after it is rebuilt with the new frame. Here is the console information before:

[C4Log] <C4Shape: 0x7b63820; baseClass = UIControl; 
frame = (263 691; 200 200); 
animations = { position=<CABasicAnimation: 0x1082c490>; 
animateFillColor=<CABasicAnimation: 0x8a62c00>; 
animateLineDashPhase=<CABasicAnimation: 0x8a64920>; 
animateStrokeColor=<CABasicAnimation: 0x8a64ef0>; 
animateStrokeEnd=<CABasicAnimation: 0x8a65190>; 
animateStrokeStart=<CABasicAnimation: 0x8a65430>; }; 
layer = <C4ShapeLayer: 0x7b63d00>>

and after:

[C4Log] <C4Shape: 0x1082d3a0; baseClass = UIControl; 
frame = (204 17; 180 180); 
layer = <C4ShapeLayer: 0x1082d4e0>>

Setting shape to nil first, or redoing the animations after the redefine do not seem to solve the problem.

CODE

//
//  C4WorkSpace.m
//  touchgame
//
//  Created by Adam Tindale on 2013-09-28.
//

#import "C4WorkSpace.h"

@implementation C4WorkSpace
{
    C4Shape * shape;
    C4Timer * timer;
    C4Label * text; 
    C4Font * font;
    int score;
}

-(void)setup
{
    score = 0;
    shape = [C4Shape ellipse:CGRectMake(self.canvas.center.x, self.canvas.center.y, 200, 200)];

    font = [C4Font fontWithName:@"Chalkduster" size:40];
    text = [C4Label labelWithText:@"Score : 0" font:font];

    [shape setAnimationDuration:0.05];
    timer = [C4Timer automaticTimerWithInterval:1.0 target:self method:@"runaway" repeats:YES];

    [self listenFor:@"touchesBegan" fromObject:shape andRunMethod:@"imhit"];

    [self.canvas addSubview:text];
    [self.canvas addSubview:shape];
}

-(void) runaway
{
    [shape setCenter:CGPointMake([C4Math randomIntBetweenA:0 andB:self.canvas.width], [C4Math randomIntBetweenA:0 andB:self.canvas.height])];

    C4Log(@"%@",shape);
}

-(void) imhit
{
    [text setText:[NSString stringWithFormat:@"Score: %d",++score]];
    [text sizeToFit];

    CGRect r = shape.frame;
    r.size = CGSizeMake(shape.size.width * 0.9, shape.size.height * 0.9);
    shape = [C4Shape ellipse:r];
}

@end
Was it helpful?

Solution

Interactive Animations

C4Control / C4View / C4Window all have an animation option that allows for user interaction during animations. It's part of the C4AnimationOptions struct that can be found in C4Defines.h.

Make sure to call this before you start your animations.

shape.animationOptions = ALLOWSINTERACTION;

And, just like other options it can be bitmasked:

shape.animationOptions = EASEOUT | AUTOREVERSE | ALLOWSINTERACTION;

(You don't have to rework C4View, yet!)

Changing Shape Size

To change a shape's size, you want to call methods on the shape itself like so:

[shape ellipse:r];

The following...

shape = [C4Shape ellipse:r];

... won't work for 3 reasons:

  1. By calling C4Shape you're actually creating a new object, not affecting the one that already exists
  2. By setting shape = [...]; you're changing the pointer from the original shape to the new one that you just created
  3. The new shape doesn't exist on screen, the shape that stops is the original one that you added as a subview. This is why your original shape stops moving, because you're now referencing a new object.

The following code is my modified version of what you have above:

#import "C4WorkSpace.h"

@implementation C4WorkSpace
{
    C4Shape * shape;
    C4Timer * timer;
    C4Label * text;
    C4Font * font;
    int score;
}

-(void)setup
{
    score = 0;
    shape = [C4Shape ellipse:CGRectMake(self.canvas.center.x, self.canvas.center.y, 200, 200)];

    font = [C4Font fontWithName:@"Chalkduster" size:40];
    text = [C4Label labelWithText:@"Score : 0" font:font];

    [shape setAnimationDuration:0.05];
    timer = [C4Timer automaticTimerWithInterval:1.0 target:self method:@"runaway" repeats:YES];

    [self listenFor:@"touchesBegan" fromObject:shape andRunMethod:@"imhit"];

    [self.canvas addSubview:text];
    [self.canvas addSubview:shape];
}

-(void) runaway {
    shape.animationOptions = ALLOWSINTERACTION;
    [shape setCenter:CGPointMake([C4Math randomIntBetweenA:0 andB:self.canvas.width], [C4Math randomIntBetweenA:0 andB:self.canvas.height])];

    C4Log(@"%@",shape);
}

-(void) imhit
{
    [text setText:[NSString stringWithFormat:@"Score: %d",++score]];
    [text sizeToFit];

    CGRect r = shape.frame;
    r.size = CGSizeMake(shape.size.width * 0.9, shape.size.height * 0.9);
    [shape ellipse:r];
}

@end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top