Category Archives: Apps

Compiling to Android

I ran into a really interesting, some might say frustrating, quirk of the Apportable Engine.

In order to get XCode to compile on the Android OS, it turns out that you have to explicitly add any file or resource that your project is going to use to your project.

In order to do this, first navigate to the Build Phase Tab in you Project Navigator.

Then, in the Compile Sources Section you’ll have to manually add references to your Class files.

Apportable_Adding Code

Then, in the Copy Bundle Resources Section you’ll have to manually add references to you resource file.

Apportable_Adding Reseources

 

And that should clear up the error.

Platform Generation

Now that we have our Grid Laid out, we can move on with our Platform Generation Methods.

Our platform generation algorithm will break down into 5 Steps:
1. We will create a new sprite node for our Platform.
2. We will use the methods we developed last time to determine the position of our Platform.
3. We will set the Physics attributes of our Platform (in our case we will treat our Platforms like SKPhysicsBody).
4. We will add the Platform to our PlatformNode.
5. We will add the Platform to our Platform Buffer of our PlatformNode.

IMG_0671

Here’s our code for this algorithm:

– (void) generatePlatformAtPosition:(CGPoint) mapPosition
{
// 1. Create a new SKSpriteNode
SKSpriteNode *newPlatform = [SKSpriteNode spriteNodeWithTexture:self.platformBrickTexture];

// 2. Set the Position by converting the grid coordinate system to the coordinate of the Scene
newPlatform.position = [self convertMapCoordinateToWorldCoordinate:mapPosition];

// 3. Set Up the Physics Attributes
newPlatform.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(self.platformBrickTexture.size.width,
self.platformBrickTexture.size.width)];
newPlatform.physicsBody.dynamic = NO;
newPlatform.physicsBody.restitution = 0.0f;
newPlatform.physicsBody.friction = 1.0f;

// 4. Add the SKSpriteNode to our Platform Node
[self addChild:newPlatform];

// 5. Add the SKSpriteNode to our Platform Buffer
[platformBlockBuffer addObject:newPlatform];
}

Now we can add a platform at whatever position we want.

Next time we’ll start adding and removing the platforms dynamically.

Hooray!

Positioning the Platforms – Dos Equis

Last time we built a function to add Platforms to our Scene at a specified point, so we can place our platforms wherever we want! All we need is an X-Y Coordinate in our tile grid that we’ve already developed here:

But just getting the platforms scrolling along our scene is really the easy part; the tricky part is developing a procedure to place them in order to make our game looked like a pre-designed platform level.

There are two parts to this issue: getting an X-coordinate, and getting a Y-coordinate. The first part will be fairly easy, and the second part will take a bit more design work.

To select our Platform’s X-Coordinate, we’ll use the platform buffer we developed previously.

If you recall, the entire point of our platform buffer was to hold all of our Platform Nodes as they scroll across the screen. This means that if  we can visualize our platform buffer as a line of Platform Nodes positioned across the screen, with the first Platform Node in our Platform Buffer as being the first Platform Node in a line of across the screen and the last Platform Node in our Platform Buffer as being the last Platform Node in a line of across the screen.

This is a pretty key concept, here! What this concept allows us to do is simply use a Platform’s position in the Platform Buffer as it’s X-Coordinate.

We’ll implement this in a new method below:

AddPlatform_01

This method will add a new platform, using the generate platform method we developed previously. We place the platform at the end position of our platform buffer.

For now we’ve got the platform’s X-coordinate sorted out, and we just place at a height of 4 four now, but we’ll be changing that later.

Coordinate Conversions

Last time, I held off on going over our method to add Platforms to our SKScene. The reason I did this is because I wanted to take some time to go over a bit of background before diving headfirst into the code.

This time I’m going to go over the coordinate system that we’ll use to place our Platforms.

The strategy that we’ll use is to break our SKScene into a grid. Every column of our grid will have exactly one Platform, so the width of our grid will be the size of our  Platform Buffer and the size of each square of our grid will be the size of our Platforms.

The trick is going to be finding a way to change the coordinates of our grid to the coordinates of our SKScene.

To do this, we’ll add two new methods to our PlatformNode  class:

- (CGPoint) convertGridCoordinate ToSceneCoorindate:(CGPoint)gridCoordinate {return CGPointMake(gridCoordinate .x * self.platformBrickTexture.size.width,
gridCoordinate .y * self.platformBrickTexture.size.height + self.platformBrickTexture.size.height / 2);}
– (CGPoint) convertSceneCoorindateToGridCoordinate :(CGPoint)sceneCoorindate
{return CGPointMake(roundf(sceneCoorindate.x / self.platformBrickTexture.size.width),
roundf((sceneCoorindate.y – self.platformBrickTexture.size.height/2)/self.platformBrickTexture.size.height) );}

 

These two methods will convert a CGPoint between the coordinate system of our grid and the coordinate system of our SKScene.

Buffing Up Our Platforms

Last time we built a quick class to get our scene moving, but that’s not particularly helpful until we have something to move. In this post, we’ll add a set of platforms to our scene.

This first step is to create a new class that sub-classes our ScrollingNode that we built in the last post.

#import “ScrollingNode.h”
@interface PlatformNode : ScrollingNode
@end

This will ensure that whatever we add to this whatever we add to our PlatformNode will be able to scroll at whatever speed we decide, which was the point of our work in the last post.

Now that we have a class to get things started (or scrolled), we will build a way to keep track of a set of platforms.

One of the advantages of using a procedural level generator, is that it can lower our overhead when it comes to keeping a number of  large map or level in system memory. So, as we build our platform side-scroller we have to keep in mind that we want to limit the total number of platforms that our program will need to keep track of at any given time.

To do this, we’ll build a platform buffer to limit the number of platforms we track. Change our PlatformNode.h file as shown below:

@interface PlatformNode : SKScrollingNode
{
NSMutableArray *platformBlockBuffer;
}
@property (nonatomic) NSUInteger platformBufferSize;
@end

 

What we’ve done is to add:

  1. A Mutable Array that can store any number of objects. We’ll use this to store our Platform Nodes.
  2. An Integer to track how many Platform Nodes we’ll keep track of.

The next step is to make sure these two variables get set up correctly; in our PlatformNode.m file, change our init method as shown below:

- (id) init
{
if (( self = [super init] ))
{
platformBlockBuffer = [[NSMutableArray alloc] init];
self.platformBufferSize = 10;// Generate the first set of platform tiles on the Ground
for (int i = 0; i < self.platformBufferSize; i++)
{
// Generate a New Platform
}
}
return self;
}

 

All this code does is to:

  1. Instantiate our Platform Buffer array.
  2. Set our Platform Buffer size to a default value (I’ve just used 10 here because it’s easy.
  3. Added a loop that will fill up our Platform Buffer.

Now all we’ll need to do is to come up with a way to Generate our Platforms, which we’ll do in our next post.

Apportable CCClippingNode Problem

I had some trouble with the CCClippingNode on the Apportable Compiler earlier this week. I had it working perfectly well in iOS, but when I cross-compiled my application to Android, my CCClippingNode wasn’t working and all I was getting was this lovely little error message:

 [CCClippingNode initWithStencil:]_block_invoke : Stencil buffer is not enabled; enable it by passing GL_DEPTH24_STENCIL8_OES into the depthFormat parrameter when initializing CCGLView. Until then, everything will be drawn without stencil.

The solution to this problem is actually pretty simple. We will need to modify function setupView:  in Platforms/Android/CCGLView.m.

CCGLView is setting the depth and stencil size to 0 when it calls its eglChooseConfig method. In order to get non-zero values, we’ll have to add the data to our CCGLView class manually.

This can be done by adding the following two lines to structure configAttribs[] (at the very beginning of function setupView:)

Apportable_CCClippingNode_01

And Voila! We’ve got our CCClippingNode starting to clip contents on Android too.