Today’s guest tutorial comes to you courtesy of Greg Pugh. In addition to working as a Flash and mobile app developer for MC Strategies, Greg is the owner of GP Animations, an independent studio in Nanticoke, Pennsylvania. Greg’s apps include those listed on his blog here. Additionally, he writes Corona tutorials for RayWenderlich.com and Kwiksher.com. As a Corona Ambassador, Greg recently started to write an iBook that introduces new developers to the world of Corona SDK.
Preface
As a new parent, my iPad is quickly filling up with children’s books, games, and learning activity apps. Right now, my daughter seems to gravitate towards the two books I’ve written (http://www.ColinTurtle.com) and oddly enough, “Game For Cats.” Soon she will be the appropriate age for learning her shapes, colors, alphabet, etc. and she’ll want to use different apps. Today, I’m going to show you how to create a basic kids’ activity app where children can drag and drop shapes to the correct outlined area.
First, I suggest that you watch this video to see the app in action.
You’ll notice that you’re able to drag both shapes at the same time. I like this feature because kids have a tendency to use both their hands when playing on smart devices. In order to create this feature, you’ll utilize dmc_multitouch by David McCuskey (I’ve included the necessary module files in the project so you don’t have to download them). It should be noted that at the time of this writing, the Corona Simulator doesn’t support multitouch events. You will need to publish the completed project to test on an actual device in order to use multitouch.
You can download the project files here. Once the SnapShapes folder is unzipped, inside you’ll see two folders. SnapShapes_FINAL contains the completed main.lua file for you to try and SnapShapes_START just contains the artwork and supporting files.
Project Code
To get started, open your text editor of choice, create a new file, and save it as main.lua in the SnapShapes_START folder you downloaded. The first step is to import the dmc_multitouch.lua file, so copy and paste the following code into main.lua:
-- Require dmc_multitouch
MultiTouch = require("dmc_multitouch");
Next, you’ll hide the status bar since kids don’t seem to care about time or how much service your phone has.
-- Hide status bar display.setStatusBar(display.HiddenStatusBar);
Now you’ll insert the images provided to you in the images folder onto the display. Copy and paste the following into main.lua and then save.
-- Background image
local background = display.newImageRect("images/background.png", 640, 960);
background.x = display.contentCenterX;
background.y = display.contentCenterY;
-- Square outline
local sqLine = display.newImageRect("images/sqLine.png", 228, 228);
sqLine.x = 473;
sqLine.y = 181;
-- Square
local square = display.newImageRect("images/square.png", 188, 188);
square.x = 144;
square.y = 778;
-- Circle outline
local circLine = display.newImageRect("images/circLine.png", 245, 245);
circLine.x = 181;
circLine.y = 180;
-- circle positioning
local circle = display.newImageRect("images/circle.png", 200, 200);
circle.x = 473;
circle.y = 778;
-- myText positioning
local myText = display.newImageRect("images/myText.png", 508, 78);
myText.x = 311;
myText.y = 475;
Open your Corona SDK Simulator, navigate to File > Open, browse for main.lua in your SnapShapes_START folder and open it for iPhone. Your Simulator will now look like the image at right.
Now that you’ve got all of the artwork displaying correctly, it’s time to add the functionality. First, you’ll create the code for the blue circle and once that’s done, it’s just a matter of changing variable names to the red square. You’ll need to activate multitouch for the circle and set initial positioning variables to 0. Copy and paste the following into your main.lua file:
-- Circle MultiTouch.activate(circle, "move", "single"); -- Set initial variables to 0 local circlePosX = 0; local circlePosY = 0;
When the circle is dragged, it will become the target of touch events such as “moved” and “ended.” If the circle is dragged within 50 pixels on the center of the circle outline, it should “snap” into the center of the outline. Otherwise it should just stay where the user drags it. Add the following code:
-- User drag interaction on blue circle local function circleDrag (event) local t = event.target -- If user touches & drags circle, follow the user's touch if event.phase == "moved" then circlePosX = circle.x - circLine.x; circlePosY = circle.y - circLine.y; if (circlePosX < 0) then circlePosX = circlePosX * -1; end if (circlePosY < 0) then circlePosY = circlePosY * -1; end -- If user drags circle within 50 pixels of center of outline, snap into middle if (circlePosX <= 50) and (circlePosY <= 50) then circle.x = circLine.x; circle.y = circLine.y; end
If the circle is snapped into the center of the outline and the user stops dragging it, the circle will permanently be placed in the middle of the outline. Add the following code:
-- When the stops dragging circle within 50 pixels of center of outline, snap into middle, and...
elseif event.phase == "ended" then
if (circlePosX <= 50) and (circlePosY <= 50) then
circle.x = circLine.x;
circle.y = circLine.y;
-- ...lock circle into place where it cannot be moved.
MultiTouch.deactivate(circle);
end
end
return true;
end
Finally, add an event listener for the circleDrag function and save:
circle:addEventListener(MultiTouch.MULTITOUCH_EVENT, circleDrag);
When the Simulator refreshes, you will now be able to drag the circle around the screen, and when it is within 50 pixels of the outline, it will snap into place. If you stop dragging it after it’s in place, it will become permanently stuck.
Now it’s just a matter of adding the same code for the red square, so just substitute the variable names:
-- Same actions for the square as the circle
MultiTouch.activate(square, "move", "single");
local squarePosX = 0;
local squarePosY = 0;
local function squareDrag (event)
local t = event.target
if event.phase == "moved" then
squarePosX = square.x - sqLine.x;
squarePosY = square.y - sqLine.y;
if (squarePosX < 0) then squarePosX = squarePosX * -1; end
if (squarePosY < 0) then squarePosY = squarePosY * -1; end
if (squarePosX <= 50) and (squarePosY <= 50) then
square.x = sqLine.x;
square.y = sqLine.y;
end
elseif event.phase == "ended" then
if (squarePosX <= 50) and (squarePosY <= 50) then
square.x = sqLine.x;
square.y = sqLine.y;
-- If you'd like to be able to move the square again, comment out the line below
MultiTouch.deactivate(square);
end
end
return true;
end
square:addEventListener(MultiTouch.MULTITOUCH_EVENT, squareDrag);
You can comment out the “deactivate” line of code if you’d like users to be able to move the shapes even after they’ve put them in the correct locations. And, of course, you can add conditional statements to congratulate users when they’ve completed all the tasks.
And there you have it, a very quick and easy way to make an activity for children to play in an app!
The Next Step?
This basic concept can, of course, be expanded to suit other children-oriented or casual apps. For example:
- Use this same code to create a “dress up game” where children can place clothing on “dolls”.
- Create a puzzle game with many pieces, expanding the core function(s) to handle all pieces.
- Build a puzzle challenge into an adventure game.
As the mobile revolution continues, educational apps will likely grow in popularity. Understanding the basics behind a multitouch shape-match implementation is a first step towards building a great app that has the potential to be used not only at home, but in schools as well.




James
This tutorial came just in time for us. We’ll be basing our next app – a dress up game, on this very tutorial. Just wanted to say thanks guys, you really helped us on this one!!
Erich Grüttner
Thank you Rob… That’s a great and well-explained tutorial.
Great job!
Stefan
This is a great tutorial. Excellent for my next game:)
typhoons
it is great, thank you Rob… : )
Inna Treyger
@typhoons – This tutorial was actually put together by Corona developer, Greg Pugh. You can check out Greg’s apps here: http://gpanimationsblog.com/apps-by-gp-animations/
Kiffin Ayers
Totally agree! This is a perfect addition to add to our bag of tricks. Thanks Rob, always a pleasure!
Cheers, Kiffin
Morten
Thank you for this tutorial. I’m currently making a puzzle for kids and was trying to find a more generic approach for comparing the source and destination. It turned out the answer was right in front of me once I saw your tutorial. Thanks!
russell
The way it was written made it very easy to understand. You have planted a seed that allow us developers may grow a plant or beanstalk ang grow our own beans.
Thet Paing
This is a nice tutorial for me. This will help me on my project. Thanks.
Latchmanan
Thanks for sharing your knowledge, Rob. I’d like to build my first game (puzzle) based on your code above. I’m in the middle of integrate your code with Conona’s storyboard module. However, I’m seeing a small blue and red squares at top left of my screen. But no errors on the console. As my troubleshoot, I’ve removed all code except the include line – require(“dmc_multitouch”). Any hints or advice pls? Thank you again.
zulfahmi
Latchmanan, try add a background layer/picture.
Stefan
@Latchmanan, if you found a solution for the red and blue square please take a look here http://forums.coronalabs.com/topic/34050-basic-shape-matching-and-storyboard-api/#entry176411 and submit a resolve (or reply to this post). Thanks!
hamid
Thanks for the tutorial
Could anyone advise me how to code an additional feature whereby you can duplicate the draggable shape by double clicking it for example? Thanks