diff --git a/HISTORY.md b/HISTORY.md
index d4923888..d7bf739b 100755
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -6,6 +6,15 @@
* **Notable Fixes:**
* **Translation Updates:**
+## v5.2.2:
+* **Notable Fix:**
+ * more optimizations for collision detection
+ * prepared patch
+
+### 2019-10-25
+* morphic, objects: optimized collision detection yet more
+* prepared patch
+
## v5.2.1:
* **Notable Fix:**
* optimized collision detection
diff --git a/snap.html b/snap.html
index d180c0ae..c1b36bb6 100755
--- a/snap.html
+++ b/snap.html
@@ -2,14 +2,14 @@
- Snap! Build Your Own Blocks 5.2.1
+ Snap! Build Your Own Blocks 5.2.2
-
+
-
-
+
+
diff --git a/src/gui.js b/src/gui.js
index db017ece..4320a710 100644
--- a/src/gui.js
+++ b/src/gui.js
@@ -79,7 +79,7 @@ BlockEditorMorph, BlockDialogMorph*/
// Global stuff ////////////////////////////////////////////////////////
-modules.gui = '2019-October-24';
+modules.gui = '2019-October-25';
// Declarations
@@ -3626,7 +3626,7 @@ IDE_Morph.prototype.aboutSnap = function () {
module, btn1, btn2, btn3, btn4, licenseBtn, translatorsBtn,
world = this.world();
- aboutTxt = 'Snap! 5.2.1\nBuild Your Own Blocks\n\n'
+ aboutTxt = 'Snap! 5.2.2\nBuild Your Own Blocks\n\n'
+ 'Copyright \u24B8 2019 Jens M\u00F6nig and '
+ 'Brian Harvey\n'
+ 'jens@moenig.org, bh@cs.berkeley.edu\n\n'
diff --git a/src/morphic.js b/src/morphic.js
index 46b292fb..be629c02 100644
--- a/src/morphic.js
+++ b/src/morphic.js
@@ -1178,7 +1178,7 @@
/*global window, HTMLCanvasElement, FileReader, Audio, FileList, Map*/
-var morphicVersion = '2019-October-24';
+var morphicVersion = '2019-October-25';
var modules = {}; // keep track of additional loaded modules
var useBlurredShadows = getBlurredShadowSupport(); // check for Chrome-bug
@@ -4495,43 +4495,46 @@ Morph.prototype.evaluateString = function (code) {
// Morph collision detection:
Morph.prototype.isTouching = function (otherMorph) {
- var oImg = this.overlappingImage(otherMorph),
- data, len, i;
+ var data = this.overlappingPixels(otherMorph),
+ len, i;
- if (!oImg) {return false; }
- data = oImg.getContext('2d')
- .getImageData(0, 0, oImg.width, oImg.height)
- .data;
- len = data.length;
- for(i = 3; i < len; i += 4) {
- if (data[i] !== 0) {return true; }
+ if (!data) {return false; }
+ len = data[0].length;
+ for (i = 3; i < len; i += 4) {
+ if (data[0][i] && data[1][i]) {return true; }
}
return false;
};
-Morph.prototype.overlappingImage = function (otherMorph) {
+Morph.prototype.overlappingPixels = function (otherMorph) {
var fb = this.fullBounds(),
otherFb = otherMorph.fullBounds(),
oRect = fb.intersect(otherFb),
- oImg, ctx;
+ thisImg, thatImg;
if (oRect.width() < 1 || oRect.height() < 1) {
return false;
}
- oImg = newCanvas(oRect.extent());
- ctx = oImg.getContext('2d');
- ctx.drawImage(
- this.fullImage(),
- oRect.origin.x - fb.origin.x,
- oRect.origin.y - fb.origin.y
- );
- ctx.globalCompositeOperation = 'source-in';
- ctx.drawImage(
- otherMorph.fullImage(),
- otherFb.origin.x - oRect.origin.x,
- otherFb.origin.y - oRect.origin.y
- );
- return oImg;
+ thisImg = this.fullImage();
+ thatImg = otherMorph.fullImage();
+ if (thisImg.isRetinaEnabled !== thatImg.isRetinaEnabled) {
+ thisImg = normalizeCanvas(thisImg, true);
+ thatImg = normalizeCanvas(thatImg, true);
+ }
+ return [
+ thisImg.getContext("2d").getImageData(
+ oRect.left() - this.left(),
+ oRect.top() - this.top(),
+ oRect.width(),
+ oRect.height()
+ ).data,
+ thatImg.getContext("2d").getImageData(
+ oRect.left() - otherMorph.left(),
+ oRect.top() - otherMorph.top(),
+ oRect.width(),
+ oRect.height()
+ ).data
+ ];
};
// ShadowMorph /////////////////////////////////////////////////////////
diff --git a/src/objects.js b/src/objects.js
index 7fee3079..fb394fd2 100644
--- a/src/objects.js
+++ b/src/objects.js
@@ -84,7 +84,7 @@ BlockEditorMorph, BlockDialogMorph, PrototypeHatBlockMorph, BooleanSlotMorph,
localize, TableMorph, TableFrameMorph, normalizeCanvas, VectorPaintEditorMorph,
HandleMorph, AlignmentMorph, Process, XML_Element, WorldMap*/
-modules.objects = '2019-October-24';
+modules.objects = '2019-October-25';
var SpriteMorph;
var StageMorph;
@@ -4242,30 +4242,36 @@ SpriteMorph.prototype.goBack = function (layers) {
// SpriteMorph collision detection optimization
-SpriteMorph.prototype.overlappingImage = function (otherSprite) {
+SpriteMorph.prototype.overlappingPixels = function (otherSprite) {
// overrides method from Morph because Sprites aren't nested Morphs
var oRect = this.bounds.intersect(otherSprite.bounds),
- oImg, ctx;
-
+ thisImg = this.image,
+ thatImg = otherSprite.image;
+
if (oRect.width() < 1 || oRect.height() < 1 ||
- !this.image.width || !this.image.height
- || !otherSprite.image.width || !otherSprite.image.height) {
+ !this.image.width || !this.image.height ||
+ !otherSprite.image.width || !otherSprite.image.height
+ ) {
return false;
}
- oImg = newCanvas(oRect.extent(), true);
- ctx = oImg.getContext('2d');
- ctx.drawImage(
- this.image,
- this.left() - oRect.left(),
- this.top() - oRect.top()
- );
- ctx.globalCompositeOperation = 'source-in';
- ctx.drawImage(
- otherSprite.image,
- otherSprite.left() - oRect.left(),
- otherSprite.top() - oRect.top()
- );
- return oImg;
+ if (thisImg.isRetinaEnabled !== thatImg.isRetinaEnabled) {
+ thisImg = normalizeCanvas(thisImg, true);
+ thatImg = normalizeCanvas(thatImg, true);
+ }
+ return [
+ thisImg.getContext("2d").getImageData(
+ oRect.left() - this.left(),
+ oRect.top() - this.top(),
+ oRect.width(),
+ oRect.height()
+ ).data,
+ thatImg.getContext("2d").getImageData(
+ oRect.left() - otherSprite.left(),
+ oRect.top() - otherSprite.top(),
+ oRect.width(),
+ oRect.height()
+ ).data
+ ];
};
// SpriteMorph pen ops
@@ -7570,11 +7576,7 @@ StageMorph.prototype.penTrailsMorph = function () {
morph = new Morph();
trails = this.penTrails();
morph.bounds = this.bounds.copy();
- if (this.image.width === trails.width) {
- morph.image = trails;
- return morph;
- }
- morph.image = newCanvas(this.extent());
+ morph.image = newCanvas(this.extent(), true);
ctx = morph.image.getContext('2d');
ctx.drawImage(
trails,