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 2 of 7 of this article. Click here to view the first page.

Ready Player One — Getting Your Project Ready

For the game you’re making in this tutorial, I’ve created a starter project for you. It doesn’t contain any code yet, but it contains all of the files and sounds you’ll need for the game, as well as a nice directory structure.

So Download the starter project and unpack it. Inside you’ll find a project folder named AnimalFeeding. As well, you’ll find a set of image and audio assets along with the main.lua file, which will contain the main game code. The structure is shown below:

Project files

Project files

Fire up your text editor of choice and open up main.lua.

Whoa — it’s empty! That will get you nowhere fast! First, you’ll need to display a window on the screen. Every visual application needs a window (or a view in iOS) to display your work.

Paste the following code into the main.lua:

----------------------------------------------------------------
-- screen (window) initialization
----------------------------------------------------------------
-- 1.
local STAGE_WIDTH = 960
local STAGE_HEIGHT = 640
local SCREEN_WIDTH = 960
local SCREEN_HEIGHT = 640
print ( "System: ", MOAIEnvironment.osBrand )
print ( "Resolution: " .. SCREEN_WIDTH .. "x" .. SCREEN_HEIGHT )

-- 2.
MOAISim.openWindow ( "Animal Feeding", SCREEN_WIDTH, SCREEN_HEIGHT ) -- window/device size

-- 3.
local viewport = MOAIViewport.new ()
viewport:setSize ( SCREEN_WIDTH, SCREEN_HEIGHT ) -- window/device size
viewport:setScale ( STAGE_WIDTH, STAGE_HEIGHT ) -- size of the "app"

-- 4. 
local layer = MOAILayer2D.new ()
layer:setViewport ( viewport )
layer:setClearColor (0.53, 0.53, 0.53, 1)

-- 5.
local partition = MOAIPartition.new ()
layer:setPartition ( partition )

-- 6.
MOAIRenderMgr.setRenderTable ( { layer } )

Here’s a quick rundown of the code above, comment by comment:

  1. Set some local constants (stage and screen width and height) and print them out to the console. If you’re new to Lua, keep in mind that the local keyword gives the variable limited rather than global scope. In this app the scope doesn’t really matter, but it’s a good practice to limit the number of global variables floating around.
  2. Open the window, name it “Animal Feeding” and set width and height to the previously defined 960 and 640.
  3. Create the viewport, which is what allows you to “look” at the scene. The viewport size refers to the actual display size, while the scale defines the coordinates. In this case, the size and scale are the same. If you have a Retina display, you might set the size to 960×640 but the scale to 480×320.
  4. Create a layer, which is sort of like the “root” view or window. A layer needs to be viewed through a viewport, so the viewport from step #3 is linked to the layer. The “clear color” is the background color of the layer, which is set to a nice grey (RGB 0.53, 0.53, 0.53)
  5. A partition is used to catch user interactions, such as clicks and touch events. This will come in use later when you add the interactive bits.
  6. Finally, the Moai Render Manager is set up to handle rendering on the newly created layer.

To run the code, open up a Terminal window and navigate to the folder containing main.lua.

Build and run your code with this command:

$ moai main.lua

You’ll see the following stunning window:

Empty window

Empty window

Success! A nice blank grey window. You should also notice the output of the two print statements in the terminal:

System: 	OSX
Resolution: 960x640

Now that the window is set up, it’s time to add something more interesting to it.

What’s Invisible and Smells Like Carrots? — Adding Sprites to the Game

You’ll need to add a few things to liven up this game. Start by adding some sprites.

Add this code to the bottom of main.lua:

local quad = MOAIGfxQuad2D.new ()
quad:setTexture ( "gfx/carrot.png" )
quad:setRect ( -84/2, -98/2, 84/2, 98/2 )

local prop = MOAIProp2D.new()
prop:setDeck ( quad )

layer:insertProp ( prop ) 

A “quad” is a rectangle — hence the name “quad” — that can hold a texture image. Think of it as an abstract object, much like a class definition.

A “prop” is what might be called a “sprite” in another framework. It is something that is displayed on-screen. If a quad is comparable to a class, then a prop is like a practical, usable instance of that class.

With this setup, you could load a texture into a quad, and then use it multiple times in many props. You can read more about the distinction between the two on the Moai wiki.

Run your project, and now you are rewarded with a mighty-looking carrot in the center of the screen!



Note that the default position of your graphics is smack dab in the center of the screen.

Coordinates in a typical Moai application are a bit different than what you’re used to in Cocos2D or Corona SDK applications. The (0, 0) point is at the center of the window! Positive X values are to the right side and negative to the left; positive Y values are up and negative on the bottom, as shown in the image below:

Default coordinates system has the (0, 0) point in the center of the window. Upper part of the window has positive Y values, lower has negative Y values.

Default coordinates system has the (0, 0) point in the center of the window. Upper part of the window has positive Y values, lower has negative Y values.

You’re likely thinking “That’s a heck of a lot of code to display a single sprite! Do I really need to type all that code for every graphic on my screen?”

It probably makes sense to set up a reusable function that will do all the graphics housekeeping for your game. The average game will probably have many sprites, so you’ll want to make creating a sprite nice and easy to save you coding time.

Replace the last bit of code you pasted in (from “local quad = “MOAIGfxQuad2D.new ()” down to “layer:insertProp ( prop )”) with the following:

----------------------------------------------------------------
-- Textures and sprites creation
----------------------------------------------------------------
local textureCache = {}

local function textureFromCache ( name, width, height )
  if textureCache [ name ] == nil then
    textureCache[name] = MOAIGfxQuad2D.new ()
    textureCache[name]:setTexture ( name )
    textureCache[name]:setRect ( -width/2, -height/2, width/2, height/2 )
  end
  return textureCache [ name ]
end

local function newSprite ( filename, width, height ) 
	if width == nil or height == nil then
		-- read width/height from the image
		local img = MOAIImage.new ()
		img:load ( filename )
		width, height = img:getSize ()
		img = nil
	end

	local gfxQuad = textureFromCache ( filename, width, height )
	local prop = MOAIProp2D.new ()
	prop:setDeck ( gfxQuad )
	prop.filename = filename
	return prop
end

In the code above, newSprite() takes a filename as an argument with optional width and height of the image. If the width and height aren’t passed in as arguments, the function will figure out the image dimensions once it’s been loaded.

The textureCache object is used by newSprite() to represent the graphics object to display on-screen. As well, setDeck is a Lua hashtable, comparable to an NSDictionary that will hold each texture as it’s loaded. Since textures will be reused a lot, this will help speed things up.

Finally, newSprite sets the filename property of the object and returns the newly created sprite to the caller for later reference.

Now you’re able create a sprite with a single line of code! However, you’ll still need three lines total to add and position the sprite on the layer.

Paste in these lines at the bottom of main.lua:

local sp1 = newSprite ( "gfx/carrot.png", 84, 98 ) -- here we supply width and height
sp1:setLoc( -100, -230 ) -- set location - we move the sprite to the left and down
layer:insertProp ( sp1 )

local sp2 = newSprite ( "gfx/bone.png" ) -- no width and height supplied, it will be read from the file size
sp2:setLoc ( 100, -230 ) -- move to the right and down
layer:insertProp ( sp2 )

Run your app, and now your screen should look like the image below:

Carrot, meet bone

Carrot, meet bone

You could of course have a super-function that (in addition to loading the image) also sets the position and adds it to a layer. However, in this tutorial, you’ll keep things simple and depend on newSprite() to only load the image and handle the caching.

Now that you have an easy way to throw images up on the screen, it’s time to get those images moving around!

First, remove those six lines that you just pasted in main.lua; you’ll be adding a more generic spawnFoodObject() method in the next section that will make your life a little easier.