Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm making a game on the HTML5 canvas and my intent is to run or port this code to work on cell phones. Right now it only runs on my desktop computer. I'm trying to write my GUI code but I'm not confident in any of the architectures I come up with so I'm getting stuck in a refactoring loop.

So far I've got a Dialog and a Clickable (basically a button) type. The Dialog is initialized with a hardcoded list of Clickables . Whenever the user clicks on a dialog, a function iterates the current Dialog's Clickables to see if any of them were clicked and if so, runs that Clickable's action. This action can be basically anything.

This all worked for my needs until I needed to make the number of Clickables on a Dialog dynamic depending on the game state. For example, the inventory dialog. This is a grid and each cell may contain an item. Is every cell a Clickable, or only cells with an item? When are these dynamic Clickables created? Who creates them and where?

Also consider the level chooser dialog. It should contain a list of levels you can play. The more levels you beat the more Clickables on this screen. This screen will probably be scrollable. Keeping track of where the user clicked when the window may be scrolled is blowing my mind.

I feel like any decision I make will paint me into a corner later. I've never done this before so I'm looking for some advice from seasoned veterans. Thanks

BTW, I've looked around the site for other similar questions. They seem to be asking, "How do I do this in C++ w/ a library". Here I'm asking how to design it by hand.

share|improve this question

closed as too broad by Anko, bummzack, Sean Middleditch, Byte56 Aug 16 '13 at 0:20

There are either too many possible answers, or good answers would be too long for this format. Please add details to narrow the answer set or to isolate an issue that can be answered in a few paragraphs.If this question can be reworded to fit the rules in the help center, please edit the question.

1 Answer 1

I found your question hard to answer as it seems quite broad. "The GUI" can more or less be considered your whole game. Answering that question accurately would be designing the game, which I believe is out of scope for this forum.

There are numerous frameworks (Sencha, qooxdoo, Kendo, ...) that can make things easier, however if you want to learn and explore I'm all for it.

I've tried to answer the 3 questions I found in your post and provide some examples. I hope you find it useful.

Maybe you should divide this question into one or more concrete questions. Some code examples usually helps too.

"Clickable" sounds like an interface. The name only describes a single aspect of the required object (I assume you want to represent a square of custom graphics which might also be clickable).

I think I would represent the buttons as simply a "component".

function Component(cx, cy, cw, ch, caction) {
    this.pos  = {
        x: cx || 0,
        y: cy || 0
    };
    this.size  = {
        w: cw || 0,
        h: ch || 0
    };
    this.action = caction || false;

    this.activate = function () {
        if (this.action) this.action();
    };
}

You'll have to add some properties representing the actual graphics (this depends on how you manage your graphics).

Dialog can call action on components that intersect with a mouseclick (or touch).

function intersects(x, y, pos, size) { ... }
function Dialog(components) {
    this.components = components || [];

    //...

    this.onclick = function (x, y) {
        for (int i = 0; i < this.components.length; ++i) {
            if (    intersects(x, y,
                    this.components[i].pos,
                    this.components[i].size)) {
                this.components[i].activate();
                break; // assuming non-overlapping components
            }
        }
    };
}

For any non-clickable component, just leave action unset and it will default to false.

You could implement a statemachine for gamestate (menu, levels, credits, etc). Statemachine example I've authored.

Implement an inventory which dynamically creates a dialog with components for each item, or components fill the screen, but only components with items have actions.

The inventory would have to be managed by your game state for that level.

Inventory might look something like this:

function Item(component) {
    this.component = component || false;

    if (this.component) {
        // mimic component behaviour
        this.pos      = this.component.pos;
        this.size     = this.component.size;
        this.activate = this.component.activate;

        // im not sure if this.pos and this.size refer
        // to this.component.* or if the assignment creates
        // a copy (however i think it's reference)

        // anyways, test to find out or make sure not to 
        // change component after it's added to item.
    }
}

function Inventory(items) {
    this.items = items || [];

    //...
}

This would allow Inventory to act as a dialog, and items as components while it's possible to add more data to an item without interfering with regular components.

You can use array.push and .splice to add/remove items from inventory (make sure to implement management for component/item coordinates and sizes).

share|improve this answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.