Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon
26. October 2014

 

As I mentioned earlier in the introduction to Codea, it does not support Spritesheets out of the box. I also mentioned earlier that it was a fairly simple thing to add. In this tutorial I am going to show how I created a class in Codea for enabling sprite sheets, which can also serve as a bit of an introduction to non-trivial Codea development.

 

A spritesheet is simply a number of sprite graphics that have put together into a single image.  This often results in better performance because of more efficient memory usage, as well as quicker load times and easier asset management.  There area  number of spritesheet creation tools such as TexturePacker which I discussed how to use here and here.  I am also using the spritesheet graphic mentioned in this post.  It’s important to realize that tools like TexturePacker can create very tightly packed sheets that rotate textures to fit them in best.  In this case however, we are expecting our textures to be arranged in a simple grid pattern.

 

Let’s jump right in to Codea and create a new project.  At the home screen simply click the Add New Project button shown below:

IMG 0280

 

In the resulting dialog, name your project, I’m going with SpritesheetDemo.  When done, click Create.  In my case the create button is slightly bugged, in that case, click slightly to the left of it.

IMG 0283

 

This will now bring you to the main code editing page.  It will start with the following simple “Hello World” code:

 

-- SpritesheetDemo

 

-- Use this function to perform your initial setup

function setup()

   print("Hello World!")

end

 

-- This function gets called once every frame

function draw()

   -- This sets a dark background color 

   background(40, 40, 50)

 

   -- This sets the line thickness

   strokeWidth(5)

 

   -- Do your drawing here

 

end

 

 

What we want to do now is add a new class for our Spritesheet, simply click the + icon in the top right corner of the Codea screen:

IMG 0279

 

Now select Create New Class

IMG 0278

 

In the text field, enter Spritesheet as the name:

IMG 0281

 

It will start with an empty class definition, we will replace it will this code:

Spritesheet = class()

 

function Spritesheet:init(img,x,y,rows,cols,frameWidth,frameHeight,frame,totalFrames)

   self.x = x

   self.y = y

   self.frame = frame

   self.totalFrames=totalFrames

 

   self.frameWidth = frameWidth

   self.frameHeight = frameHeight

   self.frameRows = rows

   self.frameCols = cols

   self.frameSize = vec2(self.frameWidth,self.frameHeight)

 

   self.counter = 0

 

   self.mesh = mesh()

   --self.texture = img

   self.mesh.texture = img -- self.texture

   self.mesh:addRect(0,0,self.frameWidth,self.frameHeight)

end

 

function Spritesheet:draw()

 

   self.counter = self.counter + DeltaTime

   if self.counter > 1/30 then

 

   self.frame = self.frame + 1 

   if self.frame > self.totalFrames then

       self.frame=0

   end

 

   self.x = self.x -1

 

 

   colUnit = 1/self.frameCols

   rowUnit = 1/self.frameRows

 

   row = math.floor(self.frame / self.frameRows)

   col = math.floor(self.frame % self.frameCols)

 

   self.mesh:setRectTex(1,

   col * colUnit,

  ( 1-rowUnit) - row * rowUnit,

   colUnit,

rowUnit)

 

       self.mesh:setRect(1,self.x,self.y,self.frameWidth,self.frameHeight)

 

    self.counter = 0

    end

 

   self.mesh:draw()

end

 

function Spritesheet:touched(touch)

 

end

 

A quick explanation of what the above code does.  First off, you create a Spritesheet by passing in the image to use for the sheet, the x and y coordinates to draw the individual sprite at, the number of rows and columns in your sprite grid, the width and height of each row and column, the frame to start on as well as the total number of frames in the sheet.  The rest of the init() method is mostly about storing these values.  The key call is addRect() which you can think of as creating a viewport into the sprite sheet, so we can view a single sprite.  The critical part is we create a mesh.  This is a quad that we apply our texture to.  In the draw() method you will see why this is important.

 

The draw() function has a lot of functionality built in that you obviously wouldn’t want in a more generalize Spritesheet class.  It does however show you how to display a single frame within the sheet and to iterate through each frame.  First we update our internal counter by DeltaTime, which is the amount of time since the last frame was drawn.  We are animating at a fixed rate of 30hz (obviously something you would want to change ), and each time 1/30th a second elapses, we move on to the next frame, unless its the last frame of animation, in which case we go back to first frame.

 

It’s all of the following bit that is the core of how we make the sprite sheet work.  We have created a mesh and applied the image texture to it.  Obviously though, that texture has a number of sprites on it.  What we are doing is finding the coordinates of our current frame of animation within the mesh.  The critical part here is mesh does not use pixel coordinates!  Instead it uses standard GL device coordinates ( similar to UV coordinates ), that start at 0 and go to 1.  The coordinate (0,0) is the bottom left corner of the texture, while (1,1) is the top right.  So we have to map our texture coordinates to pixel coordinates within the image.  This is also a challenge since our frames of animation start at the top left, not bottom left.  This is why we do (1-rowUnit).  In simpler English, colUnit and rowUnit convert from pixel sizes to fractions of 1.0.  For example, if we have 5 columns, each column is then 0.2 in width.  Once we have figured out the location of our individual frame in texture space, we set it using setRectTex().  Finally we set our elapsed time counter back to 0 then draw our updated mesh using mesh:draw().

 

Now let’s take a look at how we actually use spritesheet in code:  Go back to your Main and alter it like so:

 

 

function setup()

   local img = readImage("Documents:birds")

   bird = Spritesheet(img,WIDTH,HEIGHT/2,5,5,240,314,0,21)

end

 

function draw() 

   background(40, 40, 50)

   bird:draw()

end

 

function touched(touch)

   bird:touched(touch)

end

 

Here we simply load our spritesheet from the local pictures ( or use dropbox, wherever you wish ).  We then create a Spritesheet passing in the image, as well as the parameters that describe the sheet.  Draw and touched aren’t called automatically, so each time we get a draw or touched call in our app, we simply call our sprite’s draw and touched functions.

 

When you run the code you should see ( assuming you used the same image I did that is! ):

IMG 0275

 

If you are curious how I got an animated gif of a playing application out of Codea and onto this site, there is a neat bit of functionality built into Codea.  You can record a video of your game running in the run screen of Codea using this button:

IMG 0282

 

As you may be able to guess, I then used the iPad app PicPlayPost to convert to animated gif.  It did a solid job and produced a small file, but it also stripped away all of the colour!  So instead here it is exported as MP4 and created with my ole trust Gif Brewery:

AnimatedBird

 

So that’s a simple project in Codea.  Next up I’m going to start looking at Vector graphics instead of sprites.

Programming


20. October 2014

 

Now we are going to look at available raster graphics programs available on iPad.  While this post is part of an over all series about creating a game using only an iPad, this post should be of use to anyone looking to create art in general.  The iPad ( and other tablets ) are becoming increasingly viable ways of creating art, especially 2D art.  One major reason for this is cost.  An iPad is generally cheaper than a PC/Mac + graphics tablet, but it’s software costs where this really becomes obvious.  For example, the desktop version of Photoshop ( before it went subscription ) used to cost about $800.  The tablet version of Photoshop… $10!  Another desktop/tablet example is ArtRage, which ( although vastly cheaper ) is available at $50 on Desktop, it is only $5 on iPad.  Granted, they aren’t identical products, and often the iPad version has less functionality, but I tend to find it has all the functionality I generally need.  You mileage may vary.

 

So we are going to take a look at some of the Raster and Vector packages available on iPad.  Raster and Pixel mean basically the same thing, although “Pixel Art” has often come to represent a very specific style, with fat chunky pixels like from the 8 and 16bit era.  We will also look at two options aimed specifically at this style.  We will also look at Vector graphics packages, which allow you to define brush strokes mathematically, making for nice scalable graphics. 

 

I have also done a video quickly showing each application running, so you can have a better idea what the experience is like.  I only spend a couple minutes with each, but a few minutes is often all you need to decide if something is right for you or not!  All testing was done on a iPad Air, so if your device is slower, your experience may not be as good.

 

This video is a quick demonstration of every application mentioned below.  You can view it directly here.

 

 

Ok, let’s jump right in:

 

Photoshop Touch

iTunes Link

Cost: $9.99

Screenshot(s):

Photoshop

 

Comments:

Be careful when it comes to the Photoshop products, Adobe have released a number of Photoshop branded iOS projects and most of them are focused on photo manipulation and most useless to you.  The version you want is Photoshop Touch.  This is the mobile version of the venerable desktop Photoshop application.  While certainly stripped from it’s desktop counterpart, it is still impressively capable.

One immediately useful feature is the allowed canvas size.  Earlier versions where limited in canvas size, while now you can successfully create a 4096x4096 texture, which is the reasonable upper limit of what you will ever want to create.  I will admit though, at this size things can get a bit sluggish at times, although the painting experience is just fine, running tools like magic wand select or applying fx can bring up a wait logo.  Speaking of which, that is two areas where Photoshop really shines compared to it’s peers.  The selection tools are great, including a magic wand, scribble selection, polygon, lasso, etc select and deselect tools.

Tools are solid but not exceptional.  Feedback is great, there is no lag even on large files.  Navigation takes a bit to get used to, but is quick once you know what you are doing.  It has a few standout tools, such as the clone and heal brushes, which are somewhat rare.  Otherwise you are left with paint, burn, smudge, spray and erase as your primary art tools.  You do however have a ton of fine control over each tool, such as brush patterns, angle, scatter, size, flow and transparency.  You have to set it up yourself, but you can emulate basically any brush type you desire.

Of less use to game art, but still occasionally valuable, Photoshop Touch has 16 built in adjustments like Black&White, Shadow/Highlight, etc.  There are also 30+ filters built in, such as Sharpen, Drop Shadow, Blur, Glass, Comic, Watercolor, Sephia, etc.  There are also an impressive number of manipulation tools tucked away in here for cropping, scaling, rotating, transforming(warping) and fairly solid text tools as well.

Where Photoshop Touch really shines is layers.  You can have several layers, either new, cloned or imported from existing media.  Layer control is solid making it easy to move layers up, down, merge and delete as well as altering the opacity.  Additionally layers can be normal, darken, multiply, lighten, overly, subtracted, etc.  Fx can be limited to an individual layer. 

While Photoshop Touch may not be the program you create your art in, it should probably be in your toolbox for the sheer amount of flexibility it gives you.  In terms of alterations and manipulation of images, it can’t really be touched.  The selection, copy/paste, import and layering tools are easily the best out of any tool I look at.

In terms of getting your work out at the end of the day, unfortunately there is no direct Dropbox integration, but that isn’t really surprising given Adobe have their own cloud storage system, Creative Cloud.  In addition to their cloud offering, you can also save to the local photo roll.  There is however a Share option, allowing you to export the file ( as JPG, PSD, PSDX or PNG ) to just about any iPad application ( including dropbox ) or to email, printers, etc.  However the process is remarkably slow and sometimes simply doesn’t work.  At the end of the day, you can get just about anything in and out of Photoshop Touch that you would expect, but it can be awfully slow at times.

I suppose it’s fair to point out, it’s actually Photoshop Touch I used to resize and export the screenshots from my iPad to my Mac while creating this post.  It’s just a handy tool to have.

 


 

Autodesk Sketchbook Pro

iTunes Link

Cost: $3.99 for Pro Tools

Screenshot(s):

AutodeskSketchbook

 

Comments:

This product is a bit difficult for me to cover, as the version I have doesn’t actually seem to exist anymore.  At some point they moved from a premium iPad only product (Sketchbook Pro) to an freemium model, where you can download the base (Sketchbook Express), then for $3.99 unlock the premium tools.  I believe at the end of the day, they become the same product, but if there are minor differences, I apologize now.  As I am not entirely certain what is in the free vs pro edition, the below will be describing the complete purchased product.

Sketchbook is exactly what the name suggests, a virtual sketchpad.  It’s an impressive one at that.  It’s got a minimal interface that get’s out of your way ( all of the things you see in the above screenshot are brought up by pressing the circular icon.  Let go and it’s just you and your drawing. Drawing tools are pretty typical with pen, pencil, market, highlighter, erase, smudge and airbrush available, plus the ability to choose custom brushes/stamps from probably 100+ presets, including common pencil type (2H, 8B, etc) and oddly enough, so clip art.  Responsiveness while drawing is instant.  Using a quick pop up tool you are able to alter your brushes dimensions and opacity with a single touch.  One nice feature, lacking from many similar products, is the ability to draw lines and shapes, although curves didn’t seem to work.

There are a couple unique to Sketchbook features, of varying levels of usefulness.  There is a symmetry draw mode, enabling you to draw mirrored about a centre point.  You can also do time lapsed recording and collaborative sketching with someone else with their own copy of Sketchbook.  Sketchbook also has decent text creation abilities built in.  Most importantly (to me), Sketchbook also has layer support, although nowhere near that of Photoshop Touch.  Even just a single layer to enable tracing for animation is invaluable. 

You can export from your gallery directly to the local photo gallery, to iTunes, email, etc… as well as directly to Dropbox.  You can create images up to 1800x2400 in size, although the size of image limits the number of layers.  A 1800x2400 image can for example have 4 layers, while a 768x1024 image can have up to 18 layers.  The largest image you are able to create is 2830x2830.  No idea why it stops there…  Even at that size, performance remains smooth.

Sketchbook is a great product for creating sketches, the brushes are natural, performance is good and tools are complete enough to recreate most anything.  The interface is faster to navigate than Photoshop Touch, but it has a great deal less functionality, with absolutely no filters, effects, selection tools and minimal layer functionality.  For drawing however, I would take it over Photoshop Touch every day.


 

Art Rage

iTunes Link

Cost: $4.99

Screenshot(s):

ArtRage

 

Comments:

This is the most applicably named application I have ever encountered!  It’s an amazing application for creating digital art, and it is horrifically rage inspiring!  ArtRage attempts to recreate real world art process digital, and does an incredibly good job of it.  You can choose your paper type (grain), metallic-ness then go to town using tools like paint, roller, trowel, crayons, markers, pens, erasers, pencils, airbrush and a couple different paint brushes.  For each brush you can set a number of settings specific to each tool such as pressure, thinning etc.  You really can recreate a very “painterly” feel.  So why the rage?

Well that part is simple.  This application lags.  Always lags and I absolutely cannot use it for that reason.  Regardless to the complexity of your scene, your paint brush will always been a half a second behind where you are touching.  Of all the applications I looked at, this one had by far the worst performance.  If you can handle the delay while drawing, this application is certainly worth checking out, especially if you are looking for a natural media look.  I personally cannot get over the lag.

From a technical perspective, Art rage allows a maximum canvas size of 2048x2048.  It supports layers with an absolute ton of blending modes.  There is no manipulation tools for selection, transformation nor any filters or effects.  This is a painting program focused on painting and nothing more.  It however probably does the best job of recreating brushes and paper in the digital world.  It has the ability to export to Dropbox as well as save locally, but not to send to other applications on your iPad.


 

Bamboo Paper

iTunes Link

Cost: Free for Base + up to $3.99 to add tools

Screenshot(s):

BambooPaper

 

Comments:

Made by Wacom, famous for the titular Bamboo tablets.  The free version ships with a pen, then for 99 cents each, or $3.99 for all, you can add tools such as Brush, Crayon, Pencil etc.  It’s got a slick package, good export support (including Dropbox) and does feel like working in a notebook.

That said, it’s simply too limited to be used for much more than sketching.  Lack of layer support, minimal dimension options, no selection tools, filters or advanced brushes.

 


 

Paper

iTunes Link

Cost: Free then up to $6.99 for all tools

Screenshot(s):

Paper

Comments:

Paper is a somewhat famous application, as it has been used in Apple promotional materials.  It is also incredibly basic, basically just trying to mimic the drawing on paper experience.  As you can see from the screenshot above, I only have the free version installed.  For up to $6.99 you can add other art tools like a pencil, marker, paint brush, colour mixer, etc.  Export abilities are limited to save to camera roll and send to app.

The drawing is nice and natural, but it’s too limited to be of much use for game development.  Additionally, it’s price is hard justified compared to similar applications.  Can’t really recommend paper other than for sketching if the minimal interface floats your boat.


 

Skeches

iTunes Link

Cost: Free to start, up to $4.99 for all tools, plus text and layers

Screenshot(s):

Sketches

 

Comments:

Sketches is very similar to Paper and  Bamboo Paper, in that it emulates a classic sketchbook.  However the major exception is, with the premium purchase of $4.99 you gain among other things, layer support.  Additionally the free version includes a complete set of tools, but limits the customizability of each.  It contains all of the same tools as the previous two applications.  The interface can be minimized by swiping aside panels.  Navigation is multitouch based and to be honest is confusing as hell until you get used to it.

You are able to export to a number of formats, including Dropbox.  You can select from a number of paper types, but unfortunately have very little control of resolution of the image, maxing out at that of a Retina iPad.

Of all the sketch based drawing applications, this one was easily my favourite, even with it’s somewhat unnatural navigation interface. 


 

Concepts

iTunes Link

Cost: Free to $6.99 for full toolset

Screenshot(s):

Concepts 

 

Comments:

Of all the applications I’ve covered yet, Concepts is probably the most unique, and in some ways, the most powerful.  Designed for creating sketches for concept art, it comes with several tools you haven’t seen yet.  For example, there is a tool for tracing lines and arcs.  There are snapping tools for snapping to the grid.  Speaking of which, the grid can be turned off, on, and set to a number of different densities and formats, including isometric, which can be invaluable if that is the art style you are going for.  There is full layering support, but they are intended for organization/tracing/layering and not artistic effects.  Beyond transparency, there are no blending options for layers.

Artistic tools are somewhat limited to pens, pencils and markers.  More natural art style would be hard to achieve in this program as a result.  That said, the color system is amazing and emulates COPIC markers, allowing you to create pretty much the same tools that concept artists use.

For precision works, this is hands down the best choice out there.  For drawing striaght edges, lines and curves, only the next option comes close.  For more painterly effects, this is a poor choice.  There is no filter or fx support.  Export support is robust, and actually capable of exporting to DXF ( Autocad ), SVG ( Vector ) and PSD formats.  You can also export as an image to the local camera roll, as well as export to Dropbox and others ( including somewhat shockingly, Adobe’s Creative Cloud ).

If you are doing concept art, or going for a technical look, this is hands down your best choice.

 


 

Adobe Illustrator Draw

iTunes Link

Cost: Free!

Screenshot(s):

 AdobeDraw

Comments:

Adobe make a number of products of a very similar nature, Adobe Ideas, Adobe Lines and Adobe Sketch.  Adobe Draw however ties together the best of each of them and has some very interesting abilities.  By far and away the most important feature is the ability to use an angle or french curve ( like shown above ) to draw straight lines and curves.  The actual drawing features are somewhat limited, mostly pen/pencil style drawing implements.  You can control the brush tip size, colour and opacity and that’s it. There is layer support buts it’s tied to each tool somewhat oddly.  The response is quick, the interface is nice and clean and though limited, the brushes are different enough to be useful.

All that said, this application is free.  It’s good and it’s free.  In some ways the drawing tools are amongst the best available.  The angle/french curve functionality is exceedingly well implemented, much better than the curve support in Concepts, which is the only other program that offers similar functionality.  Export functionality is fairly traditional, you can save to the local camera roll, upload to creative cloud and hit the standard share with targets, including Dropbox.  Unfortunately it seems you have little (no?) control over the canvas size.

I don’t really understand the business model here, but free is a wonderful price.  Be sure to check this one out.

 


 

Inkist

iTunes Link

Cost: Free *for a limited time, seemingly forever

Screenshot(s):

Inkist 

 

Comments:

I will be honest, I had a great deal of trouble navigating my way around this application.  Even saving a file was somewhat perplexing.  In many ways it has an interface like many desktop art packages like GIMP or Paintshop.  That interface doesn’t necessarily work on a touch device.

There is actually a LOT of functionality packed in here, more so than most of the packages listed here, except perhaps Photoshop Touch. There is full layering support, but limited to 3 layers ( I think, who knows whats behind that interface that I couldn’t figure out! ), and all kinds of blending functionality between layers.  Art tools are somewhat limited.  I think everything you need is in here, but accessing it is somewhat of a trick.

That said, it’s listed as free for a limited time, and that was over a year ago.  It doesn’t seem like this application is still being developed, so it’s a completely free option.  For that reason alone you should check it out, the interface might click for you better than it did me.  If nothing else, the price is right!

 


 

Pixel Art Packages

 

Sprite Something

iTunes Link

Cost: $4.99

Screenshot(s):

SpriteSomething

 

Comments:

This application is unique in the list as it is specifically aimed at low resolution ( 8/16bit ) pixel art.  At it’s core it’s a fat bit grid editor.  You draw pixel by pixel, although it does have some handy tools like fill, line drawing, etc. There is also layering ability, but there is no blending between layers, it’s literally just stacked pixels. You work in a massively zoomed in window, but you can preview the end result as you work.  There are also tools for doing frame by frame animation sequences, including onion skinning functionality.  This part of the interface can be a bit clunky.

One very unique thing about sprite something is, it has a simple level editor built in as well.  See the video for more details.  Export is limited to email and local camera roll.  If you are working in fat bit pixel style, this is your best ( and almost only ) option. 

 


Codea

iTunes Link

Cost: $9.99

Screenshot(s):

Codea 

 

Comments:

I’m just mentioning this one for thoroughness.  If you are reading this as part of the overarching iPad game creation tutorial, there is a simple pixel art example “Spritely” built into Codea.  Its another fat bit grid editor for pixel art.  It’s very simple but may be enough for you if you have simple requirements.

Obviously not recommended to non-Codea users.

 


Vector Graphics Packages

 

Vector graphics applications work a bit differently than raster packages we described above ( except perhaps Concepts which is a cross between Raster and Vector graphics ).  Raster applications work on a pixel by pixel basis.  Vector graphics on the other hand work on mathematic formulas representing each brush stroke.  This gives you a bit less fine control over the end results, but allows you to scale up or down to any graphic resolution you want.

 

Inkpad

iTunes Link

Cost: Free and Open Source

Screenshot(s):

 Inkpad

Comments:

Completely free and open source, Inkpad is a powerful vector graphics package.  If you’ve ever used Inkscape on a PC, you know what you are in for.  You draw using paths, manipulate curves either straight line or bezier for curved edges and using simple geographic shapes, build, color and layer them to create more complex images. 

Inkpad has full layer support, although they don’t really effect each other like in raster packages.  You can however bring in a standard graphic as a background or to trace over.  Inkscape supports saving as an image locally or exporting as PDF or SVG.

Once again, it’s completely free.  Free is nice.

 

iDraw

iTunes Link

Cost: $8.99

Screenshot(s):

IDraw

 

Comments:

iDraw has one of those iNames iAbsolutely iHate, but don’t judge the package by it’s name.  I absolutely love this package and strongly recommend it to anybody reading this that wants to work with vector graphics.  This application works very similar to Inkpad, except with more functionality, more polish and a higher price tag.  I have struggled in the past with vector graphics applications such as Inkscape ( unwieldy ) and Illustrator ( overwhelming ) and iDraw is the first one that just “clicked” for me.  Once again, the basic concept remains the same, you draw shapes using lines (paths), fill those paths with colors or gradiants, and layer them to make more complex shapes.  One major difference between this and Inkpad is the free form drawing tools, that allow you to use it much more similar to a traditional drawing package.

iDraw is also available as a complete application on Mac and files are interchangeable.  This page has full layer support and is capable of saving directly to Dropbox.  Files can be exported as iDraw, PDF ( very very very useful with Codea as we will soon see ), SVG, PSD, PNG and JPEG, with resolutions of 72, 144 or 300dpi.

 

 

Summary

 

This is only a small subset of graphics packages available on iPad, but does represent a large cross section of them, as well as featuring most of the “big names”.

 

Myself, if I were to only be able to keep a couple applications, my personal choices would be:

  • Photoshop Touch — for image manipulation, modification, effects and some creation
  • iDraw — Vector graphics made easy
  • Adobe Draw — Great sketching app, excellent line and curve support, completely free
  • Sketches — Most versatile drawing app with different brushes like watercolour, paint, etc
  • Concepts — Perfect for technical drawings, similar to Adobe Draw but much more technical, Copic integration
 
If I had absolutely no budget available, I would most certainly recommend people download:
 
  • Sketches — For all your sketching needs, I’d pay for it, so free is awesome
  • Inkpad — Powerful vector graphics, completely free
  • Inkist — The interface is rather awful, but it gives you a lot of editing functionality, completely free
 
All told, that represents under 20$ worth of purchases and provides a level of power way taken together that exceeds any desktop application at many times the price.  Even for a total spend of $0, you can end up with a remarkably complete 2D art package.

Art


16. June 2014

 

In the previous tutorial part we looked at working with a single Sprite.  Reality is, very few games are composed of singular sprites.  UI’s are made up of a number of different sprites, animations are composed of several different frames, each composed of a single image.  Loading hundreds of individual textures is not good for performance.  A very common solution is to use a texture atlas ( or sprite sheet ).  Fortunately Xcode make it extremely easy.

 

We are going to use the same sprite we did in the previous tutorial, you can download it here.  As you can see, it’s actually a zip file containing a number of png images:

Ta1

 

Extract the zip file and rename it jet.atlas.

Now in Xcode, in Project Navigator, right click your project and select Add to Project

Ta2

 

Select the directory ( not the files ) and click add.  Defaults should be ok, but make sure it’s set to copy.

Ta3

 

And you are done.  The following code:

import SpriteKit

 

class GameScene: SKScene {

    

    override func didMoveToView(view: SKView) {

        var sprite = SKSpriteNode(imageNamed:"sprite4")

        sprite.xScale = 4

        sprite.yScale = 4

        sprite.position = CGPoint(x:0,y:0)

        view.scene!.anchorPoint = CGPoint(x: 0.5,y: 0.5)

        self.addChild(sprite)

    }

    

}

 

Will load the sprite from the Atlas that had the file name “sprite4.png”.  NOTE HOWEVER, if you add an image named sprite4 to your project, it will be loaded instead of the Texture Atlas.

 

So, what exactly did Xcode do?  We behind the scenes, it went ahead an combined all of your images together into a single OpenGL optimized image, and created a reference file telling SpriteKit how to access it.  Let’s take a look at the results.

 

First, build your game.  Select Product->Build For->Running

Ta4

 

You should now have a Products folder in your project.  Right click the .app file for your project and select Show in Finder:

Ta5

 

Now right click the .app file and select Show Package Contents:

Ta6

 

Navigate into contents->resources->jet.atlasc and you will see two files, one is an image, the other a plist.  Let’s look at the image first:

 

Jet 1

 

That’s out images smash together in a power of 2 friendly texture that your GPU can handle efficiently.  The plist file:

Ta7

 

This plist shows SpriteKit how to access each individual image within the larger image.  To you however the process is pretty transparent.  Basically group all common images together in a directory.  Give the directory a .atlas name and add it to your project, then access each image as you would normally.

 

Sometimes however you may want to access the TextureAtlas itself.  You can do that as well, let’s take a look at how:

import SpriteKit

 

class GameScene: SKScene {

    let textureAtlas = SKTextureAtlas(named:"jet.atlas")

    var currentTexture:Int = 1;

    

    override func didMoveToView(view: SKView) {

        view.scene!.anchorPoint = CGPoint(x: 0.5,y: 0.5)

        

        let sprite=SKSpriteNode(texture:textureAtlas.textureNamed("sprite1"))

        sprite.xScale = 8

        sprite.yScale = 8

        self.addChild(sprite)

    }

    

    override func keyDown(theEvent: NSEvent!) {

        // On any key press move to the next texture

        var sprite = self.scene.children[0] asSKSpriteNode

 

        switch currentTexture {

            case 1:

                sprite.texture = textureAtlas.textureNamed("sprite2")

            case 2:

                sprite.texture = textureAtlas.textureNamed("sprite3")

            case 3:

                sprite.texture = textureAtlas.textureNamed("sprite1")

            default:

                break

        }

        ++currentTexture

        if(currentTexture > 3) {

            currentTexture = 1

        }

    }

}

 

Now run it, and each time you press a key it will advance to the next frame.

 

 

 

First let me stop right here and make one thing perfectly clear… THIS IS NOT HOW YOU DO ANIMATION! :)  We will cover animation later. This was just a small code segment to illustrate how to access a TextureAtlas directly.  

 

As you can see, it’s as simple a matter as creating an SKTextureAtlas and passing in the file name.  You can then access each individual SKTexture within the atlas using textureNamed passing in the file name you used for the original image in the atlas directory.  As you can see, you do not need to pass in the file extension.  Here we see a Swift switch statement in action.  Switch statements are important to Swift and quite capable.  You can switch on Ints like we have done here, but you can also use strings. It is tempting to use the sprite name here, but an important thing to realize is the SKSprite name is NOT the same as the SKTexture name.  Unless you manually name the sprite, it will be nil.  Unlike C++, case statements in Swift do not fall through, so you do not need to provide a break statement for each case.  However, there are two caveats to be aware of.  First, every single possible value must be handled.  If you don’t want to handle every possible value you can provide a default handler which will catch everything else.  However each case ( even default ) must contain at least one executable statement, thus the break in default.  This only scratches the surface of switch… you can also specify multiple values in a case using commas, provide ranges using the .. and … operators, etc.

 

That’s it for TextureAtlases, on to the next part!


13. June 2014

 

As you can imagine by the name “SpriteKit”, Sprites are a pretty core part of creating a game using SpriteKit.  We are going to continue building on the minimal application we created in the previous part.  I want to point out, this isn’t the recommended way of working with SpriteKit, it is instead the simplest way.  In a proper application we would be more data driven and store our data in SKS files instead of simply adding them to the project.  This is something we will cover later on.  First lets jump right in with code.

 

We are going to replace the the class GameScene we created in the last tutorial.  In SpriteKit, the fundamentals of your game are organized into SKScene objects.  For now we only have one.  Let’s look:

 

import SpriteKit

 

class GameScene: SKScene {

        let sprite = SKSpriteNode(imageNamed: "sprite1.png")

    

    override func didMoveToView(view: SKView) {

        sprite.anchorPoint = CGPoint(x:0.5,y:0.5)

        sprite.xScale = 4

        sprite.yScale = 4

        self.addChild(sprite)

    }

    

    override func mouseDown(theEvent: NSEvent!) {

        self.sprite.position = CGPoint(x:theEvent.locationInWindow.x,y:theEvent.locationInWindow.y)

    }

}

 

We add the sprite “sprite1.png” to our project directory, simply drag and drop it from Finder.  The sprite(s) ill be using are from the zip file available here.  When you run this code, click anywhere and you should see:

 

Sd1

 

Where ever you click the mouse, the sprite will be drawn.

One immediate change you will notice in this code is sprite was moved out of didMoveToView and made a member variable.  This allows us to access sprite in different functions ( although we could retrieve the sprite from the Scene, something we will see later ). In Swift there are only two main ways of declaring a variable, let and var.  var is a variable meaning it’s value can change.  Using let on the other hand you are declaring a the the value cannot change, this is the same as a const in other languages.  As we touched on briefly in the last part, a let declared value can be assigned later using the ? postfix operator.  In this case, it will have the value of nil at initialization, unless one is specifically given like in the code we just did.  One thing you may notice is, unlike C++, C# and Java, Swift currently has no access modifiers.  In other words all variables are publicly available ( there are no private, internal, protected, etc modifiers available ).  Apparently this is only temporary and will be changed in the language later.  This personally seems like a very odd thing not to have in a language from day one.

Since we set the sprite’s anchor to the middle (0.5,0.5), the sprite will be centred to your mouse cursor.  As you can see we added a mouseDown event handler.  This class is available because SKScene inherits UIResponder, this is how you handle I/O events in your scene.  The only other new aspect to this code is:

        sprite.xScale = 4

        sprite.yScale = 4

 

 

This code causes the sprite to be scaled by a factor of 4x.  We do this simply because our source sprite was only 64x64 pixels, making it really really tiny in an empty scene!  As you can see, scaling sprites in SpriteKit is extremely easy.

 

The structure of a SpriteKit game is actually quite simple.  Your SKScene contains a graph of SKNodes, of which SKSpriteNode is one.  There are others too including SKVideoNode, SKLabelNode, SKShapeNode, SKEmitterNode and SKEffectNode.  Even SKScene itself is a SKNode, which is how all the magic happens.  Let’s take a quick look at an SKLabelNode in action.

 

import SpriteKit

 

class GameScene: SKScene {

    

    override func didMoveToView(view: SKView) {

        var label = SKLabelNode();

        label.text = "Hello World"

        label.fontSize = 128

        label.position = CGPoint(x:0,y:0)

        view.scene!.anchorPoint = CGPoint(x: 0.5,y: 0.5)

        self.addChild(label)

    }

    

}

Which predictably enough gives you:

Sd2

 

These nodes however can be parented to make hierarchies of nodes.  Take for example a combination of the two we’ve seen, our sprite node with a text label parented to it.

import SpriteKit

 

class GameScene: SKScene {

    

    override func didMoveToView(view: SKView) {

        view.scene!.anchorPoint = CGPoint(x: 0.5,y: 0.5)

        

        var sprite = SKSpriteNode(imageNamed:"sprite1.png")

        sprite.position = CGPoint(x:100,y:0);

        sprite.xScale = 4.0

        sprite.yScale = 4.0

        

        var label = SKLabelNode();

        label.text = "Jet Sprite"

        label.fontSize = 12

        label.position = CGPoint(x:0,y: 15)

        label.fontColor = NSColor.redColor()

        label.alpha = 0.5

 

        

        sprite.addChild(label)

        

        self.addChild(sprite)

    }

    

}

 

And when you run it:

Sd3

 

There are a few things to notice here.  Each Node get’s its default coordinates from it’s parents.  Since the jet sprite is parented to the scene and the scene’s anchor is set to the middle of the screen, when we position the screen 100 pixels to the right, that’s 100 pixels to the right of the centre of the screen.  Additionally, the text label is positioned relative to the sprite, so it’s positioning is relative to the sprite.  Another thing you might notice is the text is blurry as hell.  That is because the label is inheriting the scaling from it’s parent, the sprite.  As you can see you compose your scene by creating a hierarchy of various types of nodes.  Now if we were to transform the parent sprite, all the transformations will apply to the child nodes.

 

The following example shows how transforming a parent node effects all child nodes.  Spoilers, it also shows you how to Update a Scene… we will cover this in more detail later, so don’t pay too much attention to the man behind the curtain.

import SpriteKit

 

class GameScene: SKScene {

    

    var sprite = SKSpriteNode(imageNamed:"sprite1.png")

    override func didMoveToView(view: SKView) {

        view.scene!.anchorPoint = CGPoint(x: 0.5,y: 0.5)

        

        sprite.position = CGPoint(x:0,y:0);

        sprite.xScale = 8.0

        sprite.yScale = 8.0

        

        var label = SKLabelNode();

        label.text = "Jet Sprite"

        label.fontSize = 12

        label.position = CGPoint(x:0,y: 15)

        label.fontColor = NSColor.redColor()

        label.alpha = 0.5

 

        

        sprite.addChild(label)

        

        self.addChild(sprite)

    }

    

    override func update(currentTime: NSTimeInterval) {

        if(sprite.yScale > 0) {

            sprite.yScale -= 0.1

            sprite.xScale -= 0.1

        }

        else {

            sprite.xScale = 8.0

            sprite.yScale = 8.0

        }

    }

    

}

 

Now if we run this code:

 

 

Each time update() is called, the sprite is reduced in scaling until it disappears, at which point it’s zoomed back to 8x scaling.  As you can see, the child labelNode is scaled as well automatically.

 

Notice how until this point if we wanted to access our sprite across functions we had to make it a member variable?  As I said earlier, there is another option here, you name your nodes and retrieve them later using that name.  Like so:

 

import SpriteKit

 

class GameScene: SKScene {

    

 

    override func didMoveToView(view: SKView) {

        view.scene!.anchorPoint = CGPoint(x: 0.5,y: 0.5)

        var sprite = SKSpriteNode(imageNamed:"sprite1.png")

        

        sprite.name = "MyJetSprite"

        sprite.position = CGPoint(x:0,y:0);

        sprite.xScale = 4.0

        sprite.yScale = 4.0

        

        self.addChild(sprite)

    }

    

    override func update(currentTime: NSTimeInterval) {

        var sprite = self.childNodeWithName("MyJetSprite");

        if(sprite != nil){

            if(sprite.yScale > 0) {

                sprite.yScale -= 0.1

                sprite.xScale -= 0.1

            }

            else {

                sprite.xScale = 8.0

                sprite.yScale = 8.0

            }

        }

    }

    

}

You can perform some pretty advanced searches, such as searching recursively through the tree by prefixing your name with “//“.  You can also search for patterns and receive multiple results.  We will look at this in more details later.

 

This part is starting to get a bit long so I am going to stop now.  The next part will look at more efficient ways of using Sprites, such as using an Atlas, as well as look at basic animation and whatever else I think to cover!

 

Continue to Part 3


2. June 2014

EDIT:  For a better understand of Apple’s Metal API and what it means for OpenGL, click here. 

So finally we are getting some developer related announcements out of the Apple Developer Conference.  For game developers, todays announcement is a dozy.  iOS 8 SDK includes 4,000 new API calls but most importantly includes Metal, a new lower level graphics API similar to AMD’s Mantle.  The idea is to get closer to the metal ( thus the name ) and remove the overhead of OpenGL:

 

Gaming on iOS takes a huge leap forward in iOS 8 with Metal, a new graphics technology that maximizes performance on the A7 chip. With its dramatic 10 times improvement in draw call speed, Metal enables leading game providers for the first time to bring console-class 3D games to mobile devices. For casual games, iOS 8 now features SceneKit, making it easy to create fun 3D games, along with major enhancements to SpriteKit, including field forces, per-pixel physics and inverse kinematics.

 

10 times performance improvement over OpenGL?  That sounds like marketing BS to me or describes an edge case.  If OpenGL was that bloated it would have died off year ago.  The important take away is it’s A7 only, so newest iPad and iPhones are the only ones that support it.  Unity, Crytek and Unreal are all expected to support it so it should be pretty transparent to most developers.

 

The other major announcement was Swift:

 

Swift is a powerful new programming language for iOS and OS X® that makes it easier than ever for developers to create incredible apps. Designed for Cocoa® and Cocoa Touch®, Swift combines the performance and efficiency of compiled languages with the simplicity and interactivity of popular scripting languages. By design, Swift helps developers write safer and more reliable code by eliminating entire categories of common programming errors, and coexists with Objective-C® code, so developers can easily integrate Swift into their existing apps. Xcode® Playgrounds make writing Swift code incredibly interactive by instantly displaying the output of Swift code.

 

The iOS beta software is available now for registered Apple developers.  XCode 6 is required to support the Swift programming language.  You can learn more about Swift here.  I LOVE new programming languages, so I will certainly be taking a closer look.  Some Apple toted features of swift are:

 

Swift has many other features to make your code more expressive:

  • Closures unified with function pointers
  • Tuples and multiple return values
  • Generics
  • Fast and concise iteration over a range or collection
  • Structs that support methods, extensions, protocols.

 

… interesting.  I hate ObjC, so an alternative is certainly appreciated. 


AppGameKit Studio

See More Tutorials on DevGa.me!

Month List