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,