This is a follow up for the 2D Gravity Simulator-like Game question.
Since then I have developed my javascript skills further, and now I'm using ES6 mainly. Note that even through this code uses the EaselJS library, the question is principally about its design so no EaselJS skill needed.
Also I wanna avoid posting a bigger version of the bible here, so this question is only about the game's Planet
class and its properties.
The code is more well divided, but I don't know if this organization is effective, and how can changes in a planet's .physicsBody
affect its graphical .skin
– colors specially. Any tips and ratings on how I'm using class inheritance are really appreciated.
Also, is there any part that could use a more ES6-ish approach?
Planet class:
class Planet {
constructor (x, y, radius, color) {
this.physicsBody = new CircleBody(x, y, radius);
this.skin = new CircleSkin(x, y, radius, color);
}
update (scene) {
// This part is responsible for changing a planet's radius and animating the transition. I have no idea if this should in fact be made here or elsewhere.
if (this.physicsBody.radius !== this.skin.radius) {
this.skin.scaleX = this.skin.scaleY = this.skin.radius / this.physicsBody.radius;
this.skin.radius = this.physicsBody.radius;
this.skin.redraw();
createjs.Tween.get(this.skin, {override: true}).to({scaleX: 1, scaleY: 1}, 1000, createjs.Ease.elasticOut);
}
if (!this.physicsBody.destroyed) {
this.skin.x = this.physicsBody.x;
this.skin.y = this.physicsBody.y;
} else scene.removeChild(this);
}
}
CircleBody class:
class CircleBody extends PhysicsBody {
constructor (x, y, radius) {
super(x, y);
this.radius = radius;
}
get area () {
return this._area;
}
set area (newValue) {
this._area = newValue;
this._radius = Math.sqrt(newValue / Math.PI / 4);
}
get radius () {
return this._radius;
}
set radius (newValue) {
this._radius = newValue;
this._area = 4 * Math.PI * newValue * newValue;
}
get mass () {
return this.area * this.density;
}
}
PhysicsBody class:
class PhysicsBody {
constructor (x, y) {
this.x = x;
this.y = y;
this.px = x;
this.py = y;
this.vx = 0;
this.vy = 0;
this.density = 1;
this.affectedByGravity = true;
this.static = false;
this.collision = null;
this.destroyed = false;
}
get dynamic () {
return !this.static;
}
set dynamic (newValue) {
this.static = !newValue;
}
get velocity () {
return new Vector(this.vx, this.vy);
}
clearCollisions () {
this.collision = null;
}
}
CircleSkin class:
class CircleSkin extends Skin {
constructor (x, y, radius, color) {
super(x, y, color);
this.radius = radius;
this.redraw();
}
redraw (resolution) {
var r = this.radius;
this.graphics.clear();
this.graphics.f(this.color).dc(0, 0, r);
//this.cache(-r, -r, r * 2, r * 2, resolution || 1);
}
}
Skin class:
class Skin extends createjs.Shape {
constructor (x, y, color) {
super();
this.x = x;
this.y = y;
this.color = color;
}
}
And finally, this is the class usage in engine:
for (var i = 0; i < 1024; ++i) {
var x = Utils.getRandomInt(0, innerWidth),
y = Utils.getRandomInt(0, innerHeight);
var myPlanet = new Planet(x, y, 2, Utils.getRandomItem(colors));
myPlanet.physicsBody.n = i;
myScene.addChild(myPlanet);
}
Utils
and Vector
dependencies are out of scope and I think their method names are pretty clear so no declaration needed here.