Learning Three.js

or WebGL for Dummies

Lets Make a 3D Game: Make It Embedded

This post is part of the “Let’s make a 3D game” series. The previous post was on fullscreen API. Here is another one on resizing the display area. This post is about embedding your game in another page. It is usefull to include it in a blog, in facebook, iGoogle or other game plateforms.

MarbleSoccer now contains all the tricks explained in this post. Show dont tell, you can see it embedded on the left. Embedding your game implies various things. As your game is hosted in another page, it likely got a smaller display area. HTML5 CSS media query makes it easy to fit various sizes. Another part are the DOM events from the iframe. They will be propagated to the host page and may produce undesirable effects. We see how to shield them. But first let’s see about iframe

Let’s go play in an iframe

iframe is an easy and secure way to embed a page in another. Let’s declare it.

1
2
3
4
<iframe src="http://marblesoccer.com"
  allowfullscreen webkitallowfullscreen mozallowfullscreen
  width="480" height="320" frameborder="0">
</iframe>

The attributes are pretty classics: frameborder to remove an ugly default border, width and height for size and src for your game page. The ones ending with allowfullscreen tell the browser that this iframe is allowed to go fullscreen. More about fullscreen in this previous post or in the spec.

You may need to determined if your game is embedded or not. Use this line will tell if it is in a iframe or not.

1
var isInIframe = (window != window.top);

Fit in a smaller display area

When your game is embedded, it is likely to have a smaller display area. How to deal with this ? First, we have 2 types of rendering in our game: a 3D display where three.js displays the WebGL, and a DOM display for OSD such as score, timers and other popups.

For 3D rendering, we have already seen window resizing in this post. Just download THREEx.WindowResize and add this line and you are done. Not too hard, hey.

1
THREEx.WindowResize(renderer, camera);

Now the DOM display. It may simply be done via CSS and media queries. Typically, you may reduce the size of your font or icons. I won’t try to teach css, other do that much better than me. Just a pick of what i did, not sure at all it is the best way. I reduce the OSD display if your game page is 640px or less.

1
2
3
4
5
@media all and (max-width: 640px) {
  /* here put your style specific for embedded case */
  body { font-size : 60%; }
  img { width : 48px; }
}

Shield Events

Strange section title, hey. It means prevents DOM events from the iframe to interfere with the host page. Not much clearer… Maybe with an example ? Let’s see the arrows+scroll case. Show dont tell. Below are 2 iframes: on the left, no shielding happens, on the right shielding happens. Try to click on them and use arrows up/down.

On the left, the host page scrolls, but not on the right. Why does this happen ? good question :) If our game iframe got the focus and users press up or down, the iframe will received keydown/keyup events. Up to now, all is ok… Troubles appear when those events are bubbling to the host page, they may trigger a scrolling.

Imagine the page going up and down while you play, the game becomes unplayable very fast :) So here is the code which prevents this behavior. It listens to arrows keydown events. and prevent their default.

1
2
3
4
5
6
document.addEventListener('keydown', function(event){
  // if it is keydown on a arrow, prevent default
  if( event.keyCode >= 37 && event.keyCode <= 40 ){
      event.preventDefault();
  }
}, true);

Conclusion

I gathered the code in threex.embedded, see its annoted source. Iframe is a easy and secure way to make your game embeddable. We have seen how to handle smaller display area with THREEx.WindowResize and media queries. Additionnaly we even shield DOM events, so we can use arrow keys for player control. You are all set! Go embed your game now :)

Comments