Combining A Simple Canvas Game with Inform 7

Here are the steps I took to combine @richtaur’s A Simple Canvas Game with Inform 7.

Basics

I first took the canvas game code from https://github.com/lostdecade/simple_canvas_game. It is a simple game with 3 graphical attributes and 1 javascript file with clearly labelled code chunks.

On the Inform side, I just used ‘release along with an interpreter’.

Combination

I made the following changes to the play.html created by Inform: I deleted the links div, and I changed the coverimage div to repurpose it for the canvas game:

I included the main javascript file of the canvas game directly after the coverimage div. I copied and pasted the entire code when I was trying to fix some problems with passing parameters, but the final code should work even if it was just included. I changed the first line of that javascript code to:

var canvas = document.getElementById(“maincanvas”);

and I removed the appending line.

Now the two games were combined, but the canvas was invisible.

Styling

I made a few big changes. The .coverimage style I changed to:

.coverimage{
 left: 0px;
 width: 512px;
 height: 480px; 
 margin: 0;
 background: #1A354A; 
}

The later .play .coverimage style I changed to be empty.

I changed the gameport style to:

#gameport{
 background: #1A354A;
 bottom: 0px;
 left: 520px;
 line-height: 1.4;
 margin: 0px;
 position: absolute;
 right: 0px;
 top: 0px;}

Glkote.min.js forces some styling on the game, so depending on how you do your formatting, you may find it overridden. If that happens, use your browser’s developer tools to inspect the element that is being messed up, and see what element .style says (this represents the styles forced by javascript) then search glkote.min.js for the offending part, and change it.

I tweaked glkote.css in the interpreter folder, messing with backgrounds and such. I changed the buffer window to have a bottom border and to have a fixed width with auto margins. I also added new fonts and font sizes/colors to the various user styles.

Communication (the big part)

I use the status line to communicate from Inform to the game. My inform code contains lines like the following:

Instead of going east:
 say "You go east.";
 now the left hand status line is "East";

Instead of talking to the goblin:
 say "The goblin says, 'Greetings, stranger.'";
 now the left hand status line is "";

In glkote.min.js, there is a function called ‘insert_text_detecting’. It is called twice. The first time is for the status line, and once is for the rest of the text. It is the function that actually prints to the screen.

I intercept it to receive commands from it:

if(rlink==undefined){
 if(rtext.slice(1,6) == 'North'){
  hero.y -= 30;
 } 
 if(rtext.slice(1,6) == 'South'){
  hero.y += 30;
 }
 if(rtext.slice(1,5) == 'East'){
  hero.x += 30; 
 }
 if(rtext.slice(1,5) == 'West'){
  hero.x -= 30; 
 } 
insert_text_detecting(el,rtext);
}

These commands (hero.x -=30;) directly alter the simple canvas game’s objects. This can be done because this code is loaded after the simple canvas game. If that were not the case, you could still use jquery events.

This is what I did for the opposite direction. In the simple canvas game, there is code for collision detection. I added one line to that code:

 $(document).trigger("end_game");

What this does is signal all code everywhere that something called ‘end_game’ is happening.

I wanted to tell glkote.min.js to ‘type in’ some code into Inform when this happened. The correct code for this is submit_line_input, which types something into a given window. Unfortunately, there is no easy way to identify which window you’ve been typing in. Its ID is established randomly each time.

So I added a global variable at the beginning of glkote.min.js called last_window, which I initialized as null. I added a line to submit_line_input setting last_window to the window currently in use. That way I would know which window to use for my own code, which I tacked onto glkote.min.js:

$( document ).on( "end_game", {
 }, function( event) {
  if (last_window){
   submit_line_input(last_window, "zzxvm", null); 
  }
});

ZZXVM was the ‘secret word’ I wrote into my inform game to trigger an Inform event:

Successing is an action out of world. Understand "zzxvm" as successing.

Carry out successing:
 say "You caught the goblin!";

So now, if your sprite runs into the goblin sprite, Inform will print something out. This works even if we animate the sprite, allowing ‘real time’ Inform events!

But it looks gross in-game, because the zzvxm is unsightly. So I hack the other insert_text_detecting to remove it, along with the > sign that would otherwise remain:

if(rlink==undefined){
 if(rtext=='>'){
 }
 else if(rtext.slice(0,5) == 'zzxvm'){
 }
 else if(rstyle=='input'){
  insert_text_detecting(el,rtext);
 }
 else if(rstyle=='Style_input'){
  insert_text_detecting(el,rtext); 
 }
 else{ 
  insert_text_detecting(el,rtext); 
 }
}

Thus, the zzxvm never gets printed. Any number of ‘secret codes’ can be sent into the game this way.

 

Conclusion

Communication is two-way: the inform game prints the status line, which javascript intercepts and interprets as signals.

The canvas game inputs commands into inform, which are then hidden.

In this way, all kinds of messages can be passed back and forth. One major disadvantage is that the status line only updates once ‘per turn’. However, Inform 6 can be used to force a status line update. Even then, it is difficult to fire several signals in quick succession. It would probably be better to improve the status line detecting code to process several events at once (for instance, taking a sequence of numbers separated by spaces, splitting up into a list of numbers, and interpreting each number as a command).

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s