diff options
Diffstat (limited to 'objects.js')
| -rw-r--r-- | objects.js | 249 |
1 files changed, 146 insertions, 103 deletions
@@ -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 () { |
