Building games for the web – Ash Kyd



Building games for the web – Ash Kyd

0 1


web-games-campjs-2015

Learn to teach yourself to make games for the web

On Github AshKyd / web-games-campjs-2015

Building games for the web

Ash Kyd

ashkyd.github.io/web-games-campjs-2015/

How to make games

How to teach yourself to make games

Making games is easy?

Kinda

Sorta

Once you get the hang of it

Making games is easy!

Make something achievable

Work to your strengths

Take ALL of the shortcuts

Some basics

  • 2D Canvas
  • WebGL
  • Then all the libraries on top of those

Some concepts

  • Rendering
  • Interaction
  • Sound
  • Physics
  • Tweening
  • Pathfinding
  • Particles
  • Terrain generation
  • And so much more!

My story: Road Blocks!

Something achievable

Work to your strengths

  • Prototype with familiar tech
  • Programmer art is awesome
  • Polish comes second to function

In my case

  • I'm all about isometric art
  • You can do some cool stuff in 13kb
  • Stacking boxes is fun

Stacking boxes is fun

Code: ~420 bytes

var cubes = [
    [1, 2.0 ,1,1,1,.7,'#C8AF9E'],
    [1, 1.3 ,1,1,1,.3,'#7DD17D'],
    [1, 0.5 ,.1,.1,.1,.1,'#DFA656'],
    [1, 0.45,.3,.3,.3,.05,'#84C171'],
    [1, 0.35,.2,.2,.2,.05,'#84C171'],
    [1, 0.25,.1,.1,.1,.05,'#84C171'],
];

function draw(){
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  var wobble = 1 + Math.max(Math.sin(Date.now()/250), 0)/10;

  var cubeSize = 150;
  cubes.forEach(function(cube){
      drawCube(
        cube[0] * canvas.width/2,
        cube[1] * cubeSize * wobble,
        cube[3] * cubeSize, // x1
        cube[4] * cubeSize, // x2
        cube[5] * cubeSize, // y
        cube[6], // color
        ctx
      );
  });
  requestAnimationFrame(draw);
}
draw();

Take all the shortcuts!

  • NPM is full of goodies
  • You don't need to reinvent the wheel (or the physics)
  • Do what you know best

HEY COOL LET'S USE THIS

Attractive attractors

Code: ~840 bytes

var canvas = document.querySelector('.physics canvas');
canvas.width = window.innerWidth * 0.66;
canvas.height = canvas.width * 0.66;
var ctx = canvas.getContext('2d');

var physics = new Physics();

var radius = 50;
var mass = 25;

var x1 = canvas.width * 0.25;
var x2 = canvas.width * 0.75;
var y = canvas.height / 2;

var a = physics.makeParticle(mass, x1, y);
var b = physics.makeParticle(mass, x2, y);

// Create an attraction between the particles.

// The strength of the bond between two particles.
var strength = 50000;

// The proximity at which the attraction will be enabled.
var minDistance = canvas.width;

// Make the attraction and add it to physics
var attraction = physics.makeAttraction(a, b, strength, minDistance);
var cubeSize = 80;

var update = {};

var render = function() {

    if (canvas.class !== 'active') {
        return;
    }

    ctx.clearRect(0, 0, canvas.width, canvas.height);

    var x1 = a.position.x;
    var y1 = a.position.y;

    var x2 = b.position.x;
    var y2 = b.position.y;

    drawCube(
        x1 - cubeSize * 2,
        y1,
        cubeSize, // x1
        cubeSize, // x2
        cubeSize, // y
        '#ff8888', // color
        ctx
    );

    drawCube(
        x2 - cubeSize * 2,
        y2,
        cubeSize, // x1
        cubeSize, // x2
        cubeSize, // y
        '#8888ff', // color
        ctx
    );

    if (b.resting()) {
        a.position.set(x1, y);
        b.position.set(x2, y);
    }

};

// Bind the render function to when physics updates.
physics.onUpdate(render);

// Render a posterframe.
render();

physics.toggle();

// store our physics object on the canvas so we can access it later
canvas.physics = physics;

Pathfinding

The code: ~770 bytes

function getIsometricPos(x, y, tileWidth) {
    return [
        (x - y) * (tileWidth / 2), (x + y) * (tileWidth / 4)
    ];
}

// Animation function
function draw() {
    // Create a grid
    var grid = new PF.Grid(10, 10);

    // Create some obstacles
    for (var i = 0; i < 10; i++) {
        var x = Math.round(Math.random() * 9);
        var y = Math.round(Math.random() * 9);
        grid.setWalkableAt(x, y, false);
    }

    // Find a path
    var finder = new PF.AStarFinder();
    var path = finder.findPath(0, 0, 9, 9, grid);

    // start drawing
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    var cubeSize = canvas.width / 20;
    grid.nodes.forEach(function(row, x) {
        row.forEach(function(col, y) {
            // Get x and y coords to draw at.
            var pos = getIsometricPos(x, y, cubeSize * 2);

            // Pick a colour
            var color = (x + y) % 2 === 0 ? '#00ff00' : '#66ff66';
            if (col.walkable === false) {
                color = '#333333';
            }

            // Is this point in the path?
            // Todo: make this more efficient.
            path.forEach(function(point) {
                if (point[0] === y && point[1] === x) {
                    color = '#8888ff';
                }
            });

            // Draw the cube
            drawCube(
                canvas.width / 2 + pos[0],
                canvas.height / 4 + pos[1],
                cubeSize,
                cubeSize,
                cubeSize * (col.walkable ? 1 : 1.5),
                color,
                ctx
            );
        });
    });


    setTimeout(draw, 2000);
}
draw();

Point is…

  • You can rapidly prototype stuff
  • without having to learn a framework

Useful libraries

2D pixi.js Canvas & WebGL abstraction 2D Phaser Game engine Built on Pixi 3D three.js WebGL engine 3D Babylon.js WebGL engine - Cordova Go mobile!

Useful resources

Mozilla Hacks Articles & tutorials phaser.to Bunch of tutorials js13k 13 kb game competition One Game a Month Challenge to finish a game every month Global Game Jam Create a game in a team over a weekend

Building games for the web

http://ash.ms/rb - play now

http://ash.ms/rb