Corona – Sprites

Sprites are similar to movieclips but more efficient. Where movieclips use a separate image for each frame of an animation. A sprite uses one single image that contains all of the frames. Mobile devices have limited memory and images take up most of the memory your projects might use. Using a single image where you once had several can dramatically cut down the amount of memory your app may be using.

Sprite Sheets

A sprite sheet is a single image that contains all of the individual images that make up an animated sequence of images. Here’s an example. This image contains three animated images of the saucer (the four spots in the center move). Each individual image is 48pixels wide by 21 pixels tall. I used a transparent png, where the red was transparent, in my original test. I had to fill in the transparent area or you would not be able to see the white image against the page here.

A sprite sheet can have more than one series of images. As a matter of fact you could have all of the images used in your project inside of a single sprite sheet. Note the iPhone has a maximum image size that is can work with. On earlier iPhones the max size is 1024 by 1024 while newer models support up to 2048 by 2048 pixels.

Try it for yourself

The artwork for this example is more difficult to create than the other examples you’ll need to pay close attention to how it is created and sized. You can use the example image above if you like.

  1. Create a new folder where you will store this project
  2. Create a new text file and save it to your folder with the name main.lua
  3. You’ll need an image containing each image of an animated sequence. That’s one image containing all frames of the animated sequence. See the example image above. Keep your images simple at first to avoid trouble.
  4. Note the height and width of each frame. Each frame should be exactly the same size. (this isn’t a requirement for using sprites in Corona, but it is required for the code sample below)

Add the following code to your main.lus file. You’ll need to change the file name of saucer_sprites.png to the name of your image file.

You’ll also need to change 48 to the width of your sprites and 21 to the height. These are the width and height of each individual frames.

 

-- Include the sprite
require "sprite"
-- name the image file containing your sprites, followed by the width and height of each sprite
local saucer_sheet = sprite.newSpriteSheet("saucer_sprites.png", 48, 21)
-- Create a set by naming the sheet and starting frame and number of frames
local saucer_sprite = sprite.newSpriteSet(saucer_sheet, 1, 3)

-- Now create new sprite, give it a name, set the starting frame, end frame,
-- and time between frames in ms, 0 means loop
sprite.add( saucer_sprite, "saucer1", 1, 3, 100, 0 )

-- Create a new Sprite in the display object so we can see it on the screen
local saucer = sprite.newSprite( saucer_sprite )
-- Position your sprite
saucer.x = display.contentWidth / 2
saucer.y = display.contentHeight / 2

-- Prep your sprite
saucer:prepare("saucer1")
-- Start the sprite playing
saucer:play()

Some resources:

Corona – Movie Clips

Often you will want to create a short animated clip. This is good for a lots of things especially games. A movieClip is an object that contains a series of images. Movieclips can play display their images in succession to create animated effect.

MovieClips are really a series of images loaded into to Corona and played in sequence. You could accomplish this with a Group containing all of the images and an array. Then writing an enterFrame function to cycle through the images in the array making each one visible in turn.

You could do all of that but, you don’t need to since someone over at Corona has all ready done it for you! This example uses the movieclip.lua file. You can find this in CoronaSDK/SampleCode/Graphics/MovieClip.

Create a new Corona project.

  1. Create a folder to work in
  2. Copy the movieclip.lua file from CoronaSDK/SampleCode/Graphics/MovieClip into the folder where you will be working
  3. Create a new text file and save it into the folder an name it main.lua
  4. Create a series of small images to use for the animated sequence. Imagine these images as frames in a movie. Save the images into the project folder

Add the following code to main.lua

-- Import an external library
local movieclip = require("movieclip")

-- Since we're importing a library we need to make a main function
-- to run after the library has loaded

-- Define the main function to initialize this program
function main()
 -- This line makes a new animated "movieClip" from the saucer images in the table
 saucer = movieclip.newAnim{"saucer_01.png", "saucer_02.png", "saucer_03.png"}

 saucer.x = display.contentWidth / 2
 saucer.y = display.contentHeight / 2

 -- Start the animation playing
 saucer:play()
end

-- Call main to start the program
main()

Corona – frame based animation

Transitions work well for situations when you want a motion to run from start to finish with a set length of time. For example you’d like to have en element move onto the page and stop in the center over 3 seconds. At other times you’ll want to create a motion that plays continuously. For example, you have object that moves back and forth across the screen for as long as it is on the screen. In these cases transition.to() doesn’t work so well. For these situations we can use the “enterFrame” event.

The enterFrame event

The enterFrame event is an event that us dispatched once every frame. Which of course brings up the idea of frames. Think of frames as the number of times Corona updates the screen. This is typically 30 times per second. So the enterFrame event is an event that is sent 30 times per second.

You can use the enterFrame event to do lots of things. A common purpose is animation. Imagine you had a object on the screen you added 12 degrees to it’s rotation 30 times each second. It would make a complete rotation every second.

Test the enterFrame event

Create a new Corona project

  1. Make a folder to work in
  2. Create a new text file and save into the folder with the name main.lua
  3. Copy a small image into your folder

In your main.lua file add the following code.

-- Make a new image
local invader = display.newImage("invader_04.png")

-- Position the image at a starting location off the left edge of the screen
invader.x = -80
invader.y = 160

-- Use this function move the image, this function will be run once each frame
-- each frame add 5 to the x. If x is greater than 400 move the image to the left
local function move(event)
 invader.x = invader.x + 5
 if invader.x > 400 then
 invader.x = -80
 end
end

-- Add an enterFrame event to the Runtime object
Runtime:addEventListener( "enterFrame", move )

Corona – Events

Think of notifications from the program about things that have happened in the program. Use events to determine when an object is tapped or when period of time has passed. Use events to animate things and react to user interaction.

Listeners and Handlers

Listeners are objects that have been assigned to respond to an event. Handlers are the functions that are run when an event occurs. Think of listeners as waiting for and notifying their handlers when the event occurs.

Most objects in Corona can be assigned a listener. Use the addEventListener() method to assign the listener. For example imagine you want a create an event is fired when you tap an image. You might write the following. Try it for yourself.

  1. Create a new folder to work in
  2. Open a new text file and save it to your folder with the name main.lua
  3. Copy an image to use in the example to your folder

Add the following code to main.lua:

-- Create an image and position it in the center of the screen
local invader = display.newImage("invader_04.png")

invader.x = display.contentWidth / 2
invader.y = display.contentHeight / 2

-- Define a handler
local function tapInvader( event )
 transition.to(invader, {time=1000, rotation=invader.rotation+360})
end

-- Add an event listener to the invader
invader:addEventListener("tap", tapInvader)

I added a few comments to the code to explain what is going on. Any line that begins with “–” is ignored and the rest of the line can be used to write a message or description of your code.

Test your project and tap the invader. With each tap it rotates 360!