Gaming: Battle on the High Seas, Part 1

Share this article

Web browsers supporting HTML5’s Audio, Canvas, and Web Storage APIs are an exciting gaming platform. These APIs can be used to create interesting games with money-making potential. As a demonstration, this article begins a five-part HTML5 game development series focused on a simple SeaBattle game. Part 1 introduces SeaBattle, shows how to embed it in a Web page, and overviews its architecture. The game presented here has been tested in Chrome, Firefox, Internet Explorer 9, Opera 12, and Safari 5 desktop browsers.

Introducing SeaBattle

Years ago, I played a game in which a destroyer and multiple submarines engage in battle. Because this game was lots of fun to play, I implemented a simpler form of the game for this series. Figure 1 presents a snapshot of my SeaBattle game’s title screen. The destroyer photo was obtained from Wikimedia Commons.
SeaBattle Title Screen
Figure 1: The title screen introduces SeaBattle.
Figure 1’s title screen introduces you to SeaBattle and tells you to press the Return key to begin this game. When you press this key, you are greeted by a screen that’s similar to the screen shown in Figure 2.
SeaBattle Gameplay
Figure 2: A destroyer battles a submarine. Depth charge and torpedo sizes are exaggerated to improve the visibility of these game objects.
Figure 2 reveals a scene where you, the destroyer, appear in front of a starry background. The current score and the most recent high score (in parentheses) appear in the upper-left corner. The high score is retrieved from local storage. The number of destroyer images in the lower-right corner indicates the number of lives left. Somewhere below you, a submarine enters the scene and starts firing torpedoes. You can try to evade a torpedo by using the left and right arrow keys. The destroyer image changes to reflect the new direction. Its speed changes when it reaches either canvas edge. You can press the spacebar to fire up to two (at any one time) depth charges. When a depth charge hits the submarine, the submarine is destroyed and your score advances by 100 points. If the high score is exceeded, it is updated and saved in local storage. The current round of gaming continues until the submarine is destroyed by a depth charge or the destroyer is destroyed by a torpedo. At this point, a message appears stating whether you won or lost and whether or not the game is over. When you restart an ended game, the score is reset to zero.

Embedding SeaBattle in a Web Page

SeaBattle consists of a SeaBattle.js JavaScript file that relies on jQuery and the jQuery HotKeys plugin (discussed in Part 2 of this series). To embed this game in a Web page, include these files as shown in Listing 1.
<script type="text/javascript" src="https://code.jquery.com/jquery-1.7.2.min.js"></script><script type="text/javascript" language="javascript" src="jquery.hotkeys.js"></script>
<script type="text/javascript" src="SeaBattle.js"></script>
Listing 1: SeaBattle relies on three external JavaScript files. SeaBattle.js must be included last. Next, embed a <script>element in the page’s body that initializes SeaBattle, and repeatedly executes a function that updates game state and redraws the canvas to reflect the new state. Listing 2 shows you one way to accomplish this task.
<script type="text/javascript">// <![CDATA[
  SeaBattle.init(800, 480);

  // The following function is courtesy of Opera Engineer Erik Mіller -- see
  // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
  (function()
   {
     var lastTime = 0;
     var vendors = ['ms', 'moz', 'webkit', 'o'];
     for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x)
     {
        window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
        window.cancelRequestAnimationFrame = window[vendors[x]+'CancelRequestAnimationFrame'];
     }

     if (!window.requestAnimationFrame)
     {
       var f = function(callback, element)
               {
                 var currTime = new Date().getTime();
                 var timeToCall = Math.max(0, 16-(currTime-lastTime));
                 var id = window.setTimeout(function()
                                            {
                                              callback(currTime+timeToCall);
                                            }, timeToCall);
                 lastTime = currTime+timeToCall;
                 return id;
               };
       window.requestAnimationFrame = f;
     }

     if (!window.cancelAnimationFrame)
       window.cancelAnimationFrame = function(id)
                                     {
                                       clearTimeout(id);
                                     };
  }());

  (function gameloop()
  {
    SeaBattle.update();
    requestAnimationFrame(gameloop);
    SeaBattle.draw();
  })();
// ]]></script>
Listing 2: SeaBattle initializes and then enters an infinite update-then-draw loop. Listing 2 first initializes the pre-created SeaBattle
object by calling its init(width, height) function, which creates a <canvas> element of the specified width (800 pixels) and height (480 pixels), loads game resources, and performs other tasks. Next, a cross-browser requestAnimationFrame() function that delegates to a browser-specific function is installed. The browser function produces smoother animation by scheduling a pixel-painting callback function for invocation just before the next browser window repaint. Browsers that provide their own request animation frame functions (such as Mozilla’s mozRequestAnimationFrame() function) can automatically throttle back the frame rate when you switch to another tab. After all, there’s no point in the game running at top speed when its output isn’t visible. However, not all browsers support this feature: Internet Explorer 9 is an example. For these browsers, setInterval() is used to invoke the callback function. Regardless of which function is called, rendering occurs at up to 60 frames per second. Lastly, Listing 2 specifies and invokes a gameloop() function, which defines SeaBattle’s game loop. This function performs the following tasks:
  1. Execute SeaBattle‘s update() function to compute new game state based on user input and other factors.
  2. Execute requestAnimationFrame(gameloop) to schedule gameloop() for invocation before painting the browser window (if “requestAnimationFrame()” is supported) or at the next time point (via setTimeout()).
  3. Execute SeaBattle‘s draw() function to redraw the canvas with the updated game state.

Overviewing SeaBattle’s JavaScript Architecture

At some point, you’ll want to enhance SeaBattle, so you’ll need to understand how it works. The first step in gaining this knowledge is to grasp the object’s overall JavaScript architecture. See Listing 3.
var SeaBattle =
{
  init: function(width, height)
        {
        },

  update: function()
          {
          },

  draw: function()
        {
        },

  MAX_DC: 2,
  MAX_TORP: 15,
  STATE_INIT: 0,
  STATE_TITLE: 1,
  STATE_PLAY: 2,
  STATE_WINLOSE: 3,
  STATE_RESTART: 4,

  allResourcesLoaded: function()
                      {
                      },

  intersects: function(r1, r2)
              {
              },

  makeDepthCharge: function(bound)
                   {
                   },

  makeExplosion: function(isShip)
                 {
                 },

  makeShip: function(x, y, bound1, bound2)
            {
            },

  makeSub: function(x, y, bound1, bound2)
           {
           },

  makeTorpedo: function(bound)
               {
               },

  rnd: function(limit)
       {
       },

  supports_html5_storage: function()
                          {
                          }
}
Listing 3: SeaBattle defines 19 static properties. Additional properties are dynamically added to this object. Listing 3’s global SeaBattle object first presents a public API consisting of init(width, height)
, update(), and draw(). It then presents a private API that defines the following pseudo-constant (a variable pretending to be a constant) properties:
  • MAX_DC specifies the maximum number of depth charges that can be in play at any given time. A small value makes it harder to destroy the submarine and results in more interesting gaming. This pseudo-constant appears in init(width, height), update(), and draw().
  • MAX_TORP specifies the maximum number of torpedoes that can be in play at any given time. A larger value than the number of depth charges results in a more interesting game. This pseudo-constant appears in init(width, height), update(), and draw().
  • STATE_INIT identifies the game’s initial state. SeaBattle loads image and audio resources and displays an initialization message. The state changes to STATE_TITLE after all resources have loaded. This pseudo-constant appears in init(width, height), update(), and draw().
  • STATE_TITLE identifies the game’s title state. SeaBattle displays a message telling you to press Return to play the game. This pseudo-constant appears in update() and draw().
  • STATE_PLAY identifies the game’s play state. You interact with the game by pressing the left arrow, right arrow, and spacebar keys while SeaBattle remains in this state. This pseudo-constant appears in update() only.
  • STATE_WINLOSE identifies the game’s win/lose state. The game is set to this state after an explosion has finished, and is used to ensure that a win/lose message is displayed. This pseudo-constant appears in update() and draw().
  • STATE_RESTART identifies the game’s restart state. The game is set to this state after an explosion has finished and there are no lives left. It’s used to ensure that a “Game Over” message is displayed, to reset the score to zero, and to reset the total number of lives to four. This pseudo-constant appears in update() and draw().
The private API also defines the following function properties:
  • allResourcesLoaded() returns true when all image and audio resources have loaded; otherwise, it returns false.
  • intersects(r1, r2) returns true when the rectangle defined by r1 intersects the rectangle defined by r2; otherwise, it returns false.
  • makeDepthCharge(bound) creates a depth charge object with the specified lower bound. Depth charges disappear once they reach this bound.
  • makeExplosion(isShip) creates an explosion where isShip determines whether the ship or submarine is exploding.
  • makeShip(x, y, bound1, bound2) creates a new ship where the center location of its image is passed to x and y, and whose horizontal movement is bounded by bound1 on the left and bound2 on the right.
  • makeSub(x, y, bound1, bound2) creates a new submarine object where the center location of its image is passed to x and y, and whose horizontal movement is bounded by bound1 on the left and bound2 on the right.
  • makeTorpedo(bound) creates a torpedo with the specified upper bound. Torpedoes disappear once they reach this bound.
  • rnd(limit) returns a random integer from zero through limit-1.
  • supports_html5_storage() returns true when the browser supports the local aspect of Web storage; otherwise, it returns false.

Conclusion

SeaBattle is an example HTML5 game that leverages the Audio, Canvas, and Web Storage APIs. Now that you’ve been introduced to this game, have learned how to embed it in a Web page, and have received an architectural overview, you’re ready to move deeper. Next Friday, Part 2 begins this task by exploring the init(width, height), rnd(limit) and supports_html5_storage() functions.

Frequently Asked Questions about HTML5 Games and WordPress Integration

How can I embed HTML5 games on my WordPress site?

Embedding HTML5 games on your WordPress site is a straightforward process. First, you need to have the game’s HTML5 code. This code is usually provided by the game developer or the platform where you got the game. Once you have the code, go to your WordPress dashboard, create a new post or page, and switch to the ‘Text’ editor. Paste the HTML5 code where you want the game to appear. Click ‘Publish’ or ‘Update’ to save your changes. The game should now be visible on your site.

Can I use a plugin to embed HTML5 games on my WordPress site?

Yes, you can use a plugin to embed HTML5 games on your WordPress site. One such plugin is the ‘Embed HTML5 game WordPress plugin’ by Redfoc. This plugin allows you to easily embed HTML5 games on your site without having to manually insert the game’s code. Simply install and activate the plugin, then follow the instructions provided to embed your game.

What are some good sources for HTML5 games?

There are many sources for HTML5 games. Some popular ones include HTMLGames.com, Gamezop, and W5Games. These sites offer a wide variety of games in different genres, from puzzle and strategy games to action and adventure games. Most of these sites provide the HTML5 code for their games, which you can then embed on your WordPress site.

Can I monetize HTML5 games on my WordPress site?

Yes, you can monetize HTML5 games on your WordPress site. There are several ways to do this. One way is through advertising. You can display ads on your site and earn revenue every time a visitor clicks on an ad. Another way is through in-game purchases. Some HTML5 games allow players to buy virtual goods or premium features, and you can earn a commission from these purchases.

Are there any limitations to embedding HTML5 games on my WordPress site?

There are a few limitations to embedding HTML5 games on your WordPress site. First, not all games are compatible with all browsers or devices. Some games may not work properly on certain browsers or mobile devices. Second, some games may require a lot of bandwidth, which could slow down your site. Finally, some games may have licensing restrictions that prevent you from embedding them on your site.

How can I optimize the performance of HTML5 games on my WordPress site?

There are several ways to optimize the performance of HTML5 games on your WordPress site. First, make sure your site is running on a reliable hosting provider. Second, use a content delivery network (CDN) to deliver your game files faster. Third, optimize your game’s code to reduce its size and improve its loading speed. Finally, use a caching plugin to cache your game files and serve them faster to your visitors.

Can I customize the appearance of HTML5 games on my WordPress site?

Yes, you can customize the appearance of HTML5 games on your WordPress site. Most games allow you to change their size, background color, and other visual elements. You can usually do this by modifying the game’s HTML5 code. However, be careful not to change any essential parts of the code, as this could break the game.

Can I create my own HTML5 games for my WordPress site?

Yes, you can create your own HTML5 games for your WordPress site. There are several game development tools available, such as GameMaker, that allow you to create HTML5 games without any coding knowledge. Once you’ve created your game, you can embed it on your site using the same process as for any other HTML5 game.

Are HTML5 games safe for my WordPress site?

Yes, HTML5 games are generally safe for your WordPress site. However, like any other type of content, they can pose a risk if they come from an untrustworthy source. Always make sure to get your games from reputable sources, and scan them for malware before embedding them on your site.

Can I use HTML5 games to engage my site’s visitors?

Yes, HTML5 games can be a great way to engage your site’s visitors. Games can provide entertainment and challenge, encouraging visitors to spend more time on your site. They can also encourage social interaction, as players can share their scores or compete against each other. Finally, games can be a great way to showcase your brand or products in a fun and interactive way.

Jeff FriesenJeff Friesen
View Author

Jeff Friesen is a freelance tutor and software developer with an emphasis on Java and mobile technologies. In addition to writing Java and Android books for Apress, Jeff has written numerous articles on Java and other technologies for SitePoint, InformIT, JavaWorld, java.net, and DevSource.

HTML5 Gaming
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week