Gameplay in HTML5: Application Framework

Homework #1 review

Instructor's solution

http://EpsilonDelta.us/UW_GameplayHTML5/Homework/Solutions/1

App size and placement

Objective

Place the game in the browser window at an appropriate size.

HTML

<!DOCTYPE HTML>
<html>
...
  <body>
    <div id="game">
...
    </div>
    <script src="Loader.js"></script>
  </body>
</html>
          

CSS

body
{
    margin: 0;
    text-align: center;
}

#game
{
    position: relative;
    font-size: 20px;
    width: 40em;
    height: 24em;
    margin-left: auto;
    margin-right: auto;
    margin-top: 1em;
    background: #DFDFFF;
    color: rgb( 0, 0, 200 );
}
          

Mobile

Small screens

Mobile devices (phones & tablets) come in a variety of screen sizes, often smaller than a PC's.

Viewport

By default mobile devices render Web pages into an off-screen viewport and scale the result to fit the screen. In games we want more complete control, so we set the viewport's size to match the screen's.
  <head>
    ...
    <meta name="viewport" content="width=device-width, user-scalable=no" />
    ...
  </head>
            

CSS @media

CSS3 allows for styles that are conditional upon the size, orientation, and other features of the rendering device.
We can have our game div fill the whole window on smaller devices:
@media ( max-width: 800px )
{
    #game
    {
        width: 100%;
        height: 100%;
        margin: 0;
    }
}
            

Height fix

If you just do that, you will find that the width is OK, but the height becomes 0. That is because the containing elements determine their height dynamically. We need to fix this:
html
{
    height: 100%;
}

body
{
    ...
    height: 100%;
}
            

Example

Example 1

App screens

Objective

Display one of the app screens (splash, main menu, game, etc.), hiding the rest.

HTML

  <body>
    <div id="game">

      <div id="splashScreen" class="screen">
        Splash screen
      </div>

      <div id="mainMenu" class="screen">
        Main menu
      </div>
      .
      .
      .
    </div>
          

CSS

#game .screen
{
    position: absolute;
    width: 100%;
    height: 100%;
    z-index: 10;
    display: none;
}

#game .screen.active
{
    display: block;
}
          

JavaScript

A function to switch to a screen:
app.showScreen = function( screenId )
{
    var oldScreenDiv = $("#game .screen.active"),
        newScreenDiv = $("#" + screenId);
    if ( oldScreenDiv )
    {
        oldScreenDiv.removeClass( "active" );
    }
    newScreenDiv.addClass( "active" );
};
          
Use it to show the splash screen on start-up:
app.start = function( )
{
    app.showScreen( "splashScreen" );
};
          

Example

Example 2

Splash screen (appearance)

Objective

A title screen with some styling

HTML

      <div id="splashScreen" class="screen">
        <div class="logo">
          <h1>Beach</h1>
          <h1>Spin</h1>
        </div>
        <span class="continue">[Click to continue]</span>
      </div>
          

CSS

.logo
{
    margin-top: 4em;
    margin-bottom: 4em;
}

.logo h1
{
    font-size: 4em;
    margin: 0;
    color: rgb( 255, 255, 255 );
    text-shadow: 0.05em 0.05em 0.05em rgb( 0, 0, 200 ),
                 -0.05em -0.05em 0.05em rgb( 0, 0, 200 ),
                 0.05em -0.05em 0.05em rgb( 0, 0, 200 ),
                 -0.05em 0.05em 0.05em rgb( 0, 0, 200 ),
                 0.2em 0.2em 0.2em rgb( 0, 0, 0 );
}

#splashScreen
{
    text-align: center;
    padding-top: 0em;
}

#splashScreen .continue
{
    cursor: pointer;
    font-size: 1.5em;
}
          

Example

Example 3

Web fonts

Objective

Control look of a Web app by using fonts that may not already be on client's computer.

Sources

Format conversion

  • Web fonts is an evolving standard.
    Different browsers currently handle different formats.
  • FontSquirrel has an excellent @font-face Generator which allows you to upload a font in one format and download a .zip file with all of the important ones.
    It also generates a CSS file with the @font-face declaration. (You may need to edit it and/or copy it into your own CSS file.)

CSS

Declare the @font-face like this (assuming you have the font files, or links to them, in the font/ subdirectory):
@font-face {
    font-family: 'Text';
    src: url('fonts/capriola-regular-webfont.eot');
    src: url('fonts/capriola-regular-webfont.eot?#iefix') format('embedded-opentype'),
         url('fonts/capriola-regular-webfont.woff') format('woff'),
         url('fonts/capriola-regular-webfont.ttf') format('truetype'),
         url('fonts/capriola-regular-webfont.svg#CapriolaRegular') format('svg');
    font-weight: normal;
    font-style: normal;
}
          
The font-family value is whatever name you want to use to refer to the font. Keeping it generic allows you to make a font change in just one place.
The browser will download the first format it supports, so having several formats does not incur extra bandwidth.
Now you can use the font simply by referring to its name in your CSS:
#game
{
    ...
    font-family: "Text";
}
          

Example

Example 4

Splash screen (behavior)

Screens object

  • In addition to the DOM element, each screen will need an object with public and private variables and functions.
  • We need an object to keep references to these screen objects by name:
    app.screens = { }
  • When we switch to a screen, we run its code:
    app.showScreen = function( screenId )
    {
        var oldScreenDiv = $("#game .screen.active"),
            newScreenDiv = $("#" + screenId),
            newScreen = app.screens[ screenId ];
        if ( oldScreenDiv )
        {
            oldScreenDiv.removeClass( "active" );
        }
        newScreenDiv.addClass( "active" );
        newScreen.run( );
    };
                  

Splash screen object

app.screens[ "splashScreen" ] =
    (function()
     {
    //-------------------------------------------------------------------------

         var firstRun = true;
         
    //=========================================================================

         function run( )
         {
             if ( firstRun )
             {
                 init( );
                 firstRun = false;
             }
         }
         
    //-------------------------------------------------------------------------
         
         function init( )
         {
             $("#splashScreen").click(
                 function( event )
                 {
                     app.showScreen( "mainMenu" );
                 }
             );
         }
         
    //=========================================================================

         return {
             run: run
         };
         
    //-------------------------------------------------------------------------
     }
)();
          

Example

Example 5

Main menu

HTML

      <div id="mainMenu" class="screen">
        <div class="logo">
          <h2 class="beach">Beach</h2>
          <h2 class="spin">Spin</h2>
        </div>
        <menu>
          <li><button type="button" name="beachScreen" class="beach">Beach</button></li>
          <li><button type="button" name="spinScreen" class="spin">Spin</button></li>
          ...
        </menu>
      </div>
          

CSS

We want all of the buttons in our app to have a uniform appearance:
button
{
    font-family: "Text";
    color: rgb( 255, 255, 255 );
    background: rgb( 0, 0, 64 );
    border: 0.1em solid rgb( 0, 0, 200 );
}

button:hover
{
    background: rgb( 0, 30, 100 );
}

button:active
{
    background: rgb( 0, 30, 100 );
    border: 0.1em solid rgb( 64, 64, 255 );
}
          
A menu displays like a list (ul), but we don't want bullet points. We also need to size the buttons for this screen.
menu
{
    padding: 0;
    margin: 0;
    list-style: none;
}

menu li
{
    margin: 1em 0;
}

menu li button
{
    font-size: 1.5em;
    width: 5em;
    height: 2em;
    border-radius: 0.25em;
}
          

JavaScript

app.screens[ "mainMenu" ] =
    (function()
     {
    //-------------------------------------------------------------------------

         var firstRun = true;
         
    //=========================================================================

         function run( )
         {
             if ( firstRun )
             {
                 init( );
                 firstRun = false;
             }
         }
         
    //-------------------------------------------------------------------------
         
         function init( )
         {
             $("#mainMenu menu").click(
                 function( event )
                 {
                     var target = $(event.target),
                         screenId;
                     if ( target.is( "button" ) == false )
                         return;
                     screenId = target.attr( "name" );
                     app.showScreen( screenId );
                 }
             );
         }
         
    //=========================================================================

         return {
             run: run
         };
         
    //-------------------------------------------------------------------------
     }
)();
          

Example

Example 6

Homework #2

http://EpsilonDelta.us/UW_GameplayHTML5/Homework/Homework_2.html