Skip to content

Commit

Permalink
[#560][#833][#1008] major internal rewrite of bound implementation
Browse files Browse the repository at this point in the history
- me.Rect finally fully replaced by me.Bounds
- fix long opened issues linked to anchor point and bounds
- simplify and unify API accross shape and bounds objects
- simplify lots of code across the renderable inheritance tree
- other misc related improvement and clean-up along the road
  • Loading branch information
obiot committed Sep 1, 2021
1 parent 239464c commit bba1d49
Show file tree
Hide file tree
Showing 51 changed files with 693 additions and 660 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

## 9.0.0 (WIP)
- Audio : Howler audio core update (2.2.3)
- Core : melonJS build process now automatically output one ES5 umd bundle, and one pure ES6 module
- Core : melonJS build process now automatically output one ES5 umd "legacy" bundle, and one pure ES6 module
- Core : the "legacy" es5 umd bundle is now automatically transpiled (from ES6 to ES5) using rollup and bubble
- Core : `me.Stage` constructor now accept new argument properties to specify the `onResetEvent` and `onDestroyEvent` functions
- Core : internal rewrite on object bound implementation, now fully using/relying on the me.Bounds object introduced in last version
- Tiled : add TMX `tintcolor` parsing for tile and object layers
- TMX : fix crash when trying to add collisionType to text nodes (thanks @framp)
- TMX : fix a regression with the Tile Layer preRender feature
Expand Down
72 changes: 36 additions & 36 deletions plugins/debug/debugPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,6 @@
me.debug.renderQuadTree = me.debug.renderQuadTree || hash.quadtree || false;

var _this = this;
var bounds = new me.Rect(0, 0, 0, 0);

// patch me.game.update
me.plugin.patch(me.game, "update", function (dt) {
Expand All @@ -376,7 +375,7 @@
});

// patch sprite.js
me.plugin.patch(me.Sprite, "draw", function (renderer) {
me.plugin.patch(me.Sprite, "postDraw", function (renderer) {

// call the original me.Sprite.draw function
this._patched(renderer);
Expand All @@ -389,30 +388,27 @@

// draw the sprite rectangle
if (me.debug.renderHitBox) {
var bounds = this.getBounds();
var ax = this.anchorPoint.x * bounds.width,
ay = this.anchorPoint.y * bounds.height;

var ancestor = this.ancestor;
if (ancestor instanceof me.Container && ancestor.root === false) {
ax -= ancestor._absPos.x;
ay -= ancestor._absPos.y;
} else if (ancestor instanceof me.Entity) {
ancestor = ancestor.ancestor;
if (ancestor instanceof me.Container && ancestor.root === false) {
// is this correct ???
ax = ay = 0;
}
}
var absolutePosition = this.ancestor.getAbsolutePosition();

// translate back as the bounds position
// is already adjusted to the anchor Point
renderer.translate(ax, ay);
if (!this.ancestor.root && this.ancestor.floating) {
renderer.translate(
-absolutePosition.x,
-absolutePosition.y
);
}

// draw the sprite bounds
renderer.setColor("green");
renderer.stroke(bounds);
renderer.stroke(this.getBounds());


renderer.translate(-ax, -ay);
if (!this.ancestor.root && this.ancestor.floating) {
renderer.translate(
absolutePosition.x,
absolutePosition.y
);
}

// the sprite mask if defined
if (typeof this.mask !== "undefined") {
Expand All @@ -421,20 +417,24 @@
}

if (typeof this.body !== "undefined") {
renderer.translate(this.pos.x, this.pos.y);
var bounds = this.getBounds();
renderer.translate(bounds.x, bounds.y);

renderer.setColor("orange");
renderer.stroke(this.body.getBounds());

// draw all defined shapes
renderer.setColor("red");
for (var i = this.body.shapes.length, shape; i--, (shape = this.body.shapes[i]);) {
renderer.stroke(shape);
_this.counters.inc("shapes");
}
renderer.translate(-this.pos.x, -this.pos.y);
renderer.translate(-bounds.x, -bounds.y);
}
}
}
});


me.plugin.patch(me.BitmapText, "draw", function (renderer) {
// call the original me.Sprite.draw function
this._patched.apply(this, arguments);
Expand Down Expand Up @@ -513,8 +513,8 @@
renderer.save();

renderer.translate(
-this.pos.x - this.body.getBounds().x - this.ancestor._absPos.x,
-this.pos.y - this.body.getBounds().y - this.ancestor._absPos.y
-this.pos.x - this.body.getBounds().x - this.ancestor.getAbsolutePosition().x,
-this.pos.y - this.body.getBounds().y - this.ancestor.getAbsolutePosition().y
);

if (this.renderable instanceof me.Renderable) {
Expand All @@ -524,15 +524,15 @@
);
}

// draw the bounding rect shape
renderer.setColor("orange");
renderer.stroke(this.getBounds());

renderer.translate(
this.pos.x + this.ancestor._absPos.x,
this.pos.y + this.ancestor._absPos.y
this.pos.x + this.ancestor.getAbsolutePosition().x,
this.pos.y + this.ancestor.getAbsolutePosition().y
);

// draw the bounding rect shape
renderer.setColor("orange");
renderer.stroke(this.body.getBounds());

// draw all defined shapes
renderer.setColor("red");
for (var i = this.body.shapes.length, shape; i--, (shape = this.body.shapes[i]);) {
Expand All @@ -544,7 +544,7 @@

if (me.debug.renderVelocity && (this.body.vel.x || this.body.vel.y)) {
bounds.copy(this.getBounds());
bounds.pos.sub(this.ancestor._absPos);
bounds.pos.sub(this.ancestor.getAbsolutePosition());
// draw entity current velocity
var x = bounds.width / 2;
var y = bounds.height / 2;
Expand Down Expand Up @@ -585,8 +585,8 @@

if (!this.root) {
renderer.translate(
-this._absPos.x,
-this._absPos.y
-this.getAbsolutePosition().x,
-this.getAbsolutePosition().y
);
}

Expand Down Expand Up @@ -673,7 +673,7 @@
if (_alpha > 0.0) {
renderer.save();
renderer.setColor("rgba(255,0,0," + _alpha + ")");
renderer.fillRect(bounds.pos.x, bounds.pos.y, bounds.width, bounds.height);
renderer.fillRect(bounds.left, bounds.top, bounds.width, bounds.height);
renderer.restore();
}
} else {
Expand Down
23 changes: 12 additions & 11 deletions src/camera/camera2d.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,11 @@ var Camera2d = Renderable.extend({
/**
* Camera bounds
* @public
* @type me.Rect
* @type me.Bounds
* @name bounds
* @memberOf me.Camera2d
*/
this.bounds = new Rect(-Infinity, -Infinity, Infinity, Infinity);
this.bounds = pool.pull("Bounds");

/**
* [IMTERNAL] enable or disable damping
Expand Down Expand Up @@ -166,6 +166,8 @@ var Camera2d = Renderable.extend({
// enable event detection on the camera
this.isKinematic = false;

this.bounds.setMinMax(minX, minY, maxX, maxY);

// update the projection matrix
this._updateProjectionMatrix();

Expand Down Expand Up @@ -314,8 +316,7 @@ var Camera2d = Renderable.extend({
*/
setBounds : function (x, y, w, h) {
this.smoothFollow = false;
this.bounds.shift(x, y);
this.bounds.resize(w, h);
this.bounds.setMinMax(x, y, w + x, h + y);
this.moveTo(this.pos.x, this.pos.y);
this.update();
this.smoothFollow = true;
Expand Down Expand Up @@ -407,12 +408,12 @@ var Camera2d = Renderable.extend({
this.pos.x = clamp(
x,
this.bounds.left,
this.bounds.width - this.width
this.bounds.width
);
this.pos.y = clamp(
y,
this.bounds.top,
this.bounds.height - this.height
this.bounds.height
);

//publish the VIEWPORT_ONCHANGE event if necessary
Expand Down Expand Up @@ -558,8 +559,8 @@ var Camera2d = Renderable.extend({
* });
*/
fadeOut : function (color, duration, onComplete) {
this._fadeOut.color = pool.pull("me.Color").copy(color);
this._fadeOut.tween = pool.pull("me.Tween", this._fadeOut.color)
this._fadeOut.color = pool.pull("Color").copy(color);
this._fadeOut.tween = pool.pull("Tween", this._fadeOut.color)
.to({ alpha: 0.0 }, duration || 1000)
.onComplete(onComplete || null);
this._fadeOut.tween.isPersistent = true;
Expand All @@ -580,10 +581,10 @@ var Camera2d = Renderable.extend({
* me.game.viewport.fadeIn("#FFFFFF", 75);
*/
fadeIn : function (color, duration, onComplete) {
this._fadeIn.color = pool.pull("me.Color").copy(color);
this._fadeIn.color = pool.pull("Color").copy(color);
var _alpha = this._fadeIn.color.alpha;
this._fadeIn.color.alpha = 0.0;
this._fadeIn.tween = pool.pull("me.Tween", this._fadeIn.color)
this._fadeIn.tween = pool.pull("Tween", this._fadeIn.color)
.to({ alpha: _alpha }, duration || 1000)
.onComplete(onComplete || null);
this._fadeIn.tween.isPersistent = true;
Expand Down Expand Up @@ -636,7 +637,7 @@ var Camera2d = Renderable.extend({
* @param {Boolean} [floating===object.floating] if visibility check should be done against screen coordinates
* @return {Boolean}
*/
isVisible : function (obj, floating) {
isVisible : function (obj, floating = obj.floating) {
if (floating === true || obj.floating === true) {
// check against screen coordinates
return video.renderer.overlaps(obj.getBounds());
Expand Down
29 changes: 6 additions & 23 deletions src/entity/entity.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import collision from "./../physics/collision.js";
* @param {String} [settings.name] object entity name
* @param {String} [settings.id] object unique IDs
* @param {Image|String} [settings.image] resource name of a spritesheet to use for the entity renderable component
* @param {me.Vector2d} [settings.anchorPoint=0.0] Entity anchorpoint
* @param {Number} [settings.framewidth=settings.width] width of a single frame in the given spritesheet
* @param {Number} [settings.frameheight=settings.width] height of a single frame in the given spritesheet
* @param {String} [settings.type] object type
Expand Down Expand Up @@ -57,6 +58,9 @@ var Entity = Renderable.extend({
// Update anchorPoint
if (settings.anchorPoint) {
this.anchorPoint.set(settings.anchorPoint.x, settings.anchorPoint.y);
} else {
// for backward compatibility
this.anchorPoint.set(0, 0);
}

// set the sprite name if specified
Expand Down Expand Up @@ -148,26 +152,6 @@ var Entity = Renderable.extend({
return this._super(Renderable, "update", [dt]);
},

/**
* update the bounds position when the position is modified
* @private
* @name updateBoundsPos
* @memberOf me.Entity
* @function
*/
updateBoundsPos : function (x, y) {
if (typeof this.body !== "undefined") {
var bounds = this.body.getBounds();
this._super(Renderable, "updateBoundsPos", [
x + bounds.x,
y + bounds.y
]);
} else {
this._super(Renderable, "updateBoundsPos", [x, y]);
}
return this.getBounds();
},

/**
* update the bounds position when the body is modified
* @private
Expand All @@ -176,9 +160,8 @@ var Entity = Renderable.extend({
* @function
*/
onBodyUpdate : function (body) {
var bounds = body.getBounds();
// update the entity bounds to match with the body bounds
this.getBounds().resize(bounds.width, bounds.height);
// update the entity bounds to include the body bounds
this.getBounds().addBounds(body.getBounds(), true);
// update the bounds pos
this.updateBoundsPos(this.pos.x, this.pos.y);
},
Expand Down
16 changes: 8 additions & 8 deletions src/input/pointerevent.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import device from "./../system/device.js";
import Pointer from "./pointer.js";
import Rect from "./../shapes/rectangle.js";
import Container from "./../renderable/container.js";
import Renderable from "./../renderable/renderable.js";
import game from "./../game.js";


Expand Down Expand Up @@ -298,23 +299,22 @@ function dispatchEvent(normalizedEvents) {
pointer.gameX = pointer.gameLocalX = pointer.gameWorldX;
pointer.gameY = pointer.gameLocalY = pointer.gameWorldY;
}

// adjust gameLocalX to specify coordinates
// within the region ancestor container
if (typeof ancestor !== "undefined") {
var parentPos = ancestor.getBounds().pos;
pointer.gameLocalX = pointer.gameX - parentPos.x;
pointer.gameLocalY = pointer.gameY - parentPos.y;
var parentBounds = ancestor.getBounds();
pointer.gameLocalX = pointer.gameX - parentBounds.x;
pointer.gameLocalY = pointer.gameY - parentBounds.y;
}

// XXX using instanceof Sprite here crash the browser now (WHY?)
// XXX TODO : apply this to all renderable, not just Sprite based object
//if (typeof region.setAnimationFrame === "function") {
if (typeof region.setAnimationFrame === "function") {
// apply inverse transformation for renderable
if (region instanceof Renderable) {
var gameX = pointer.gameX;
var gameY = pointer.gameY;
if (!region.currentTransform.isIdentity()) {
var invV = region.currentTransform.applyInverse(
pool.pull("me.Vector2d", gameX, gameY)
pool.pull("Vector2d", gameX, gameY)
);
gameX = invV.x;
gameY = invV.y;
Expand Down
6 changes: 3 additions & 3 deletions src/level/tiled/TMXLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,8 @@ var TMXLayer = Renderable.extend({
}

// Resize the bounding rect
var bounds = this.getRenderer().getBounds(this);
this.getBounds().resize(bounds.width, bounds.height);
this.getBounds().addBounds(this.getRenderer().getBounds(), true);
this.getBounds().shift(this.pos);

// if pre-rendering method is use, create an offline canvas/renderer
if ((this.preRender === true) && (!this.canvasRenderer)) {
Expand Down Expand Up @@ -303,7 +303,7 @@ var TMXLayer = Renderable.extend({
var tile = null;

if (this.contains(x, y)) {
var coord = this.getRenderer().pixelToTileCoords(x, y, pool.pull("me.Vector2d"));
var coord = this.getRenderer().pixelToTileCoords(x, y, pool.pull("Vector2d"));
tile = this.cellAt(coord.x, coord.y);
pool.push(coord);
}
Expand Down
Loading

0 comments on commit bba1d49

Please sign in to comment.