Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon
15. May 2012

 

This part of the tutorial is going to look at using UIComposer to create a simple UI, then the code to actually run the resulting GUI.  This two part tutorial was originally just one part, covering how to make a UDP socket request.  However, in putting together the required code, I had to build an interface, which resulted in a rather long post.  Therefore I have split this into two parts.  This part covers creating the UI, the next part covers wiring up the UI to actually do something and of course, the networking.

 

Once you are done both parts of this tutorial you will have a fully functional networked high score client with a primitive GUI.

 

Now, let’s create our application, fire up UIComposer.

 

File->Create New Project

 

image

 

 

In the Create New Project dialog, name and path it.  I’m going with HighScoreApp.

 

image

 

 

File->Create New Layout

image

 

 

Assuming you are developing for Vita, leave it at 960x544, I named it MainWindow.

 

image

 

 

Now drag in controls from the widget panel:

 

image

 

 

Start with a Panel, the size of the entire window:

 

image

 

 

Drag and drop Label, Button and EditableText widgets to create the following result:

 

image

 

 

Now the most important part is to match my naming or your code will end up being different.  The top two labels names don’t matter.  On the next line, name them from left to right: textBoxName, textBoxScore, buttonAddScore and buttonGetScores.

 

You set the variable name by selecting the widget, then filling in the following form:

 

image

 

 

Variable Name is the field that you are most interested in.

 

Finally, at the bottom of the form, drag in a Label widget to fill the rest of the available space.  Here are the settings I used:

 

 

image

 

 

Most importantly, make sure Variable Name is set to labelResults.

 

Now that we’ve created our screen, lets build it.  Select File->Build or hit F5:

 

image

 

 

Your results should look like:

 

 

image

 

 

Now we are theoretically done with UIComposer, lets fire up PS Studio.  Create a new solution, I called mine Networking.  Add a reference to Sce.Pss.HighLevel.UI.  Now we want to import our newly created UI files.

 

Right click your project and select Add->Add Files…

 

image

 

 

Navigate to the files you just created in UIComposer and add them.  The key here is to Add them as a link.  You don’t have to do this, but if you do, if you go back to the UIComposer and make a change ( and Build ), it will be automatically brought into Studio.

 

 

image

 

 

Add MainWindow.cs and MainWindow.composer.cs.  MainWindow.composer.cs is the system generated file that wires together your windows code; you do not edit it.  Instead, it makes use of partial classes and you do your editing in MainWindow.cs.

 

Now add the following code:

 

using System; using System.Collections.Generic; using Sce.Pss.Core; using Sce.Pss.Core.Environment; using Sce.Pss.Core.Graphics; using Sce.Pss.Core.Input; using Sce.Pss.HighLevel.UI; namespace Networking { public class AppMain { public static void Main (string[] args) { GraphicsContext graphics = new GraphicsContext(); UISystem.Initialize(graphics); HighScoreApp.MainWindow window = new HighScoreApp.MainWindow(); UISystem.SetScene(window); while(true) { SystemEvents.CheckEvents(); List<TouchData> touchData = Touch.GetData(0); UISystem.Update (touchData); graphics.SetViewport(0, 0, graphics.Screen.Width, graphics.Screen.Height); graphics.SetClearColor(new Vector4(0,0,0,1)); graphics.SetClearDepth(1.0f); graphics.Clear(); UISystem.Render (); graphics.SwapBuffers(); } } } }

 

This is about the simplest code you can create to display a UI on screen.  First we create our GraphicsContext, then initialize the UISystem singleton with it.  The UISystem singleton is contained in Sce.Pss.HighLevel.UI.  Next we create our UIComposer generated class, HighScoreApp.MainWindow.  If you are wondering where this name came from, the namespace was defined by the Project Name you specified in UIComposer, while the class name is the Class Name from the New Layout dialog.  Just like when working with Director from GameEngine2D, we add the window using SetScene().  Note, these are different scenes and cannot be interchanged.

 

Next we loop infinitely.  In our app loop, we check for new events, check what the current touch status is and pass the results to UISystem.Update().  Again, UISystem follows the same basic premise as the Director singleton, so it’s use should be familiar at this point.  We then clear the screen, tell our UISystem to draw, then finally tell the graphics to SwapBuffers displaying our screen.

 

Here is the results of our actions:

 

image

 

In the next section we will actually put the GUI to use doing something.  In the next part we are going to make a UDP socket connection to a high score server, to add new scores as well as retrieve the current high scores.

 

On to Part 2

Programming , ,

blog comments powered by Disqus

Month List

Popular Comments

Battle of the Lua Game Engines: Corona vs. Gideros vs. Love vs. Moai
Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon
21. September 2012

 

Alright, the title might be a bit over the top… what we are about to do is look at some of the most popular 2D game engines powered by Lua.  First there will be a matrix of features, to give you an “at a glance” view of what each engine offers.  Then we will follow up with a simple Hello World example for each, so you can see what the code would look like.  Hopefully this will help you decide which engine is right for you.

 

Engine Features Matrix

 

 

 

Corona

Gideros

LÖVE

Moai

Site Link

Link Link Link Link

Price

199$ /year iOS
199$ /year Android
349$ /year Both
Free trial available
149$ /year Indie
449$ /year Pro
0$ /year Community
Free Free

Free Limitations

Cannot publish to app store with free version Mandatory splash screen
Pro required if income greater than 100K$
N/A N/A

Target Platforms

iOS
Android
iOS
Android
(Mac and Windows under development)
Windows
Mac
Linux
iOS
Android
Windows
Mac
Linux (in late stage development)
Chrome NacL

Dev Platforms

Windows
Mac
Windows
Mac
Windows
Mac
Linux
Windows
Mac
Linux

Support Available

Forum
Paid support
Forum Forum Forum
Paid Support

Open Source

No No Yes Yes

Books

Corona SDK Mobile Game Development

Learning Corona SDK (DVD)
N/A N/A N/A

Other Details

Builds occur on Corona Labs servers, internet connection required
3rd party tools available
Enterprise version available
Includes it’s own IDE Gideros Studio   Paid cloud computing offering for back-end services

Example Published Games

Go Ninja
The Lorax (Movie Game)
Joustin Beaver
Cerberus: The Puppy
N/A?
Unpublished list
Crimson Steam Pirates
Strikefleet Omega

 

* Note, I gave iTunes link only, although many of those games are also available on Google Play.

 

 

Now we are going to look at a simple Hello World app written with each suite.  I do not pretend mastery of any of these suites, or Lua in general, so take the code for what it’s worth.  If you wish to submit a better rendition, please do so!

 

In this sample we are going to create a window at a resolution of 1280x800, then we are going to start a background song looping ( Richard Wagners – Ride of the Valkyrie taken from here ).  Then we are going to create a Hello World text/graphic centered to the screen, and position it where ever the user clicks/touches.  Some files handle window creation in a different file, some handle it in a single file.  That is why some versions have two lua files, while others have only one.

 

Corona SDK Hello World

 

config.lua

-- config.lua

application =
{
    content =
    {
        width = 1280,
        height = 800,
        scale = "letterbox"
    },
}

main.lua

-- HelloWorld sample

-- Load audio file
local song = audio.loadSound("../../Media/Ride_of_the_Valkyries.mp3")

-- set volume to 50%
audio.setVolume(0.5)

-- play audio file, looping forever
audio.play(song,{ channel=1,loops=-1})


-- create text to display on screen in 72point font
local helloText = display.newText("Hello World!",0,0,native.systemFont,72)

-- center to screen
helloText.x = display.contentWidth/2
helloText.y = display.contentHeight/2

-- red
helloText:setTextColor(255,0,0)

-- function to handle touch event, move helloText to the touch location
function onTouchHandler(event)
    helloText.x = event.x
    helloText.y = event.y
end

-- register touch function to respond to global touch events
Runtime:addEventListener("touch",onTouchHandler)

 

 

Gideros

 

main.lua

-- Helloworld sample

-- setup our window to our 1280x800 resolution
application:setLogicalDimensions(1280,800)
application:setOrientation(Application.LANDSCAPE_LEFT)

-- Load song, cannot use relative path to parent directory since file needs to be added to project
local song = Sound.new("Ride_of_the_Valkyries.mp3")

-- play audio file, looping forever
local soundChannel = song:play(0,math.huge)

-- Set song volume to 50%, not set globally
soundChannel:setVolume(0.5)


-- need to load a ttf font, size cannot specify character size in TextField
local font = TTFont.new("arial.ttf",72,false)

-- create text to display on screen
local helloText = TextField.new(font,"Hello World!")

-- center to screen
helloText:setPosition(
        application:getLogicalWidth()/2 - helloText:getWidth()/2,
        application:getLogicalHeight()/2 + helloText:getHeight()/2)

-- set text to red, color is hex encoding
helloText:setTextColor(0xff0000)

-- display text
stage:addChild(helloText)

-- function to handle touch event, move helloText to the touch location
function onTouchHandler(event)
    helloText:setPosition(event.x - helloText:getWidth()/2,event.y + helloText:getHeight()/2)
end

-- register touch function to respond to global touch events
stage:addEventListener(Event.TOUCHES_BEGIN,onTouchHandler)
-- The above doesn't work in the simulator, so handle mouse too
stage:addEventListener(Event.MOUSE_DOWN,onTouchHandler)

LÖVE

 

love.conf

function love.conf(t)
    t.screen.width = 1280
    t.screen.height = 800
end

main.lua

-- love2d works slightly different, expecting users to implement methods that will be called within the game loop
-- such as love.draw() and love.update()

-- create a 72 point font using the system default
font = love.graphics.newFont(72)
-- set the font active
love.graphics.setFont(font)
-- set red as the active color
love.graphics.setColor(255,0,0,255)

-- load audio file
local song = love.audio.newSource("Ride_of_the_Valkyries.ogg")

-- we want to loop, we want to loop, we want to loop, we want t^Z
song:setLooping(true)

-- set volume to 50%
love.audio.setVolume(0.5)
-- play song
love.audio.play(song)

-- create a variable for print coordinates to update on touch, default to screen center
-- LOVE does not have a positionable text object, so we call print each frame
local x = love.graphics.getWidth()/2
local y = love.graphics.getHeight()/2
local stringWidth = font:getWidth("Hello World!")
local stringHeight =  font:getHeight("Hello World!")


-- This function is called once per frame to draw the screen
function love.draw()
    love.graphics.print("Hello World!",x - stringWidth/2,y-stringHeight/2)
end

-- called on click, move our print x,y to the click location
-- no touch handler because LOVE is desktop only
function love.mousepressed(mouse_x,mouse_y,button)
        x = mouse_x
        y = mouse_y
end

 

Moai

 

main.lua

-- create the window, viewport and layer
MOAISim.openWindow("Window", 1280, 800)
local viewport = MOAIViewport.new()
viewport:setSize(1280,800)
viewport:setScale(1280,800)

local layer =  MOAILayer2D.new()
layer:setViewport(viewport)

-- Let Moai know we want this layer rendered
MOAIRenderMgr.pushRenderPass(layer)

-- Initialize the audio system
MOAIUntzSystem.initialize()

-- set volume to 50%
MOAIUntzSystem.setVolume(0.5)

-- load the song
song1 = MOAIUntzSound.new()
song1:load("../Media/Ride_of_the_Valkyries.ogg")

-- play audio file, looping forever
song1:setLooping(true)
song1:play()

-- save memory by only rendering the chars we need
chars = 'Helo Wrd!'

-- create a font
local font = MOAIFont.new()
font:loadFromTTF('../Media/arial.ttf',chars,72)

-- create and position text centered
local helloText = MOAITextBox.new()
helloText:setString('Hello World!')
helloText:setFont(font)
helloText:setYFlip(true)
helloText:setRect(-640,-400,640,400)
helloText:setAlignment(MOAITextBox.CENTER_JUSTIFY,MOAITextBox.CENTER_JUSTIFY)

layer:insertProp(helloText)

-- handle mouse/touch click events
function handleClickOrTouch(x,y)
    helloText:setLoc(layer:wndToWorld(x,y))
end

if MOAIInputMgr.device.pointer then
    -- Mouse based device
    MOAIInputMgr.device.mouseLeft:setCallback(
        function(isButtonDown)
            if(isButtonDown) then
                handleClickOrTouch(MOAIInputMgr.device.pointer:getLoc())
            end
        end
    )
else
    -- Touch based device
    MOAIInputMgr.device.touch:setCallback(
        function(eventType,idx, x, y, tapCount)
            if eventType == MOAITouchSenser.TOUCH_DOWN then
                handleClickOrTouch(x,y)
            end
        end
    )
end

 

 

 

My Opinions

 

 

First off, take these with a grain of salt, these are just my initial impressions and nothing more.  Obviously it is all very subjective.  It is also stupid to say X is best, they are all good libraries, each with their own strengths and weaknesses.  I think that is perhaps the greatest surprise, not one of these four options is bad.

 

 

Love: Not a big fan of the abstraction and it forces a design on you, but this isn’t necessarily a bad thing, especially for a beginner.  Good for beginners, so-so to slight levels of documentation but absolutely wonderful reference materials.  Only library in this group with no mobile support, which is a big deal.  Open source and free, targeted to hobbyist.  Few ( none? ) commercial games.  All told, it reminded me a lot of the Python based PyGame, which is frankly a great beginners library.  Also the name “Love” proved a gigantic handicap, as it made Googling for anything beyond the Love2D website very difficult.  This is the downside to using a very generic name for your library ( cough… GamePlay, I’m looking at you! ).  The generic name really did prove to be a pain in the butt at times.  Love is certainly a good library, but probably not for professional use, at least, as is. 

 

 

Corona: Most polished of the four.  Best documentation, good API.  Only library with published books available and good tooling support.  Also most expensive and closed.  If it isn’t part of Corona, you are hosed.  Have to pay more for native access.  Great developer backing, lots of successful companies using Corona.  Corona is certainly a great library, although thanks to the price tag, it wont appropriate for all developers.  The lack of freedom ( no source, paying for native access ) are definitely the biggest drawbacks.

 

 

Gideros: Ok-good documentation, good reference but other material is a bit too scattered.  IDE is a HUGE boon for newer developers, especially with auto-completion.  That said, the IDE got a bit flaky at times too.  API itself a bit less intuitive ( to me ).  Licensing terms reasonable ( better than Corona, worse than Love and Moai ), same for price.  Good choice for beginner who wants to support mobile, lack of major published games a bit of a deterrent for professional developers, as is the lack of source code.

 

 

Moai: Moai is certainly the most difficult of the four, and the documentation is in heavy need of updating.  The reference itself is actually very good, where it exists.  In some cases there is none and in others, it is lacking or out-dated.  The developers are aware and this is a priority for them to fix.  On the other hand, Moai is also the most flexible by a mile.  The code ( as you can see from the example above ), is a bit more verbose, but that is because the library makes less decisions for you.  This is a double edged sword of flexibility vs ease, and Moai slants heavily towards flexibility.  Supports the most targets of all the libraries, has complete source code, and more importantly, the source code is very well written and very easy to read.  Like Corona, there are some very good shipped games.

 

 

Final verdict:

For a commercial product for iOS/Android, I would select Moai.  The API is a natural fit to my coding style ( I prefer flexibility over accessibility for time critical code ) and the C++ source code is a great boon to me, but to a non-C++ programmer, this would obviously be less important.  Also of course, the price is nice.  Most importantly, the open nature means I know I will never encounter a problem that I can’t code my way out of, the biggest downside to Corona.  If it wasn’t for the open source nature of Moai, I would probably go with Corona for the sake of it’s excellent documentation and clean API.

 

If I was just starting out, I would be torn between Gideros and LOVE.  LOVE is certainly the most beginner friendly, but the turn-key all in one nature of Gideros… you literally install, load the studio, write some code and hit play… with full autocomplete code editing.  This really is a huge deal!  In it’s favour over LOVE is also the support for mobile platforms.  That said, if the API isn’t to your liking, or you struggle with it, Love is easily the most accessible code wise.  I will be looking a bit closer at Gideros in the future.  Ran into a few annoyances during my brief exposure, like the inability to set anchor points for TextField values ( http://bugs.giderosmobile.com/issues/41 ), forcing me to wait for the feature to be added by someone else.

 

This isn’t to say Corona is bad, it obviously isn’t.  It is polished, has the best documentation and a very solid/natural API.  For me though, the lack of flexibility and access to source code provides outweigh it’s advantages.  If the source isn’t a big deal to you, or you do not have access to C++ resources and are willing to pay 200$ a year or more, Corona is a very good option with a ton of developers using it.  Also, Corona is the only option with a paid support option, which can be a huge advantage.

 

 

 

TL;DR verdict:

 

For a Pro developer:  Go Moai, unless you have no in-house C++ talent, in which case, go Corona.

For a new developer: Go Gideros, especially if you want to do mobile development. If you don’t like it, Love is always a great option.

Programming, Design, General , , ,

blog comments powered by Disqus

Month List

Popular Comments