How To Make a Simple Game with Moai

This is a tutorial for beginner Moak SDK developers, you’ll learn how to create a new animal-feeding game for iOS from scratch. With Moai, you don’t need to fear being locked in to one platform — you can let everyone enjoy the fruits of your labors! By .

Leave a rating/review
Save for later
Share
You are currently viewing page 5 of 6 of this article. Click here to view the first page.

You’ve Been Fed, Now Shoo! – Removing Sprites

Now for the final bits of game logic — removing customers once they’re full, and rearranging the customers when one disappears.

Paste the following code in just underneath the playAudio() function from a few steps back:

local points = 0
local function rearrangeCustomers ()
	for customerIdx, cust in pairs ( listOfCustomers ) do
		local x, y = cust:getLoc ()
		cust:seekLoc ( horizontalPositionForCustomerNumber ( customerIdx ), y, 1 )
	end
end

local function removeCustomer ( cust )
	layer:removeProp ( cust.plate )
	layer:removeProp ( cust )
	cust.plate.customerSprite = nil
	cust.plate = nil

	for custIdx, c in pairs ( listOfCustomers ) do
		if c == cust then
			table.remove ( listOfCustomers, custIdx )
			break
		end
	end
	rearrangeCustomers ()
	points = points + 1
	print ( " Points: ", points )
end

removeCustomer() does what it says, and removes a customer. The sprite and plate images are removed and then rearrangeCustomers() is called so that customers are lined up from left to right with no gaps in between.

You’ll also notice a new points variable. When a customer is full and gets removed, the player will get one point.

You can now call removeCustomer() once the animal’s sound finishes playing.

Find foodReleasedAfterDrag() – where you added the playAudio() call – and add the call to removeCustomer() so the code looks like this:

	-- make a sound
	playAudio ( "audio/" .. cust.soundName, 1, false, function ()
		removeCustomer ( cust )
	end )

Run the game! You’ll note that a customer will now disappear after they’re fed and the sound has played.

Won’t These Animals Ever Stop Eating? — Displaying the Score On-Screen

The score is printed out to the console, but that isn’t particularly useful to the player. Surely it’s better to display it on the screen where they can see it!

There’s a few steps to accomplish this. First you need a MOAIFont object loaded up with the appropriate font file. Then you create a MOAITextBox object that uses the specified font to render text on screen. MOAITextBox can be added to a layer just like a sprite.

Paste in this code at the top of main.lua, just before removeCustomer:

----------------------------------------------------------------
-- TextBox code
----------------------------------------------------------------
local charcodes = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
            .."0123456789 .,:;!?()&/-"
 
local font = MOAIFont.new ()
font:load ( "arial-rounded.TTF" )
font:preloadGlyphs ( charcodes, 7.5, 163 )
 
infoBox = MOAITextBox.new ()
infoBox:setFont ( font )
infoBox:setString ( "Animals fed: 0" )
infoBox:setRect ( -STAGE_WIDTH/2, 0, 0, STAGE_HEIGHT/2 )
infoBox:setYFlip ( true )

layer:insertProp ( infoBox )

arial-rounded.TTF is already included in the starter bundle you downloaded. The call to preloadGlyphs() helps speed up text rendering since you’re letting Moai know which characters you’ll be using via the charcodes string.

Finally, it sets up an infoBox variable, which is basically a label on the screen that can display some text with the above font.

Now that you have an infoBox available, you can go back to removeCustomer() and display the current score on the screen.

Update the last line of removeCustomer() in main.lua to read as follows:

	infoBox:setString ( "Animals fed: " .. points )

Run your game and you should see your score increase as you feed the animals, as in the screenshot below:

Hungry customers + food = points!

Hurry up! These hungry animals won’t feed themselves, you know! :]

Taking this Dog and Pony Show On the Road — The Mobile Version

Okay – you have a complete game running on the desktop! Congratulations – you’re done…

“Hey, wait a second,” you’re thinking. “I was promised a cross-platform toolkit here!”

There are just a few more elements to add if you want to run the game on an iOS device. The initial setup of these elements might take a bit of time, but you will only need to do this once per project — and then it’s done!

First, make one change to support Retina displays. At the top of main.lua, replace the SCREEN_WIDTH and SCREEN_HEIGHT definitions to match the following:

local SCREEN_WIDTH = MOAIEnvironment.verticalResolution or 960
local SCREEN_HEIGHT = MOAIEnvironment.horizontalResolution or 640

MOAIEnvironment is an object that contains information about the current platform. verticalResolution and horizontalResolution will be empty when you run Moai from the command line, as it’s up to you to decide on a window size. On iPhones, for example, it will return an actual number such as 480 on non-Retina devices, 960 on Retina devices, and 1136 on the iPhone 5.

There are two possible ways of handling the next few steps of Xcode setup:

  1. Copy the headers and libs folders from Moai into your project. This increases the project size but means your project is self-contained and has no external dependencies. The final project archive uses this method so that everything is in one place.
  2. Keep the SDK files in their original location (/Users/username/moai-sdk or wherever) and build the project from there. This will make the Moai SDK you unpacked specific to this game, so keep the original archive around for your next game!

In this tutorial you’ll follow method #2 since you already have the Moai SDK and you know where it lives.

From the Moai SDK folder, navigate to the hosts/ios folder. You should see a whole set of project files.

Open up moai.xcodeproj with Xcode.

Pick the iPhone Simulator target with the latest SDK and run the project. You should see a standard Moai app that doesn’t do very much, as you can see below:

The next step is to tell Xcode about the amazing main.lua you just fleshed out, as well as the image and audio asset files.

From the animalFeeding folder you were working in, drag iTunesArtwork.png and the moai folders into the Xcode project, as shown in the image below:

Make sure to select these options:

  • Copy items into destination group’s folder, and
  • Create folder references for any added folders

Also, select all the targets in the “Add to targets” section, as shown below:

Navigate to the Resources/build group in your project navigator, and open moai-target. It contains the list of folders needed for the Lua part of Moai. Replace the contents of the file with this one line:

./moai

That one line tells the build script to copy everything in the moai folder to the built project. The important thing to note here is that even though you’re now developing the app in Xcode, you should still use your regular Lua editor for Lua files.

Next, you need to let Xcode know to include the Untz system for audio playback.

Open up the Build Settings for the project and add an “Other C Flags” value of -DUSE_UNTZ, as seen below:

The last thing to do before running the game in the simulator is to set the app to run in landscape mode, and set the size of the views accordingly.

Open up MoaiAppDelegate.mm and find this line (around line 48):

mMoaiView = [[ MoaiView alloc ] initWithFrame:[ UIScreen mainScreen ].bounds ];

Replace that line with the following code:

CGRect viewBounds = [ UIScreen mainScreen ].bounds;
viewBounds.size.width = [ UIScreen mainScreen ].bounds.size.height;
viewBounds.size.height = [ UIScreen mainScreen ].bounds.size.width;
mMoaiView = [[ MoaiView alloc ] initWithFrame:viewBounds ];

In the code above, you’re flipping the width and height values since the app will be running in landscape.

Now you need to fix your project to landscape mode.

Open up MoaiVC.mm and replace shouldAutorotateToInterfaceOrientation: with the following:

- ( BOOL ) shouldAutorotateToInterfaceOrientation :
  ( UIInterfaceOrientation )interfaceOrientation {
 
    if ( interfaceOrientation == UIInterfaceOrientationLandscapeRight ) {
        return true;
    } else {
        return false;
    }
}

Finally, go to the project Summary tab and select Landscape Right as a Supported Interface Orientations, as seen in the screenshot below:

Supported interface orientations: Landscape Right

That’s it – do a final build and run to see your final app running on a mobile device!