Corona SVG Level Builder 1.3 features and examples!

 

The massive Corona SVG Level Builder 1.3 update has been finally released! It has dozens of new features and it finally comes with examples.

Now you can edit even more of your game properties direct into Inkscape. You will edit Lua source code only to add and take care of your game logic! Let’s take a look at the new features and at the examples!

Resolution Independence and Dynamic Scaling

Draw your levels just once and it will work for all resolutions: iPhone, iPhone Retina, iPad, Android Phones and Android Tablets.
Corona SVG Level Builder - Resolution Independent Levels
It comes with an example showing the resolution independence, so it is easy to achieve it. You just need to worry on exporting the different graphical assets on different sizes, other than that, Corona SVG Level Builder does all the job for you.

Spritesheets

Corona SVG Level Builder now loads and take care of spritesheets created with TexturePacker.

Assigning SpriteTo create levels that use spritesheets you just have to create them with TexturePacker and add one variable with the spritesheet name when you load your levels:

local level = svg:new("levelFile", {spriteGrabber = "game"})

You can have levels with:

  • Single spritesheet.
  • Multiple spritesheets.
  • Externally loaded spritesheets.

Assigning a game object with a sprite is as simple as assigning it with an image: the step is the same! Just add an image attribute with the sprite name.

Animations

Corona SVG Level Builder AnimationsTo add more sauce to the spritesheet support, you can have animated sprites and objects as simple as having static objects. By simple assigning the frame names, giving a pose name and frame positions to a game object, you can animate, change poses and pause it in your code, with methods provided by Corona SVG Level Builder (from SpriteGrabber)!

-- Grab the body with the ID you set
local monkeyNpc = level.bodies.monkeyNpc
-- Call playClip with the pose name
monkeyNpc:playClip("left")

Game Materials

This is one of the coolest additions. You can now define your materials (game objects properties) in an external file and they will persist for all your levels.

As an example let’s consider a game where you have a zombie and a type of block to construct the levels. You need to make 100 levels in Inkscape. If you had to define your block properties along 100 levels, this would be too time consuming. And what if you had to update properties (like friction) from this block? It would require you to manually edit 100 levels.

With game materials, you define and update only once, and the attributes and properties will reflect in all levels for bodies that use the materials name!

local gameMaterials = {
    brick = {
        type = "static",
        image = "brickImageName",
        width = 45,
        height = 20,
        friction = 0.5,
        bounce = 0
    },

    zombie = {
        type = "dynamic",
        image = "zombie",
        frames = "idle:1:1:100:0; walking:2:5:200:0",
        width = 40,
        height = 100,

        custom = {
            health = 120,

            lootRate = {
                coin = 10,
                ammo = 20
            }
        }
    }
}

Custom Attributes

Consider an example game where you add coins, and then you want to set the value of the coin. The “value” can be set as a custom attribute, additionally to all attributes you already add. Other examples could be the health of an enemy type, the score for a breakable block, etc.

That means: you are tweaking and editing game values in Inkscape. You don’t need to edit a line of Lua code!

You can also now set Custom Level Attributes, which allow you to set level specific attributes you can read in you game code. Examples of level attributes are the OpenFeint Leaderboard ID, Level Speed, Highscore ranks (10.000 = 1 star, 12.000 = 2 stars), whenever you need on a higher level just after loading the level, edited all in Inkscape.

Multiple Named Layers, z-ordering and object filtering

Now you can have multiple named layers, which means you can group common objects in your Inkscape drawing and treat them on your code accordingly to the layer they are in.

Also the order they are placed in Inkscape is the order that your game objects will be placed (z-ordering).

Want to put curtains above all your elements? Just move the layer with curtains above the other layers and all your game objects will be covered! I can’t imagine doing that manually in a level with 100+ elements!

Drawing Vectors and Primitives

You don’t need to always assign a sprite or image to your game objects. You now can have them in your game in the same way you drew them in Inkscape: as a rectangle, ellipse or path! Corona SVG Level Builder will even draw them with the fill color, stroke color and stroke size you choose.

Massive Documentation

Well, this isn’t new: the documentation has always been massive. But now it is even bigger! With all the new features it has grown up and got updated. You can check it here: http://levelbuilder.karnakgames.com/doc/.

Examples

Nothing better than learning by practice. Now Corona SVG Level Builder comes with source codes showing each one of its features. Some examples even add some more: what about an example with camera and level scrolling? You have it!

Let’s see a fast video showing the examples in action:

Platformer Game Kit

I’m working now on the Platformer Game Kit! Well, I think the name says it all, right? Along all the dozens and dozens of the Corona SVG Level Builder features, the Platformer Game Kit will be killer. You won’t have anything similar out there.

With the 1.3 update you can already make practically any type of level and game with the Corona SVG Level Builder, while editing your game values and properties all in Inkscape.

But, that is not enough for me: the Platformer Game Kit not only will contain the main features of the classic platformers, but will also come with menus, etc, that means: the source code for a complete game!

What now?

If you don’t have it, what are you waiting for? Go buy it now and save dozens if not hundred hours of development! Or you may consider checking all the features first? Here they are: levelbuilder.karnakgames.com!

Graphics

The 1.3 update uses Free Art Packs made by Vicki Wenderlich – http://www.vickiwenderlich.com/. All credits go to Vicki Wenderlich.

Angry Trolls and what’s coming to Corona SVG Level Builder 1.3

 

I made a slingshot game using Corona SVG Level Builder which features similar stuff as Castle Crusher and Angry Birds: characters expressions, progressive destructible objects, etc. For the shooting logic it uses Beebe’s Ghosts vs. Monsters sample code, but after that it has a complex custom camera and all the additional character and physics fancy features, plus lots of levels.

Initially this game was intended only to show Corona SVG Level Builder features, but I liked working on it so much, that it has grown up as a very playable and polished game (graphics may not look polished, but actually that’s the “troll/meme” style). It has been submitted to the AppStore already. You can follow about it in the official site www.angry-trolls.com and check it in action:

And where does all that stuff relate with Corona SVG Level Builder? First all levels are made in Inkscape and taken care by Corona SVG Level Builder. Take a look at how one of the levels look like in Inkscape:

Angry Trolls level in Inkscape

Upcoming Corona SVG Level Builder features

Next it simply contains everything that is coming to the next update:

  • Spritesheets support (TexturePacker and SpriteGrabber), with multiple spritesheets per level, persistent spritesheets, external spritesheets.
  • Dynamic scaling: draw your level only once and it will work for all resolutions, loading related graphics for the resolution.
  • Multiple layers support.
  • Composite backgrounds (images, vectors, colors).
  • Vector display objects as you draw in Inkscape (the actual support consists only in showing the physics objects assigned with images).
  • Persistent and external game materials: define all your objects in an external table and you can use them accross your SVG elements by assigning the material name to them. This makes life extremely easy, since you have to define objects properties only once. You may be wondering: isn’t there material support already? Yes, there is. But in the actual support you have to define your materials in your SVG level, for every level. This time you define them in an external lua file.
  • Mark objects as non physical.
  • Custom attributes for bodies and materials.

And an extensive list of fixes and small adjustments.

When is the update coming out?

I’m now working on the documentation, a game example and video tutorial and then it will be released!

Corona SVG Level Builder released! Get it now!

 

After two months of work, the Corona SVG Level Builder is here!

Corona SVG Level Builder is a set of libraries to be used in a Corona SDK game that allows you to create Corona SDK physics based games, levels and maps by just drawing in the free and open source vector drawing Inkscape. Everything you draw in Inkscape is automatically converted into Corona physics bodies or paths.

It supports almost every Inkscape tool, allowing the creation of simple (rectangles, ellipses) to very complex physics bodies and paths (bezier paths). Then you can set physical properties and attributes (density, friction, vertices, etc) direct into Inkscape, without ever programming them. It supports all Corona SDK physics properties.

With it you only have to program the game logic itself. You won’t have to worry about element placement and positioning, which can be very time consuming when done by hand.

You can see the complete list of features and buy it on the official page: http://levelbuilder.karnakgames.com.

What kinds of games can you make with it?

With the Corona SVG Level Builder you can create and edit Corona SDK physics based games and levels by just drawing in Inkscape and then setting physics properties with the built in Inkscape XML editor. Corona SVG Level Builder allows you to create very simple levels with just a few elements to very complex levels with lots of physics curves, complex terrains and lots of elements (example: an Incredible Machine like game).
It is a drag and drop level and physics editor.
Examples of games that can be created:
  • Platformers.
  • Top view racing games.
  • Labyrinths and mazes.
  • Slingshot based games.
Basically: any physics based game and level based game.

Big Discount

But even if it took all that time, not all planned features are implemented, including no Game Examples and no Templates. For this reason, it is being released with a price almost 65% off! Buy it now!

* Price increased by $10 on May 30, 2011. It will increase again once the first update is released. So grab it as soon as you can.


Corona SVG Level Builder: Complex Corona physics based terrains with Inkscape paths and bezier curves

 

It’s been more than one month since the first preview of the Corona SVG Level Builder! Since then I made a huge progress. It’s now possible to have any kind of Inkscape drawing as physics 2D bodies and game elements. This is going to be the perfect tool to any kind of physics driven game. I can’t image doing a Bezier curve coordinate by coordinate manually: with the SVG Parser you simply draw a Bezier Curve and it is added to your game as a Box2D static body, enabling perfect collisions and every supported Corona physics interactions.

You can create levels for “traditional” platform games (boxes, circles, curves), as well any kind of terrains, walls, etc. Take a look at this video:

Physics Materials

Next I’ll showcase physics settings and materials as well game elements templates. And then you will be ready to grab it!

Want to know more?

This is still a work in progress, so if you want to hear more about it when it is ready, you can follow me on Twitter: @KarnakGames and/or signup to my Corona Newsletter:

Karnak Games Corona SDK and Corona SDK book newsletter. Your e-mail:

Presenting the drag and drop level editor for Corona SDK with Inkscape and SVG!

 

Inkscape Level Editor for Corona SDK

I’m working on another cool Corona SDK thing along with the book: a SVG based level editor for Corona SDK!

By just dragging and dropping rectangles in an Inkscape* document you can have game levels with physics bodies deployed instantly.

No more manual physics bodies positioning and tuning! Take the pain out of level creation.

* Free and open source vector graphics editor – http://inkscape.org/

Demonstration and level creation process video

Want to know more?

This is still a work in progress, so if you want to hear more about it when it is ready, you can follow me on Twitter: @KarnakGames and/or signup to my Corona Newsletter:

Karnak Games Corona SDK and Corona SDK book newsletter. Your e-mail:

Disclaimer

This is not intended to be a competitor or replacement to the excellent Lime. Lime is totally based on Tiled. My level editor is based on Inkscape and SVG parsing (which is a XML file). Although I make use of Tiled, I don’t use the Tiled map itself, I just use the IMAGE exported from a Tiled map (File, Save as Image…).

Transition Manager for Corona SDK: Pause, Resume and Manage all transitions in a scene

 

UPDATE: Transition Manager is outdated and lacks features. Instead, I recommend that you check and use this: http://developer.anscamobile.com/code/pausable-timers-and-transitions-speed-adjustment.

Actually to pause a transition in Corona, you have to cancel it. Then to resume it later, you have to keep track of the elapsed time and create the transition again. That means, it still doesn’t have a pause and resume function. For this reason I’ve created the class “TransitionManager” that keeps track of all transitions in a Corona scene and allows you to pause, resume and cancel them all at once.

This totally simplifies dealing with interruptions, pausing and resuming the game or simply moving to another scene. I won’t explain it here, instead, you can watch the following video and download the class and example code from GitHub.

Announcing the first Corona SDK book

 

This is something that has been on the works and I feel it’s time to start talking about it already!

I’m writing the first dedicated book about the Corona SDK, and it will be published by a very good and known publisher. Although I can’t reveal which one yet.

The book will be beginner focused, but that doesn’t mean you won’t learn advanced subjects. Also if you already are a programmer or game developer, it will help you learn Lua and the whole Corona SDK.

You will learn Lua and almost all details of the Corona SDK. The book will be tutorial and example driven: you won’t read boring texts about this or that. You will be actually making games while learning Corona! It will be a ready-to-action book.

I will try to give weekly previews about the book, this way I can get your feedback of what you think and expect. Expect more news soon!

Getting news about the book

There is nothing fancy set yet, but you can already like the Facebook page for the book, add the book’s official site to your bookmarks or follow me on Twitter, @KarnakGames.

Book newsletter. Your e-mail:

The last #iDevBlogADay for now

#iDevBlogADay has new rules, and for this reason, I have to give my spot to another person. It’s been almost 6 months of writing 4 posts per month. It was a pleasant and nice experience. And I could say that my time is over in a good moment: I have to focus on the book as well on the dozens of game development contracts I have on my hands.

That doesn’t mean the blog is over. I will keep writing and updating here, probably not weekly, but at least monthly (or weekly for the book previews). You can find constant updates from me on my Twitter @KarnakGames.

With #iDevBlogADay, my blog went from 200 visits/monthly to more than 4000, which is stable now. Thanks Miguel and all the community for the amazing #iDevBlogADay! And good luck for the blogger that is taking my spot.

How to make a simple physics based shooter game with the Corona SDK

 

Corona Simple ShooterIn this article I’ll share with you a very super simple shooter with Corona. The aim of this code is to show you how simple is to setup physic based behaviors with the Corona SDK, how to setup a game loop, handle basic touches, score system and play sound effects.

About the game

  • We have the player (which is a plane) and this plane is constantly shooting bullets automatically with random speed.
  • Physics based, where the enemies just fall down thanks to the gravity, so we don’t need to worry about moving them.
  • The player and the bullets are of the type “kinematic” so they aren’t affected by gravity.
  • For each bullet that hits an enemy plane, we earn one point, show on the top left of the screen.
  • The only way of losing the game is colliding with an enemy plane.
  • There is pew-pew!

The Complete Game with Assets

I’m using 3 sprites from the SpriteLib by Ari Feldman (those sprites are under GPL, which means we can freely using it under some conditions). For the sounds I used the excellent cfxr.

Download everything here.

NOTE: the code is not ready for production use.

The Source Code

Here is the complete code for the game. It is commented, and you can read it up down, it is placed in a form of tutorial. If you have any doubts/questions, please drop a comment below.

The game code itself without comments is around 150 lines. Also it took me around 20 minutes to make. So you bet it? How simple is that? :)

-- Hide status bar, so it won't keep covering our game objects
display.setStatusBar(display.HiddenStatusBar)

-- Load and start physics
local physics = require("physics")
physics.start()

-- A heavier gravity, so enemies planes fall faster
-- !! Note: there are a thousand better ways of doing the enemies movement,
-- but I'm going with gravity for the sake of simplicity. !!
physics.setGravity(0, 20)

-- Layers (Groups). Think as Photoshop layers: you can order things with Corona groups,
-- as well have display objects on the same group render together at once.
local gameLayer    = display.newGroup()
local bulletsLayer = display.newGroup()
local enemiesLayer = display.newGroup()

-- Declare variables
local gameIsActive = true
local scoreText
local sounds
local score = 0
local toRemove = {}
local background
local player
local halfPlayerWidth

-- Keep the texture for the enemy and bullet on memory, so Corona doesn't load them everytime
local textureCache = {}
textureCache[1] = display.newImage("assets/graphics/enemy.png"); textureCache[1].isVisible = false;
textureCache[2] = display.newImage("assets/graphics/bullet.png");  textureCache[2].isVisible = false;
local halfEnemyWidth = textureCache[1].contentWidth * .5

-- Adjust the volume
audio.setMaxVolume( 0.85, { channel=1 } )

-- Pre-load our sounds
sounds = {
	pew = audio.loadSound("assets/sounds/pew.wav"),
	boom = audio.loadSound("assets/sounds/boom.wav"),
	gameOver = audio.loadSound("assets/sounds/gameOver.wav")
}

-- Blue background
background = display.newRect(0, 0, display.contentWidth, display.contentHeight)
background:setFillColor(21, 115, 193)
gameLayer:insert(background)

-- Order layers (background was already added, so add the bullets, enemies, and then later on
-- the player and the score will be added - so the score will be kept on top of everything)
gameLayer:insert(bulletsLayer)
gameLayer:insert(enemiesLayer)

-- Take care of collisions
local function onCollision(self, event)
	-- Bullet hit enemy
	if self.name == "bullet" and event.other.name == "enemy" and gameIsActive then
		-- Increase score
		score = score + 1
		scoreText.text = score

		-- Play Sound
		audio.play(sounds.boom)

		-- We can't remove a body inside a collision event, so queue it to removal.
		-- It will be removed on the next frame inside the game loop.
		table.insert(toRemove, event.other)

	-- Player collision - GAME OVER
	elseif self.name == "player" and event.other.name == "enemy" then
		audio.play(sounds.gameOver)

		local gameoverText = display.newText("Game Over!", 0, 0, "HelveticaNeue", 35)
		gameoverText:setTextColor(255, 255, 255)
		gameoverText.x = display.contentCenterX
		gameoverText.y = display.contentCenterY
		gameLayer:insert(gameoverText)

		-- This will stop the gameLoop
		gameIsActive = false
	end
end

-- Load and position the player
player = display.newImage("assets/graphics/player.png")
player.x = display.contentCenterX
player.y = display.contentHeight - player.contentHeight

-- Add a physics body. It is kinematic, so it doesn't react to gravity.
physics.addBody(player, "kinematic", {bounce = 0})

-- This is necessary so we know who hit who when taking care of a collision event
player.name = "player"

-- Listen to collisions
player.collision = onCollision
player:addEventListener("collision", player)

-- Add to main layer
gameLayer:insert(player)

-- Store half width, used on the game loop
halfPlayerWidth = player.contentWidth * .5

-- Show the score
scoreText = display.newText(score, 0, 0, "HelveticaNeue", 35)
scoreText:setTextColor(255, 255, 255)
scoreText.x = 30
scoreText.y = 25
gameLayer:insert(scoreText)

--------------------------------------------------------------------------------
-- Game loop
--------------------------------------------------------------------------------
local timeLastBullet, timeLastEnemy = 0, 0
local bulletInterval = 1000

local function gameLoop(event)
	if gameIsActive then
		-- Remove collided enemy planes
		for i = 1, #toRemove do
			toRemove[i].parent:remove(toRemove[i])
			toRemove[i] = nil
		end

		-- Check if it's time to spawn another enemy,
		-- based on a random range and last spawn (timeLastEnemy)
		if event.time - timeLastEnemy >= math.random(600, 1000) then
			-- Randomly position it on the top of the screen
			local enemy = display.newImage("assets/graphics/enemy.png")
			enemy.x = math.random(halfEnemyWidth, display.contentWidth - halfEnemyWidth)
			enemy.y = -enemy.contentHeight

			-- This has to be dynamic, making it react to gravity, so it will
			-- fall to the bottom of the screen.
			physics.addBody(enemy, "dynamic", {bounce = 0})
			enemy.name = "enemy"

			enemiesLayer:insert(enemy)
			timeLastEnemy = event.time
		end

		-- Spawn a bullet
		if event.time - timeLastBullet >= math.random(250, 300) then
			local bullet = display.newImage("assets/graphics/bullet.png")
			bullet.x = player.x
			bullet.y = player.y - halfPlayerWidth

			-- Kinematic, so it doesn't react to gravity.
			physics.addBody(bullet, "kinematic", {bounce = 0})
			bullet.name = "bullet"

			-- Listen to collisions, so we may know when it hits an enemy.
			bullet.collision = onCollision
			bullet:addEventListener("collision", bullet)

			bulletsLayer:insert(bullet)

			-- Pew-pew sound!
			audio.play(sounds.pew)

			-- Move it to the top.
			-- When the movement is complete, it will remove itself: the onComplete event
			-- creates a function to will store information about this bullet and then remove it.
			transition.to(bullet, {time = 1000, y = -bullet.contentHeight,
				onComplete = function(self) self.parent:remove(self); self = nil; end
			})

			timeLastBullet = event.time
		end
	end
end

-- Call the gameLoop function EVERY frame,
-- e.g. gameLoop() will be called 30 times per second ir our case.
Runtime:addEventListener("enterFrame", gameLoop)

--------------------------------------------------------------------------------
-- Basic controls
--------------------------------------------------------------------------------
local function playerMovement(event)
	-- Doesn't respond if the game is ended
	if not gameIsActive then return false end

	-- Only move to the screen boundaries
	if event.x >= halfPlayerWidth and event.x <= display.contentWidth - halfPlayerWidth then
		-- Update player x axis
		player.x = event.x
	end
end

-- Player will listen to touches
player:addEventListener("touch", playerMovement)

How to take in-game screenshots with Cocos2D and upload them to a Facebook album

 

I’ll be covering a very cool feature to add a new social feature in your game: posting in-game screenshots straight from the game to a Facebook album! I managed to do it today for a client game and it worked smoothly, so why not sharing?

What is covered in this article?

  1. Taking a screenshot via code from your Cocos2D game and storing it in an UIImage.
  2. Integrating Facebook into your Cocos2D game.
  3. Posting the screenshot to the Facebook account of the player (upon permission).

Taking Screenshots in Cocos 2D

This step was the easiest one for me. Oh wait, it’s not that easy to take a screenshot of the actual state of your game: what I have done was using a code written by Manu Corporat (Infinity Field developer). Grab the “Cocos2D Screenshot” methods here and add them inside the class CCDirectorIOS (cocos2d/Platforms/iOS/CCDirectorIOS.m) – it works for iPhone, iPhone 4 and iPad screenshots, e.g. all iOS devices and versions.

You can now take screenshots from your game by just calling:

UIImage *screenshot = [[CCDirector sharedDirector] screenshotUIImage];

You can even save this image in a folder (or even the Photo Album):

NSString *savePath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/Screenshot.png"];

// Write image to PNG
[UIImagePNGRepresentation(tempImage) writeToFile:savePath atomically:YES];

Integrating Facebook into your Cocos2D game

- First of all, Setup a New App on Facebook: http://www.facebook.com/developers/. Once the application is created, click on the left tab “Mobile and Devices”, change the “Application type” to “Native App” and copy the “Application ID”.

- Open your Xcode project and add the following keys to your info.plist: Key: URL types -> Key: Item 0 -> Key: URL Schemes -> Key: Item 0 -> Value: fbYOUR_APP_ID (include the fb), it should look like:

Facebook - info.plist

- Clone the Facebook iOS-SDK from Git: https://github.com/facebook/facebook-ios-sdk.

Drag the “src” folder into your Xcode project.

- If you want the official “Login with Facebook” blue button, open the folder “sample” that you cloned with the Facebook SDK, and right click “FBConnect.bundle” -> Show Package Contents -> copy and paste the images you want in your Cocos2D project. Consider renaming @2x to -hd.

- Import FBConnect.h into your Cocos2D Scene or Layer, the one in which you want to open the Facebook connection:

#import "FBConnect.h"

- Your class interface has to implement the Facebook delegates, as well have some members:

@interface HelloWorld : CCLayer
{
	// Facebook
	Facebook *facebook;
	BOOL isFBLogged;

	// GUI
	CCLayer *shareLayer;
	CCMenuItem *facebookLoginButton, *facebookLogoutButton;
	CCLabelTTF *message;
}

- Add the GUI to handle facebook messages, as well the Login button (in this case you do as you wish, the way I’m doing is just an easy example). Although my GUI code is just an example, note that I’m inserting them inside a child CCLayer. When we are going to take the screenshot, we won’t want the Facebook button in the screenshot, nor the label saying “SHARE”, so I’ll just turn visibility of the layer on and off, instead of turning every element individually.

-(id) init
{
	if( (self=[super init] )) {
		CGSize size = [[CCDirector sharedDirector] winSize];

		CCSprite *gameElement = [CCSprite spriteWithFile:@"poolplane.png"];
		gameElement.position = ccp(size.width * .5, gameElement.contentSize.height * .5);
		[self addChild:gameElement];

		shareLayer = [CCLayer node];
		[self addChild:shareLayer];

		facebookLoginButton = [CCMenuItemImage itemFromNormalImage:@"LoginWithFacebookNormal.png" selectedImage:@"LoginWithFacebookPressed.png" disabledImage:@"LoginWithFacebookPressed.png" target:self selector:@selector(facebookLogin)];

		CCMenu *fbMenu = [CCMenu menuWithItems:facebookLoginButton, facebookLogoutButton, nil];
		fbMenu.position = ccp(size.width * .5, size.height * .5 + facebookLoginButton.contentSize.height * 3);
		[shareLayer addChild:fbMenu];

		message = [CCLabelTTF labelWithString:@"Share in Facebook!" fontName:@"Marker Felt" fontSize:24];
		message.position = ccp(size.width * .5, fbMenu.position.y + facebookLoginButton.contentSize.height);
		[shareLayer addChild:message];
	}
	return self;
}

Logging in into Facebook and getting permissions

We may enable the user to login into his Facebook account by simply calling the Facebook:authorize method passing in the permissions we want to get. We also may already hide unecessary items for the screenshot before calling the Facebook authorize method. You will know why later on.

- (void) facebookLogin
{
	// The screenshot is going to be taken instantly after the login,
	// so already hide GUI/unecessary stuff
	shareLayer.visible = NO;

	if (facebook == nil) {
		facebook = [[Facebook alloc] initWithAppId:@"FACEBOOK-APP-ID"];
	}	

	NSArray* permissions =  [[NSArray arrayWithObjects:
							  @"publish_stream", @"offline_access", nil] retain];

	[facebook authorize:permissions delegate:self];
}

Now we implement the delegate functions to handle the login request responses. They are very simple. The game will take the screenshot right after logging in (inside FBSessionsDelegate:fbDidLogin) and that is why we’ve hidden the GUI before logging in (the takeScreenshot screen is detailed below).

#pragma mark -
#pragma mark FBSessionDelegate
/**
 * Called when the user has logged in successfully.
 */
- (void)fbDidLogin {
	isFBLogged = YES;
	[self takeScreenshot];
}

/**
 * Called when the user canceled the authorization dialog.
 */
-(void)fbDidNotLogin:(BOOL)cancelled {
	if (cancelled) {
		[message setString:@"Login cancelled. No Login, No Share, No Game! :)"];
	} else {
		[message setString:@"Error. Please try again."];
	}

	shareLayer.visible = YES;
}

Taking the screenshot, uploading to Facebook and handling the responses

This is where the real magic happens: sending the screenshot to Facebook. It’s a very simple GRAPH API call to “me/photos” that sends the UIImage we make with the CCDirector:screenshotUIImage method.

According to the documentation this call uploads an image to the application’s album in the user account: “We automatically create an album for your application if it does not already exist. All photos from your application will be published to the same automatically created album.”

- (BOOL) takeScreenshot
{
	UIImage *tempImage = [[CCDirector sharedDirector] screenshotUIImage];

	NSMutableDictionary* params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
								   tempImage,@"message",
								   nil];

	[facebook requestWithGraphPath:@"me/photos"
						 andParams:params
					 andHttpMethod:@"POST"
					   andDelegate:self];

	[message setString:@"Uploading screenshot. Please wait..."];
	shareLayer.visible = YES;

	return YES;
}

The last step is handling the responses: the upload may fail or be successful. For the first case we would need to alert the user about the error andshow the Facebook button again and enable a new upload, for the later we have to show a positive notification for the user. In both case we need to show the GUI layer again.

#pragma mark -
#pragma mark FBRequestDelegate
/**
 * Called when a request returns and its response has been parsed into
 * an object. The resulting object may be a dictionary, an array, a string,
 * or a number, depending on the format of the API response. If you need access
 * to the raw response, use:
 *
 * (void)request:(FBRequest *)request
 *      didReceiveResponse:(NSURLResponse *)response
 */
- (void)request:(FBRequest *)request didLoad:(id)result {
	[message setString:@"Photo posted in the \"APP NAME\" album on your account!"];
	shareLayer.visible = YES;

}

/**
 * Called when an error prevents the Facebook API request from completing
 * successfully.
 */
- (void)request:(FBRequest *)request didFailWithError:(NSError *)error {
	[message setString:@"Error. Please try again."];
	shareLayer.visible = YES;
}

Example/Template project

I’ve packed everything in a Cocos2D Xcode project, ready to be used and compiled: just change your Facebook App’s ID and adapt in your project.
Download the example project here.

This post is part of iDevBlogADay, a group of indie iOS development blogs featuring two posts per day. You can keep up with iDevBlogADay through the web site, RSS feed, Twitter.

Tips #1: Cornerstone, AgileZen and Compressed Cocos2D textures with Texture Packer

 

I’m really busy this week, so this is not an article. I wanted to share some tips from what I’ve been dealing recently, that I found to be very useful.

Cocos2D pixel formats and highly compressed textures with Texture Packer

One of the games I’m working on has dozens of sprite sheets, and most of them are 2048×2048. That is a killer even for the iPhone 4 and iPad, and I can’t even consider older devices.

Consider using 4 Sprite Sheets at once that are 2048×2048 each and PNG: the game wouldn’t even run, because the consumed memory would be too big. Also, the loading times would be terrible.

What is the solution?

  1. Get Texture Packer.
  2. Group background images and other squared sprites in the same sprite sheet, choose the RGB565 pixel format, select “FloydSteinberg+Alpha” as the Dithering algorithm and export it as a compressed PVR texture (pvr.ccz). BINGO! The image looks the same as 32-bits pixel format, the file size is smaller than PNG, and the loading time is decreased from around 15s to 1s (at least with my 2048×2048 spritesheet!).
  3. For sprites with alpha/transparency required, you may use RGBA4444 + FloydSteinberg+Alpha for those with a few to no gradients, or even RGBA8888, but in both cases export them as pvr.ccz! Using RGBA4444 reduces the memory usage by half. For RGBA8888 you still have the same memory usage, but since it is pvr.ccz, at least the loading times are cut.The problem is that most of the times RGBA4444 looks bad, so you may give a chance to RGGBA8888 + PVR.CCZ.

To learn more about Texture Packer and Cocos2D textures, read How to Create and Optimize Sprite Sheets in Cocos2D with Texture Packer and Pixel Formats by Ray Wenderlich!

On the end: Texture Packer is probably the most important tool for a Cocos2D developer.

The real good Mac SVN Client: Cornerstone!

After I wrote the last article dealing with SVN, where I recommended Versions as the best Mac client, I received lots of suggestions in Twitter and in the comments to use Cornerstone. I decided to try it, and now I can’t even open Versions anymore. The only problem is buying another $59 license!

From a tweet I posted (that got retweeted by the developers of Cornerstone): “After using Cornerstone for some days, I can’t even use Versions anymore. It lacks everything and looks old. #svn”.

AgileZen and Lean project management

Got to know about agile lean project management yesterday, which lead me to meet AgileZen – probably the simplest project management system on earth, yet probably the most efficient.

You can read a good overview of AgileZen here: AgileZen for Solo Remote Development.

This post is part of iDevBlogADay, a group of indie iOS development blogs featuring two posts per day. You can keep up with iDevBlogADay through the web site, RSS feed, Twitter.