How to implement a messagebox?

Hi, I’ve been using the browser’s “alert” function for displaying data to the player, but it’s come a time in my project that I need something better, so I thought of displaying a message within the game, naturally.

The approach I thought of consisted in:
# Create a cc.LayerColor with opacity so that the game is partially hidden (note also that this layer should swallow all inputs and that the game itself should be paused while the message is shown)
# Draw a colored sprite in the center of the screen for better viewing the message’s text
# Show the message as a LabelTTF
# Show an “OK” button

Sadly, I’ve encountered a few problems:
* I can’t make the layer have an opacity and color (I’m using cc.c4b(0,255,0,123) which in another application of mine works fine)
* I don’t know how to pause the game (nor how to make it resume when the button is activated)
* I don’t know how to make the layer “swallow” all inputs so they don’t propagate to elements below the layer

Here’s my (currently broken, you just neeed to walk upwards to the first “portal” to see what I currently have going on) project: http://proto.heart-bit.com.ar/laberinto_broken

The project moment’s prior to trying to implement this new feature (minus a few tweaks in other parts of the code) is here for comparison: http://proto.heart-bit.com.ar/2013_11-laberinto

Am I re-inventing the wheel here? Is there a better (and quicker and easier) way to do this? Like with CocoStudio or some other way?

I’m supporting this post. I’ve been through a lot of sample codes (not a js expert but ya…) and cocos2dx tutorials but I find the guide for managing “modal window” for html5 cocos2d really lacking.

I am also looking for assistance with swallowing touches (sounds nasty) with faux modal windows - created with new layer. The closest tutorial I saw was FruitAttack. However, that completely kills off the touch with unregisterTouchDelegate method. These are the logical steps I wish to accomplish:

  1. create new layer. key in text and perform other tasks. Click confirm (or OK) to close. [works]
    *2. capture touches without propogating them to any layers beneath the “modal window” [a nightmare. can someone explain how the touchDispatcher works when setTouchEnabled is called? An example with one scene and two layers (one of which is the modal window) will be awesome]*
  2. Once the new layer has been removed, the user should be able to instantiate a new layer for the “modal window” on any label’s callback.
    [works]

@Sebastian, I have been messing with layers and all these few days and find the coordination system a tad unwieldy. I believe I grasp the concept properly but upon workarounds to the coordinates for set Position methods, my layers appeared. I am not sure if it’s a bug and am waiting for someone to verify it.
And dude I played your game. cool. is it an intended behavior for your up and right buttons to swap? it’s a challenge?

Thanks~

Well, let’s wait and see if someone with more experience can give us some insight.

PS: Yeah, that’s the intended mechanic, I made it for a contest under the theme “change”. There’s more info about that here:

Alright, so, I’ve made some progress:

var ShowMessageBoxOK = function(parent, message, callback){
    parent.pauseSchedulerAndActions(); //it'd be beautiful if this worked wouldn't it? Sadly, it doesn't seem to do anything..

    var layBackground = cc.LayerColor.create(cc.c4b(125,125,125,125));
    parent.addChild(layBackground, 10);

    var lblMessage = cc.LabelTTF.create(message, "Trebuchet MS", 24);
    lblMessage.setPosition(/*center of the screen*/);
    layBackground.addChild(lblMessage, 2);

    var menu = this._menu = cc.Menu.create();
    menu.setPosition(cc.p(0, 0));
    layBackground.addChild(this._menu, 3);

    var btnOK = cc.MenuItemLabel.create(
        cc.LabelTTF.create("OK", "Trebuchet MS", 36),
        function(){
            layBackground.removeAllChildren(true);
            layBackground.removeFromParent(true);
            parent.resumeSchedulerAndActions(); //it'd be beautiful if this worked wouldn't it? Sadly, it doesn't seem to do anything..
            callback(parent);
        },
        this
    );
    btnOK.setPosition(cc.p(/*center of the screen*/.x, /*center of the screen*/.y-lblMessage.getContentSize().height));
    menu.addChild(btnOK);
};

I still can’t find a way to properly “pause” the game nor to make my message layer stop events from propagating, but I moved all the code that originally followed after alert(message) in my original code into a continueGameplay function, and so I use ShowMessageBoxOK(this, message, this.continueGameplay);, that way at least stuff that shouldn’t happen by itself until the user has clicked the “OK” button won’t happen before that.

Hence, this:

gameLayer = cc.Layer.extend({
...
    someFunc:function(){
        ...
        alert(message);
        this.something();
        ...
    },
...
});

Became this:

gameLayer = cc.Layer.extend({
...
    someFunc:function(){
        ...
        alert(message);
        ShowMessageBoxOK(this, message, this.continueGameplay);
    },

    continueGameplay:function(that){
        that.something();
        ...
    },
...
});

I’m still a long ways to go, but I think I’m going to try and keep expanding and parametrizing this approach.

OK, so, I think I’m going to drop that approach and examine the newly released sample and docs for CocoStudio with cocos2d-html5, which can be found here:
http://www.cocos2d-x.org/cocos-docs/tutorial/parkour_game_with_cocostudio/chapter3/en

looks good.
will have a look at it later this week.

however, we still need help for touch propogation.

Indeed we do.

I’m hoping to find something relevant in that example.

Welp, the example resorts to implementing a “pause” and a “play” method for everything that’s on screen and then call them when appropiate (they internally use “pauseSchedulerAndActions” and “unscheduleUpdate” to pause, and their counterparts to play)…

Not particularly useful if you want to keep the game running in the background and just unaffected by touches that should be swallowed by the pop-up layer.

Alright: I went ahead and coded an approach that travels all nodes, disabling them iwth “setEnabled(false)”, “setTouchEnabled(false)” and “setKeyboardEnabled(false)” on all relevant nodes (first checking if they actually implement those methods before calling them with, for example “this.setKeyboardEnabled === ‘function’”). It’s a bit extreme but it does what I need (I still think there should be a way to easily stop touch/click events from propagating of couse).

I’m polishing it’s edges and squashing a bug I keep getting with some buttons (it’s really ugly code, I’d be ashamed to post it as it is right now), but I’ll post it later.

Hi,

For the solution of touch propagation, please check out the response to this post:

Huabin

Thanks!
I’ll check it out now.