JavaScript: Do you like games? (part 6)

Written by radu.bogdan.gaspar | Published 2016/11/27
Tech Story Tags: javascript | game-engine | canvas | es6 | game-development

TLDRvia the TL;DR App

On this topic: Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6

It’s time to cover asteroid generation. I bet you never thought playing with rock would be fun… well, you were wrong!

Before we code, let’s visualize and put into words what we want to achieve:

  • we want a class that will draw an asteroid (stroke of genius right here)
  • it should be drawn randomly within a given set of parameters, as seeing the same rock over and over again will get a tad boring really quick

In terms of actual steps, such an object can be drawn as follows:

asteroid drawing approach

It all starts with two concentric circles. You can think of these as two simple parameters that our class will receive; a minimum and maximum radius if you will.

In step two, we split the circle evenly into slices. The number of slices will give us the asteroid “resolution”… its granularity. The bigger the number, the finer our rock details will be. Increasing this number also comes at a performance cost.

Moving on to steps three and four, we show the area of interest. We want to generate a set of random points within that range on our slices. To be more exact, each of those points will be positioned at a radius greater than or equal to the minimum radius we provide, but not greater than the maximum radius.

Steps five and six represent the easy part… connecting those points with a line and applying a fill color, resulting in a randomly generated asteroid. Pretty neat huh? Here’s a canvas based visual representation:

Calling this class will create a plethora of rocks shapes but be careful of those min and max radius values… you don’t want your asteroids looking too pointy; or do you? We’ll keep the logic above in a RockModel class which will extend VerletModel:

asteroids/models/RockModel.js

We’re also doing some extra work to calculate the width and height of the resulting rock based on the points we generate. The rock will have a (very small) random rotation and velocity applied to it.

Since we want the rock randomly positioned in the scene, and since that scene instance is not available within the models, we’ll set its x and y positions in the Rock class.

The actual display object Rock class will look like this:

asteroids/objects/Rock.js

It just renders the lines between all those points which it gets from the model.

By this point it should already be clear to everyone that working with scripted shapes is more processor intensive that working with sprites. While traversing a few points and drawing lines between them is no big deal, it quickly becomes one if you’re working with thousands of such objects. Long story short, this won’t scale well… so consider yourself warned.

We said we wanted an asteroid field, much like the star field we already have… those rock move, but their movement needs to be affected by the space ship velocity, so let’s do that next:

asteroids/objects/RockField.js

We want our Map to track these new objects, but it doesn’t really know how to do that yet. We want the map to accept DisplayObject classes and if any of them have children, it should recursively iterate and display them.

asteroids/objects/Map.js

The only difference here is basically the renderMarker() method which accepts a set of objects as a parameter. If it finds any children within a given set entry, it will iterate over them.

Next up it’s time to actually shoot some bullets. The Player class needs to handle that, as it’s a player specific action, so we’ll be adding in this piece of code:

asteroids/objects/Player.js

As you can see, whenever the SPACE bar is pressed, we’re generating a new Bullet, that class looks like this:

asteroids/objects/Bullet.js

The Bullet class extends Particle so we don’t need to replicate the render() method. Instead on update() we’re just setting the x and y based on the ships angle as we always want to fire the bullet in the direction the ship’s facing.

We’re also automatically destroying a bullet after 3 seconds. You can also achieve this with a setTimeout() method in the constructor… but we’re not savages :D (and it would be nice if everything works on the same frame rate as we said it would).

Putting everything together:

asteroids/index.js

You can now fire more bullets than you’ll ever need and with no collision to speak of (yet) it makes for a pretty impressive display… just fly around a fire away (the SPACE and J keys can be used to fire).

You might notice a small quirk in the rock wrapping logic, as it’s a bit wonky at the moment but we’ll get around to it eventually.

Demo in action:

Source code:

raduGaspar/game-physx_game-physx - A small utility for JavaScript game making_github.com

Next we should probably start discussing collision. This is a larger topic that involves quite a bit of math, so I’m expecting it to span over the course of a few articles. A refresher on vector mathematics is required, so we’ll continue with that.


Published by HackerNoon on 2016/11/27