diff --git a/history.txt b/history.txt index 9dc90800..a441c293 100755 --- a/history.txt +++ b/history.txt @@ -1875,3 +1875,7 @@ ______ ------ * Objects, GUI: Nestable Sprites fixes * German translation update + +130812 +------ +* Objects, Threads: Nestable Sprites Collision Detection & fixes diff --git a/objects.js b/objects.js index e29a0f51..022594bd 100644 --- a/objects.js +++ b/objects.js @@ -124,7 +124,7 @@ PrototypeHatBlockMorph*/ // Global stuff //////////////////////////////////////////////////////// -modules.objects = '2013-August-10'; +modules.objects = '2013-August-12'; var SpriteMorph; var StageMorph; @@ -2649,7 +2649,7 @@ SpriteMorph.prototype.drawLine = function (start, dest) { } }; -// SpriteMorph motion +// SpriteMorph motion - adjustments due to nesting SpriteMorph.prototype.moveBy = function (delta, justMe) { // override the inherited default to make sure my parts follow @@ -2667,6 +2667,32 @@ SpriteMorph.prototype.moveBy = function (delta, justMe) { } }; +SpriteMorph.prototype.slideBackTo = function (situation, inSteps) { + // override the inherited default to make sure my parts follow + var steps = inSteps || 5, + pos = situation.origin.position().add(situation.position), + xStep = -(this.left() - pos.x) / steps, + yStep = -(this.top() - pos.y) / steps, + stepCount = 0, + oldStep = this.step, + oldFps = this.fps, + myself = this; + + this.fps = 0; + this.step = function () { + myself.moveBy(new Point(xStep, yStep)); + stepCount += 1; + if (stepCount === steps) { + situation.origin.add(myself); + if (situation.origin.reactToDropOf) { + situation.origin.reactToDropOf(myself); + } + myself.step = oldStep; + myself.fps = oldFps; + } + }; +}; + SpriteMorph.prototype.setCenter = function (aPoint, justMe) { // override the inherited default to make sure my parts follow // unless it's justMe @@ -2674,6 +2700,20 @@ SpriteMorph.prototype.setCenter = function (aPoint, justMe) { this.moveBy(delta, justMe); }; +SpriteMorph.prototype.nestingBounds = function () { + // same as fullBounds(), except that it uses "parts" instead of children + var result; + result = this.bounds; + this.parts.forEach(function (part) { + if (part.isVisible) { + result = result.merge(part.nestingBounds()); + } + }); + return result; +}; + +// SpriteMorph motion primitives + Morph.prototype.setPosition = function (aPoint, justMe) { // override the inherited default to make sure my parts follow // unless it's justMe @@ -2830,32 +2870,34 @@ SpriteMorph.prototype.glide = function ( }; SpriteMorph.prototype.bounceOffEdge = function () { + // taking nested parts into account var stage = this.parentThatIsA(StageMorph), + fb = this.nestingBounds(), dirX, dirY; if (!stage) {return null; } - if (stage.bounds.containsRectangle(this.bounds)) {return null; } + if (stage.bounds.containsRectangle(fb)) {return null; } dirX = Math.cos(radians(this.heading - 90)); dirY = -(Math.sin(radians(this.heading - 90))); - if (this.left() < stage.left()) { + if (fb.left() < stage.left()) { dirX = Math.abs(dirX); } - if (this.right() > stage.right()) { + if (fb.right() > stage.right()) { dirX = -(Math.abs(dirX)); } - if (this.top() < stage.top()) { + if (fb.top() < stage.top()) { dirY = -(Math.abs(dirY)); } - if (this.bottom() > stage.bottom()) { + if (fb.bottom() > stage.bottom()) { dirY = Math.abs(dirY); } this.setHeading(degrees(Math.atan2(-dirY, dirX)) + 90); this.setPosition(this.position().add( - this.bounds.amountToTranslateWithin(stage.bounds) + fb.amountToTranslateWithin(stage.bounds) )); this.positionTalkBubble(); }; diff --git a/threads.js b/threads.js index b46e18cb..ab36e87e 100644 --- a/threads.js +++ b/threads.js @@ -83,7 +83,7 @@ ArgLabelMorph, localize, XML_Element, hex_sha512*/ // Global stuff //////////////////////////////////////////////////////// -modules.threads = '2013-August-02'; +modules.threads = '2013-August-12'; var ThreadManager; var Process; @@ -2161,32 +2161,69 @@ Process.prototype.createClone = function (name) { // Process sensing primitives Process.prototype.reportTouchingObject = function (name) { - // also check for temparary clones, as in Scratch 2.0 - var thisObj = this.homeContext.receiver, + var thisObj = this.homeContext.receiver; + + if (thisObj) { + return this.objectTouchingObject(thisObj, name); + } + return false; +}; + +Process.prototype.objectTouchingObject = function (thisObj, name) { + // helper function for reportTouchingObject() + // also check for temparary clones, as in Scratch 2.0, + // and for any parts (subsprites) + var myself = this, those, stage, mouse; - if (thisObj) { - if (this.inputOption(name) === 'mouse-pointer') { - mouse = thisObj.world().hand.position(); - if (thisObj.bounds.containsPoint(mouse)) { - return !thisObj.isTransparentAt(mouse); - } - return false; + if (this.inputOption(name) === 'mouse-pointer') { + mouse = thisObj.world().hand.position(); + if (thisObj.bounds.containsPoint(mouse) && + !thisObj.isTransparentAt(mouse)) { + return true; } + } else { stage = thisObj.parentThatIsA(StageMorph); if (stage) { - if (this.inputOption(name) === 'edge') { - return !stage.bounds.containsRectangle(thisObj.bounds); + if (this.inputOption(name) === 'edge' && + !stage.bounds.containsRectangle(thisObj.bounds)) { + return true; } - if (this.inputOption(name) === 'pen trails') { - return thisObj.isTouching(stage.penTrailsMorph()); + if (this.inputOption(name) === 'pen trails' && + thisObj.isTouching(stage.penTrailsMorph())) { + return true; } those = this.getObjectsNamed(name, thisObj, stage); // clones - return those.some( - function (any) { + if (those.some(function (any) { return thisObj.isTouching(any); + })) { + return true; + } + } + } + return thisObj.parts.some( + function (any) { + return myself.objectTouchingObject(any, name); + } + ); +}; + +Process.prototype.reportTouchingColor = function (aColor) { + // also check for any parts (subsprites) + var thisObj = this.homeContext.receiver, + stage; + + if (thisObj) { + stage = thisObj.parentThatIsA(StageMorph); + if (stage) { + if (thisObj.isTouching(stage.colorFiltered(aColor, thisObj))) { + return true; + } + return thisObj.parts.some( + function (any) { + return any.isTouching(stage.colorFiltered(aColor, any)); } ); } @@ -2194,28 +2231,25 @@ Process.prototype.reportTouchingObject = function (name) { return false; }; -Process.prototype.reportTouchingColor = function (aColor) { - var thisObj = this.homeContext.receiver, - stage; - - if (thisObj) { - stage = thisObj.parentThatIsA(StageMorph); - if (stage) { - return thisObj.isTouching(stage.colorFiltered(aColor, thisObj)); - } - } - return false; -}; - Process.prototype.reportColorIsTouchingColor = function (color1, color2) { + // also check for any parts (subsprites) var thisObj = this.homeContext.receiver, stage; if (thisObj) { stage = thisObj.parentThatIsA(StageMorph); if (stage) { - return thisObj.colorFiltered(color1).isTouching( - stage.colorFiltered(color2, thisObj) + if (thisObj.colorFiltered(color1).isTouching( + stage.colorFiltered(color2, thisObj) + )) { + return true; + } + return thisObj.parts.some( + function (any) { + return any.colorFiltered(color1).isTouching( + stage.colorFiltered(color2, any) + ); + } ); } }