A tutorial series about Moai basics.

Welcome to another Moai Tutorial. This time, we’re going to focus a bit on text boxes and the things you can do with them. But first, a bit of information on how Moai handles fonts. When a font is loaded in, Moai creates a new texture so that it can draw the glyphs quickly. The downside to this is that once the font is called with a certain point size, scaling up or down from there will make the fonts look less smooth, so if you want nice looking fonts in different sizes, it is suggested to create a separate font for each point size. Talk about the tutorial here!


To get started, like always, we’ll need to set up our window.

MOAISim.openWindow ( "Textboxes", 320, 480 )

viewport = MOAIViewport.new ()
viewport:setScale ( 320, 480 )
viewport:setSize ( 320, 480 )
layer = MOAILayer2D.new ()
layer:setViewport ( viewport )
MOAISim.pushRenderPass ( layer )

Now that we have our window set up, we will have to set up our charCodes. This will tell Moai which of the glyphs to use from our ttf, instead of just loading the entire file (which can take up a lot of unnecessary space.) The order doesn't matter, just as long as every symbol you will use is included in this. Also, be sure to include a space! For the entirety of this tutorial, we will use the following line of code.

charcodes = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 .,:;!?()&/-'

Next up, we’ll load in the font that we will use. Moai allows users to load a font directly from a true type font file and use that. And, unfortunately for you, I’m picking an obnoxious font because I like the style. Feel free to use any TTF file that you would like.

font = MOAIFont.new ()
font:loadFromTTF ( 'Bastarda-K.ttf', charcodes, 16, 163 )

The loadFromTTF function takes in the following parameters:

loadFromTTF ( file name, char codes, point size for the font to render, device dpi ) 

Now that we’re done with our setup, it is time to create our text box.

textbox = MOAITextBox.new ()
textbox:setString ( "This is our text for the tutorial over textboxes" )
textbox:setFont ( font )
textbox:setTextSize ( font:getScale ())
textbox:setRect ( -150, -230, 150, 230 )
textbox:setYFlip ( true )
layer:insertProp ( textbox ) 

One thing to note about "setYFlip." While all other props in Moai will automatically assume a world style coordinate, a textbox will assume a window style. To get the textbox to render with world style, you set YFlip to true. And running that, you should see the following: Now that our first text box has been created, we can start changing it a bit. You may have noticed that the text appeared instantly. We can change that to spool in with

textbox:spool () 

This will slowly scroll the text through one space at a time. Perhaps you aren't too fond of the color white for your text. We can simply change that by using seekColor.

 textbox:seekColor ( 1, 0, 0, 1, 3, MOAIEaseType.EASE_IN )

If you read our tutorial on prop animations, this should look familiar to you. Textboxes in Moai are actually considered props, so any of the animations we talked about in that tutorial will also apply here. Moves, rotates, scale; all of them apply to textboxes. Now let’s say that you want to change the alignment of the textbox, it’s as easy as inserting another line. This can just be added in the main textbox chunk.

textbox:setAlignment ( MOAITextBox.RIGHT_JUSTIFY ) 

And now our text will be justified to the right side of the screen. We could also do MOAITextBox.LEFT_JUSTIFY or MOAITextBox.CENTER_JUSTIFY if that was what we wanted. Now we’re going to get a bit more complicated. Our textbox is currently the size of the screen, but what if it was smaller? And what if we had too much text for it? We’re about to find out. Go ahead and delete the shading and the alignment, we don’t need them for what we’re doing. Now we’ll need to edit the size of the textbox rect, so replace our code with this

textbox:setRect ( -150, 100, 150, 230 ) 

and run the file. You should get: As you can see, the text didn’t finish displaying. One method that we can use in order to scroll through the rest of the text is to create a function that will check, once the text can spool no more, if there is any more text in the string; if there is, it will then start spooling the rest of the text. This sample will just quickly run through the text; for games, you might want to wait for user input before moving onto a the next textbox. This is what our completed file will look like, and we will break it down bit by bit.

MOAISim.openWindow ( "Textboxes", 320, 480 )
viewport = MOAIViewport.new ()
viewport:setScale ( 320, 480 )
viewport:setSize ( 320, 480 )
layer = MOAILayer2D.new ()
layer:setViewport ( viewport )
MOAISim.pushRenderPass ( layer )

charcodes = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 .,:;!?()&/-'
text1 = 'This is our text for the tutorial over textboxes'
font = MOAIFont.new ()
font:loadFromTTF ( 'Bastarda-K.ttf', charcodes, 16, 163 )
textbox = MOAITextBox.new ()
textbox:setFont ( font )
textbox:setTextSize ( font:getScale ())
textbox:setRect ( -150, 100, 150, 230 )
textbox:setYFlip ( true )
layer:insertProp ( textbox )


function page ( text )
	textbox:setString ( text )
	textbox:spool ()
	
	while textbox:more () do
		
		
		while textbox:isBusy () do coroutine.yield () end		
		if textbox:more () then		
			
			textbox:nextPage ()
			textbox:spool ()
		end
	end
end

function main ()
	page ( text1 )
end
thread = MOAIThread.new ()
thread:run ( main )

Just going down from the top, the first change is that we’ve moved our string to a variable “text1”. This is so we can just call “text1” for our function instead of having to call the entirety of our textbox. After that, we create our page scrolling function.

 function page ( text )
	-- start spooling the text
	textbox:setString ( text )
	textbox:spool ()
	-- more will be true as long as there is any remaining text
	while textbox:more () do
		
		-- wait until we're done spooling the page
		while textbox:isBusy () do coroutine.yield () end		
		-- if there's more to spool, show the next page
		if textbox:more () then		
			-- this shows the next page and restarts the spool action
			textbox:nextPage ()
			textbox:spool ()
		end
	end
end

Now that we’ve created our page scrolling function, we create our main game loop and the thread to run it.

function main ()
	page ( text1 )
end

thread = MOAIThread.new ()
thread:run ( main ) 

And there we go, our thread running is complete. When it’s all finished, you should see the following: Now we’re finished with the basics of textboxes.