macdevcenter.com
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Animating Graphics in Cocoa, Part 1
Pages: 1, 2, 3, 4, 5

In Interface Builder

As it is, the AnimationView container takes up the entirety of the window. Without changing the size of this container, make the window a little bigger vertically to allow room for some sliders. Add the sliders and some labels as I have done in the image below.



AnimationView

I have configured the sliders such that they are small, and the ranges on the x- and y-speed sliders are 0 to 10, with the default set at 1. These attributes are all set in the Info panel. Now we need to create a controller class. In the nib window, select the Classes tab, and create a subclass of NSObject called AnimationController. You can add outlets and actions to this class by clicking the class name in the list and opening the Info panel. We will have two action methods: one for each slider, and an outlet that gets connected to the AnimationView container. The actions are changeXSpeed: and changeYSpeed:. The outlet is simply called animationView. Now all we need to do is instantiate AnimationController, make the appropriate connections, and create the project files for this class.

Meanwhile, Back at the Ranch -- Speed Control

We now have a controller class that will communicate information between controls with which the user interacts and the animation view. Fundamentally, what we want to happen when the user slides the sliders is for the ball to change speed in the appropriate direction. To do this, we change the stepsize of the translation, dx or dy. This will have the effect of moving the ball a different distance in the same time interval.

Currently, however, no method exists for an outside object to change the AnimationViews values of dx and dy. To enable this, we must add to AnimationView a couple of accessory methods called -setDx: and -setDy:, which will be invoked by AnimationController in its respective action methods. To AnimationView.h add the following method declarations:


- (void)setDx:(float)_dx;
- (void)setDy:(float)_dy;

The implementations of both of these methods is identical, save the xs and ys, so well look only at the first. The method is simple, but has one small catch: the sliders have only positive values, but dx could be positive or negative.

What we would like to happen is for the slider to change the magnitude of dx and not the sign. We dont want to set dx to a positive value if it's negative to begin with, and vice versa. This would result in unnatural and erratic motion.

To get around this, we check the sign of the current value of dx in setDx: and dy in setDy:, and if the sign is negative, we set dx to the negative of the argument value of setDx: and vice versa. One last thing we must do in these two methods is make the affine transform at reflect these changes. This is done in the same three-line way as we did in the -checkCollision: we release at, create a new instance of NSAffineTransform, and then set it to the desired translation. This is what it looks like:


- (void)setDx:(float)_dx
{
    if ( dx < 0 )
        dx = -_dx;
    else 
        dx = _dx;

    [at release];
    at = [[NSAffineTransform transform] retain];
    [at translateXBy:dx yBy:dy];
}

and for setDy:

- (void)setDy:(float)_dy
{
    if ( dy < 0 )
        dy = -_dy;
    else
        dy = _dy;

    [at release];
    at = [[NSAffineTransform transform] retain];
    [at translateXBy:dx yBy:dy];
}

And that's all there is to that. Now, going back to AnimationController, we set up the action methods to invoke these accessory methods. Again, the x and y are analogous. In the method changeXSpeed: we retrieve the new value of the slider, and pass it along to AnimationView via setDx:.


- (IBAction)changeXSpeed:(id)sender
{
    [animationView setDx:[sender floatValue]];
}

and similarly for changeYSpeed:

- (IBAction)changeYSpeed:(id)sender
{
    [animationView setDy:[sender floatValue]];
}

The receiver animationView is, of course, the outlet to the view container AnimationView. Simple as that. Now compile the code, play around with the controllers, and see what happens. While it's all good and well to change the speed of the ball, the fact that the ball stops moving when we use the control is slightly annoying. The solution to this problem is, of course, the next topic of discussion.

Pages: 1, 2, 3, 4, 5

Next Pagearrow