Tag: kranthi

Tutorial: How To Design A Mobile Game With HTML5


  

Care to make a cross-platform mobile game with HTML5? No need to dabble in Java or Objective-C? Bypass the app stores? Sounds like an instant win!

A handful of game developers are pushing the envelope of mobile HTML5 games at the moment. Check out the likes of Nutmeg and Lunch Bug for some shining examples. The great thing about these titles is that they work equally well on both mobile and desktop using the same code. Could HTML5 finally fulfill the holy grail of “write once, run anywhere�?

Getting Started

Before you start sketching the next Temple Run or Angry Birds, you should be aware of a few things that could dampen your excitement:

  • Performance
    Mobile browsers are not traditionally known for their blazing JavaScript engines. With iOS 6 and Chrome beta for Android, though, things are improving fast.
  • Resolution
    A veritable cornucopia of Android devices sport a wide range of resolutions. Not to mention the increased resolution and pixel density of the iPhone 4 and iPad 3.
  • Audio
    Hope you enjoy the sound of silence. Audio support in mobile browsers is poor, to say the least. Lag is a major problem, as is the fact that most devices offer only a single channel. iOS won’t even load a sound until the user initiates the action. My advice is to hold tight and wait for browser vendors to sort this out.

Now, as a Web developer you’re used to dealing with the quirks of certain browsers and degrading gracefully and dealing with fragmented platforms. So, a few technical challenges won’t put you off, right? What’s more, all of these performance and audio problems are temporary. The mobile browser landscape is changing so quickly that these concerns will soon be a distant memory.

In this tutorial, we’ll make a relatively simple game that takes you through the basics and steers you away from pitfalls. The result will look like this:

Screenshot of finished demo

It’s a fairly simple game, in which the user bursts floating bubbles before they reach the top of the screen. Imaginatively, I’ve titled our little endeavour Pop.

We’ll develop this in a number of distinct stages:

  1. Cater to the multitude of viewports and optimize for mobile;
  2. Look briefly at using the canvas API to draw to the screen;
  3. Capture touch events;
  4. Make a basic game loop;
  5. Introduce sprites, or game “entities�;
  6. Add collision detection and some simple maths to spice things up;
  7. Add a bit of polish and some basic particle effects.

1. Setting The Stage

Enough of the background story. Fire up your favorite text editor, pour a strong brew of coffee, and let’s get our hands dirty.

As mentioned, there is a plethora of resolution sizes and pixel densities across devices. This means we’ll have to scale our canvas to fit the viewport. This could come at the price of a loss in quality, but one clever trick is to make the canvas small and then scale up, which provides a performance boost.

Let’s kick off with a basic HTML shim:

<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, 
    user-scalable=no, initial-scale=1, maximum-scale=1, user-scalable=0" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />

<style type="text/css">
body { margin: 0; padding: 0; background: #000;}
canvas { display: block; margin: 0 auto; background: #fff; }
</style>

</head>

<body>

<canvas> </canvas>
<script>
// all the code goes here
</script>

</body>
</html>

The meta viewport tag tells mobile browsers to disable user scaling and to render at full size rather than shrink the page down. The subsequent apple- prefixed meta tags allow the game to be bookmarked. On the iPhone, bookmarked apps do not display the toolbar at the bottom of the page, thus freeing up valuable real estate.

Take a look at the following:

// namespace our game
var POP = {

    // set up some initial values
    WIDTH: 320, 
    HEIGHT:  480, 
    // we'll set the rest of these
    // in the init function
    RATIO:  null,
    currentWidth:  null,
    currentHeight:  null,
    canvas: null,
    ctx:  null,

    init: function() {

        // the proportion of width to height
        POP.RATIO = POP.WIDTH / POP.HEIGHT;
        // these will change when the screen is resized
        POP.currentWidth = POP.WIDTH;
        POP.currentHeight = POP.HEIGHT;
        // this is our canvas element
        POP.canvas = document.getElementsByTagName('canvas')[0];
        // setting this is important
        // otherwise the browser will
        // default to 320 x 200
        POP.canvas.width = POP.WIDTH;
        POP.canvas.height = POP.HEIGHT;
        // the canvas context enables us to 
        // interact with the canvas api
        POP.ctx = POP.canvas.getContext('2d');

        // we're ready to resize
        POP.resize();

    },

    resize: function() {

        POP.currentHeight = window.innerHeight;
        // resize the width in proportion
        // to the new height
        POP.currentWidth = POP.currentHeight * POP.RATIO;

        // this will create some extra space on the
        // page, allowing us to scroll past
        // the address bar, thus hiding it.
        if (POP.android || POP.ios) {
            document.body.style.height = (window.innerHeight + 50) + 'px';
        }

        // set the new canvas style width and height
        // note: our canvas is still 320 x 480, but
        // we're essentially scaling it with CSS
        POP.canvas.style.width = POP.currentWidth + 'px';
        POP.canvas.style.height = POP.currentHeight + 'px';

        // we use a timeout here because some mobile
        // browsers don't fire if there is not
        // a short delay
        window.setTimeout(function() {
                window.scrollTo(0,1);
        }, 1);
    }

};

window.addEventListener('load', POP.init, false);
window.addEventListener('resize', POP.resize, false);

First, we create the POP namespace for our game. Being good developers, we don’t want to pollute the global namespace. In keeping good practice, we will declare all variables at the start of the program. Most of them are obvious: canvas refers to the canvas element in the HTML, and ctx enables us to access it via the JavaScript canvas API.

In POP.init, we grab a reference to our canvas element, get its context and adjust the canvas element’s dimensions to 480 × 320. The resize function, which is fired on resize and load events, adjusts the canvas’ style attribute for width and height accordingly while maintaining the ratio. Effectively, the canvas is still the same dimensions but has been scaled up using CSS. Try resizing your browser and you’ll see the canvas scale to fit.

If you tried that on your phone, you’ll notice that the address bar is still visible. Ugh! We can fix this by adding a few extra pixels to the document and then scrolling down to hide the address bar, like so:

// we need to sniff out Android and iOS
// so that we can hide the address bar in
// our resize function
POP.ua = navigator.userAgent.toLowerCase();
POP.android = POP.ua.indexOf('android') > -1 ? true : false;
POP.ios = ( POP.ua.indexOf('iphone') > -1 || POP.ua.indexOf('ipad') > -1  ) ? 
    true : false;

The code above sniffs out the user agent, flagging for Android and iOS if present. Add it at the end of POP.init, before the call to POP.resize().

Then, in the resize function, if android or ios is true, we add another 50 pixels to the document’s height — i.e. enough extra space to be able to scroll down past the address bar.

// this will create some extra space on the
// page, enabling us to scroll past
// the address bar, thus hiding it.
if (POP.android || POP.ios) {
    document.body.style.height = (window.innerHeight + 50) + 'px';
}

Notice that we do this only for Android and iOS devices; otherwise, nasty scroll bars will appear. Also, we need to delay the firing of scrollTo to make sure it doesn’t get ignored on mobile Safari.

2. A Blank Canvas

Now that we’ve scaled our canvas snuggly to the viewport, let’s add the ability to draw some shapes.

Note: In this tutorial, we’re going to stick with basic geometric shapes. iOS 5 and Chrome beta for Android can handle a lot of image sprites at a high frame rate. Try that on Android 3.2 or lower and the frame rate will drop exponentially. Luckily, there is not much overhead when drawing circles, so we can have a lot of bubbles in our game without hampering performance on older devices.

Below, we’ve added a basic Draw object that allows us to clear the screen, draw a rectangle and circle, and add some text. Nothing mind-blowing yet. Mozilla Developers Network has excellent resources as always, replete with examples for drawing to the canvas.

// abstracts various canvas operations into
// standalone functions
POP.Draw = {

    clear: function() {
        POP.ctx.clearRect(0, 0, POP.WIDTH, POP.HEIGHT);
    },

    rect: function(x, y, w, h, col) {
        POP.ctx.fillStyle = col;
        POP.ctx.fillRect(x, y, w, h);
    },

    circle: function(x, y, r, col) {
        POP.ctx.fillStyle = col;
        POP.ctx.beginPath();
        POP.ctx.arc(x + 5, y + 5, r, 0,  Math.PI * 2, true);
        POP.ctx.closePath();
        POP.ctx.fill();
    },

    text: function(string, x, y, size, col) {
        POP.ctx.font = 'bold '+size+'px Monospace';
        POP.ctx.fillStyle = col;
        POP.ctx.fillText(string, x, y);
    }

};

Our Draw object has methods for clearing the screen and drawing rectangles, circles and text. The benefit of abstracting these operations is that we don’t have to remember the exact canvas API calls, and we can now draw a circle with one line of code, rather than five.

Let’s put it to the test:

// include this at the end of POP.init function
POP.Draw.clear();
POP.Draw.rect(120,120,150,150, 'green');
POP.Draw.circle(100, 100, 50, 'rgba(255,0,0,0.5)');
POP.Draw.text('Hello World', 100, 100, 10, '#000');

Include the code above at the end of the POP.init function, and you should see a couple of shapes drawn to the canvas.

3. The Magic Touch

Just as we have the click event, mobile browsers provide methods for catching touch events.

The interesting parts of the code below are the touchstart, touchmove and touchend events. With the standard click event, we can get the coordinates from e.pageX and e.pageY. Touch events are slightly different. They contain a touches array, each element of which contains touch coordinates and other data. We only want the first touch, and we access it like so: e.touches[0].

Note: Android provides JavaScript access to multi-touch actions only since version 4.

We also call e.preventDefault(); when each event is fired to disable scrolling, zooming and any other action that would interrupt the flow of the game.

Add the following code to the POP.init function.

// listen for clicks
window.addEventListener('click', function(e) {
    e.preventDefault();
    POP.Input.set(e);
}, false);

// listen for touches
window.addEventListener('touchstart', function(e) {
    e.preventDefault();
    // the event object has an array
    // named touches; we just want
    // the first touch
    POP.Input.set(e.touches[0]);
}, false);
window.addEventListener('touchmove', function(e) {
    // we're not interested in this,
    // but prevent default behaviour
    // so the screen doesn't scroll
    // or zoom
    e.preventDefault();
}, false);
window.addEventListener('touchend', function(e) {
    // as above
    e.preventDefault();
}, false);

You probably noticed that the code above passes the event data to an Input object, which we’ve yet to define. Let’s do that now:

// + add this at the bottom of your code,
// before the window.addEventListeners
POP.Input = {

    x: 0,
    y: 0,
    tapped :false,

    set: function(data) {
        this.x = data.pageX;
        this.y = data.pageY;
        this.tapped = true; 

        POP.Draw.circle(this.x, this.y, 10, 'red');
    }

};

Now, try it out. Hmm, the circles are not appearing. A quick scratch of the head and a lightbulb moment! Because we’ve scaled the canvas, we need to account for this when mapping the touch to the screen’s position.

First, we need to subtract the offset from the coordinates.

var offsetTop = POP.canvas.offsetTop,
    offsetLeft = POP.canvas.offsetLeft;

this.x = data.pageX - offsetLeft;
this.y = data.pageY - offsetTop;

Diagram showing canvas offset relative to the browser window

Then, we need to take into account the factor by which the canvas has been scaled so that we can plot to the actual canvas (which is still 320 × 480).

var offsetTop = POP.canvas.offsetTop,
    offsetLeft = POP.canvas.offsetLeft;
    scale = POP.currentWidth / POP.WIDTH;

this.x = ( data.pageX - offsetLeft ) / scale;
this.y = ( data.pageY - offsetTop ) / scale;

Difference between CSS scaled canvas and actual dimensions

If your head is starting to hurt, a practical example should provide some relief. Imagine the player taps the 500 × 750 canvas above at 400,400. We need to translate that to 480 × 320 because, as far as the JavaScript is concerned, those are the dimensions of the canvas. So, the actual x coordinate is 400 divided by the scale; in this case, 400 ÷ 1.56 = 320.5.

Rather than calculating this on each touch event, we can calculate them after resizing. Add the following code to the start of the program, along with the other variable declarations:

    // let's keep track of scale
    // along with all initial declarations
    // at the start of the program
    scale:  1,
    // the position of the canvas
    // in relation to the screen
    offset = {top: 0, left: 0},

In our resize function, after adjusting the canvas’ width and height, we make note of the current scale and offset:

 
// add this to the resize function.
POP.scale = POP.currentWidth / POP.WIDTH;
POP.offset.top = POP.canvas.offsetTop;
POP.offset.left = POP.canvas.offsetLeft;

Now, we can use them in the set method of our POP.Input class:

 
this.x = (data.pageX - POP.offset.left) / POP.scale;
this.y = (data.pageY - POP.offset.top) / POP.scale;

4. In The Loop

A typical game loop goes something like this:

  1. Poll user input,
  2. Update characters and process collisions,
  3. Render characters on the screen,
  4. Repeat.

We could, of course, use setInterval, but there’s a shiny new toy in town named requestAnimationFrame. It promises smoother animation and is more battery-efficient. The bad news is that it’s not supported consistently across browsers. But Paul Irish has come to the rescue with a handy shim.

Let’s go ahead and add the shim to the start of our current code base.

// http://paulirish.com/2011/requestanimationframe-for-smart-animating
// shim layer with setTimeout fallback
window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       || 
          window.webkitRequestAnimationFrame || 
          window.mozRequestAnimationFrame    || 
          window.oRequestAnimationFrame      || 
          window.msRequestAnimationFrame     || 
          function( callback ){
            window.setTimeout(callback, 1000 / 60);
          };
})();

And let’s create a rudimentary game loop:

// Add this at the end of POP.init;
// it will then repeat continuously
POP.loop();

// Add the following functions after POP.init:

// this is where all entities will be moved
// and checked for collisions, etc.
update: function() {

},

// this is where we draw all the entities
render: function() {

   POP.Draw.clear(); 
},

// the actual loop
// requests animation frame,
// then proceeds to update
// and render
loop: function() {

    requestAnimFrame( POP.loop );

    POP.update();
    POP.render();
}

We call the loop at the end of POP.init. The POP.loop function in turn calls our POP.update and POP.render methods. requestAnimFrame ensures that the loop is called again, preferably at 60 frames per second. Note that we don’t have to worry about checking for input in our loop because we’re already listening for touch and click events, which is accessible through our POP.Input class.

The problem now is that our touches from the last step are immediately wiped off the screen. We need a better approach to remember what was drawn to the screen and where.

5. Spritely Will Do It

First, we add an entity array to keep track of all entities. This array will hold a reference to all touches, bubbles, particles and any other dynamic thing we want to add to the game.

// put this at start of program
entities: [],

Let’s create a Touch class that draws a circle at the point of contact, fades it out and then removes it.

POP.Touch = function(x, y) {

    this.type = 'touch';    // we'll need this later
    this.x = x;             // the x coordinate
    this.y = y;             // the y coordinate
    this.r = 5;             // the radius
    this.opacity = 1;       // initial opacity; the dot will fade out
    this.fade = 0.05;       // amount by which to fade on each game tick
    this.remove = false;    // flag for removing this entity. POP.update
                            // will take care of this

    this.update = function() {
        // reduce the opacity accordingly
        this.opacity -= this.fade; 
        // if opacity if 0 or less, flag for removal
        this.remove = (this.opacity < 0) ? true : false;
    };

    this.render = function() {
        POP.Draw.circle(this.x, this.y, this.r, 'rgba(255,0,0,'+this.opacity+')');
    };

};

The Touch class sets a number of properties when initiated. The x and y coordinates are passed as arguments, and we set the radius this.r to 5 pixels. We also set an initial opacity to 1 and the rate by which the touch fades to 0.05. There is also a remove flag that tells the main game loop whether to remove this from the entities array.

Crucially, the class has two main methods: update and render. We will call these from the corresponding part of our game loop.

We can then spawn a new instance of Touch in the game loop, and then move them via the update method:

// POP.update function
update: function() {

    var i;

    // spawn a new instance of Touch
    // if the user has tapped the screen
    if (POP.Input.tapped) {
        POP.entities.push(new POP.Touch(POP.Input.x, POP.Input.y));
        // set tapped back to false
        // to avoid spawning a new touch
        // in the next cycle
        POP.Input.tapped = false;
    }

    // cycle through all entities and update as necessary
    for (i = 0; i < POP.entities.length; i += 1) {
        POP.entities[i].update();

        // delete from array if remove property
        // flag is set to true
        if (POP.entities[i].remove) {
            POP.entities.splice(i, 1);
        }
    }

},

Basically, if POP.Input.tapped is true, then we add a new instance of POP.Touch to our entities array. We then cycle through the entities array, calling the update method for each entity. Finally, if the entity is flagged for removal, we delete it from the array.

Next, we render them in the POP.render function.

// POP.render function
render: function() {

    var i;

   POP.Draw.rect(0, 0, POP.WIDTH, POP.HEIGHT, '#036');

    // cycle through all entities and render to canvas
    for (i = 0; i < POP.entities.length; i += 1) {
        POP.entities[i].render();
    }

},

Similar to our update function, we cycle through the entities and call their render method to draw them to the screen.

So far, so good. Now we’ll add a Bubble class that will create a bubble that floats up for the user to pop.

POP.Bubble = function() {

    this.type = 'bubble';
    this.x = 100;
    this.r = 5;                // the radius of the bubble
    this.y = POP.HEIGHT + 100; // make sure it starts off screen
    this.remove = false;

    this.update = function() {

        // move up the screen by 1 pixel
        this.y -= 1;

        // if off screen, flag for removal
        if (this.y < -10) {
            this.remove = true;
        }

    };

    this.render = function() {

        POP.Draw.circle(this.x, this.y, this.r, 'rgba(255,255,255,1)');
    };

};

The POP.Bubble class is very similar to the Touch class, the main differences being that it doesn’t fade but moves upwards. The motion is achieved by updating the y position, this.y, in the update function. Here, we also check whether the bubble is off screen; if so, we flag it for removal.

Note: We could have created a base Entity class that both Touch and Bubble inherit from. But, I’d rather not open another can of worms about JavaScript prototypical inheritance versus classic at this point.

// Add at the start of the program
// the amount of game ticks until
// we spawn a bubble
nextBubble: 100,

// at the start of POP.update
// decrease our nextBubble counter
POP.nextBubble -= 1;
// if the counter is less than zero
if (POP.nextBubble < 0) {
    // put a new instance of bubble into our entities array
    POP.entities.push(new POP.Bubble());
    // reset the counter with a random value
    POP.nextBubble = ( Math.random() * 100 ) + 100;
}

Above, we have added a random timer to our game loop that will spawn an instance of Bubble at a random position. At the start of the game, we set nextBubble with a value of 100. This is subtracted on each game tick and, when it reaches 0, we spawn a bubble and reset the nextBubble counter.

6. Putting It Together

First of all, there is not yet any notion of collision detection. We can add that with a simple function. The math behind this is basic geometry, which you can brush up on at Wolfram MathWorld.

// this function checks if two circles overlap
POP.collides = function(a, b) {

        var distance_squared = ( ((a.x - b.x) * (a.x - b.x)) + 
                                ((a.y - b.y) * (a.y - b.y)));

        var radii_squared = (a.r + b.r) * (a.r + b.r);

        if (distance_squared < radii_squared) {
            return true;
        } else {
            return false;
        }
};

// at the start of POP.update, we set a flag for checking collisions
    var i,
        checkCollision = false; // we only need to check for a collision
                                // if the user tapped on this game tick

// and then incorporate into the main logic

if (POP.Input.tapped) {
    POP.entities.push(new POP.Touch(POP.Input.x, POP.Input.y));
    // set tapped back to false
    // to avoid spawning a new touch
    // in the next cycle
    POP.Input.tapped = false;
    checkCollision = true;

}

// cycle through all entities and update as necessary
for (i = 0; i < POP.entities.length; i += 1) {
    POP.entities[i].update();

    if (POP.entities[i].type === 'bubble' && checkCollision) {
        hit = POP.collides(POP.entities[i], 
                            {x: POP.Input.x, y: POP.Input.y, r: 7});
        POP.entities[i].remove = hit;
    }

    // delete from array if remove property
    // is set to true
    if (POP.entities[i].remove) {
        POP.entities.splice(i, 1);
    }
}

The bubbles are rather boring; they all travel at the same speed on a very predictable trajectory. Making the bubbles travel at random speeds is a simple task:

POP.Bubble = function() {

    this.type = 'bubble';
    this.r = (Math.random() * 20) + 10;
    this.speed = (Math.random() * 3) + 1;

    this.x = (Math.random() * (POP.WIDTH) - this.r);
    this.y = POP.HEIGHT + (Math.random() * 100) + 100;

    this.remove = false;

    this.update = function() {

        this.y -= this.speed;

    // the rest of the class is unchanged

And let’s make them oscillate from side to side, so that they are harder to hit:

    // the amount by which the bubble
    // will move from side to side
    this.waveSize = 5 + this.r;
    // we need to remember the original
    // x position for our sine wave calculation
    this.xConstant = this.x;

    this.remove = false;

    this.update = function() {

        // a sine wave is commonly a function of time
        var time = new Date().getTime() * 0.002;

        this.y -= this.speed;
        // the x coordinate to follow a sine wave
        this.x = this.waveSize * Math.sin(time) + this.xConstant;

    // the rest of the class is unchanged

Again, we’re using some basic geometry to achieve this effect; in this case, a sine wave. While you don’t need to be a math whiz to make games, basic understanding goes a long way. The article “A Quick Look Into the Math of Animations With JavaScript� should get you started.

Let’s also show some statistics on screen. To do this, we will need to track various actions throughout the game.

Put the following code, along with all of the other variable declarations, at the beginning of the program.

// this goes at the start of the program
// to track players's progress
POP.score = {
    taps: 0,
    hit: 0,
    escaped: 0,
    accuracy: 0
},

Now, in the Bubble class we can keep track of POP.score.escaped when a bubble goes off screen.

// in the bubble class, when a bubble makes it to
// the top of the screen
    if (this.y < -10) {
        POP.score.escaped += 1; // update score
        this.remove = true;
    }

In the main update loop, we increase POP.score.hit accordingly:

// in the update loop
if (POP.entities[i].type === 'bubble' && checkCollision) {
    hit = POP.collides(POP.entities[i], 
                        {x: POP.Input.x, y: POP.Input.y, r: 7});
    if (hit) {
        POP.score.hit += 1;
    }

    POP.entities[i].remove = hit;
}

In order for the statistics to be accurate, we need to record all of the taps the user makes:

// and record all taps
if (POP.Input.tapped) {
    // keep track of taps; needed to 
    // calculate accuracy
    POP.score.taps += 1;

Accuracy is obtained by dividing the number of hits by the number of taps, multiplied by 100, which gives us a nice percentage. Note that ~~(POP.score.accuracy) is a quick way (i.e. a hack) to round floats down to integers.

// Add at the end of the update loop
// to calculate accuracy
POP.score.accuracy = (POP.score.hit / POP.score.taps) * 100;
POP.score.accuracy = isNaN(POP.score.accuracy) ?
    0 :
    ~~(POP.score.accuracy); // a handy way to round floats

Lastly, we use our POP.Draw.text to display the scores in the main update function.

// and finally in the draw function
POP.Draw.text('Hit: ' + POP.score.hit, 20, 30, 14, '#fff');
POP.Draw.text('Escaped: ' + POP.score.escaped, 20, 50, 14, '#fff');
POP.Draw.text('Accuracy: ' + POP.score.accuracy + '%', 20, 70, 14, '#fff');

7. Spit And Polish

There’s a common understanding that a playable demo can be made in a couple of hours, but a polished game takes days, week, months or even years!

We can do a few things to improve the visual appeal of the game.

Particle Effects

Most games boast some form of particle effects, which are great for explosions. What if we made a bubble explode into many tiny bubbles when it is popped, rather than disappear instantly?

Take a look at our Particle class:

POP.Particle = function(x, y,r, col) {

    this.x = x;
    this.y = y;
    this.r = r;
    this.col = col;

    // determines whether particle will
    // travel to the right of left
    // 50% chance of either happening
    this.dir = (Math.random() * 2 > 1) ? 1 : -1;

    // random values so particles do not
    // travel at the same speeds
    this.vx = ~~(Math.random() * 4) * this.dir;
    this.vy = ~~(Math.random() * 7);

    this.remove = false;

    this.update = function() {

        // update coordinates
        this.x += this.vx;
        this.y += this.vy;

        // increase velocity so particle
        // accelerates off screen
        this.vx *= 0.99;
        this.vy *= 0.99;

        // adding this negative amount to the
        // y velocity exerts an upward pull on
        // the particle, as if drawn to the
        // surface
        this.vy -= 0.25;

        // off screen
        if (this.y < 0) {
            this.remove = true;
        }

    };

    this.render = function() {
        POP.Draw.circle(this.x, this.y, this.r, this.col);
    };

};

It’s fairly obvious what is going on here. Using some basic acceleration so that the particles speed up as the reach the surface is a nice touch. Again, this math and physics are beyond the scope of this article, but for those interested, Skookum Digital Works explains it in depth.

To create the particle effect, we push several particles into our entities array whenever a bubble is hit:

// modify the main update function like so:
if (hit) {
    // spawn an explosion
    for (var n = 0; n < 5; n +=1 ) {
        POP.entities.push(new POP.Particle(
            POP.entities[i].x, 
            POP.entities[i].y, 
            2, 
            // random opacity to spice it up a bit
            'rgba(255,255,255,'+Math.random()*1+')'
        )); 
    }
    POP.score.hit += 1;
}

Waves

Given the underwater theme of the game, adding a wave effect to the top of the screen would be a nice touch. We can do this by drawing a number of overlapping circles to give the illusion of waves:

// set up our wave effect;
// basically, a series of overlapping circles
// across the top of screen
POP.wave = {
    x: -25, // x coordinate of first circle
    y: -40, // y coordinate of first circle
    r: 50, // circle radius
    time: 0, // we'll use this in calculating the sine wave
    offset: 0 // this will be the sine wave offset
}; 
// calculate how many circles we need to 
// cover the screen's width
POP.wave.total = Math.ceil(POP.WIDTH / POP.wave.r) + 1;

Add the code above to the POP.init function. POP.wave has a number of values that we’ll need to draw the waves.

Add the following to the main update function. It uses a sine wave to adjust the position of the waves and give the illusion of movement.

// update wave offset
// feel free to play with these values for
// either slower or faster waves
POP.wave.time = new Date().getTime() * 0.002;
POP.wave.offset = Math.sin(POP.wave.time * 0.8) * 5;

All that’s left to be done is to draw the waves, which goes into the render function.

// display snazzy wave effect
for (i = 0; i < POP.wave.total; i++) {

    POP.Draw.circle(
                POP.wave.x + POP.wave.offset +  (i * POP.wave.r), 
                POP.wave.y,
                POP.wave.r, 
                '#fff'); 
}

Here, we’ve reused our sine wave solution for the bubbles to make the waves move gently to and fro. Feeling seasick yet?

Final Thoughts

Phew! That was fun. Hope you enjoyed this short forage into tricks and techniques for making an HTML5 game. We’ve managed to create a very simple game that works on most smartphones as well as modern browsers. Here are some things you could consider doing:

  • Store high scores using local storage.
  • Add a splash screen and a “Game overâ€� screen.
  • Enable power-ups.
  • Add audio. Contrary to what I said at the beginning of this article, this isn’t impossible, just a bit of a headache. One technique is to use audio sprites (kind of like CSS image sprites); Remy Sharp breaks it down.
  • Let your imagination run wild!

If you are interested in further exploring the possibilities of mobile HTML5 games, I recommend test-driving a couple of frameworks to see what works for you. Juho Vepsäläinen offers a useful summary of most game engines. If you’re willing to invest a little cash, then Impact is a great starting point, with thorough documentation and lively helpful forums. And the impressive X-Type demonstrates what is possible. Not bad, eh?

(al) (jc)


© Eoin McGrath for Smashing Magazine, 2012.


Community Strength: The Immersive Web And Design Writing


  

I have an idea for a new product — can I tell you about it? It will take months to develop, and even though this kind of thing is usually given away for free, I’m going to charge for it. Oh, and the market for it probably won’t be very big… Wait, come back! Where are you going?!

It does sound like a crazy idea, but it’s exactly what a small group of designers and writers have been doing for the past year or so. On a Web littered with SEO-ified headlines (“17 Jaw-Dropping Responsive Design Templates and Funny Cat Pictures�), easy-to-share design gallery slideshows and quick tutorials that help you recreate the latest texture fetish in Photoshop, these people are taking a step back from what we have now come to refer to as the “fast Web.� In the words of Jack Cheng:

“What is the Fast Web? It’s the out of control Web. The oh my god there’s so much stuff and I can’t possibly keep up Web. It’s the spend two dozen times a day checking Web. The in one end out the other Web. The Web designed to appeal to the basest of our intellectual palettes, the salt, sugar and fat of online content Web. It’s the scale hard and fast Web. The create a destination for billions of people Web. The you have two hundred twenty six new updates Web. Keep up or be lost. Click me. Like me. Tweet me. Share me. The Fast Web demands that you do things and do them now. The Fast Web is a cruel wonderland of shiny shiny things.”

Slow Web
(Image: Jack Cheng)

A new wave of publications are avoiding this trap, and they appear almost quaint or old school compared to the fast Web. Or worse, as n+1 magazine points out:

“But all contemporary publications tend toward the condition of blogs, and soon, if not yet already, it will seem pretentious, elitist, and old-fashioned to write anything, anywhere, with patience and care.”

I’m talking about collaborative print and digital publications such as The Manual, Distance, Codex, 8 Faces and Ferocious, and even books such as Frank Chimero’s The Shape of Design. These publications all have two things in common:

  • First, they’re about the meaning of creativity and design, more than they are about the doing of these things.
  • Secondly, they are written with patience and care, and they are designed to be read and enjoyed in the same way.

This kind of thing is, admittedly, a hard sell. There are two main reasons for this.

First, we’re not trained to spend time doing things with patience and care on the Web. As Robin Sloan points out in his brilliant essay “Fish�:

“On the internet today, reading something twice is an act of love.”

And the reason for this is that we’re being fed junk food, and we love it. Clay Johnson talks about this in his book The Information Diet:

“Driven by a desire for more profits, and for wider audiences, our media companies look to produce information as cheaply as possible. As a result, they provide affirmation and sensationalism over balanced information. […] Just as food companies learned that if they want to sell a lot of cheap calories, they should pack them with salt, fat, and sugar — the stuff that people crave — media companies learned that affirmation sells a lot better than information. Who wants to hear the truth when they can hear that they’re right?”

So, instead of looking for nutrition, we settle for the quick fast-food rush. Short articles fit nicely into lunchtime breaks. They don’t distract us from the Twitter feed long enough for us to lose track of the day’s most important discussions. Most of all, this bite-sized information effectively manages one of our biggest fears: the sunk cost phenomenon, whereby we worry that if we “waste� time on a long piece of writing, we can never get that time back to do something else instead.

Secondly, convincing people to care about why they do something is much harder than getting them to learn how to do it. One is about meaning, the other is about doing. And only one of these things brings cash directly into the bank account. As Frank Chimero points out in The Shape of Design:

“The relationship between form and purpose — How and Why — is symbiotic. But despite this link, Why is usually neglected, because How is more easily framed. It is easier to recognize failures of technique than those of strategy or purpose, and simpler to ask “How do I paint this tree?â€� than to answer “Why does this painting need a tree in it?â€� The How question is about a task, while the Why question regards the objective of the work. If an artist or designer understands the objective, he can move in the right direction, even if there are missteps along the way. But if those objectives are left unaddressed, he may find himself chasing his own tail, even if the craft of the final work is extraordinary.”

The irony in all of this is that taking a break from doing, to look slowly and carefully at why we do things and how they fit into the world around us, will almost certainly make us better at the doing part. All creative pursuits have importance and meaning only through their audience, so understanding that audience and the world it operates in is an essential ingredient in our craft.

At least, that’s what I think. But I could be wrong. So, to find out more, I got in touch with some of the publishers who work on these publications and asked them a series of questions about what they’re doing and why they’re doing it. What follows are excerpts from email discussions with the following publishers:

Why should you care about what these people have to say? The purpose of this article is not to convince you to stop reading articles that help you learn the techniques of your craft. Its purpose is to make the case for a more balanced information diet, with which we all take the time to nourish the parts of our brain that give us much-needed context to understand and effectively use the techniques that we see in galleries and tutorials. So, let’s get to it.

Q: What made you start your publication? Why do you think it’s important to do?

Andy McMillan: “For the past two decades, we’ve done an incredible job as a community of discussing, debating and sharing, all of which has contributed to driving our techniques and technologies forward at a staggering pace. This is the energy that provided us with the Web standards movement, and I would argue we’re on the cusp of another major shift. Web design is beginning to define itself as less of a technical skill, but rather as a mature and distinct design discipline.

“Our extraordinary passion for prototyping, experimenting, documenting and sharing the how has gotten us to where we are today. But we believe that as Web design matures as a discipline, there is an additional requirement for greater discussion around the why of what we do. The manual aims to give a home to deeper explorations of our work through sharing stories behind the why of Web design and who we are as designers.�

The Manual
The Manual, Image: Andy McMillan)

Nick Disabato: “I started figuring out the ideas behind Distance in April 2011, when I noticed a few problems in design writing. Most long-form stuff was either hyperbolic and incendiary, thin on citation and high on personal opinion, or it involved this hand-wavy, un-actionable “it dependsâ€� kind of conclusion. But it’s possible for writing to take a confident stand without turning into flame bait — by providing justification and offering a way forward. Otherwise, we risk losing something tremendously important about the exchange of meaningful ideas. This is the gap that Distance hopes to help fill.â€�

John Boardley: “I started I Love Typography, We Love Typography and Codex all for the same reason: they are ways to share my obsession with typography. I never imagined that these projects would become so popular. I had no grand plan. And that reminds me: I still don’t. I think these projects are important simply because type matters. And type matters because words matter — whether they are words that inspire (in prose or poetry), words that guide us (wayfinding), beseech, implore, persuade (advertising) — they all matter. Beyond the fundamentals of legibility and readability, the choice of typeface and the typography, the mise en page, imbue those words with a voice beyond words, with a personality that sets the scene. The choice of typefaces is analogous to the music score for a movie — the very same scene made more sober, more exuberant, more frightening, more comical, more beautiful, more inspiring, simply through the accompanying music score.â€�

Codex
Codex, Image: John Boardley)

Q: What have been some of the biggest challenges in getting it off the ground?

Nick: “It’s been challenging to have no idea what I am doing. Let’s say you have this principle: you believe that online discourse is degrading, and that design writing could do better by being slower, more thoughtful and more focused on research. How do you work in a way that fulfills that principle? You’d probably get others involved, because leading by example often carves a niche vacuum on the Internet. It probably involves writing; actually, it probably involves long writing. In order to keep the scope from getting too insane, you’d probably want to constrain it somehow.

“But that’s only the beginning of an avalanche of questions. How do you execute on it? How do authors react to a hands-on editor? How do you make money? Do you sell digital, print or both? How do you market it? How do you conduct outreach without coming off as a shameless, desperate Willy Loman type? How do you handle fulfillment on the print editions?

“All that for well-researched essays about design and technology. Each one of those questions needs to be addressed, because each one is critical to the final success. Every day is a new challenge, a new step forward — all done with the risk that it may never pay off (figuratively and literally).â€�

Distance
Distance, Image: Brent Knepper)

John: “Launching Codex was quite different from launching the blog projects. It necessitated hiring a small team, paying a small team, finding advertisers and sponsors, commissioning articles, finding a printer, a distributor, choosing paper, doing art direction — the list is endless. I guess the biggest challenge is finding the right collaborators — those who share your vision and those who you can work with night and day without wanting to put a hit out on them.â€�

Andy: “Of course, it’s been a lot of hard work, but I think a lot of what we might have considered initially “challenging� was negated by having the first issue funded through Kickstarter. While Kickstarter is a great tool for pre-selling an idea into reality, it’s really much more valuable as a tool for gauging interest and support. While we thought The Manual should exist, and friends agreed, we needed the support of the Web design community at large to know there was demand for a publication like this. Having The Manual successfully funded through Kickstarter let us know that it was something the community wanted, too.

“While there are always a lot of challenges that come with each issue, it’s always worth it in the end. What we have so far are three beautiful books, with some of the strongest editorial ever written about designing for the Web by some of the most exceptionally talented people in our field. We’re incredibly proud of what we’ve produced so far.�

Q: What are some of the high points you’ve experienced throughout the process?

Nick: “The past year of my life has been a ridiculous emotional roller coaster. I haven’t felt “meh� about anything in a very long time. You know the stereotype about startup life being prone to intense mood swings? That applies to Distance, too.

“We funded our beginnings on Kickstarter. Our campaign was funded on a Friday afternoon in the dead of winter, a couple of hours before I was about to leave work and go to a gallery show that many of my friends were exhibiting in. After trudging through snow for a mile, my girlfriend and I walked inside to cheering and hugs in a packed room. I couldn’t have asked for a better way to celebrate.

“Receiving a first draft never gets old. Watching an essay come together is intensely gratifying and humbling. I wouldn’t trade it for the world. I throw down everything every single time one hits my inbox. One time I excused myself from a bar at 2:00 am to read the whole thing outside, without a jacket, in the middle of winter, drunk and shivering.

“And then, of course, taking a shipment of the print edition feels amazing. Carrying 25 boxes full of six months’ hard work by several people is a big catharsis.�

Andy: “One of my all-time favorite memories will always be opening the first box of the first shipment of the first issue and holding it in my hands for the first time. As someone who had, up until that point, only created by pushed pixels and writing code, there was an immense satisfaction of seeing months of work distilled into a single physical artefact. All the writing, editing, production, discussions, emails, to-do lists, Skype calls, arguments, debates, victories and celebrations — every one of them was contained in this thing I was holding in my hand.

“I get emails every day from people who have read The Manual for the first time, telling me it’s changed how they view their work, or motivated them to think differently, or led them to try something different. I’ll never get tired of receiving and replying to those emails. It’s been immensely satisfying to know we’re having that kind of impact with people.�

The Manual
The Manual, Image: Andy McMillan)

Q: What is the purpose behind the publications? What would you like people to do once they’ve read it?

John: “To be frank, purpose is not something I give much thought to. I enjoy making things. If people find value in what I’ve created, then the purpose comes ex post facto. I’ve always believed that if you have the opportunity, you should create what you want. There is no guarantee that what you create will find a large audience, but if it does, then you’ve had your cake and eaten it, so to speak.

“Share your passions passionately; never be condescending; don’t ever present yourself as an expert (let others be the judges of that). Again, when it comes to what I would like people to do once they’ve read I Love Typography or Codex, well, I’d hope that they come out with a richer appreciation of typography; but I have no roadmap for where they should head next. That is best determined by the reader.�

Nick: “I hope people learn from our essays, so that they can be more thoughtful and considerate in their own work. It would also be great if Distance inspired somebody to write a long essay of their own: this model isn’t exactly proprietary, and I happily invite others to participate.

“And if our readers disagree with anything, they should critique the essays. Tell us what you think is wrong about them and what could be done to improve them. We all have blogs — there’s no excuse. And we’d love to hear from you; our essays aren’t complete without your thoughts.â€�

Distance
Distance, Image: Brent Knepper)

Andy: “We’re proud to be part of the conversation, to be contributing to and encouraging further discourse about what it is we do and why exactly we do it. We like to think we’re giving a home to more ideas and contributing to the intelligent, critical thinking around our design discipline.

“This is a conversation that’s been stewing and bubbling up for a good while now, and we’re proud to give a home to part of it. What we hope people do once they’ve read The Manual is to continue doing what we’ve always done as designers of the Web: discuss, debate and share and, by doing so, continue to drive us forward.�

Conclusion

As I wrote and edited this article, reading through the responses over and over, it struck me how lucky we are to work in an industry and at a time where there is so much passion for the work we do. It is inspiring to realize that these authors and publishers do what they do without knowing whether their projects will succeed. And then it all came full circle as it dawned on me that it is up to us as a community to help them succeed, not just by supporting their projects, but by allowing their passion and the words they put out into the world to encourage us to do something about the topics we obsess over every day.

So, maybe what I initially thought was an article about design publications is actually an article about all of us instead. The point is not just that we should have a balanced information diet, but that the real power of that balanced diet lies in the energy it gives us to get started on our own projects. Seek out these nutritious words. You won’t regret it.

(il al)


© Rian van der Merwe for Smashing Magazine, 2012.


Community Strength: The Immersive Web And Design Writing


  

I have an idea for a new product — can I tell you about it? It will take months to develop, and even though this kind of thing is usually given away for free, I’m going to charge for it. Oh, and the market for it probably won’t be very big… Wait, come back! Where are you going?!

It does sound like a crazy idea, but it’s exactly what a small group of designers and writers have been doing for the past year or so. On a Web littered with SEO-ified headlines (“17 Jaw-Dropping Responsive Design Templates and Funny Cat Pictures�), easy-to-share design gallery slideshows and quick tutorials that help you recreate the latest texture fetish in Photoshop, these people are taking a step back from what we have now come to refer to as the “fast Web.� In the words of Jack Cheng:

“What is the Fast Web? It’s the out of control Web. The oh my god there’s so much stuff and I can’t possibly keep up Web. It’s the spend two dozen times a day checking Web. The in one end out the other Web. The Web designed to appeal to the basest of our intellectual palettes, the salt, sugar and fat of online content Web. It’s the scale hard and fast Web. The create a destination for billions of people Web. The you have two hundred twenty six new updates Web. Keep up or be lost. Click me. Like me. Tweet me. Share me. The Fast Web demands that you do things and do them now. The Fast Web is a cruel wonderland of shiny shiny things.”

Slow Web
(Image: Jack Cheng)

A new wave of publications are avoiding this trap, and they appear almost quaint or old school compared to the fast Web. Or worse, as n+1 magazine points out:

“But all contemporary publications tend toward the condition of blogs, and soon, if not yet already, it will seem pretentious, elitist, and old-fashioned to write anything, anywhere, with patience and care.”

I’m talking about collaborative print and digital publications such as The Manual, Distance, Codex, 8 Faces and Ferocious, and even books such as Frank Chimero’s The Shape of Design. These publications all have two things in common:

  • First, they’re about the meaning of creativity and design, more than they are about the doing of these things.
  • Secondly, they are written with patience and care, and they are designed to be read and enjoyed in the same way.

This kind of thing is, admittedly, a hard sell. There are two main reasons for this.

First, we’re not trained to spend time doing things with patience and care on the Web. As Robin Sloan points out in his brilliant essay “Fish�:

“On the internet today, reading something twice is an act of love.”

And the reason for this is that we’re being fed junk food, and we love it. Clay Johnson talks about this in his book The Information Diet:

“Driven by a desire for more profits, and for wider audiences, our media companies look to produce information as cheaply as possible. As a result, they provide affirmation and sensationalism over balanced information. […] Just as food companies learned that if they want to sell a lot of cheap calories, they should pack them with salt, fat, and sugar — the stuff that people crave — media companies learned that affirmation sells a lot better than information. Who wants to hear the truth when they can hear that they’re right?”

So, instead of looking for nutrition, we settle for the quick fast-food rush. Short articles fit nicely into lunchtime breaks. They don’t distract us from the Twitter feed long enough for us to lose track of the day’s most important discussions. Most of all, this bite-sized information effectively manages one of our biggest fears: the sunk cost phenomenon, whereby we worry that if we “waste� time on a long piece of writing, we can never get that time back to do something else instead.

Secondly, convincing people to care about why they do something is much harder than getting them to learn how to do it. One is about meaning, the other is about doing. And only one of these things brings cash directly into the bank account. As Frank Chimero points out in The Shape of Design:

“The relationship between form and purpose — How and Why — is symbiotic. But despite this link, Why is usually neglected, because How is more easily framed. It is easier to recognize failures of technique than those of strategy or purpose, and simpler to ask “How do I paint this tree?â€� than to answer “Why does this painting need a tree in it?â€� The How question is about a task, while the Why question regards the objective of the work. If an artist or designer understands the objective, he can move in the right direction, even if there are missteps along the way. But if those objectives are left unaddressed, he may find himself chasing his own tail, even if the craft of the final work is extraordinary.”

The irony in all of this is that taking a break from doing, to look slowly and carefully at why we do things and how they fit into the world around us, will almost certainly make us better at the doing part. All creative pursuits have importance and meaning only through their audience, so understanding that audience and the world it operates in is an essential ingredient in our craft.

At least, that’s what I think. But I could be wrong. So, to find out more, I got in touch with some of the publishers who work on these publications and asked them a series of questions about what they’re doing and why they’re doing it. What follows are excerpts from email discussions with the following publishers:

Why should you care about what these people have to say? The purpose of this article is not to convince you to stop reading articles that help you learn the techniques of your craft. Its purpose is to make the case for a more balanced information diet, with which we all take the time to nourish the parts of our brain that give us much-needed context to understand and effectively use the techniques that we see in galleries and tutorials. So, let’s get to it.

Q: What made you start your publication? Why do you think it’s important to do?

Andy McMillan: “For the past two decades, we’ve done an incredible job as a community of discussing, debating and sharing, all of which has contributed to driving our techniques and technologies forward at a staggering pace. This is the energy that provided us with the Web standards movement, and I would argue we’re on the cusp of another major shift. Web design is beginning to define itself as less of a technical skill, but rather as a mature and distinct design discipline.

“Our extraordinary passion for prototyping, experimenting, documenting and sharing the how has gotten us to where we are today. But we believe that as Web design matures as a discipline, there is an additional requirement for greater discussion around the why of what we do. The manual aims to give a home to deeper explorations of our work through sharing stories behind the why of Web design and who we are as designers.�

The Manual
The Manual, Image: Andy McMillan)

Nick Disabato: “I started figuring out the ideas behind Distance in April 2011, when I noticed a few problems in design writing. Most long-form stuff was either hyperbolic and incendiary, thin on citation and high on personal opinion, or it involved this hand-wavy, un-actionable “it dependsâ€� kind of conclusion. But it’s possible for writing to take a confident stand without turning into flame bait — by providing justification and offering a way forward. Otherwise, we risk losing something tremendously important about the exchange of meaningful ideas. This is the gap that Distance hopes to help fill.â€�

John Boardley: “I started I Love Typography, We Love Typography and Codex all for the same reason: they are ways to share my obsession with typography. I never imagined that these projects would become so popular. I had no grand plan. And that reminds me: I still don’t. I think these projects are important simply because type matters. And type matters because words matter — whether they are words that inspire (in prose or poetry), words that guide us (wayfinding), beseech, implore, persuade (advertising) — they all matter. Beyond the fundamentals of legibility and readability, the choice of typeface and the typography, the mise en page, imbue those words with a voice beyond words, with a personality that sets the scene. The choice of typefaces is analogous to the music score for a movie — the very same scene made more sober, more exuberant, more frightening, more comical, more beautiful, more inspiring, simply through the accompanying music score.â€�

Codex
Codex, Image: John Boardley)

Q: What have been some of the biggest challenges in getting it off the ground?

Nick: “It’s been challenging to have no idea what I am doing. Let’s say you have this principle: you believe that online discourse is degrading, and that design writing could do better by being slower, more thoughtful and more focused on research. How do you work in a way that fulfills that principle? You’d probably get others involved, because leading by example often carves a niche vacuum on the Internet. It probably involves writing; actually, it probably involves long writing. In order to keep the scope from getting too insane, you’d probably want to constrain it somehow.

“But that’s only the beginning of an avalanche of questions. How do you execute on it? How do authors react to a hands-on editor? How do you make money? Do you sell digital, print or both? How do you market it? How do you conduct outreach without coming off as a shameless, desperate Willy Loman type? How do you handle fulfillment on the print editions?

“All that for well-researched essays about design and technology. Each one of those questions needs to be addressed, because each one is critical to the final success. Every day is a new challenge, a new step forward — all done with the risk that it may never pay off (figuratively and literally).â€�

Distance
Distance, Image: Brent Knepper)

John: “Launching Codex was quite different from launching the blog projects. It necessitated hiring a small team, paying a small team, finding advertisers and sponsors, commissioning articles, finding a printer, a distributor, choosing paper, doing art direction — the list is endless. I guess the biggest challenge is finding the right collaborators — those who share your vision and those who you can work with night and day without wanting to put a hit out on them.â€�

Andy: “Of course, it’s been a lot of hard work, but I think a lot of what we might have considered initially “challenging� was negated by having the first issue funded through Kickstarter. While Kickstarter is a great tool for pre-selling an idea into reality, it’s really much more valuable as a tool for gauging interest and support. While we thought The Manual should exist, and friends agreed, we needed the support of the Web design community at large to know there was demand for a publication like this. Having The Manual successfully funded through Kickstarter let us know that it was something the community wanted, too.

“While there are always a lot of challenges that come with each issue, it’s always worth it in the end. What we have so far are three beautiful books, with some of the strongest editorial ever written about designing for the Web by some of the most exceptionally talented people in our field. We’re incredibly proud of what we’ve produced so far.�

Q: What are some of the high points you’ve experienced throughout the process?

Nick: “The past year of my life has been a ridiculous emotional roller coaster. I haven’t felt “meh� about anything in a very long time. You know the stereotype about startup life being prone to intense mood swings? That applies to Distance, too.

“We funded our beginnings on Kickstarter. Our campaign was funded on a Friday afternoon in the dead of winter, a couple of hours before I was about to leave work and go to a gallery show that many of my friends were exhibiting in. After trudging through snow for a mile, my girlfriend and I walked inside to cheering and hugs in a packed room. I couldn’t have asked for a better way to celebrate.

“Receiving a first draft never gets old. Watching an essay come together is intensely gratifying and humbling. I wouldn’t trade it for the world. I throw down everything every single time one hits my inbox. One time I excused myself from a bar at 2:00 am to read the whole thing outside, without a jacket, in the middle of winter, drunk and shivering.

“And then, of course, taking a shipment of the print edition feels amazing. Carrying 25 boxes full of six months’ hard work by several people is a big catharsis.�

Andy: “One of my all-time favorite memories will always be opening the first box of the first shipment of the first issue and holding it in my hands for the first time. As someone who had, up until that point, only created by pushed pixels and writing code, there was an immense satisfaction of seeing months of work distilled into a single physical artefact. All the writing, editing, production, discussions, emails, to-do lists, Skype calls, arguments, debates, victories and celebrations — every one of them was contained in this thing I was holding in my hand.

“I get emails every day from people who have read The Manual for the first time, telling me it’s changed how they view their work, or motivated them to think differently, or led them to try something different. I’ll never get tired of receiving and replying to those emails. It’s been immensely satisfying to know we’re having that kind of impact with people.�

The Manual
The Manual, Image: Andy McMillan)

Q: What is the purpose behind the publications? What would you like people to do once they’ve read it?

John: “To be frank, purpose is not something I give much thought to. I enjoy making things. If people find value in what I’ve created, then the purpose comes ex post facto. I’ve always believed that if you have the opportunity, you should create what you want. There is no guarantee that what you create will find a large audience, but if it does, then you’ve had your cake and eaten it, so to speak.

“Share your passions passionately; never be condescending; don’t ever present yourself as an expert (let others be the judges of that). Again, when it comes to what I would like people to do once they’ve read I Love Typography or Codex, well, I’d hope that they come out with a richer appreciation of typography; but I have no roadmap for where they should head next. That is best determined by the reader.�

Nick: “I hope people learn from our essays, so that they can be more thoughtful and considerate in their own work. It would also be great if Distance inspired somebody to write a long essay of their own: this model isn’t exactly proprietary, and I happily invite others to participate.

“And if our readers disagree with anything, they should critique the essays. Tell us what you think is wrong about them and what could be done to improve them. We all have blogs — there’s no excuse. And we’d love to hear from you; our essays aren’t complete without your thoughts.â€�

Distance
Distance, Image: Brent Knepper)

Andy: “We’re proud to be part of the conversation, to be contributing to and encouraging further discourse about what it is we do and why exactly we do it. We like to think we’re giving a home to more ideas and contributing to the intelligent, critical thinking around our design discipline.

“This is a conversation that’s been stewing and bubbling up for a good while now, and we’re proud to give a home to part of it. What we hope people do once they’ve read The Manual is to continue doing what we’ve always done as designers of the Web: discuss, debate and share and, by doing so, continue to drive us forward.�

Conclusion

As I wrote and edited this article, reading through the responses over and over, it struck me how lucky we are to work in an industry and at a time where there is so much passion for the work we do. It is inspiring to realize that these authors and publishers do what they do without knowing whether their projects will succeed. And then it all came full circle as it dawned on me that it is up to us as a community to help them succeed, not just by supporting their projects, but by allowing their passion and the words they put out into the world to encourage us to do something about the topics we obsess over every day.

So, maybe what I initially thought was an article about design publications is actually an article about all of us instead. The point is not just that we should have a balanced information diet, but that the real power of that balanced diet lies in the energy it gives us to get started on our own projects. Seek out these nutritious words. You won’t regret it.

(il al)


© Rian van der Merwe for Smashing Magazine, 2012.


Removing whitespace around text fields

Trying to be pixel perfect on the Web is like begging to be frustrated. I try to not worry so much about a pixel here or there, but sometimes you just have to get complete control to make things look right.

Until recently I had never paid any special attention to the exact amount of whitespace some browsers create around textarea and input[type="text"] elements, but then I started implementing a design that required there to be exactly no whitespace around them. And I noticed that browser behaviour differs a bit here, so I needed to find a fix.

Read full post

Posted in .

Copyright © Roger Johansson


The Infinite Grid

The Infinite Grid

Grid systems are a key component of graphic design, but they’ve always been designed for canvases with fixed dimensions. Until now. Today we’re designing for a medium that has no fixed dimensions, a medium that can and will shape-shift to better suit its environment—a medium capable of displaying a single layout on a smartphone, a billboard in Times Square, and everything in between.

We’re designing for an infinite canvas—and for that, we need an infinite grid system.

It’s common to think of responsive design as multiple layouts: mobile, tablet, desktop, etc. The problem is the “in-between� sizes tend to suffer, so we end up with layouts that look great at specific dimensions (320, 720, 960), but less than great for everything else. So while a site may look perfect on your 640x960 iPhone 4, it’s going to be a bit off on a visitor’s Nokia Lumia (480x800), or the 685x308 browser window you have open on your desktop. It might even look a little off on that shiny new iPhone 5 (640x1136) your cousin just bought, not to mention the countless other older or less-popular devices out there.

As the spectrum of device resolutions gets wider and smoother, focusing all our attention on “key dimensions� for each page is going to result in a subpar experience for more and more users. Instead, we need to create a grid system that embraces the medium’s lack of fixed dimensions, resulting in a single layout with multiple states that transition seamlessly from one to another, and bring structure to our content whatever the screen size.

What is an infinite grid system?

Grids are simply a tool for visual problem solving. Creating a layout is like doing a jigsaw puzzle; you have a bunch of pieces and you have to figure out how they should fit together. When we construct a grid, we’re creating layout boundaries: known relationships and constraints that define an environment wherein an appropriate solution can occur. But when we construct an infinite grid, we’re not just setting the boundaries for a layout, but a layout system, with too many variables for us to nail everything down. If we define the important relationships, the blanks will fill in themselves.

For a grid to be useful, it has to be based on the things we know. In traditional media, canvas dimensions are a known constraint, so it makes sense that we start with the edges and define a grid’s relationships relative to them. With digital, however, the canvas is an unknown, making it a poor foundation to base a layout on.

Instead, we need to build on what we do know: content.

In order to embrace designing native layouts for the web—whatever the device—we need to shed the notion that we create layouts from a canvas in. We need to flip it on its head, and create layouts from the content out.

— Mark Boulton, “A Richer Canvas"

When designing from the canvas in, the canvas dimensions are the constant on which the whole grid is anchored. Everything is sized and positioned relative to them. Designing from the content out means finding a constant in your content—be it the ideal measure of a paragraph or the dimensions of an ad unit—and building your grid out from there to fill the space available.

Now, layouts that expand to fill the space available are nothing new—after all, fluid layouts are basically the web’s default—but very few layouts can be stretched or squashed indefinitely without the relationships between components breaking down, and that’s where states come in.

States

Fluid layouts are often compared to water, but water isn’t always fluid. H2O has three different states, and depending on the temperature can be a solid, liquid, or gas, transitioning seamlessly from one to another at specific points (0ºC, 100ºC). An infinite grid also has multiple states (single column, multi-column, etc.), and should transition as seamlessly as possible between them at specific breakpoints as well. For example, just as ice is an appropriate state for water when the temperature is low, a single-column layout may be the appropriate state for an infinite grid on smaller devices.

Water’s state change is caused by the rearrangement of its molecules. When an infinite grid changes state, we rearrange its components.

Components

Each state in a responsive layout tends to be made up of the same components, such as an image gallery or navigation menu. However, as Ethan Marcotte recently outlined, the form these components take can vary dramatically between one state and another, usually involving a change in one or more of the following attributes:

  1. Hierarchy: What’s its order and prominence in the layout?
  2. Density: How much detail do you show?
  3. Interaction: Should it be a list of links or a dropdown? A carousel or a group of images?
  4. Width: Is it fixed (a specific width), flexible (set with max-width), or fractional (set with percentages)?

Considering how each component’s attributes may change between states helps ensure that the grid system produces the right layout for the space available. In this example, watch how the different components adjust their width (between fixed and flexible) and position between states.

Designing an infinite grid system

Though we’re only beginning to scratch the surface of designing infinite grids, a few techniques are already proving useful. To get started, here are a few guidelines:

1. Use proportional units

Designing a grid is about deciding what should be proportional to what. When you choose a unit, you bind a dimension to a particular variable:

  • Pixels size an element relative to a particular resolution
  • Ems size an element relative to its font size; large rems size it relative to the document’s base font size
  • Percentages size an element relative to its container
  • VH and VW units size an element relative to the viewport

Absolute units like pixels effectively give a layout a sell-by date, locking it to a finite resolution range in which it will “work.� Proportional units (ems, rems, and percentages) enable you to define the important relationships between elements, and are a crucial first step on the road to resolution independence.

2. Start with the extremes, then work out the in-betweens

Every layout has a natural “optimum� range for its content. How wide can you stretch it before it starts to break? How small can you squish it before it starts to collapse? For example, if the width available is less than 45 characters per line, your layout starts to feel cramped; if there’s more than a column’s worth of white space on either side of your layout, the content starts to feel dwarfed. Where these extremes occur differs for every design, and depends largely on your content.

Designing for the extremes first forces you to consider how best to present your content at either end of the spectrum. Consider the hierarchy, density, interaction, and width of each component at the smallest state, then do the same for the largest state.

For example, lets say my largest state is 75em wide (any larger and the white space starts to dwarf the content), and my smallest is 34em (any smaller and the measure is less than optimal). In the largest state it makes sense for my navigation to be a horizontal list (interaction) at the top (hierarchy), but in the smallest state it might make more sense to move it to the bottom of the layout (hierarchy), or collapse it into a show/hide list (interaction). Designing these independently of one another helps you be more objective about what is best for each state, rather than stretching a one-size-fits-all solution across every state.

3. Change state where relationships break down

Once you’ve worked out the extremes, it’s time to consider how and where one state should transition to another. Just like water changes to steam when its molecules get too far apart, one state should change to another when the relationships between its components begin to break down, such as when the measure is getting too wide, or the left-aligned logo is getting so far from the right-aligned menu that the visual connection between them is broken.

This is where live prototypes come in handy. It’s incredibly difficult to predict exactly at what width (in relation to the content) a layout needs to change from one state to another. A prototype allows you to easily resize your browser to find the exact point at which relationships break down, so you can add a breakpoint there. New tools (like Gridset and Responsive.is) are making it easier than ever to create and test responsive prototypes, so there’s no excuse not to.

The number of states you require will depend on how much your layout changes from one extreme to the other. For example, my smallest state has a single column with a collapsed menu, and my largest state has three columns and an expanded menu. However neither state looks quite right between 34em and 53em, so I’ve added an “in-between� state which maintains the smallest state’s single column article, but expands the menu and divides the footer into three columns to make the most of the space available. This smooths out the transition from one extreme to another quite nicely.

With each state change, remember to reconsider the hierarchy, density, interaction, and width of each component. Perhaps your main content column should be fixed width now to ensure the measure doesn’t get too wide, or maybe you have room to add more information (density) to your navigation?

4. Go beyond the extremes

So we now have a responsive layout with multiple states, that transitions smoothly from the smallest state to the largest. But that’s only a range of 34 to 75em. What about when the available space is smaller or greater than those states? How do we get a layout that truly goes from zero to ∞?

At the smaller end of the scale space is precious, so we need to make the most of what we have. For under 20em, I’ve reduced (but not removed) margins, decreased line height, and indented bulleted lists. Basically, I’ve done what I can to optimize readability, even though I have a less-than-optimum amount of space available.

At the other end of the scale, the problem is too much space, specifically whitespace. This makes content feel dwarfed, so we need to find ways to balance it out. Unfortunately, simply scaling up a layout indiscriminately doesn’t always work, as we start to come up against reading distance. If you scale up your text size to maintain approximately sixty characters per line, but the type is so big that I have to physically turn my head to read it, that’s not a good experience.

Instead, look for elements such as headers, dividers, or images that you can scale up with the canvas, which helps anchor a layout visually without ruining readability. In my example, the ruler element that stretches full-width helps “anchor� the design in the whitespace, and at 75em I start scaling up the elements relative to the viewport size using VW units. The body text starts to get uncomfortably large at 90em so I use rem units to keep it at a comfortable reading size while the other elements scale around it.

Either way, the goal is to make the most of the space available, relative to your content, to maximize readability and presentation.

To infinity, and beyo—

Actually, infinity would be enough.

Using a predefined grid seems to make as much sense as using a predefined colour scheme.

Jeremy Keith

I’ve tried to stay away from specifics here, because there are none. Each layout is different, and there are no magic numbers that will work every time.

Instead, we have to nail down the relationships between elements, and then let the specifics take care of themselves. We don’t have all the answers yet, but doing this will help us ask the right questions.

This is a problem worth solving. And we’re not just solving it for ourselves, but for everyone who designs for digital media in the future—and that could be a lot of people. An infinite number, even.

Translations:
Italian
Russian


RSS readers: Don't forget to join the discussion!


  •   
  • Copyright © 1996-2010 BlogmyQuery - BMQ. All rights reserved.
    iDream theme by Templates Next | Powered by WordPress