Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon
9. October 2012

As we saw in the last part, our application is made up of a single view composed of 3 child views.  In this post I am going to focus on the left hand view, which is where the actual map will be drawn.  This is easily the most important part.

 

All I hoped to accomplish today was to get an EaselJS stage integrated in to a YUI View, which with some horrific hacking, I have accomplished.  There are a few very important requirements.

 

First, we need to have a canvas element that EaselJS can work with.

Second, we want the canvas element to take up as much room on the UI as possible.  The right hand view is going to be fixed at 280 pixels in width, so we want the map editing area to consume the rest of the screen.

Finally, I want the whole thing to resize if the window is resized, so our application can support any resolution.

 

To accomplish this, I have altered the person.Template ( the right hand side placeholder for now ), to look like this:

<div style="width:280px;min-width:280px;max-width: 280px;float:right">
    <div align=right>
        <img src="https://www.gamefromscratch.com/image.axd?picture=HTML-5-RPG_thumb_1.png" 
             alt="GameFromScratch HTML5 RPG logo" />
    </div>
    <p><hr /></p>
    <div>
        <h2>About {{name}}:</h2>
        <ul>
            <li>{{name}} is {{height}} feet tall and {{age}} years of age.</li>
        </ul>
    </div>
</div>

Only real change here is the alteration to the parent div.

 

In editor.View.js I made the following simple change that the bottom of the render() function:

Y.one('body').setStyle("margin",0);
return this;

This is simply overriding the YUI default BODY styling, as I do not want any margins, padding or spaces between elements.

 

Then I altered map.Template as follows:

<div style="margin:0px;float:left;display:block" id="panel">
    <canvas width=300 height=300 id="mainCanvas" style="background-color: black;">
        Your browser doesn't support the canvas tag.
    </canvas>
</div>

I needed a named div to access programmatically, so I created one called “panel”.  I also changed the styling on the canvas so the background color would be black, making debugging a bit easier.  The dimensions passed to the canvas are going to be completely ignored.  Why the heck Canvas didn’t support % layout, I will never understand.

 

Finally, the majority of changes are in map.View.js, which I basically re-wrote:

YUI.add('mapView',function(Y){
    var Instance = null;
    Y.MapView = Y.Base.create('mapView', Y.View, [], {
        events:{
          "#mainCanvas": {
              click:function(e)
              {
                  alert("Blah");
              }
          }
        },
        initializer:function(){
            Instance = this;
            var results = Y.io('/scripts/views/templates/map.Template',{"sync":true});
            template = Y.Handlebars.compile(results.responseText);
        },
        prepareCanvas:function(){
            this.resizeEvent();
            createjs.Ticker.setFPS(30);
            createjs.Ticker.addListener(this.gameloop);

            Y.on('windowresize',this.resizeEvent);
        },
        render:function(){
            if(this.template === null)
                this.initializer();
            this.get('container').setHTML(template());
            this.prepareCanvas();
            return this;
        },
        gameloop:function(){
            Instance.stage.update();
            Instance.stage.getChildAt(0).x++;
            if(Instance.stage.getChildAt(0).x > Instance.stage.canvas.width)
                Instance.stage.getChildAt(0).x = 0;
        },
        resizeEvent:function(){
            var container = Instance.get('container');
            var canvas = container.one("#mainCanvas");
            var panel = container.one('#panel');

            var body = Y.one("body");
            var screenWidth = body.get("clientWidth");
            var screenHeight = body.get("scrollHeight");

            var width = Math.floor(screenWidth -280);
            var height = Math.floor(screenHeight );

            canvas.setStyle("width",width);
            canvas.setStyle("height",height);

            this.stage = new createjs.Stage(canvas.getDOMNode());
            // for some reason, easel doesn't pick up our updated canvas size so set it manually
            this.stage.canvas.width = width;
            this.stage.canvas.height = height;

            var shape1 = new createjs.Shape();
            shape1.graphics.beginFill(createjs.Graphics.getRGB(0,255,0));
            shape1.graphics.drawCircle(200,200,200);

            this.stage.addChild(shape1);
        }
    });
}, '0.0.1', { requires: ['view','event','io-base','handlebars']});

 

The variable Instance is a horrible hack, that I intend to replace at some point in the future.  That’s the joy of exercises like this, I can refactor out my hacks later on.  So, why does it exist… well you see, I make a couple of functions that are called back by external code, which completely clobber my this pointer.  I suppose it’s a poor mans singleton of sorts.

 

The end result of this code:

 

 

First thing I did within MapView is declare an event if someone clicks on our canvas ( which needs the id mainCanvas… this is another hackish solution that should possibly be factored away, although frankly, I am OK with requiring the canvas tag to have a certain ID, so I probably wont ) this function is called.  It was simply written to figure out how YUI views handled events.  All it does is pops up an alert with the text Blah.  As you can see, handling element level events in relatively simple, although sadly I couldn’t figure out how to capture document level events here.  Another thing on the todo list.

 

In the initializer function I take a copy of the this pointer in the Instance variable ( *hack* *hack* ), and have changed the template fetching code to no longer be asynchronous, to completely remove some unnecessary race conditions that can result from a network delay retrieving the template. Frankly in this case, async bought us nothing but headaches.

 

prepareCanvas is the method responsible for setting up the easelJS integration.  It starts off by calling resizeEvents, which is where the bulk of the actual work is done.  resizeEvents was factored out to a separate function, because this logic is the same on initial creation as it is when the window is resized.  When resizeEvent() is called, we first find the BODY tag, and get its width and height using clientWidth and scrollHeight.  You would think the obvious value would be clientHeight, but you would be wrong, this is just one of those ways that HTML sucks.  Once we have the width and height, we then calculate our view dimensions, by subtracting the space needed for the other views ( or… will soon for height that is ).  We then set the canvas to those dimensions using setStyle(), which resizes the CANVAS in the browser.  We then create our Stage object from our canvas.  One thing to keep in mind, YUI get() and one() functions return YUI Node objects, not actual DOM objects, so when dealing with 3rd party libraries, you need to access the actual DOM item the node contains, that can be done with .getDOMNode().  Next we manually update the stage.canvas width and height, because of what I can only assume is a bug, EaselJS doesn’t pick up the modifications we made to the Canvas dimenions… who knows, there might be something else going on behind the scenes.  Next we create a circle… just so we have something visible on screen, and add it to our stage.

 

Now that resizeEvents is done, back in prepareCanvas we then set up a Ticker, which is an EaselJS callback mechanism, somewhat like setTimeout.  This is the heartbeat of your application, and due to the setFPS(30) call, it *should* be called 30 times per second.  This is your traditional game loop within the application and will probably be used quite a bit in the future.  Finally we handle windowresize events using the Y.on() handling mechanism, to catch the case the user resizes the screen, and if they do we call resizeEvents ( which being an eventhandler, will clobber all over our this pointer ).

 

Finally, we have the aforementioned gameloop, which is a function that is going to be called every time createjs.Ticker, um… Ticks.  For now we simply update our stage, then find the one and only item on our stage with getChildAt(0), which is our circle, and increment it’s X value until it scrolls off the screen.

 

It seems a bit more complicated than it is, but the basics of most of what we are going to want to deal with is now in place.  We can handle UI events via YUI, can render to the Canvas using the EaselJS library and best of all, take full advantage of the screen resolution, no matter how big or small, and gracefully handle changes in size, something Canvas doesn’t do easily.

 

Figuring out how everything interacted was more of a headache than I expected, but I am reasonably happy with this setup for now.  Of coure, I am going to need to add real functionality to the map view, and have it feed by a Map model instead of just drawing a circle on screen, but all things in time.

 

You can download the complete project as of this point right here.

You can see the project in action by clicking here.  As you resize, so will the canvas element.

Programming Design


8. October 2012

 

As per this post I am currently going through the process of creating some simple game creation tools using HTML5, more specifically using the YUI 3 library as well as the EaselJS canvas library.

 

This post illustrates the very skeleton upon which we are going to create our app.  YUI3 provides a full MVC framework which you can use to create your application so I decided to make use of it.  The end result of this code is remarkably minimal, it just creates a single page web application with different views representing different portions of the UI.  Specifically, we will create a top zone where the menu will go, a left hand area where the level editing will occur, then a right hand panel which will change contextually.  I also created a very simple data class, to illustrate how data works within the YUI MVC environment.

 

First off, if you have never heard of MVC, it is the acronym of Model View Controller.  MVC is a popular design practice for separating your application in to logically consistent pieces.  This allows you to separate your UI from your logic and your logic from your data ( the last two get a little gray in the end ).  It adds a bit of upfront complexity, but makes it easier to develop, maintain and test non-trivial applications… or at least, that’s the sales pitch.

 

The simplest two minute description of MVC is as follows.  The Model is your application’s data.  The View is the part of your application that is responsible for displaying to the end user.  The Controller part is easily the most confusing part, and this is the bit that handles communications between the model and view, and is where you actual “logic” presides.  We aren’t going to be completely pure in this level in this example ( MVC apps seldom are actually ), as the Controller part of our application is actually going to be a couple pieces, you will see later.  For now just realize, if it aint a view and it aint a model, it’s probably a controller.

 

It is also worth clarifying that MVC isn’t the only option.  There is also MVVM ( Model-View-ViewModel ) and MVP ( Model-View-Presenter ), and semantics aside, they are all remarkably similar and accomplish pretty much the same thing.  MVC is simply the most common/popular of the three.

 

Put simply, it will look initially more complex ( and it is more complex ), but this upfront work makes life easier down the road, making it generally a fair trade off.

 

Alright, enough chatter, now some code!  The code is going to be split over a number of files.  A lot of the following code is simply the style I chose to use, and is completely optional.  It is generally considered good practice though.

 

image 

At the top level of our hierarchy we have a pair of files, index.html and server.js.  server.js is fairly optional for now, I am using it because I will (might?) be hosting this application using NodeJS.  If you are running your own web server, you don’t need this guy, and won’t unless we add some server-side complexity down the road.

 

index.html is pretty much the heart of our application, but most of the actual logic has been parted out to other parts of the code, so it isn’t particularly complex.  We will be looking at it last, as all of our other pieces need to be in place first.

 

Now within our scripts folder, you will notice two sub-folders models and views.  These predictable enough are where our models and views reside.  In addition, inside the views directory is a folder named templates. This is where our moustache templates are.  Think of templates like simple HTML snippets that support very simple additional mark-up, allowing for things like dynamically populating a form with data, etc.  If you’ve ever used PHP, ASP or JSP, this concept should be immediately familiar to you.  If you haven’t, don’t worry, our templates are remarkably simple, and for now can just be thought of as HTML snippets.  The .Template naming convention is simply something I chose, inside they are basically just HTML.

 

If you are basing your own product on any of this code, please be sure to check out here, where I refactored a great deal of this code, removing gross hacks and cleaning things up substantially!

 

Let’s start off with our only model person.js, which is the datatype for a person entry.  Let’s look at the code now:

 

person.js

YUI.add('personModel',function(Y){
    Y.Person = Y.Base.create('person', Y.Model, [],{
            getName:function(){
                return this.get('name');
            }
        },{
            ATTRS:{
                name: {
                    value: 'Mike'
                },
                height: {
                    value: 6
                },
                age: {
                    value:35
                }
            }
        }
    );
}, '0.0.1', { requires: ['model']});

The starting syntax may be a bit jarring and you will see it a lot going forward.  The YUI.add() call is registering ‘personModel’ as a re-usable module, allowing us to use it in other code files.  You will see this in action shortly, and this solves one of the biggest shortcomings of JavaScript, organizing code.

 

The line Y.Person = Y.base.create() is creating a new object type in the Y namespace, named ‘person’ and inheriting all of the properties of Y.Model.  This is YUI’s way of providing OOP to a relatively un-OOP language.  We then define a member function getName and 3 member variables name, height and age, giving each of the three default values… just cause.  Of course, they aren’t really member variables, they are entries in the object ATTRS, but you can effectively think of them as member variables if you are from a traditional OOP background.  Next we pass in a version stamp ( 0.0.1 ), chosen pretty much at random by me.  Next is a very important array named requires, which is a list of all the modules ( YUI, or user defined ) that this module depends on.  We only need the model module.  YUI is very modular and only includes the code bits you explicitly request, meaning you only get the JavaScript code of the classes you use.

 

So that is the basic form your code objects are going to take.  Don’t worry, it’s nowhere near as scary as it looks.  Now let’s take a look at a view that consumes a person model.  That of course would be person.View.js.  Again, the .View. part of that file name was just something I chose to do and is completely optional.

person.View.js

YUI.add('personView',function(Y){
        Y.PersonView = Y.Base.create('personView', Y.View, [], {
        initializer:function(){
            var that=this,
                request = Y.io('/scripts/views/templates/person.Template',{
                    on:{
                        complete:function(id,response){
                            var template = Y.Handlebars.compile(response.responseText);
                            that.get('container').setHTML(template(that.get('model').getAttrs(['name','age','height'])));
                        }
                    }
                });
        },
        render:function(){
            return this;
        }
    });
}, '0.0.1', { requires: ['view','io-base','personModel','handlebars']});

Just like with our person model, we are going to make a custom module using YUI.add(), this one named ‘personView’.  Within that module we have a single class, Y.PersonView, which is to say a class PersonView in the Y namespace.  PersonView inherits from Y.View and we are defining a pair of methods, initializer() which is called when the object is created and render() which is called when the View needs to be displayed.

 

In initializer, we perform an AJAX callback to retrieve the template person.Template from the server.  When the download is complete, the complete event will fire, with the contents of our file in the response.responseText field ( or an error, which we wrongly do not handle ).  Once we have our template text downloaded, we “compile” it, which turns it into a JavaScript object. The next line looks obscenely complicated:

that.get('container').setHTML(template(that.get('model').getAttrs(['name','age','height'])));

A couple things are happening here.  First we are using that because this is contextual in JavaScript.  Within the callback function, it has a completely different value, so we cached the value going in.  Next we get the property container  that every Y.View object will have, and set it’s HTML using setHTML().  This is essentially how you render a view to the screen.  The parameter to setHTML is also a bit tricky to digest at first.  Essentially the method template() is what compiles a moustache template into actual HTML.  A template, as we will see in the moment, may be expecting some data to be bound, in this case name, age and height which all come from our Person model.  Don’t worry, this will make sense in a minute.

 

Our render method doesn’t particularly do anything, just returns itself.  Again we specify our modules dependency in the requires array, this time we depend on the modules view, io-base, personModel and handlebars.  As you can see, we are consuming our custom defined personModel module as if it was no different than any of the built-in YUI modules.  It is a pretty powerful way of handling code dependencies.

 

Now let’s take a look at our first template.

person.Template

<div style="width:20%;float:right">
    <div align=right>
        <img src=https://www.gamefromscratch.com/image.axd?picture=HTML-5-RPG_thumb_1.png 
alt="GameFromScratch HTML5 RPG logo" />
    </div>
    <p><hr /></p>
    <div>
        <h2>About {{name}}:</h2>
        <ul>
            <li>{{name}} is {{height}} feet tall and {{age}} years of age.</li>
        </ul>
    </div>
</div>

As you can see, a template is pretty much just HTML, with a few small exceptions.  Remember a second ago when we passed data in to the template() call, this is where it is consumed.  The values surrounded by {{ }}  ( thus the name moustache! ) are going to be substituted when the HTML is generated.  Basically it looks for a value by the name within the {{ }} marks and substitutes it into the HTML.  For example, {{name}}, looks for a value named name, which it finds and substitutes it’s value mike in the results.  Using templates allows you to completely decouple your HTML from the rest of your application.  This allows you to source out the graphic work to a designer, perhaps using a tool like DreamWeaver, then simply add moustache markup for the bits that are data-driven.

 

What you may be asking yourself is, how the hell did the PersonView get it’s model populated in the first place?  That’s a very good question.

 

In our application, our view is actually going to be composed of a number of sub-views.  There is a view for the area the map is going to be edited in, a view for the context sensitive editing will occur ( currently our person view ), then finally a view where our menu will be rendered.  However, we also have a parent view that holds all of these child views, sometimes referred to as a composite view. This is ours:

editor.View.js

YUI.add('editorView',function(Y){
    Y.EditorView = Y.Base.create('editorView', Y.View, [], {
        initializer:function(){

            var person = new Y.Person();
            this.pv = new Y.PersonView({model:person});
            this.menu = new Y.MainMenuView();
            this.map = new Y.MapView();
        },
        render:function(){
            var content = Y.one(Y.config.doc.createDocumentFragment());
            content.append(this.menu.render().get('container'));

            var newDiv = Y.Node.create("<div style='width:100%'/>");
            newDiv.append(this.map.render().get('container'));
            newDiv.append(this.pv.render().get('container'));

            content.append(newDiv);
            this.get('container').setHTML(content);
            return this;
        }
    });
}, '0.0.1', { requires: ['view','io-base','personView','mainMenuView','mapView','handlebars']});

The start should all be pretty familiar by now.  We again are declaring a custom module editorView. This one also inherits from Y.View, the major difference is in our initializer() method, we create a Y.Person model, as well as our 3 custom sub-views, a PersonView, a MainMenuView and a MapView ( the last two we haven’t seen yet, and are basically empty at this point ).  As you can see in the constructor for PersonView, we pass in the Y.Person person we just created.  This is how a view gets it’s model, or at least, one way.

 

Our render() method is a bit more complicated, because it is responsible for creating each of it’s child views.  First we create a documentFragment, which is a chunk of HTML that isn’t yet part of the DOM, so it wont fire events or cause a redraw or anything else.  Basically think of it as a raw piece of HTML for us to write to, which is exactly what we do.  First we render our MainMenuView, which will ultimately draw the menu across the screen.  Then we create a new full width DIV to hold our other two views.  We then render the MapView to this newly created div, then render the PersonView to the div.  Finally we append our new div to our documentFragment.  Finally we set our view’s HTML to our newly created fragment, causing all the views to be rendered to the screen.

 

Once again, we set a version stamp, and declare our dependencies.  You may notice that we never had to include personModel, this is because personView will resolve this dependency for us.

 

Lets quickly look at each of those other classes  ( mainMenuView and mapView ) and their templates, although all of them are mostly placeholders for now.

 

mainMenu.View.js

YUI.add('mainMenuView',function(Y){
    Y.MainMenuView = Y.Base.create('mainMenuView', Y.View, [], {
        initializer:function(){
            var that=this,
                request = Y.io('/scripts/views/templates/mainMenu.Template',{
                    on:{
                        complete:function(id,response){
                            var template = Y.Handlebars.compile(response.responseText);
                            //that.get('container').setHTML(template(that.get('model').getAttrs(['name','age','height'])));
                            that.get('container').setHTML(template());
                        }
                    }
                });
        },
        render:function(){
            return this;
        }
    });
}, '0.0.1', { requires: ['view','io-base','handlebars']});

mainMenu.Template

<div style="width:100%">This is the area where the menu goes.  It should be across the entire screen</div>

 

map.View.js

YUI.add('mapView',function(Y){
    Y.MapView = Y.Base.create('mapView', Y.View, [], {
        initializer:function(){
            var that=this,
                request = Y.io('/scripts/views/templates/map.Template',{
                    on:{
                        complete:function(id,response){
                            var template = Y.Handlebars.compile(response.responseText);
                            that.get('container').setHTML(template());
                            //that.get('container').setHTML(template(that.get('model').getAttrs(['name','age','height'])));
                        }
                    }
                });
        },
        render:function(){
            return this;
        }
    });
}, '0.0.1', { requires: ['view','io-base','handlebars']});

map.Template

<div style="width:80%;float:left">
    This is where the canvas will go
</div>

Now, we let’s take a quickly look at server.js.  As mentioned earlier, this script simply provides a basic NODEJS based HTTP server capable of serving our app.

server.js

var express = require('express'),
    server = express();

server.use('/scripts', express.static(__dirname + '/scripts'));

server.get('/', function (req, res) {
    res.sendfile('index.html');
});

server.listen(process.env.PORT || 3000);

 

I wont really bother explaining what’s going on here.  If you are going to use Node, there is a ton of content on this site already about setting up a Node server.  Just click on the Node tag for more articles.

 

Finally, we have index.html which is the heart of our application and what ties everything together and this is the file that is first served to the users web browser, kicking everything off.

index.html

<!DOCTYPE html>

<html>
<head>
    <title>GameFromScratch example YUI Framework/NodeJS application</title>
</head>
<body>

<script src="http://yui.yahooapis.com/3.5.1/build/yui/yui-min.js"></script>
<script src="/scripts/models/person.js"></script>
<script src="/scripts/views/person.View.js"></script>
<script src="/scripts/views/map.View.js"></script>
<script src="/scripts/views/mainMenu.View.js"></script>
<script src="/scripts/views/editor.View.js"></script>

<script>
    YUI().use('app','editorView', function (Y) {

        var app = new Y.App({
            views: {
                editorView: {type: 'EditorView'}
            }
        });

        app.route('/', function () {
            this.showView('editorView');//,{model:person});
        });

        app.render().dispatch();
    });
</script>


</body>
</html>

 

This sequence of <script> tags is very important, as it is what causes each of our custom modules to be evaluated in the first place.  There are cleaner ways of handling this, but this way is certainly easiest.  Basically for each module you add, include it here to cause that code to be evaluated.

 

Next we create our actual Y function/namespace.  You know how we kept adding our classes to Y., well this is where Y is defined.  YUI uses an app loader to create the script file that is served to your clients browser, which is exactly what YUI.use() is doing.  Just like the requires array we passed at the bottom of each module definition, you pass use() all of the modules you require, in this case we need the app module from YUI, as well as our custom defined editorView module.

 

Next we create a Y.App object.  This is the C part of MVC.  The App object is what creates individual views in response to different URL requests.  So far we only handle one request “/”, which causes the editorView to be created and shown.  Finally we call app.render().dispatch() to get the ball rolling, so our editorView will have it’s render() method called, which will in turn call the render method of each of it’s child views, which in turn will render their templates…

 

Don’t worry if that seemed scary as hell, that’s about it for infrastructure stuff and is a solid foundation to build a much more sophisticate application on top of.

 

Of course, there is nothing to say I haven’t made some brutal mistakes and need to rethink everything! Smile

 

Now, if you open it up in a browser ( localhost:3000/ if you used Node ), you will see:

image

 

Nothing too exciting as of yet, but as you can see, the menu template is rendered across the top of the screen, the map view is rendered to the left and the Person view is rendered on the right.  As you can see from the text, the data from our Person model is compiled and rendered in the resulting HTML.

 

You can download the complete project archive right here.

Design Programming


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


21. June 2012

 

A few weeks ago, I mentioned that I might put together an HTML5 Roleplaying game tutorial and inquired how much interest there was in the subject.  There was sufficient interest, so I dove into the subject a little bit closer and came to a bit of a conclusion.  It’s ultimately theHTML-5-RPG tools that make the game in this case.  So, in addition to a game, I would have to create an editor, which is actually where most of the guts would reside.

 

This presented an interesting problem for me, as I’ve done a lot of web development, I mostly worked server side in a traditional language like C# or Java.  For this project, I wanted it to be JavaScript end to end.  I have a few key requirements:

 

  • single language, end to end
  • server based editor, that can be run locally on the client
  • code reuse between game and editor
  • MVC/MVP or MVVM based.  ( if you don’t know these acronyms, don’t worry )
  • event driven
  • rich UI
  • run on a tablet’s browser
  • database and local/remote filesystem support
  • json-based level output, which can be used by clients in any language
  • game entity scripting, probably again, in JavaScript

 

Part of these requirements are driven by personal interest, I have always wanted to try making an MVC based game editor.  MVC means, model-view-controller ( MVP == model view presenter and MVVM == model view viewmodel ) and it is a manner of design for decoupling your data ( your game’s/editor’s objects ) from your view ( your application or webpage ).  There are a number of great advantages to implementing things this way, including testability, maintainability, reuse and perhaps most importantly, it imposes a clean separation of responsibilities between systems.

 

The single language end to end is an easy one.  JavaScript.  While JavaScript is by no means the best designed language in the world, it is a extremely well supported one with a very bright future.  It is increasingly becoming a language that every developer is going to need to know, so why fight the future?  Of course, I could use a slightly higher level implementation like Coffeescript, Closure or Dart, they all ultimately compile down to JavaScript in the end.  That said, one of the biggest reasons I want to use a single language from end to end, is so the most people can follow along without having to know or learn multiple programming languages, so I will probably go with plain Jane JavaScript.

 

Now the whole running on a server and locally, that presented a bit of a trick.  I want people to be able to follow along, and run it from their own computer for their own projects, so offline is a must.  However, I also wanted an editor available for people who are only interested in game side of the equation, which is why I want to host one on my server.  That said, I also don’t want to bog my own servers down too badly.  This presented a bit of a problem, but it was solved soon enough when I started looking into….

 

Database and local/remote file system support.  Behind the scenes, a lot of tools are actually built around a database, whether they realize it or not.  In the end, many tools end up creating their own crude database server around their own file format, or often XML.  In my view, this is awfully close to re-inventing the wheel.  If you are using database like functionality in your tool, use a database!  Fortunately when it comes to JavaScript, there are an absolute ton of options!  From redis, a simple to learn key/value based database and JSON based CouchDB to more traditional databases like MySQL and SQL Server.

 

HTML5 has some options when it comes to local storage, such as well… webStorage.  There are some pretty heavily limitations here, one of the biggies is the lack of support.  Size limits are also rather severe size limitations, in the area of 2.5-5MB, a limit that you will run into extremely quickly.  The alternative to persist these files on the server isn’t really appealing to me, when I am the one paying the server bills! Smile

 

This is where Node comes in.  Node nicely solves just about all of these problems.  Essentially I am going to develop the editor as a node based client/server, where the user has the option of installing the client and server locally, and running it just like any other application.  This gives me access to the local file system and whatever other libraries I need.  However, it also allows me to use the exact same code to provide a hosted version of the editor other users can simply run in their browser.  Essentially Node will act as the host for the DB, as a web server and as the interface between the local machine and the view.

 

Speaking of which, this leaves the view…

 

Again, as I said earlier, the majority of client/server programming I did was built over Java or C#, so the HTML5 / JavaScript approach was new to me, so I had to take a closer look at what options exist.  In short, there are an absolute ton of options… too many in fact.  However, my rather well defined needs narrows things down quite a bit.  In fact, I am down to a pair of options, and would love your opinion on them.

 

 

Option 1

 

jQuery for the UIjquery-logo1

jQueryMobiel for the mobile UI

Node for the backend

CouchDB or redis for the database layer

Express for the server bits

Backbone.js for the um, backbone ( this is where MVC comes in )

Moustache and icanhazjs for the templates

underscore, well, just to make things work

 

 

Option 2

 

YUI for the front end (desktop and mobile), routing, MVC and server bitsyuilib

Node for the backend

CouchDB or redis for the database.

Handlerbars for the templating.

 

 

 

Both have benefits and detriments, especially from the perspective of a tutorial.

 

jQuery is easily the most popular UI library out there, and there is a gigantic amount of support available ( and dozens of books ), with a gigantic community.  Backbone and Moustache are less used, but still well supported.  Unfortunately, this also means introducing a half dozen pieces of tech, a very confusing prospect.  Development on all of these products moves extremely fast, which is a double edges sword.  Finally, and this is highly personal, I hate the look of jquery and underscore code, it feels so… hackey.

 

YUI on the other hand, is from a single vendor, with much less supporting material but very good documentation and a very clean modular design.  More to the point, it is an end to end system so it is very consistent.  However, if something goes wrong the community is much smaller and the supporting materials aren’t as readily available.  Perhaps the biggest downside with YUI is the newness of it.  YUI3 is still in transition away from YUI2, and YUI App ( the YUI equivalent to Backbone ) is young and at times it shows.  From an engineering perspective though, YUI just feels more solid and less like a clever hack.

 

Right now, ease of explanation is winning out, and I am leaning towards using YUI.  Going with on all encompassing library is much easier to configure and explain to readers, so that is a big plus.

 

Any thoughts or opinions on the subject? 

 

Oh, and if this is all sounding extremely confusing, don’t worry, it really isn’t that bad.  The end product should still be a single archive you download and execute with a simple click. 

 

So, over the next few weeks ( or more ), we are going to be going off on a slightly odd tangent here at game from scratch, and crossing over into the world of web app development, I hope many of you find it interesting.  For those that don’t, don’t worry, I will still be publishing game development specific contents and tutorials too!

Design


15. August 2011

 

This began life as a post here but it became long enough and IMHO important enough, I am going to clean up the spelling a bit and repost it here.  It was in response to a fairly new developer with a question about class design.

 

 

This is one of those things that is nearly impossible to explain in a post, or hell, short of a small book.


But generally ( and yes, there are exceptions, thousands and thousands of exceptions ) you want to decouple your objects from each other as greatly as possible. You also want to keep code as self contained as possible, again, with thousands of exceptions.

 


A lot of the time when you are designing your classes ask yourself "If I changed this class, how many other aspects would need to be changed as well?" Then go about breaking those dependencies where possible. If two classes don't really need to know about each other, break that dependency. If two classes share 90% of their functionality, derive from a common base class.

 


On the other hand, you have to let common sense be a factor. One really common reason to abstract away your classes into engines and various components is so you can make switches later. For example, if you are using SDL, but want to be able to switch over to SFML at a later date, it's common to make a Renderer class, and an intermediary class over all the various objects like Bitmaps and Sprites, that both SDL and SFML provide so you can transparently change Renderers without making a code change. Reality is though, for 90+% of projects, this is just an added layer of complication and work that will never ever be used. This is where common sense has to come into play. Yes, from a purely object-oriented perspective, it is a very "pure" design that implementation details are abstracted away. From a practical and getting shit done sense, it's just a stupid waste of time.

 


This is where we get to the next sticking point and another area where new developers ( and experienced developers! ) get it really wrong most of the time. Global variables. See, when a new developer learns about global variables they seem like a godsend, as then you frankly don't have to design classes at all, just make everything globally available! This in a very short while makes extremely unreadable and maintainable code. Other new ( and experienced developers ) have heard about this and had it drilled into their heads that GLOBALS ARE BAD!!!! and react accordingly. Ironically enough, 9 times out of 10 this seems to always result in the same discovery... the Singleton. If you haven't yet, some day you will discover the singleton pattern and you will think it is the answer to your prayers. It's not a global, it's an object!!! Actually no, it really is just a global with a pretty layer of object oriented goop wrapped around it(**). Then you will encounter another group of people that will yell from the mountains SINGLETONS ARE BAD!!!! Which in the end leads you to engineering half a hundred "Manager" or "Adapter" classes to eliminate your dependencies on global variable and singletons. All the while, no work is getting done on your game.

 


Now it's time to let you in on a dirty little secret. Globals aren't bad, they are actually pretty frigging useful and important. The most important thing is, DO NOT ABUSE THEM. That is it. Chances are, you are going to have some form of global object, like perhaps a Game, App or World class, this is completely reasonable. On top of that you are going to run into code that needs to be globally accessed, such as your Audio class or Event class, which is also quite reasonable. It simply does not make sense to pass in an Audio class to say, a GameEvent, because that game event might on occasion need to play a sound. There are quite literally only a handful of things that should be made globally available but if it makes sense to be globally available, make it globally available.

 


But here is where the design gets tricky again, if you are making something globally available, do not make the relationship two-way, or at least not unless the two-way relationship is completely generic or via an interface. For example, if you have a game engine ( globally available ), and that game engine has a (globally available ) event queue, that at some point a game object needs to add events to, make sure that the event queue has the most absolutely minimal requirement to know anything about the game object and that the game engine itself needs to know absolutely NOTHING about the game object, as this is where your design can start to fall on it's face.

 


One last general rule of thumb when dealing with globally available classes, make them static whenever possible, it will lead to less potential hazards. Additionally, when make global objects provide access to other global object ( for example Game::SoundManager ), use accessor methods and const whenever possible. Keep all allocation and de-allocation specifically in the realm of the containing object.

 

 

 

 

 

 

 

 

 

 


(**) There are actually more to singletons than just object oriented globals. Yes, Singletons are global in scope but they have a couple very important properties. First of which is deferred allocation, meaning the Singleton isn't using memory until the first time it is used, unlike a traditional static variable. Additionally, a Singleton can be sub-classed as a mechanism of providing a single interface to potential disparate code bases, so for example you could have a Renderer::GetInstance(), which is sub-classed as OpenGLRenderer or DirectXRenderer, which will provide your code with a single global runtime determined instance. If you don't understand this paragraph, that’s completely fine, I'm just throwing it out there as a caveat so my over simplification of a Singleton isn't misleading... they do have their uses.

Programming Design


See More Tutorials on DevGa.me!

Month List