Corona – config.lua and making universal apps

Here’s a link to a couple articles on the Corona web site about making apps to fit a wide range of screen sizes. Be sure to comments there’s a lot of good questions and answers there. The second articles takes the whole concept to a very elegant solution.

  1. http://www.coronalabs.com/blog/2012/12/04/the-ultimate-config-lua-file/
  2. http://coronalabs.com/blog/2013/09/10/modernizing-the-config-lua/

Corona – newText positioning

Corona has great graphic handling. Making pictures and moving them on the screen is easy to and works great. When it comes to text there is a little frustration.

The API for display.newText() is:

display.newText( text, left, top, font, fontSize )

So that second and third parameter positions your text from the left and top edges. When you position with the x and y of the text object itself, you are positioning the object from the reference point which is in the center.

local myText = display.newText( "Hello World", 10, 10, "Helvetica", 24 )

The example above would place the text “Hello World” so that the upper left corner of the H would be 10 pixels right of the left edge of the screen, and 10 pixels below the top edge of the screen.

Since the reference point is in the center you can’t be sure what the x and y would be, you would have to know the width.

If you next set the x and y, as in:

myText.x = 100
myText.y = 20

You would know that that the center of the text would be at exactly 100 x and 20 y. Of course how far the left edge of the text was from the left edge of the screen would be hard to figure.

The biggest problem with with handling text in Corona, is that the reference point is reset to center when the text is redrawn. For example:

myText.text = "What!"

The text displayed is shorter and Corona reset the reference point to the center. On the screen this would look like the text were center aligned. The left and right edges would move in toward the center.

If the text is in the center there is no problem. If you have text that needs to align on the left or right, you’ll need to set the reference point and position the text anytime you change the text string it displays.

For example if you wanted to position text aligned 10 from the left edge. You could create your text field with:

local myText = display.newText( "0", 10, 10, "Helvetica", 24 )

If the text changes, imagine you have a game and this text field shows the score.

myText.text = 500

To keep the left edge 10 pixels from the left of the screen, set the reference point to the left side and then set the x position to 10.

myText:setReferencePoint( display.TopLeftReferencePoint )
myText.x = 10

 

 

Corona – Zwoptex – Sprite Sheets

Zwoptex is a tool for creating sprite sheets. Simple and easy to use. Just drag or import your images. Clicking the layout button arranges your images. Click Publish to the publish a Sprite Sheet image and coordinate data. Zwoptex exports data for several platforms.

A few tips. At the time of writing this, Zwoptex output coordinate date for the older Sprite Sheet format used by Corona. Not the newer Image Sheet format, which is much improved. Luckily this is easily remedied.

Be sure to set the Click Publish Settings and save your Zwoptext file before Publishing. You’ll need to set the file dimensions before exporting also. The sizes listed are multiples of 4 just pick the size that best fits.

Use this code example to create Module containing Image Sheet options you can import.
http://forums.coronalabs.com/topic/23624-adjustment-for-new-sprite-apis-spritesheet-object/

Both of these work differently the end result is the same. They both export your sprite data in the newer Image Sheet format. The first will create the code needed that you can copy and paste. The second creates a module you can require into a project.

There isn’t any reason why you can’t use both of these! Create a new Coordinate Format in Zwoptex > Preferences > Coordinates Format tab. Click the + button at the bottom left. Give you format a name and paste one of the code snippets from the links above. Set the Extension to .lua below the Source Extension. Repeat the process for the second code block and you can choose one or the other depending on your needs.

Screen Shot 2013-09-30 at 4.38.29 PM

Corona – Simple button

The widget button works well for many circumstances. In some cases you will want to use something simpler and more customizable. Here’s is a simple script that shows the basic concepts for creating your own button with a default and active state.

Here the button is a simple rectangle. The default and active state are represented by a simple color change. This could be an image change or any other effect.

-- This function handles animating the button's 
-- default and active states. 
local function on_touch( event ) 
	local phase = event.phase	-- Get the event phase
	local button = event.target	-- Get the event target

	-- Check the phase of the event
	if phase == "began" then 
		-- When the event begins give button focus, and color red
		display.getCurrentStage():setFocus( button )
		button:setFillColor( 255, 0, 0 )
	elseif phase == "ended" or phase == "cenceled" then 
		-- When event ends release focus, and color white
		display.getCurrentStage():setFocus( nil )
		button:setFillColor( 255, 255, 255 )
	end 
end

local function do_something() 
	print( "The button did something!" )
end 

local button = display.newRect( 0, 0, 48, 48 )
button.x = display.contentCenterX
button.y = display.contentCenterY

button:addEventListener( "touch", on_touch )
button:addEventListener( "tap", do_something )

Corona – Triple Town style Matching Game score part 4

I like the idea of animating the combing of tiles. This shows the effect of game play graphically. In some situations a play will combine three tiles setting up a situation where three more tiles can be combined. This is covered in the recursive system from the last post. The game covers this but game play is greatly enhanced if the player can see some graphical representation of what is happening. The same applied to scoring points or other in game effects.

Graphically animating the cause an effect for things that could normally be invisible on the computer enhance the experience of using your apps. This is an important part of creating good user experience. Think of the animation as a little story telling a player about the points they just earned or the new power up they just received or anything that might have happened.

A good example of this can be applied to the tile matching. In the game placing a third tile combines the three tiles into the next color of tile. When this third tile appears it might appear next to another two tiles of the same color. At this point the we have another match and the computer needs to combine them again, and so on.

We have this covered. But the action applies in a single step, no matter how many tiles have been combined. In this system it is not exactly clear what has happened. Better would be to show each step animated sequentially. For example, show red tiles combining into a green, followed by three green tiles combining into a blue tile.

Animating combining tiles

Since the system described in the last post uses a recursive function call, creating this effect is easy to achieve. We only need to delay recursive call to check_tile_match(tile) the time of the animated transition.

Inside the check_tile_match(tile) function, there is a call to check_tile_match(tile). Instead of calling this directly, wrap it in a timer.perfromWithDelay(). check_tile_match(tile) requires that you include the tile you are looking for. Since this variable is local to the function we’ll to use a closure.

timer.performWithDelay( 500, function() check_tile_match( tile ) end, 1 )

Here I’ve added a function as the handler for timer.performWithDelay(). This function wraps, or encloses, check_tile_match(tile), effectively preserving the value of tile.

Adding some animated score

As long as we’re on the subject of providing information about game state and game actions, we should also provide some score information. The game currently does not have a score, then I’ll add a an animated point value that appears at the location where points are scored.

Adding the Score

Score is a big topic games. How many points should a play be worth? Great question that points to how your game progresses and how players will view escalation and game play. Rather than concentrating on the points scored I want to focus on how the score is displayed here.

The most common place to see the score is the upper left corner of the score. We’ll use that in this example. I first hid the status bar to make room for the score.

display.setStatusBar( display.HiddenStatusBar )

Create a variable to hold the actual score value.

local score = 0 -- Add a variable to hold the score

Next, create a text object to display the score.

-- Add a text object to display the score
local score_text = display.newText( score, 0, 0, native.systemFont, 16 )

Due to the way that Corona handles text we will need to set the reference point and set the position of the text object each time we change the text it displays. I created a function to handle this.

This function receives a parameter equal to the number of points just scored. It adds these to score, sets the get in the score_text to the updated value then sets the reference point. I want the text to align with the upper right corner. Normally text objects are aligned with a center reference point. After changing the text of the object I need to set the reference point with object:setReferencePoint() and then set the x and y.

When the project loads, the last line below, calls this function once. This sets the initial position of the text field.

-- A function to update the score 
local function set_score( points ) 
	score = score + points 	-- Add points to score
	score_text.text = score	-- Display the new score 
	-- These next three lines position the score based on the top left reference point
	score_text:setReferencePoint( display.TopLeftReferencePoint )
	score_text.x = 10
	score_text.y = 5
end

set_score( 0 ) -- Call set score once to position the score text correctly

Next set the score when points are scored. Inside check_tile_match(tile) find the line that sets the point score for the last play. Right after this call set_score(points) passing the points scored.

-- Calculate points 
local points = match_color_index * 100 * #matched_array
set_score( points ) -- Call set_score to add these points to the score 
show_points( points, tile.x, tile.y ) -- Display the points at the location of the scoring tile

Show points scored at the point where they are scored with motion

Now we’ll add a text field that shows the points scored. This will show up at the tile that was last played. Then animate up the screen and fade out. This is another good spot for a factory function.

First we need a function to create a text field that will show the point value scored. This will be another factory function that returns a reference to the text object created. All that happens here, is a text field is created, and the text is set to the number of points scored. Then the text field is returned. You pass what to display to this function.

It seems like this function does’t do much. It’s job is to keep us organized. Here the only thing that happens is we make the text object. Any code that would set the color or other features of this text object would go here.

-- Add a function to create score field objects
local function Score_Field( points )
	local score_text = display.newText( points, 0, 0, native.systemFont, 12 )
	return score_text
end 

Next we’ll make a factory function that creates the points and animates the text field. We’ll use a transition to animate the text and a function to remove the text when the transition is complete.

-- This function removes score fields
local function remove_score_text( score_text )
	display.remove( score_text )
end

-- this function shows points in a score field on the game board. 
local function show_points( points, x, y )
	local score_text = Score_Field( points )
	score_text.x = x
	score_text.y = y
	
	transition.to( score_text, {y=y-100, time=300, delay=200, alpha=0, onComplete=remove_score_text} )
end 

Last call this function from check_tile_match(tile) after the line that calculates the point value.

-- Calculate points 
local points = match_color_index * 100 * #matched_array
set_score( points ) -- Call set_score to add these points to the score 
show_points( points, tile.x, tile.y ) -- Display the points at the location of the scoring tile

Here’s a full listing the code that I used. This combines the code from the last example with the new code discussed here.

Continue reading Corona – Triple Town style Matching Game score part 4

Corona – Triple Town style Matching Game matches Part 3

Here’s a nice addition to the Triple Town like matching game. Add an animated transition to a match. The effect is that the tiles appear to merge into the final tile.

The effect is created by creating new tiles above the regular game tiles. These new tiles are only temporary. They are placed above the original tiles with the same colors and are animated toward the final tile. The motion uses alpha, so they fade to transparent when the transitions is complete. Each tile removes itself when the transitions are complete using the onComplete property.

The only new code added from the previous example, is a new function: animated_match(). This function makes use of the variables: matched_array, which contains all of the matched tiles, and match_color_index which contains the index of current color that was matched.

local function animated_match()
	local color = color_array[match_color_index] 
	local t = {time=500, x=matched_array[1].x, y=matched_array[1].y, alpha=0, onComplete=remove_tile}
	
	for i = 1, #matched_array, 1 do 
		local tile = Tile()
		tile:setFillColor( color.r, color.g, color.b )
		tile.x = matched_array[i].x
		tile.y = matched_array[i].y
		transition.to( tile, t )
	end 
end

Here’s a full list of the code for this example:

Continue reading Corona – Triple Town style Matching Game matches Part 3