Construct 2 in WinForms

Applies To: Construct 2, CefSharp, VB.NET, WinForms, jsMessage

In my previous post, Embedded Chromium in WinForms, I walked you through creating a simple WinForms application that will load local html resources into an embedded Chromium browser using CefSharp. This article will build on that application to show you how to host Construct 2 games inside your WinForms application. Additionally, I will show you how to use my Construct 2 jsMessage plugin to communicate directly from .NET code to your running game.

Hosting a Construct 2 Game

For this article I will be using the jsMessageTest Basic game available on the jsMessage CodePlex site as an example download. You can use either the paid or free versions of Construct 2 to create the resources but you will need to install the jsMessage plugin. More details about this plugin and about the example game we’ll be using can be found in my posts, Introducing jsMessage for Construct 2 and jsMessage Basic Example.

You can also just use your own game or one of the many sample games that comes with Construct 2. However, you won’t be able to follow along with the Sending/Receiving messages section of this post without the jsMessage plugin.

Building the Game

Open the jsMessageTest Basic.capx in Construct 2. Choose File > Export project… In the dialog, choose HTML5 website and click Next:

ExportC2

In the Export Options dialog choose the location as a C2 folder inside your application’s directory (mine is bin/x64/debug/C2). You also need to uncheck the Minify script checkbox. I’m unsure of the reason but currently you will receive an error in the console if you attempt to load a game that has been minified using C2. I suspect this is an issue with the version of Construct 2 I am running but it could easily be CefSharp. Either way, uncheck the box for now and click Next:

C2ExportOptions

Choose Normal Style in the template options and click Export.

Loading the Game

Assuming you are using the same WinForms project created in my Embedded Chromium in WinForms post you can just switch the address in the browser constructor to local://C2/index.html

Go ahead and run the application. If the game shows up for you, fantastic!

Unfortunately, I get a blank screen when using the default settings. I’m able to fix this by disabling the GPU hardware acceleration.  This is a known issue with certain versions of Chromium when paired with specific drivers/hardware. If you have this issue, you can easily pass Chromium Command Line Switches using the CefSettings object in CefSharp. We can do this by adding this line right before we call the Cef.Initialize function in our Form constructor:

        settings.CefCommandLineArgs.Add("disable-gpu","1")

When you run the application it should look similar to the following:

C2inWinForms

This “game” doesn’t have much to offer without some additional plumbing (see below) but it is fully interactive. If you were to switch it out for a platformer game or something similar you would see that all the key presses, clicks, etc. are all passed just like you’d expect!

Sending Messages to Construct 2

The jsMessageTest Basic game was built with the jsMessage plugin. This plugin allows the game to respond to jQuery events and to trigger events of its own. You can find a lot more detail about how this works with this game in my post, jsMessage Basic Example.

It’s really pretty straightforward if you’re familiar with jQuery events so we won’t be spending much time on explaining it. Suffice it to say we are going to be injecting JavaScript in to our browser that will allow us to interact directly with the game from the code.

I’ve added a GroupBox labeled Send Messages and inside I’ve put a TextBox called txtMessageToSend and a Button called btnSendMessage. Here’s the code for the btnSendMessage Click EventHandler and the helper sub SendMessage:

    Private Sub btnSendMessage_Click(sender As Object, e As EventArgs) Handles btnSendMessage.Click
        If Not String.IsNullOrEmpty(txtMessageToSend.Text) Then
            SendMessage(txtMessageToSend.Text)
            txtMessageToSend.Text = String.Empty
        End If
    End Sub

    Private Sub SendMessage(Message As String)
        If browser IsNot Nothing Then
            addActivity(String.Format("MESSAGE: {0}", Message))
            browser.ExecuteScriptAsync(String.Format("$(document).trigger('CKjsMessageSend','{0}');", Message))
        End If
    End Sub

In the Click EventHandler (lines 49-54) we’re just making sure there is a message to send, calling the SendMessage sub and clearing the txtMessageToSend box.

The SendMessage sub is doing the actual interesting work. First, we verify the browser is setup. Then we use our addActivity sub to log the message. Finally, we call the ExecuteScriptAsync method which allows us to execute JavaScript directly on the page within our browser. This JavaScript triggers the CKjsMessageSend event with our message as the parameter (this is the format expected by the jsMessage plugin).

Run the application, type something in the box and click Send and you should have something like the following:

InitialMessageSend

Receiving Messages from Construct 2

Construct 2 can send messages via jQuery events using the jsMessage plugin. We can easily register a JavaScript function to be performed when that event is triggered. But how do we respond to that with .NET code?

CefSharp provides the ability to expose a .NET class to JavaScript. This is totally awesome. There are some limitations regarding the complexity of the objects and their return types, etc. all of which you can find on their project page. For our purposes, we just need a simple proxy object that can accept messages and route them.

Add another class to your project called MessageReceiver.vb and copy/paste the following code into it:

Public Class MessageReceiver

    Private logReceiver As Action(Of String)

    Public Sub New(LogReceiverAction As Action(Of String))
        logReceiver = LogReceiverAction
    End Sub

    Public Sub log(Message As String)
        logReceiver(String.Format("RECEIVED: {0}", Message))
    End Sub

End Class

This is not particularly exciting code but it should illustrate what is possible. It should also look somewhat familiar if you followed the steps to make our LogDialogHandler object in the last article. In our constructor (lines 5-7) we accept an Action(Of String) which we will use to handle our logging. We store this Action into our private logReceiver object (line 6) so that we can use it later.

There is just one method, log, which takes a string, adds “RECEIVED:” to the front of it and calls the logReceiver action. I’ve lowercased this method to match what will happen once exposed to JavaScript. CefSharp automatically changes methods and properties into JavaScript-casing (the first letter is downcased). I find it less confusing to just do that directly in the object.

Now we just need to register our object into our browser. We can do this once the browser is initialized using the RegisterJsObject method. Here is the line of code to do that in the Form constructor right after setting up our JsDialogHandler:

browser.RegisterJsObject("messageReceiver", New MessageReceiver(New Action(Of String)(AddressOf addActivity)))

The RegisterJsObject takes 2 parameters: The name we want to use in JavaScript for the object and the object itself. In our case we want it called messageReceiver (this will be a global object) and we just create a new instance of our MessageReceiver pointing the logReceiver Action to our addActivity method.

Go ahead and run the project and click the DevTools button. Switch to the console and start to type messageReceiver. You’ll find that Chrome’s autocomplete recognizes that there is a global messageReceiver object. If you call the messageReceiver.log function with a string you’ll see it show up in the Activity feed:

messageReceiver

Now we just need to tell jQuery to call this function when receiving a message from the Construct 2 game. We do this by using the ExecuteScriptAsync method we used earlier when sending messages.

However, we have to make sure the game is loaded before we insert the event handler or it won’t take effect. We can do this by taking advantage of the browser’s IsLoadingChanged event. Add the following line to your Form constructor right after our RegisterJsObject call:

AddHandler browser.IsLoadingChanged, AddressOf onBrowserIsLoadingChanged

So now let’s add the onBrowserIsLoadingChanged sub to our Form code:

    Private Sub onBrowserIsLoadingChanged(sender As Object, e As CefSharp.IsLoadingChangedEventArgs)
        If e.IsLoading = False Then
            browser.ExecuteScriptAsync("$(document).on('CKjsMessageReceive',function(e,m){messageReceiver.log(m);});")
            RemoveHandler browser.IsLoadingChanged, AddressOf onBrowserIsLoadingChanged
        End If
    End Sub

The IsLoadingChanged event provides us with a helpful event argument that tells us if the Browser is loading or not. We verify that it is no longer loading then inject our JS event handler and remove the .NET event handler from the IsLoadingChanged event (since we only need to call this once).

Run the application and type a message in the game textbox and click the jsMessage plugin icon (the turquoise speech bubble) and you’ll see that message come into the Activity feed:

C2Received

 

You now have all the basic plumbing in place to host a Construct 2 game directly in your WinForms application and to be able to send and receive messages directly from the game! This opens up a wide range of possible applications. I wrote all of this for an integrated project I’m working on, but I hope you find it helpful too!

jsMessage Basic Example

Applies To: Construct 2, jQuery, jsMessage

In my last post, Introducing jsMessage for Construct 2, I gave a brief overview of my C2 Plugin jsMessage. jsMessage enables sending and receiving messages in Construct 2 through jQuery events. You can read more in that post, but the basic idea is the ability to communicate to a Construct 2 game through the Browser. The license is free for everybody and attribution isn’t required.

In this post, I’m going to walk through the jsMessageTest Basic game to show you exactly how it works. You can also download it over on CodePlex if you’d like to follow along.

“Game” Overview

When you first run the project not much is going to happen. You’ll see a big red message that says “Nothing Yet…” – once you’ve successfully sent a message the contents will be displayed here.

InitialScreen

This is a very simple game project with just a few assets and only a small set of standard objects (Touch, Sprite, Browser, Particles, Text and Text Box). The only custom object is the jsMessage object. This was added to the project like any other object and can be found in the Web section (assuming you’ve installed it):

jsMessageInsertNewObject

Receiving Messages in Construct 2

The Event Sheet

jsMessage provides 2 conditions for receiving messages. The first one, Message Received, fires every time a message is received. In our game we are using it to set the text of the txtRecevied object (the big red text). We are also outputting additional information to the console. This helps illustrate several of jsMessage’s expressions but is not something you’d normally do outside of debugging. Here’s what this section of the Event Sheet looks like:

EventSheet-MessageReceived

Using the Log in console action of the built-in Browser object, we output information about the received message. The jsMessage.MessageRaw expression provides the full message string. The jsMessage.Command expression provides only the first part of the message before any values (known as the command). The jsMessage.ValueCount provides the total count of values passed (additional strings after the command separated by the Value Separator Property).

Finally, there’s a For Loop that outputs each of the message’s values (if there were any) by using the jsMessage.Value() expression.

Client-Side

Let’s give it a go. For all of the client-side examples we’re just going to type the jQuery commands directly into the console. So go ahead and run the project and open the Dev Tools (Just hit F-12 in Chrome) and switch to the console. Type the following:

$(document).trigger('CKjsMessageSend','Hello World');

Once you hit enter, your screen should look like this:

HelloWorld

You can see the txtReceived object had its text set to the message and the console has all the log messages we expected (Raw & Command are equal in this case and the Value Count is 0).

Now try sending this:

$(document).trigger('CKjsMessageSend','DoThing|Turds|Sunshine');

DoThing

You’ll see the txtReceived object gets the full message just like before, but if you look in the console you’ll see some differences. We can now see our Command is DoThing and that we have 2 values: Value 0 is Turds and Value 1 is Sunshine. Of course, we are assuming the use of the default separator (The separator is customizable so it’s always a good idea to use the Separator Events to determine what that is before sending/receiving messages on the client).

Responding to Commands in Construct 2

The Event Sheet

Another condition provided by jsMessage is Command Received. This condition lets you specify the command to listen for. This is what we’re doing in the Turtle section of the Event Sheet:

TurtleCommand

We are listening for the command, “Turtle”. When it’s received we move a turtle sprite across the screen using a Bullet behavior (There are also a couple of conditions to reset the turtle once it leaves the screen).

Client-Side

Here’s how we trigger this command from the console:

$(document).trigger('CKjsMessageSend','Turtle');

Turtle

Look at that cute turtle! LOOK AT IT!

You can see everything works just like any standard condition (Note that the console also provides us all the extra information because both the Command “Turtle” Received and Message Received conditions are firing).

Responding to Commands with Values in Construct 2

The Event Sheet

Commands are just messages which means they can also have attached values. This can be seen in the Explosions section of the Event Sheet:

ExplosionsCommand

We are listening for the command, “Explode”, but we’ve added some additional conditions to ensure that there is an included value (jsMessage.ValueCount = 1) and that that value is an integer greater than 0 (int(jsMessage.Value(0)) > 0).

Once the above conditions are met,we use a For Loop to create the number of explosions (particle objects) as specified by the passed value (with a max of 10 cause let’s not get crazy!).

Client-Side

Here’s how we trigger this command from the console:

$(document).trigger('CKjsMessageSend','Explode|7');

Explode

GLORIOUS EXPLOSIONS!

Sending Messages from Construct 2

The Event Sheet

jsMessage provides a single Action, Send Message, that is really easy to use. You just provide the message as a parameter and it’ll take care of it:

SendEventSheet

All we’re doing above is treating the icon sprite like a button by responding to a tap (or click). We flash the button to give some feedback to the user that they tapped it and then call the Send Message action with the text of the txtboxSend object. Of course, nothing is going to happen if nobody is listening on the other side…

Client-Side

To receive messages from Construct 2 you will need to register to respond to the appropriate jQuery event. Here’s an extremely simple response that just writes the sent message out to the console:

$(document).on('CKjsMessageReceive',function(e,m){console.log(m);});

To test, just write something in the text box and click the button:

SendMessage

 

Sending Messages with Values from Construct 2

The Event Sheet

To send messages with values from your game you’ll build your messages using the same format as above. You can see an example of this in the Responding to Requests section of the Event Sheet:

RespondingToRequests

 

When we get the command, “FPS?”, we use the Send Message action to send a custom message built by concatenating a command, “FPS”, the separator using the jsMessage.Separator expression and the C2 value, fps. We could have just typed the default separator but since this is a customizable property it’s always better to use the jsMessage.Separator expression.

Client-Side

To test this one, we need a slightly more elaborate response function:

$(document).on('CKjsMessageReceive',function(e,m){console.log('Client-Side Message Received!');var parts=m.split('|');console.log('Command Received: '+parts[0]);for(var v=1; v<parts.length;v++){console.log('Value Received: '+parts[v]);}});

I’ve kept it to one line above so that it can be easily pasted in the console, but here’s what it looks like where it’s a little more readable:

$(document).on('CKjsMessageReceive',function(e,m){
    console.log('Client-Side Message Received!');
    var parts = m.split('|');
    console.log('Command Received: ' + parts[0]);
    for(var v = 1; v < parts.length; v++){
        console.log('Value Received: ' + parts[v]);
    }
});

SendMessagesWithValuesWhen we send the “FPS?” message to the game it responds with the fps information. Our client-side response just outputs the C2 message right back to the console. I’ve hard-coded the default separator in this example, but you’ll want to use the Separator Events beforehand to ensure you know what the separator is before receiving/sending messages from the client.

 

Be sure to check out the full documentation for more details. Stay tuned for an upcoming post where I’ll show you an actual use case for this plugin. WOWEE!

Introducing jsMessage for Construct 2

Applies To: Construct 2, jQuery

jsMessage is a Construct 2 plugin that enables sending and receiving messages through jQuery events. I’ve just released it over on CodePlex where you can download it and a sample game to show you how to use it. You can use it in the free edition as well as all paid editions. The license is totally open so feel free to use it in your commercial or personal projects, etc. No attribution necessary (although always appreciated).

BasicTest

You can find out how to install it by checking out the documentation on CodePlex (It’s a c2addon, so just drag and drop).

What

jsMessage is a cool little plugin that adds 2 conditions (Message Received, Command Received), 1 Action (Send Message), 5 Expressions (Message Raw, ValueCount, Command, Value, Separator) and 1 Property (Value Separator).

You can use these to respond to external messages coming through the browser.

Why

There are several other plugins that allow network communication and generally this is the way you’re going to want to go. If you are trying to have games talk to each other or download things, etc. – this is not the plugin for you. The only way to communicate to the game using this plugin is to trigger jQuery events and to register to receive them as well.

I had a specific need to communicate to a running game in a browser I control. I will be demonstrating this technique in an upcoming post and hopefully it will make more sense then. However, there are lots of other uses and I’m excited to see what other people end up using it for.

How

There is some more in-depth documentation available on the CodePlex site and I’ll be posting an elaborate walkthough using the basic example game in an upcoming post. In the meantime, here’s an overview.

To communicate to a running game you can send messages by triggering the CKjsMessageSend event. Here’s a one-liner perfect for the console window:

$(document).trigger('CKjsMessageSend','SomeCommand');

This will trigger both the Message Received and Command Received conditions in your game. Command Received allows you to respond to a specific phrase. Message Received is more general and you’ll have to do some comparisons to see if it was the message you were looking for.

You can also send values by using a delimiter. The default delimiter is the pipe | but this can be changed as a game setting. To find out what the separator has been set to you can use the CKjsMessageSeparatorQ and CKjsMessageSeparatorA events. It might look something like the following:

$(document).ready(function(){
    var jsSeparator = '';

    //Prepare to respond to the Separator Answer
    $(document).on('CKjsMessageSeparatorA',function(e,m){
        jsSeparator = m;

        //Send a message with values
        $(document).trigger('CKjsMessageSend','MyCommand' + jsSeparator + 'Value1' + jsSeparator + 'Value2');
    });

    //Ask the game what the Separator is
    $(document).trigger('CKjsMessageSeparatorQ','');
});

In other words, register to respond to the CKjsMessageSeparatorA event and then trigger the CKjsMessageSeparatorQ event to have the game respond.

Within the Message Received or Command Received condition you can get a count of the values sent with the jsMessage.ValueCount expression and then request those values using the jsMessage.Value(0) expression. There are also expressions to get the raw message (jsMessage.MessageRaw), just the command (jsMessage.Command) and even the configured separator (jsMessage.Separator).

The game can also send messages using the Send Message action. Here’s a quick example of how to register to receive these messages:

$(document).on('CKjsMessageReceive',function(e,m){
    console.log(m);
});

This will simply print out whatever message was sent directly to the console.

 

That’s the basic overview of the plugin. If you have a need for this kind of interaction then go download it and check out the example “game” (it’s free!). In my next post we’ll make this a little clearer by walking through the example game in detail.