Showing posts with label thwack. Show all posts
Showing posts with label thwack. Show all posts

Friday, October 14, 2011

Loading HTML5 Game Assets

Before diving into HTML5 game development, I built a few conventional web sites (like this one - nice snapshots of the Blue Ridge). With conventional web design, page assets like images are loaded once the page loads, slowly filling out the blank screen with colorful pictures. This works well for web pages, since you can immediately begin reading the content and hardly notice the small delay as the images are painted in.

However, the wait for in-game assets can be especially long when downloading 10MB worth of images and sounds for a game like Entanglement. With Entanglement, the first issue I came across was that I couldn't draw a beautiful wooden tile to the gameboard canvas if the wooden tile image hadn't been downloaded yet.

My first attempt to solve this problem was to throw a JavaScript try/catch block around the drawImage calls so they wouldn't break the game if the image wasn't available yet. This resulted in the game starting immediately, but the gameboard slowly appeared as the images were downloaded. This is fine behavior for a web page but seemed a bit ugly for a web game.

My second attempt was a bit better: I included all the images in the html document as invisible <img> tags. This ensures that the images are indeed loaded before the game began but had the unfortunate side effect that JavaScript processing didn't start until the entire page was downloaded (including all the referenced images). This caused the long wait at a "Loading..." screen that couldn't be dynamically updated with a progress bar since JavaScript wasn't running yet.
It's doing something but we're not sure what nor how long it's going to take.
Enter the Asset Loader! This tool allows larger assets to be loaded after the page loads and the JavaScript processing begins. We're in the prototype stage of our next game, and I took this opportunity to build a proper asset loader. Seth Ladd wrote a wonderful tutorial on the basic steps to set up a simple asset manager. Using his insight and including a bit more code to handle audio assets, we created an asset loader that loads assets as well as calls two functions we can supply to track progress: what to do when a single asset is finished loading and what to do when all the assets are finished loading.
function loadAssets(assetList, onAssetLoaded, onAllAssetsLoaded){...}
The next piece we want is a nice progress bar. The <progress> HTML5 element has two properties we care about for keeping tabs on our loaded assets: max and value. Using these two properties we can create a very simple progress bar class to hand off to the asset loader that might look something like this:
function progressBar(parent){
 this.element = document.createElement('progress');
 parent.appendChild(this.element);
 
 // initialize the progress bar at zero percent
 this.element.setAttribute('value', 0);
 this.element.setAttribute('max', 1000);
 
 // for this example, progress will be some value [0,1]
 this.update = function (progress) {
  this.element.setAttribute('value', progress * 1000);
 };
};
We can then set up our asset loader to update the progress bar each time an asset is finished loading, by feeding the progressBar's update function the current state of loaded assets. In our asset loader, the "ratio" value shown below is simply the number of assets loaded divided by the total number of assets.
var assetProgress = new progressBar(document.getElementById('loading-screen'));
loadAssets(assetList, function(ratio){assetProgress.update(ratio);}, startGame);

We've already implemented the progress bar in the latest builds of both Thwack!! and Entanglement if you care to see it in action!

Thursday, September 29, 2011

Google In-App Payments: Convenient for buyers and developers

Todd and I are always looking for good ways to monetize our web games so we can continue doing what we love: making more games! With Entanglement, we created extended content that players can purchase if they really enjoy the game, and with our latest creation, Thwack!!, we created a reward system using tokens that can be won by playing the game or purchased for a few cents.

Back in January when we first released our Sakura Grove Expansion for Entanglement, we implemented an email and key system for purchasing: to access the expansion set for the first time, a player would make the purchase, wait for the confirmation email to arrive, and follow the instructions to get back into Entanglement with the key to unlock their purchase. Not only was the process indirect and inconvenient for purchasing a digital good, but it also took us quite a bit of time to develop and debug.

In developing our latest game, Thwack!!, we decided to implement Google In-App Payments. In-app payments are ideal for selling digital goods and the small 5% transaction fee is wonderful for the small transactions common to games.

Once our game's store interface was set up, I was pleasantly surprised to find integrating in-app payments very quick and straight-forward. In fact, I first began reading the documentation early one morning, and by following the very concise step-by-step instructions I had in-app payments implemented in Thwack!! by lunch time!

We were quite pleased with both the appearance and implementation for Thwack!! so converting Entanglement’s purchase process to Google In-App Payments was a natural next step. However, setting up in-app payments for two separate games on one seller account highlighted something I would need to change with my initially simplistic Thwack!! integration, where I had implemented the entire process, including the postback URL, through the web game itself.

Since I was adding a second game on the same seller account, I had to separate the postback process from Thwack!!. After a bit of restructuring, and less than a day’s work, I had In-App Payments running in both Thwack!! and Entanglement with a separate service that tracks orders apart from the games as shown below.

We now have Google In-App Payments running in both games in less than two days’ worth of programming with the additional benefit of a separate central location to track orders.

We found that Google In-App Payments is not only convenient for our game players by allowing them to remain in the game experience while making their purchase, it is also convenient for us as game developers by making the integration process quick and easy to implement.

Thursday, July 21, 2011

Key Frames Are Cool

Open Prize BallWe are planning to give away new discs (that players can collect) when games are won in Thwack!! (You can't get prizes just yet, so don't be too disappointed if you beat the skill shots and receive nothing.)

Todd thought a prize ball would be an exciting way to deliver these prizes. We could use canvas to do this, but today, just for fun, I decided to experiment with CSS key frames and use the DOM instead.

I had read about these on several occasions, but haven't tried them yet. It was much simpler to implement than similar code I could conjure up in JavaScript to do the same thing (example is for webkit browsers):

@-webkit-keyframes ballroll {
  from {left: -25%; -webkit-transform:rotate(-1440deg);}
  50% {left: 125%; -webkit-transform:rotate(0deg);}
  to {left: -25%; -webkit-transform:rotate(-1440deg);}
}

.prize-ball-roll {
  position: absolute;
  height: 75px;
  width: 75px;
  bottom: 0px;
  left: -25%;
  z-index: 20;
  -webkit-animation: ballroll 4s ease-in-out infinite;
}

If you are viewing this post in a browser that supports key frames, you should see a prize ball rolling across the blog. How cool is that!?!

Thursday, July 07, 2011

Thwack!! on html5rocks.com

HTML5Rocks.com has just published a tutorial I put together on resizing games to fit a browser's window size. I fleshed out some of my content from an earlier blog post and put together a few diagrams. Check it out!

We're working on online multiplayer for Thwack!! and are excited about releasing it soon.

Friday, May 06, 2011

Fonts for HTML5 Web Games

When we first began working with our artist to re-skin Entanglement, we ran into several issues with finding a great font to match the feel of the game.
  1. It was very difficult for us to find anything regarding licensing for fonts commonly found on a plethora of "Free Font" sites. Many would include phrases like "Check with author for license details" yet include nothing about the original author so that we could do so.
  2. Most purchased fonts on our computers are specifically licensed for use on up to 5 computers and are not for distribution. This is useless for a JavaScript web game, because, by nature of @font-face, we are providing the font itself on our website for anyone to download.
  3. Our artist initially chose Herculanum, so, fortunately, we were able find it as a web font on http://webfonts.fonts.com/. This allowed us to subscribe to their web font service and include a link to a small CSS file in our page to use it in our pages' stylesheets. However, we quickly realized this was not a sustainable solution with the impending arrival of Entanglement as a pre-installed web app in the Chrome browser, which we estimated would put us in the "professional" pricing tier, giving us a monthly cost of $100-$500.
  4. The web font subscription service provided access to a huge selection of fonts, so we thought we might check with Monotype Imaging about just licensing Herculanum by itself. Since Entanglement is hosted on Google App Engine, we found that our web game fell into the "hosting a font on 4 or more servers" category, which again put us well outside of our conservative budget.
Fortunately, while trying to find additional fonts that had licensing information, I came across Jos Buivenga's wonderful selection of fonts at http://www.exljbris.com/, including Fontin, the font we eventually decided to use for the text in Entanglement. This was a wonderful find because it fit nicely with our theme, was affordable (free), and had specific information about licensing for @font-face use.
Using Fontin in Entanglement
For Thwack!! we chose two fonts from Google Web Fonts. The selection has grown quite a bit since our last foray into font-finding, and it met our requirements in choosing a font: it is affordable (free) and is clearly licensed for @font-face use.

VT323 and Cherry Cream Soda
Embedding the two fonts was quite easy. As an example, for Cherry Cream Soda (yes, we picked it solely because of the awesome name), we added one line to our HTML template, "<link href='http://fonts.googleapis.com/css?family=Cherry+Cream+Soda' rel='stylesheet' type='text/css'></link>", and one line to our stylesheet (for the body tag), "font-family: 'Cherry Cream Soda';". This was much more straightforward than the steps we took to arrive at a solution for Entanglement.

Friday, April 29, 2011

Making HTML5 Games Match Your Screen

Sand Trap was our first opportunity to try supporting multiple resolutions, when we chose to enter it into SPIL Games' HTML5 Contest, geared towards mobile devices. At the time I decided to make it fluidly adjust to match any resolution it was opened on. This way it could not only match any width and height combination of a mobile device but also any resolution of a conventional computer browser. It worked well for Sand Trap, so we're re-using some of the same tricks on Thwack!!

Thwack!! on a maximized 1024x768 browser window
Implementing this requires taking advantage of CSS and JavaScript. Using just CSS, filling the whole screen is trivial, but CSS didn't allow us to maintain the same width-to-height ratio to prevent stretching of the gameboard, so that's where the JavaScript comes in.

Since we're not completely concerned about the exact width or height, the first piece of information we need to set is the ratio of width to height. In Thwack!!, we have it set to 4/3 (the game area is 4 units wide to 3 units high). Once we have determined this, it's a matter of making adjustments whenever the document is resized or, in the case of mobile devices, the screen orientation is changed. We handle these events by setting:
 window.addEventListener('resize', resizeGame, false);
 window.addEventListener('orientationchange', resizeGame, false);
Now we create a "resizeGame" function to handle these two events. With Thwack!! it's a bit more complicated since we're using multiple canvases, but if the game is running on a single canvas, it might look something like this:
 function resizeGame()
 {
  var gameBoard        = document.getElementById('canvas');
  var widthToHeight    = 4 / 3;

  var newWidth         = window.innerWidth;
  var newHeight        = window.innerHeight;
  var newWidthToHeight = newWidth / newHeight;

  if (newWidthToHeight > widthToHeight)
  {  // window width is too wide relative to desired game width
      gameBoard.style.height = newHeight + 'px';
      newWidth               = newHeight * widthToHeight;
      gameBoard.style.width  = newWidth + 'px';
  } else {  // window height is too high relative to desired game height
      gameBoard.style.width  = newWidth + 'px';
      newHeight              = newWidth / widthToHeight;
      gameBoard.style.height = newHeight + 'px';
  }

  // center the canvas
  gameBoard.style.marginTop  = (-newHeight / 2) + 'px';
  gameBoard.style.marginLeft = (-newWidth / 2) + 'px';
 };
Thwack!! on mobile Safari
Basically, if the window is too tall, we make width 100% of the window; if the window is too wide, we make height 100% of the window. The remaining dimension is sized according to the width-to-height ratio we previously set.

The last part re-centers our canvas in the middle of the screen. Many of the CSS properties we are concerned with are manipulated directly by the function above, but in order for those to work, we set up a few other CSS properties as follows:
 #canvas
 {
  position: absolute;
  left:     50%;
  top:      50%;
 }
This allows us to put the top left corner of the canvas in the center of the screen, and then our resizeGame() function gives the canvas a negative top and left margin half of the width and height of the game board so it is centered in the window.

Thursday, April 28, 2011

See you at Google I/O


Todd and I have been invited to show some of our work in HTML5 at the Google I/O Sandbox. We're really excited about this opportunity to connect with developers, field questions, and learn from the other developers showcasing their HTML5 work. We will be showing a special preview of Thwack!!, our latest game in development, as well as Entanglement: going behind the scenes on both to look at how we built them.

If you are planning to attend, we'll be handing out a few physical Thwack!! discs so you will be prepared should a game of table football break out over lunch. No, we're not Lego, but Todd does occasionally hang from the ceiling.

In other, unrelated news, we have over 10,000 Facebook fans! All of you are amazing - thanks for befriending us. To celebrate, we're handing out Sakura Grove codes to a few folks; check out our Facebook page if you want in on a chance to try Sakura Grove for free!

Wednesday, April 20, 2011

Making Thwack!! Fill Up Your Screen

One of the design decisions we made with Entanglement was to use up as much of the screen real estate as the browser would give us. This gives the game a more conventional, installed application atmosphere, especially if you hit F11 while playing. We're heading in a similar direction with Thwack!!, but have run into a few hiccups with the fast nature of the game-play and the slow nature of drawing to an HTML5 canvas element. Here's what we have found so far to keep things moving on a full-screen game:

Here only one disc needs to be re-rendered.
The first and most important take-away we found with our testing was to not draw to canvas unless we have to. The easiest way to keep the animation rendering short is to not draw anything. With a full-screen game, we have only a few parts of the game animating at any given time and have structured our canvases so that only the active parts of the game are being updated graphically.

To render as little as necessary, the game area is composed of several layers of canvases, similar to the layers you might work with in a paint application. Each disc and active game element has its own canvas, and its canvas is only redrawn if the game element has changed in some way. In the example at right, the yellow disc's canvas is erased and the disc is rendered in its new position while the background and the other discs remain static on the screen and no rendering calls are made.

The second drawing optimization we made was in clearing the canvas. We found that the above method works well for drawing itself, but clearing an entire canvas (or multiple canvases depending on how much action was occurring) proved to be expensive. I tried several different methods to clear a canvas before settling on using ctx.clearRect on the immediate area of the disc's last position. Using "ctx.globalCompositeOperation = 'destination-out'" and then rendering the disc at its last position would have been an elegant way to remove the last frame, but I found it's a bit more time-consuming than the ever-ready ctx.clearRect.

Are you a developer and have some wisdom to share? Let us know! Are you not a developer and just read through this post because you want to be? Awesome! You rock.

Friday, April 01, 2011

Starting on "Thwack!!"

Thwack!! with intense prototyping art
We thought it might be cool to go ahead and throw up a screenshot of our latest game that's in development, so you can get an early preview and see how it evolves over time as we iterate on making it fun and add in professional art and audio. For those more interested in the code, you may find these bits interesting:
  • We're currently localizing Entanglement, which has changed the way we are coding Thwack!! (ie. smarter). All the text is being exported from a single spreadsheet into language-specific javascript and html files that are generated from "language-less" templates. I plan to go into this with more detail in another blog post about Entanglement, but everything is being carried over to this project.
  • We're using a wonderful Javascript port of the Box2d physics engine: http://code.google.com/p/box2dweb/. If you're not familiar with Box2d, it was created by Erin Catto: http://www.gphysics.com/.
  • We're doing our best to make Thwack!! function well on portable devices from the ground up. The three biggest considerations for this are game loop and animation speed, the touch interface, and screen display size. We have a bit of experience with this from our work on Sand Trap, so we are using what we learned there to try to make this game work even better.
    1. Given that there's a lot of movement and we've added Box2d to the mix, getting animation and loop speed up may prove tough on slower mobile devices. If anyone has found great ways to speed up canvas draws on mobiles, we've already noticed we will need all the optimization we can get.
    2. Having touch events call somewhat equivalent mouse events has proved to work rather well so far. Thanks to Ross Boucher for a nice concise lead on how to go about this: http://ross.posterous.com/2008/08/19/iphone-touch-events-in-javascript/
    3. For entering Sand Trap into the SPIL Games HTML5 mobile competition last year, we put together a bit of code to auto-scale game-boards according to screen size and have used a variation of that in Thwack!! (as well as Entanglement). The hiccup with this, as before, will be scaling fonts appropriately.
Back to work now... ...oh wait... ...if you haven't seen the new Blogger layouts, my favorite: http://blog.gopherwoodstudios.com/view/mosaic