Tag Archives: javascript

HTML Canvas – torch / lightbeam

I’ve been playing around with the HTML Canvas tonight, and having a think about how I’d go about implementing a torch / light beam type effect in a platform game.

There are loads of ways to do this kind of thing, but where I usually start is with the most simple, basic (and shitty) implementation and go from there. I did some searching around the internet and found next to nothing for someone who doesn’t want to use a library, so here’s a starting point.

What I was after was the ability to draw a scene, as you normally would, and then have only a small section lit (or visible) at any one time. The lit section of the scene would be determined where the player’s torch was pointing. To me, the most basic and simple way to achieve that would be to draw the scene on one canvas, then draw a clipping mask on a separate, temporary canvas and then overlay it over the main scene canvas.

Sounds workable in theory, and a starting point at least, but the question is how? There’s a few options – you could draw a masked image over the top – a PNG with a solid background colour and transparent section representing the torchbeam – but that seemed a bit restrictive to me. I want to be able to wobble the torchlight around as the player moves and runs.

In the end, the best solution seemed to be to use the excellent compositing operations offered by the HTML Canvas:

lightCanvas.fillRect(0,0,lightCanvasWidth,lightCanvasHeight);
lightCanvas.globalCompositeOperation = 'xor';
lightCanvas.arc(100, 100, 100, 0, 2 * Math.PI);
lightCanvas.fill();

What does that code do?

It first fills the ‘lighting canvas’ with solid black, entirely. It then performs a ‘xor’ (or ‘exclusive-or’) global composite operation.

wat

What this means in practice, is that it effectively compares what was on the lighting canvas before the operation began (i.e. solid black filling the canvas), and after (i.e. the arc) – and areas where the newly drawn arc overlaps with what was there previously are made transparent.

The end result, is a clipping mask that can be overlaid over the ‘main’ canvas. You can shape the torch beam, you can move it around, you could use gradients to simulate the light faltering – plenty of options there. And a good starting point for playing around with this kind of stuff.

Javascript fundamentals: Scope

Scope, then. Not just the thing on top of a sniper rifle – it’s something that can trip you up in sometimes subtle and seemingly devious ways in JavaScript. This post will get you on your way to understand what it is.

TLDR; Summary

Scope determines which parts of your code can access other bits. This is largely controlled by using the ‘var’ keyword when declaring a variable, and where that keyword is used (inside a function, outside a function et) determines the scope. A variable with ‘global scope’ can be accessed by any part of your code.

That wasn’t particularly short. Got anything shorter?

Scope in JavaScript can be tricky until you ‘get it’. I’ll help you get it.

Go on then, what is ‘scope’. What does that mean?

In JavaScript, you can declare variables. You do it something like this:

var myVariable = "some text";

You might also have seen a variable declared like this – without ‘var’:

myVariable2 = "some more text";

I know that. So what?

That var keyword – that can be the source of lots of pain. Luckily, there are some simple rules:

  • If you omit the ‘var’ keyword when declaring a variable, and there isn’t already a global variable with the same name in your code, that variable will have ‘global scope’ – meaning any part of your code can access and modify that variable.
  • If you do include the ‘var’ keyword, the scope of the variable will be determined by which part of your code you’ve declared it in.

That second bit was… vague.

Luckily that’s also quite simple. JavaScript has ‘function-level scope’. That means that if you declare a variable using the ‘var’ keyword, and you do it inside a function, generally speaking only code within that function can access and modify it. Unless you pass it around to other functions, but we won’t worry about that right now. Fancy some examples?

Yeeaaaaaah boooyyyy.

// Welcome to some code examples.

/* Both of these variables are Global.
 The first one is using the 'var' keyword, but it's not declared in a function.
 This means it's global. */

var myGlobalVariable1 = true;

/* This one hasn't used var, and there isn't a pre-existing variable with the same name.
 This means it's global. */

myGlobalVariable2 = true;

function myFunction() {

  /* We haven't used the var keyword here. There is a pre-existing variable with the same name.
   This means the pre-existing variable just gets updated. */

  myGlobalVariable2 = false;

  /* We've used the var keyword. We're inside a function.
   This means this variable has local scope to this function. */

  var myLocalVariable1 = true;

}

// What happens when you try to access the local variable declared inside the above function?
console.log(myLocalVariable1);
// ...it doesn't work.

That’s the basics. Play around with some code (by far the best way to learn), and bear in mind those rules.

Those of you who might be reading this and thinking “Hang on, you lying bastard, there are plenty of exceptions to what you’ve said above! TWAT” – you’re right. There are. But this is for beginners. If you find a beginner, help them out. When they’ve figured it out, you can bore them to death with the exceptions.

Javascript fundamentals

I thought I’d write a series of blog posts around Javascript. It’s a funny bugger of a language, but I really enjoy using it.

I’ll assume the reader has some knowledge of the fundamentals of programming (variables, functions/methods, C-like syntax).

Something I found quite irritating when I was learning JavaScript is that it’s practically impossible to find a concise, and beginner-friendly explanation for something. Scope, closures, objects – all of those things are explained in millions of different ways, nearly all of which don’t make sense to a relative beginner.

I consider that my challenge – explaining this stuff in an accurate, concise, and easy to understand way. You can let me know if I’ve failed.

I’ll tag these posts (unsurprisingly) as JavaScript.