This is the second part of a series about using EaselJS to create a simple HTML5/js based arcade game.
In this part, we’ll learn about:
In the first part, we left with just a moving plate. It’s time to give it a ball now.
Thankfully, Graphics object has just the method for this:
drawCircle. This time we’re gonna pack our ball into a class - deriving from
createjs.Shape - from the very beginning.
But before that, let’s prepare some ground for supporting multiple objects at the same time.
class Main constructor: (name) -> @canvas = document.getElementById name @plate = new Plate @canvas @ball = new Ball @canvas document.onkeydown = @handleKeyDown document.onkeyup = @handleKeyUp init: -> @plate.init() @ball.init() @stage = new createjs.Stage @canvas @stage.addChild @plate @stage.addChild @ball createjs.Ticker.useRAF = yes createjs.Ticker.setFPS 60 createjs.Ticker.addListener @ tick: -> @plate.tick() @stage.update() window.main = new Main "main" window.main.init()
Nothing fancy here. The
Plate object is a slightly refactored version of the one from previous part of this tutorial. With key handlers we’ll deal later, now let’s focus on the
class Ball extends createjs.Shape constructor: (@canvas) -> super() @graphics.beginFill("#6b0000").drawCircle 0, 0, 5 @maxwidth = @canvas.width @maxheight = @canvas.height - 10 init: -> @x = @maxwidth / 2 @y = @maxheight - 5
Alright, so the ball is in place. Oh, wait, in place?! It should move along with the plate, shouldn’t it? Of course, we need to tie them together. Let’s move to the key handlers now.
class Ball #(...) constructor: (@canvas) -> #(...) @ddx = [0, 0] tick: -> @x += @ddx + @ddx setLeft: (dx) -> @ddx = dx setRight: (dx) -> @ddx = dx class Main #(...) handleKeyDown: (e) => if !e e = window.event switch e.keyCode when KEY_LEFT @plate.setLeft -1 @ball.setLeft -1 when KEY_RIGHT @plate.setRight 1 @ball.setRight 1 handleKeyUp: (e) => if !e e = window.event switch e.keyCode when KEY_LEFT @plate.setLeft 0 @ball.setLeft 0 when KEY_RIGHT @plate.setRight 0 @ball.setRight 0
We are using the same trick here as we did for the Plate, because it suffers from the same problem. You can see that we are catching and resolving key events in the Main class. I’m still not sure if it’s the best approach, but it will do for now.
Better. Now let’s create some blocks meant to be destroyed by our Ball. Normally, I’d just place some rectangles there at random positions, but since we want to learn how to draw different things in EaselJS, we’ll do something more fancy. How about this.
I’m not going to dive into the details here (you can check the raw source if you want to). Instead, let’s focus on different shapes. Rectangles are easy, right? What about this rounded rectangle on the top? There is a
drawRoundRectComplex method in the
Graphics class, just for that. It is Complex, because it let’s you specify radius independently for every corner, in opposite to
drawRoundRect which sets the same radius for all of them. To conclude the easy part, there are
drawCircle methods for ellipses and circles, respectively.
Now, the tasty part. To draw shapes which are not available out of the box, we’ll use a concept of paths. Path is basically a collection of lines where every line has a common point with at least one other line. Note that those lines do not need to be straight, they can be some kind of curve as well. When we take a closed path (which begins and ends in the same point), they will form a figure.
It is probably better to be seen as picture(s). We’ll start with triangles, they’re quite obviously easier ones.
We are using
lineTo function here to create straight lines. It’s equivalent for curves are
Actually, they are both Bezier, former being quadratic and latter being cubic.
Let’s see a picture again here.
To find out more about Bezier curves, check out wikipedia article. It has necessary explanations, formulas and even animated gifs showing how it works.
To conclude this part, a few words about containers. We’ve seen them before: Our Stage is in fact the main container, where everything else lives. But we can create more containers and they can behave like Graphics objects and be used to group other Graphics objects. We can then manipulate multiple objects at once. Note however that, while useful, it should not be overused, because containers produce additional overhead which may cause your application to become slow.