Andy B
Andy B

Reputation: 515

CALayers Multiple Layers Based Off Of One Layer

I am currently trying to make a 2D game with Core Animation that is based off of CALayers. I have already figured out the user sprite layer, but now it comes down to the game objects.

The objects (which the user must avoid), will fall down from the top of the screen, and disappear if they never come in contact with the user. However, because all these obstacles will all be the same, I decided to have a separate .h and .m that define the object, and have a couple lines of code that make each obstacle "come into the game".

Bottom line, I have two questions: 1. How would I "import" each obstacle into the main view as a CALayer? Is having separate files for the obstacles the best way of doing things, even though the obstacles are just one image?

Upvotes: 2

Views: 617

Answers (2)

Charliehorse
Charliehorse

Reputation: 313

I have been working on a 2D tower defense game and have a pretty good solution to this. You want to make an object class for your obstacles, and store them in an array. When the obstacle makes it to the bottom of the screen, it is not destroyed but rather just hidden. When you want to create a new obstancle, you first try and recycle the old ones before creating a new one. I use this to handle thousands of different CALayer objects without hassle.

-(void)newObstacleAtLocation:(CGPoint)newPosition;
{
    //create the array if it doesn't already exist - could add this to your init
    if(!obstacles)
    {
        obstacles = [NSMutableArray array];
    }
    for(obstacle* anObstacle in obstacles)
    {
        //find the first hidden coin and use it
        if(anObstacle.hidden)
        {
            //reset the obstacles position to where you want the "new" obstacle
            obstacle.position = newPosition;
            obstacle.hidden = NO;
            return;
        }
    }
    //didn't find any unused obstacles - make a new one
    [obstacles addObject:[[[obstacle alloc]initWithSuperLayer:self.mapLayer] autorelease]];
}

Upvotes: 1

Troy
Troy

Reputation: 21

If you've already figured out the user sprite, you've likely encountered addSublayer:, which is called on another layer to add it to the layer tree. Fundamentally, to add obstacles you need to instantiate a new layer for one with -[CALayer layer], configure it, and [rootLayer addSublayer:obstacle];

Now for your question about separate files: Creating a new class with it's own header and implementation is a great idea. But just do one class (meaning one .h/.m pair) for defining how an Obstacle works, and create many instances of it by issuing the -[[Obstacle alloc] init] call (make sure to release them when they are no longer visible!)

How does "Obstacle" get imported and visible? You would most likely put a variable in the @interface{} of Obstacle which is a CALayer type. The GameBoard (or ViewController for very simple prototypes/apps) could have a method -addObstacle: which takes an Obstacle, asks it for it's layer and adds it to the rootLayer.

In trying to be thorough, I may have missed the jist of your question which was more along the lines of, "Should I have an Obstacle class at all, or just an obstacles array filled with CALayers?" You could certainly do it that way given the description of the game. But as soon as you want to start keeping any information about individual Obstacle instances you're better off having the objects themselves answer questions about that information. I've done a ton of prototype/test apps that simply have an array of layers, because although CALayer is firmly in the View sphere of MVC, it often contains all the model information I need: x,y, bounds, color, contents, etc. Anything I turned into a real app though had to have large portions re-written for maintainability.

Upvotes: 2

Related Questions