QuestionQuestion

Transcribed TextTranscribed Text

Image Sheets Before we can begin using sprites, we need to create an image sheet (also called a sprite sheet, texture atlas, or image map). This is done outside Corona, using your favorite illustration or imaging software. For animations, the idea is to make a series of images that, when quickly displayed on screen in order, create the effect of fluid motion. You could think of it as creating a “digital flip book”. We’ll use these images sheets to create sprites, and you’ll often hear references to “sprite sheet” instead of “image sheet” in these circumstances. However, as we’ll see in later chapters, these sheets can be used to create more than just animated sprites, so we’ll continue to use the more general term. We’ll use “sprite sheet” when referring to the Corona sprite sheet object that we’ll create from the image sheet file. There are two types of image sheet - a rectangular layout, or a packed layout. In a rectangularly arranged image sheet, the images (each representing a single frame of an animation) are laid out next to each other or tiled so that each image can be placed in an invisible box of the same width and height. You’ll want to position these images so that there is a minimum of wasted space, but so that are at least a few pixels between images. This is the layout we'll be using in class examples, though you're free to experiment with packing software for your own projects. As an example that we'll be using throughout these notes, a rectangular sprite sheet has been created out of frames of several different animation sequences: Note that we can draw a grid over this sheet, where each box in the grid contains one frame of the animation and all boxes are the same size: Tips for Creating Image Sheets If the images in a sheet are touching one another, you’ll see the edge of the previous or next frame during the animation. This is due to the way OpenGL (the graphics API used by Corona) interpolates images. The amount of space left depends on how much scaling will be involved. If you’re displaying all images at their saved resolution, leave a pixel around each image (so there are two pixels of space between them). If you’re saving versions of the image sheet at “@2x”, leave 4 pixels. If you have a version saved at three times the standard resolution, leave 6 pixels, and so on. In most cases, a two pixel buffer between images will work fine. Unless you’re able to create your images with the exact background color of your app, you’ll want Corona to be able to not show any whitespace surrounding your images. For this reason, it is highly recommended that you save your image sheet as a .png file with transparency preserved. Note, however, that any white areas of your image will also become transparent. To avoid this issue, try making any white areas of the actual image slightly off white. The difference will not be apparent to the user, but the area will look white in your app instead of invisible. Creating all of the frames of your image sheet is very time consuming, and you should experiment with all software available to find one you prefer. Creating the images can be done using a paint program, image editor, or vector illustration software. Sprite creation software is available, though it's still a tedious effort to produce image sheets for animated sprites. Generally, each frame of the animation will be drawn individually, often by making minor adjustments to the previous frame. Pixelated sprites are usually created this way. You can use any illustration or image editing software to create these, but some dedicated software for drawing pixel art sprites include:  piskelapp.com Create pixel art sprites in a web browser and export to .png for use in your app. Fun to play with!  GraphicsGale A pixel art sprite builder with lots of features. Download for about 2000 yen (a little under $20).  Pixothello Another feature rich pixel art sprite maker, with lots of tutorials available on their site. Free, with donations accepted. If you don't want to draw each frame individually, you can use software that assigns "bones" to the various parts of your object. You'll need to create images representing the parts of each frame, then connect these with joints. For instance, to create a character that runs on screen, you'd typically have a separate image for the head, torso, upper arms, forearms, hands, thighs, shins, and feet. After specifying exactly how these parts are to be connected (with bones and joints), you can record your animation, frame by frame, by moving the character's parts. An image sheet can then be created from this animation. Some available sprite builders include:  Spriter Free, with a Pro license available for $25. Comes with some "art packs" so you can get a feel for how the software works before creating your own image packs. Additional art packs available for purchase. Plenty of tutorials available on their site.  Spine Essential version costs $69, but has many features. Very popular among developers, and you'll find many tutorials and helpful advice in their forums. Includes Corona runtime library to easily load and render your animation in your app. Importing Image Sheets After you’ve created your image sheet, we need to give Corona a set of instructions on how to read it. We begin by creating a table with information about the image sheet. You’ll need to know how wide and tall each frame is (these should all be the same dimensions), the total number of frames, and the total width and height of the image sheet. We’ll also assign a variable name to this table, as we’ll need to refer to it later. local table sheet sheettable = { width = width_value, height = height_value, numFrames = num_value, sheetContentWidth = num_value, -- choose a unique name for the -- width of each frame -- height of each frame -- the number of frames -- total width of the image -- total height of the sheetContentHeight = num_value image sheet } As usual, these values are all in terms of pixels. Next, we’ll define an image sheet using the image file, and tell Corona to use the information in the table to interpret it. We’ll need to name our sheet: local image_sheet_name = graphics.newImageSheet( "filename.png", sheettable ) The filename should be the exact name of your image sheet file, including the extension, in quotation marks. Also, include a path to the file if it is not stored in the same folder as the scene’s lua file. To follow along with the example below, save the following image to the same folder as your main.lua file: Do not change the size, type, or name of the file (it should be saved as "android_sheet.png"). In the main.lua file, we’ll define a table called androidSheetTable and then create a sprite sheet called androidSheet. local androidTable , androidSheet androidTable = { width = 329, height = 241, } numFrames = 30, sheetContentWidth = 3290, sheetContentHeight = 723 androidSheet = graphics.newImageSheet( "android_sheet.png", androidTable ) Note we did not need to explain that there are three rows of ten images. Corona uses the size of each frame and the size of the entire sheet to figure out how the frames are arranged. If you run this code, you will not see anything in the simulator. We have not yet created a display object, so there's nothing on the screen. Displaying a Single Frame If you're just using image sheets to minimize the number of files included in your app, you'll need a way to reference each image in the sheet. For instance, suppose you've created the following image sheet, containing the various stages of a character's "health bar" for a game. You can create an image sheet, with accompanying data table, for this sheet as follows: local healthbarOptions = { width = 100, height = 15, numFrames = 7, sheetContentWidth = 100, sheetContentHeight = 105 } healthbarSheet = graphics.newImageSheet( "healthmeter.png", healthbarOptions ) Now, to display only the first frame (as you might when the game starts and your character has full health), you would define a display object referencing just the first frame: local myHealth = display.newImage( healthbarSheet, 1 ) Animated Sprites After Corona has imported our image sheet, we will still not see any of our images on screen, because we have not yet created any display objects. To create and modify the animated sprite object, we'll need to set up some tables. The Sequence Table We’ll first create another table contains a series of sequence tables, each giving directions on how to display animations using the frames in our image sheet. We have two ways of creating each sequence: consecutively and non-consecutively. If you have placed the images in your sheet in the order you’d like them displayed, you can use the consecutive sequence style. You can also create an animation using a subsequence of all the frames in your sheet. local sequencetable = { sequence table { name = sequencename, animation sequence start = num_value, count = num_value, time = num_value, loopCount = num_value, is 0 for infinite loopDirection = "forward" "bounce" } } -- choose a unique name for the -- choose a unique name for this -- starting frame, default is 1 -- total number of frames to include -- time, in milliseconds, of animation -- number of times to repeat, default -- optional, use either "forward" or We need to specify a name for this sequence, as well as which frame to begin with and the total number of frames to play in the sequence. The other arguments above are optional. If not specified, the time value is based on the number of frames, though you will almost certainly want to adjust this. The default loopCount is 0, which causes the sequence to repeat indefinitely. The loopDirection is also optional, and may be set to "forward" or "bounce". When set to forward, the animation ends (or begins the next loop) with the last frame in the sequence. When set to bounce, the animation is played forward and then backward, returning to the original frame. Alternately, we can create a non-consecutive sequence by specifying which frames should be played, and in which order. Most of the data in the sequence table is the same, except instead of specifying the starting frame and number of frames, we provide a list of the frames to be played: local sequencetable = { { name = sequencename, animation sequence frames = { x1, x2, x3, ... }, order time = num_value, animation loopCount = num_value, repeat, default is 0 for infinite loopDirection = "forward" "forward" or "bounce" } } -- choose a unique name for this -- list of frames to play, in -- time, in milliseconds, of -- number of times to -- optional, use either The frames table can contain any number of frames, in any order, and frame numbers can be repeated. All values in the table should be integers between 1 and the total number of frames in your sheet. Conveniently, we can include more than one of these sequences within the sequence table. This means we can create multiple animation sequences from the same sprite sheet. We can also combine the types of sequence (consecutive and non-consecutive) within a single sequence table. Be sure to separate each of these sequence tables with a comma. The Sprite Object Finally, we’re ready to create the display object that will show our animation. As we’ll see, this display object can be treated in many of the same ways as other display objects - it can be positioned, scaled, and transitioned just as any other images. We’ll give a variable name to this object as usual. We use the display.newSprite function, passing the name of the sprite sheet and sequence table: local spritename = display.newSprite( spritename, sequencetable ) Note that we can create more than one such object from the same sprite sheet and sequence table - this means multiple instances of the animation can occur simultaneously on screen. If we have only specified one sequence in the sequence table, that will be the one used for the animation. However, we also have the option of specifying which sequence should be used (only one can be used at a time, though it can be changed later). If we do not specify a sequence, the first one in the table will be chosen by default. To use a particular sequence, refer to it by the name used in the table: local spritename = display.newSprite( spritename, sequencetable ) spritename:setSequence( sequencename ) Animating the Sprite To see your sequence play as defined in the sequence table, include the line spritename:play() after defining the sprite and specifying which sequence to use. We can pause the animation at any time using spritename:pause() We can also skip to a particular frame in the sequence. This would typically be done after pausing the animation. spritename:setFrame( num_value ) Here, the value is the integer value of the frame in the sequence, which is not necessarily the same as the frame number in the sheet. Note that the setSequence method can be used at any time after defining the sprite. This means that we create a sprite that performs one animation, and change which animation it plays later, rather than creating an entirely new sprite object. Changing the sequence will stop the former sequence if it is currently being played, and so you’ll need to restart the animation using the play method again. Example: Animated Droid

Solution PreviewSolution Preview

These solutions may offer step-by-step problem-solving explanations or good writing examples that include modern styles of formatting and construction of bibliographies out of text citations and references. Students may use these solutions for personal skill-building and practice. Unethical use is strictly forbidden.

--   Program Name: Animation Android Program (main.lua)
--   Description: This program is to animate a image sheet. First, the the image sheet
--                information and sprite sheet itself. Second, the sequence data is loaded
--                to animate the image sheet. Third, the sprite is declared and displayed
--               on screen with a message of instructions on how interacting with the
--               simulated android phone in Corona.
--

-- Image sheet information
local sheetInfo = require("cavemanspritesheet")
-- Image sheet is loaded
local myImageSheet = graphics.newImageSheet ( "cavemanspritesheet.png", sheetInfo:getSheet() )

-- Sequence Data
local sequenceData = {
    {
    name="caveM",
    sheet=myImageSheet,
    start=1,
    count=6,
    time=1000,
    loopCount=0
    },
}

-- Load the sprite from image sheet
local caveguy = display.newSprite( myImageSheet, sequenceData )
-- Display a centered animation
caveguy.x = display.contentCenterX
caveguy.y = display.contentCenterY
-- Setup the sequence
caveguy:setSequence( "caveM" )
-- Plays the animation
caveguy:play()

-- Loads text to be displayed
local myText = display.newText( "Click and hold bone picture to interact with animation.", 0, 0, native.systemFont, 14 )
-- Postion the text
myText.x = 10 ; myText.y = 100
-- Color the text
myText:setFillColor( 1, 1, 1 )
-- Set anchor X to 0
myText.anchorX = 0...

By purchasing this solution you'll be able to access the following files:
Solution.zip.

$10.00
for this solution

or FREE if you
register a new account!

PayPal, G Pay, ApplePay, Amazon Pay, and all major credit cards accepted.

Find A Tutor

View available Programming (Dynamic, Linear, Non-linear, etc.) Tutors

Get College Homework Help.

Are you sure you don't want to upload any files?

Fast tutor response requires as much info as possible.

Decision:
Upload a file
Continue without uploading

SUBMIT YOUR HOMEWORK
We couldn't find that subject.
Please select the best match from the list below.

We'll send you an email right away. If it's not in your inbox, check your spam folder.

  • 1
  • 2
  • 3
Live Chats