summaryrefslogtreecommitdiff
path: root/objects.js
diff options
context:
space:
mode:
Diffstat (limited to 'objects.js')
-rw-r--r--objects.js249
1 files changed, 146 insertions, 103 deletions
diff --git a/objects.js b/objects.js
index 1fe1309..a00c9cc 100644
--- a/objects.js
+++ b/objects.js
@@ -202,13 +202,53 @@ SpriteMorph.prototype.bubbleMaxTextWidth = 130;
SpriteMorph.prototype.initBlocks = function () {
SpriteMorph.prototype.blocks = {
+ // Map (Snap! in Your Own World)
+ userLon: {
+ type: 'reporter',
+ category: 'motion',
+ spec: 'user lon'
+ },
+ userLat: {
+ type: 'reporter',
+ category: 'motion',
+ spec: 'user lat'
+ },
+ findLocation: {
+ type: 'reporter',
+ category: 'motion',
+ spec: 'lat, lon of %s',
+ defaults: ['Tiergarten Berlin']
+ },
+ reportGeocode: {
+ type: 'reporter',
+ category: 'motion',
+ spec: 'address at lon: %n lat: %n'
+ },
+ overpassQuerySucceeds: {
+ type: 'predicate',
+ category: 'motion',
+ spec: 'overpass query %s returns elements'
+ },
+ focusMap: {
+ type: 'command',
+ category: 'motion',
+ spec: 'set focus to lon: %n lat: %n with zoom %n',
+ defaults: [0, 0, 12]
+ },
+ addMarker: {
+ dev: true,
+ type: 'command',
+ category: 'motion',
+ spec: 'debug: add a marker to %l'
+ },
+
// Motion
forward: {
only: SpriteMorph,
type: 'command',
category: 'motion',
- spec: 'move %n steps',
- defaults: [10]
+ spec: 'move %n meters',
+ defaults: [2]
},
turn: {
only: SpriteMorph,
@@ -230,6 +270,12 @@ SpriteMorph.prototype.initBlocks = function () {
category: 'motion',
spec: 'point in direction %dir'
},
+ direction: {
+ only: SpriteMorph,
+ type: 'reporter',
+ category: 'motion',
+ spec: 'direction'
+ },
doFaceTowards: {
only: SpriteMorph,
type: 'command',
@@ -240,7 +286,7 @@ SpriteMorph.prototype.initBlocks = function () {
only: SpriteMorph,
type: 'command',
category: 'motion',
- spec: 'go to x: %n y: %n',
+ spec: 'go to lon: %n lat: %n',
defaults: [0, 0]
},
doGotoObject: {
@@ -253,35 +299,35 @@ SpriteMorph.prototype.initBlocks = function () {
only: SpriteMorph,
type: 'command',
category: 'motion',
- spec: 'glide %n secs to x: %n y: %n',
+ spec: 'glide %n secs to lon: %n lat: %n',
defaults: [1, 0, 0]
},
changeXPosition: {
only: SpriteMorph,
type: 'command',
category: 'motion',
- spec: 'change x by %n',
+ spec: 'change lat by %n',
defaults: [10]
},
setXPosition: {
only: SpriteMorph,
type: 'command',
category: 'motion',
- spec: 'set x to %n',
+ spec: 'set lon to %n',
defaults: [0]
},
changeYPosition: {
only: SpriteMorph,
type: 'command',
category: 'motion',
- spec: 'change y by %n',
+ spec: 'change lat by %n',
defaults: [10]
},
setYPosition: {
only: SpriteMorph,
type: 'command',
category: 'motion',
- spec: 'set y to %n',
+ spec: 'set lat to %n',
defaults: [0]
},
bounceOffEdge: {
@@ -294,19 +340,13 @@ SpriteMorph.prototype.initBlocks = function () {
only: SpriteMorph,
type: 'reporter',
category: 'motion',
- spec: 'x position'
+ spec: 'longitude'
},
yPosition: {
only: SpriteMorph,
type: 'reporter',
category: 'motion',
- spec: 'y position'
- },
- direction: {
- only: SpriteMorph,
- type: 'reporter',
- category: 'motion',
- spec: 'direction'
+ spec: 'latitude'
},
// Looks
@@ -1359,6 +1399,42 @@ SpriteMorph.prototype.init = function (globals) {
this.changed();
};
+SpriteMorph.prototype.updateMarker = function () {
+ var myself = this;
+
+ if (!this.parent) return; // not loaded yet, xPosition is not available
+
+ if (window.spriteGroup.hasLayer(this.marker)) {
+ // if it is created the first time, it cannot be removed
+ window.spriteGroup.removeLayer(this.marker);
+ }
+ if (this.isVisible == false) return;
+
+ // create a new marker with the sprite as icon
+ this.icon = L.spriteIcon({
+ iconAnchor: [this.rotationOffset.x, this.rotationOffset.y],
+ canvas: this.image
+ });
+ // X position is longitude, Y latitude
+ this.marker = L.marker([this.yPosition(), this.xPosition()],
+ {icon: this.icon, title: this.name});
+
+ // add event handlers
+ this.marker.on('click', function () {
+ myself.mouseClickLeft();
+ });
+
+ // apply graphic effects that do not apply to the icon canvas
+ this.marker.setOpacity(this.alpha);
+ if (this.parent) {
+ var layer = this.parent.children.indexOf(this);
+ this.marker.setZIndexOffset(layer);
+ }
+
+ // display that marker
+ this.marker.addTo(window.spriteGroup);
+};
+
// SpriteMorph duplicating (fullCopy)
SpriteMorph.prototype.fullCopy = function () {
@@ -1541,6 +1617,7 @@ SpriteMorph.prototype.drawNew = function () {
}
}
this.version = Date.now();
+ this.updateMarker(); // Snap! YOW
};
SpriteMorph.prototype.endWarp = function () {
@@ -1719,6 +1796,22 @@ SpriteMorph.prototype.blockTemplates = function (category) {
}
if (cat === 'motion') {
+ blocks.push(block('userLon'));
+ blocks.push(block('userLat'));
+ blocks.push('-');
+ blocks.push(block('overpassQuerySucceeds'));
+ blocks.push('-');
+ blocks.push(block('reportGeocode'));
+ blocks.push(block('findLocation'));
+ blocks.push('-');
+ blocks.push(block('focusMap'));
+ blocks.push('-');
+
+ //if (this.world().isDevMode) {
+ blocks.push(block('addMarker'));
+ //}
+
+ blocks.push('=');
blocks.push(block('forward'));
blocks.push(block('turn'));
@@ -1736,8 +1829,6 @@ SpriteMorph.prototype.blockTemplates = function (category) {
blocks.push(block('changeYPosition'));
blocks.push(block('setYPosition'));
blocks.push('-');
- blocks.push(block('bounceOffEdge'));
- blocks.push('-');
blocks.push(watcherToggle('xPosition'));
blocks.push(block('xPosition'));
blocks.push(watcherToggle('yPosition'));
@@ -2592,7 +2683,7 @@ SpriteMorph.prototype.doSwitchToCostume = function (id) {
(id instanceof Array ? id[0] : null)
)
) {
- costume = null;
+ this.costume = null;
} else {
if (id === -1) {
this.doWearPreviousCostume();
@@ -2604,7 +2695,7 @@ SpriteMorph.prototype.doSwitchToCostume = function (id) {
if (costume === null) {
num = parseFloat(id);
if (num === 0) {
- costume = null;
+ this.costume = null;
} else {
costume = arr[num - 1] || null;
}
@@ -2761,11 +2852,13 @@ SpriteMorph.prototype.removeClone = function () {
SpriteMorph.prototype.hide = function () {
SpriteMorph.uber.hide.call(this);
this.parts.forEach(function (part) {part.hide(); });
+ this.updateMarker();
};
SpriteMorph.prototype.show = function () {
SpriteMorph.uber.show.call(this);
this.parts.forEach(function (part) {part.show(); });
+ this.updateMarker();
};
// SpriteMorph pen color
@@ -2833,6 +2926,7 @@ SpriteMorph.prototype.comeToFront = function () {
this.parent.add(this);
this.changed();
}
+ this.updateMarker();
};
SpriteMorph.prototype.goBack = function (layers) {
@@ -2843,6 +2937,7 @@ SpriteMorph.prototype.goBack = function (layers) {
this.parent.removeChild(this);
this.parent.children.splice(layer - newLayer, null, this);
this.parent.changed();
+ this.updateMarker();
};
// SpriteMorph collision detection optimization
@@ -3113,6 +3208,9 @@ SpriteMorph.prototype.clearEffects = function () {
// SpriteMorph talk bubble
SpriteMorph.prototype.stopTalking = function () {
+ if (window.map.hasLayer(this.popup)) {
+ window.map.removeLayer(this.popup);
+ }
var bubble = this.talkBubble();
if (bubble) {bubble.destroy(); }
};
@@ -3127,6 +3225,13 @@ SpriteMorph.prototype.bubble = function (data, isThought, isQuestion) {
this.stopTalking();
if (data === '' || isNil(data)) {return; }
+
+ // Snap! YOW
+ this.popup = L.popup()
+ .setLatLng([this.yPosition(), this.xPosition()])
+ .setContent(data)
+ .addTo(window.map);
+
bubble = new SpriteBubbleMorph(
data,
stage ? stage.scale : 1,
@@ -3290,6 +3395,20 @@ SpriteMorph.prototype.nestingBounds = function () {
// SpriteMorph motion primitives
+SpriteMorph.prototype.forward = function (meters) {
+ // FIXME this is an approximation
+ var kilometers = meters / 1000;
+ var diffLat, diffLon;
+ diffLat = Math.cos(radians(this.heading)) * (1 / 110.54 * kilometers);
+ diffLon = Math.sin(radians(this.heading))
+ * (1 / (111.32 * Math.cos(radians(this.yPosition()))) * kilometers);
+
+ // TODO: "0 - ..." – why does this work? The formula above looks wrong ;-)
+ var diffPoint = new Point(diffLon, 0 - diffLat);
+ this.setPosition(this.position().add(diffPoint));
+ this.updateMarker();
+};
+
Morph.prototype.setPosition = function (aPoint, justMe) {
// override the inherited default to make sure my parts follow
// unless it's justMe
@@ -3299,22 +3418,6 @@ Morph.prototype.setPosition = function (aPoint, justMe) {
}
};
-SpriteMorph.prototype.forward = function (steps) {
- var dest,
- dist = steps * this.parent.scale || 0;
-
- if (dist >= 0) {
- dest = this.position().distanceAngle(dist, this.heading);
- } else {
- dest = this.position().distanceAngle(
- Math.abs(dist),
- (this.heading - 180)
- );
- }
- this.setPosition(dest);
- this.positionTalkBubble();
-};
-
SpriteMorph.prototype.setHeading = function (degrees) {
var x = this.xPosition(),
y = this.yPosition(),
@@ -3404,6 +3507,7 @@ SpriteMorph.prototype.gotoXY = function (x, y, justMe) {
}
this.setPosition(dest, justMe);
this.positionTalkBubble();
+ this.updateMarker();
};
SpriteMorph.prototype.silentGotoXY = function (x, y, justMe) {
@@ -4450,73 +4554,12 @@ StageMorph.prototype.drawNew = function () {
};
StageMorph.prototype.drawOn = function (aCanvas, aRect) {
- // make sure to draw the pen trails canvas as well
- var rectangle, area, delta, src, context, w, h, sl, st, ws, hs;
- if (!this.isVisible) {
- return null;
- }
- rectangle = aRect || this.bounds;
- area = rectangle.intersect(this.bounds).round();
- if (area.extent().gt(new Point(0, 0))) {
- delta = this.position().neg();
- src = area.copy().translateBy(delta).round();
- context = aCanvas.getContext('2d');
- context.globalAlpha = this.alpha;
-
- sl = src.left();
- st = src.top();
- w = Math.min(src.width(), this.image.width - sl);
- h = Math.min(src.height(), this.image.height - st);
-
- if (w < 1 || h < 1) {
- return null;
- }
- context.drawImage(
- this.image,
- src.left(),
- src.top(),
- w,
- h,
- area.left(),
- area.top(),
- w,
- h
- );
-
- // pen trails
- ws = w / this.scale;
- hs = h / this.scale;
- context.save();
- context.scale(this.scale, this.scale);
- try {
- context.drawImage(
- this.penTrails(),
- src.left() / this.scale,
- src.top() / this.scale,
- ws,
- hs,
- area.left() / this.scale,
- area.top() / this.scale,
- ws,
- hs
- );
- } catch (err) { // sometimes triggered only by Firefox
- // console.log(err);
- context.restore();
- context.drawImage(
- this.penTrails(),
- 0,
- 0,
- this.dimensions.x,
- this.dimensions.y,
- this.left(),
- this.top(),
- this.dimensions.x * this.scale,
- this.dimensions.y * this.scale
- );
- }
- context.restore();
- }
+ var map = document.getElementById('map');
+ map.style.width = this.dimensions.x * this.scale + 'px';
+ map.style.height = this.dimensions.y * this.scale + 'px';
+ map.style.left = this.left() + 'px';
+ map.style.top = this.top() + 'px';
+ window.map.invalidateSize();
};
StageMorph.prototype.clearPenTrails = function () {