From 8263918b8d5d9c0f5f500e261f8d6e4cd78be7fe Mon Sep 17 00:00:00 2001 From: FrozenCow Date: Mon, 10 Jan 2011 23:58:39 +0100 Subject: [PATCH] Abstracted from cave+normal to kzedmaps. Can now have any configurable type of map. --- web/config.js | 11 ++- web/index.html | 7 +- web/kzedmaps.js | 128 ++++++++++++++++++++++++++++++++++ web/map.js | 180 ++++++++++++------------------------------------ web/style.css | 31 ++++++++- 5 files changed, 213 insertions(+), 144 deletions(-) create mode 100644 web/kzedmaps.js diff --git a/web/config.js b/web/config.js index 2f9415c9..00b68fbd 100644 --- a/web/config.js +++ b/web/config.js @@ -1,10 +1,17 @@ -var setup = { +var config = { tileUrl: 'tiles/', updateUrl: 'up/', // For Apache and lighttpd // updateUrl: 'up/default.aspx?lasttimestamp=', // For IIS updateRate: 2000, // Seconds the map should poll for updates. (Seconds) * 1000. The default is 2000 (every 2 seconds). showPortraitsOnMap: true, showPortraitsInPlayerList: true, - showPlayerNameOnMap: false + showPlayerNameOnMap: false, + defaultMap: 'defaultmap', + maps: { + 'defaultmap': new DefaultMapType(), + 'cavemap': new CaveMapType() + }, + tileWidth: 128, + tileHeight: 128 }; diff --git a/web/index.html b/web/index.html index 23150bc7..77718198 100644 --- a/web/index.html +++ b/web/index.html @@ -12,17 +12,18 @@ - - + + +
on - +
diff --git a/web/kzedmaps.js b/web/kzedmaps.js new file mode 100644 index 00000000..763bdf6d --- /dev/null +++ b/web/kzedmaps.js @@ -0,0 +1,128 @@ +function KzedProjection() {} +KzedProjection.prototype = { + fromLatLngToPoint: function(latLng) { + var x = (latLng.lng() * config.tileWidth)|0; + var y = (latLng.lat() * config.tileHeight)|0; + + return new google.maps.Point(x, y); + }, + fromPointToLatLng: function(point) { + var lng = point.x / config.tileWidth; + var lat = point.y / config.tileHeight; + return new google.maps.LatLng(lat, lng); + }, + fromWorldToLatLng: function(x, y, z) + { + var dx = +x; + var dy = +y - 127; + var dz = +z; + var px = dx + dz; + var py = dx - dz - dy; + + var lng = -px / config.tileWidth / 2 + 0.5; + var lat = py / config.tileHeight / 2; + + return new google.maps.LatLng(lat, lng); + } +}; + +function KzedMapType() {} +KzedMapType.prototype = { + projection: new KzedProjection(), + tileSize: new google.maps.Size(128, 128), + minZoom: 0, + maxZoom: 3, + prefix: null, + getTile: function(coord, zoom, doc) { + var tileDebugText = null; + var tileSize = 128; + var tileName; + var imgSize; + var offset = {x: 0, y: 0}; + + var debugred; + var debugblue; + + if (zoom == 0) { + // Most zoomed out tiles. + + tileSize = 128; + imgSize = tileSize; + tileName = 'z' + this.prefix + '_' + (-coord.x * tileSize*2) + '_' + (coord.y * tileSize*2); + } else { + // Other zoom levels. + tileSize = 128; + + // Helper functions. + var floor = Math.floor; + var div = function(x,y){return floor(x/y);} + var mod = function(x,y){return ((x%y)+y)%y;}; + + // Split the image up in ... segments (1*1 for zoom 1, 2*2 for zoom 2, 4*4 for zoom 3, etc). + var segments = Math.pow(2,zoom-1); + imgSize = segments*tileSize; + + // Calculate the location relative to the world of this segment. + var mapcoord = {x: div(coord.x,segments)*tileSize, y: div(coord.y,segments)*tileSize}; + // Calculate the location relative to the image of this segment. + offset = {x: mod(coord.x,segments)*-tileSize, y: mod(coord.y,segments)*-tileSize}; + + // The next couple of lines are somewhat of a hack, but makes it faster to render zoomed in tiles: + /*tileSize = imgSize; + + if (offset.x == 0 && offset.y == 0) { + tileName = this.prefix + '_' + (-mapcoord.x) + '_' + mapcoord.y; + } + offset = {x: 0, y: 0};*/ + // The next line is not: + tileName = this.prefix + '_' + (-mapcoord.x) + '_' + mapcoord.y; + } + var img; + var tile = $('
') + .addClass('tile') + .css({ + overflow: 'hidden', + width: tileSize + 'px', + height: tileSize + 'px' + }); + if (tileDebugText) { + $('') + .text(tileDebugText) + .css({ + position: 'absolute', + color: 'red' + }) + .appendTo(tile); + } + if (tileName) { + img = $('') + .attr('src', tileUrl(tileName)) + .error(function() { img.hide(); }) + .css({ + width: imgSize + 'px', + height: imgSize + 'px', + borderStyle: 'none', + marginLeft: offset.x + 'px', + marginTop: offset.y + 'px' + }) + .appendTo(tile); + tileDict[tileName] = img; + } else { + delete tileDict[tileName]; + } + return tile.get(0); + }, +}; + +DefaultMapType.prototype = new KzedMapType(); +DefaultMapType.prototype.constructor = DefaultMapType; +function DefaultMapType(){} +DefaultMapType.prototype.prefix = 't'; + + + +CaveMapType.prototype = new KzedMapType(); +CaveMapType.prototype.constructor = CaveMapType; +function CaveMapType(){} +CaveMapType.prototype.prefix = 'ct'; + diff --git a/web/map.js b/web/map.js index 0c29236c..c84379fe 100644 --- a/web/map.js +++ b/web/map.js @@ -1,3 +1,5 @@ +if (!console) console = { log: function() {} }; + /* generic function for making an XMLHttpRequest * url: request URL * func: callback function for success @@ -51,48 +53,6 @@ function makeRequest(url, func, type, fail, post, contenttype) http_request.send(null); } } - - - var config = { - tileUrl: setup.tileUrl, - updateUrl: setup.updateUrl, - tileWidth: 128, - tileHeight: 128, - updateRate: setup.updateRate - }; - - function MCMapProjection() { - } - - MCMapProjection.prototype.fromLatLngToPoint = function(latLng) { - var x = (latLng.lng() * config.tileWidth)|0; - var y = (latLng.lat() * config.tileHeight)|0; - - return new google.maps.Point(x, y); - }; - - MCMapProjection.prototype.fromPointToLatLng = function(point) { - var lng = point.x / config.tileWidth; - var lat = point.y / config.tileHeight; - return new google.maps.LatLng(lat, lng); - }; - - function fromWorldToLatLng(x, y, z) - { - var dx = +x; - var dy = +y - 127; - var dz = +z; - var px = dx + dz; - var py = dx - dz - dy; - - var lng = -px / config.tileWidth / 2 + 0.5; - var lat = py / config.tileHeight / 2; - - return new google.maps.LatLng(lat, lng); - } - - function mcMapType() { - } var tileDict = new Array(); var lastSeen = new Array(); @@ -108,86 +68,20 @@ function makeRequest(url, func, type, fail, post, contenttype) } } - function imgSubst(tile) { - if(!(tile in tileDict)) + function onTileUpdated(tileName, f) { + + } + + function imgSubst(tileName) { + if(!(tileName in tileDict)) return; - var src = tileUrl(tile); - var t = tileDict[tile]; - t.src = src; - t.style.display = ''; - t.onerror = function() { - setTimeout(function() { - t.src = tileUrl(tile, 1); - }, 1000); - t.onerror = ''; - } + var src = tileUrl(tileName); + var t = tileDict[tileName]; + t.attr('src', src); + t.show(); } - var caveMode = false; - - function caveSwitch() - { - caveMode = !caveMode; - - if(caveMode) { - cavebtn.src = 'cave_on.png'; - map.setMapTypeId('cavemap'); - } else { - cavebtn.src = 'cave_off.png'; - map.setMapTypeId('mcmap'); - } - } - - function getImageSize(zoom) { - return zoom > 0 ? config.tileWidth : config.tileWidth*2; - } - - function getTileSize(zoom, imageSize) { - imageSize = imageSize || getImageSize(zoom); - return Math.pow(2, 6+zoom) * (imageSize / config.tileWidth); - } - - function getTileInfo(coord, zoom) { - var imageSize = getImageSize(zoom); - var tileSize = getTileSize(zoom, imageSize); - - var imageName = ''; - if (caveMode) imageName += 'c'; - if (zoom == 0) imageName += 'z'; - imageName += 't_' + (-coord.x * imageSize) + '_' + (coord.y * imageSize); - - return { - name: imageName, - size: tileSize, - }; - } - - mcMapType.prototype.tileSize = new google.maps.Size(config.tileWidth, config.tileHeight); - mcMapType.prototype.minZoom = 0; - mcMapType.prototype.maxZoom = 3; - mcMapType.prototype.getTile = function(coord, zoom, doc) { - var img = doc.createElement('IMG'); - - img.onerror = function() { img.style.display = 'none'; } - - var tileInfo = getTileInfo(coord, zoom); - - img.style.width = tileInfo.size + 'px'; - img.style.height = tileInfo.size + 'px'; - img.style.borderStyle = 'none'; - //img.style.border = '1px solid red'; - //img.style.margin = '-1px -1px -1px -1px'; - - tileDict[tileInfo.name] = img; - - var url = tileUrl(tileInfo.name); - img.src = url; - //img.style.background = 'url(' + url + ')'; - //img.innerHTML = '' + tilename + ''; - - return img; - } var markers = new Array(); var lasttimestamp = '0'; @@ -195,7 +89,6 @@ function makeRequest(url, func, type, fail, post, contenttype) var lst; var plistbtn; - var cavebtn; var lstopen = true; var oldplayerlst = '[Connecting]'; var servertime = 0; @@ -312,7 +205,7 @@ function makeRequest(url, func, type, fail, post, contenttype) id: p[0] + '_' + p[1], text: p[1], type: p[0], - position: fromWorldToLatLng(p[2], p[3], p[4]), + position: map.getProjection().fromWorldToLatLng(p[2], p[3], p[4]), visible: ((p[0] in typeVisibleMap) ? typeVisibleMap[p[0]] : true) }; @@ -365,11 +258,10 @@ function makeRequest(url, func, type, fail, post, contenttype) } return s; } - + window.onload = function initialize() { lst = document.getElementById('lst'); plistbtn = document.getElementById('plistbtn'); - cavebtn = document.getElementById('cavebtn'); var mapOptions = { zoom: 1, @@ -381,20 +273,9 @@ function makeRequest(url, func, type, fail, post, contenttype) scaleControl: false, mapTypeControl: false, streetViewControl: false, - mapTypeId: 'mcmap', backgroundColor: '#000' }; map = new google.maps.Map(document.getElementById("mcmap"), mapOptions); - mapType = new mcMapType(); - mapType.projection = new MCMapProjection(); - caveMapType = new mcMapType(); - caveMapType.projection = new MCMapProjection(); - - map.zoom_changed = function() { - var tileSize = getTileSize(map.zoom); - mapType.tileSize = new google.maps.Size(tileSize, tileSize); - caveMapType.tileSize = mapType.tileSize; - }; google.maps.event.addListener(map, 'dragstart', function(mEvent) { plfollow(''); @@ -407,11 +288,36 @@ function makeRequest(url, func, type, fail, post, contenttype) }); map.dragstart = plfollow(''); - map.mapTypes.set('mcmap', mapType); - map.mapTypes.set('cavemap', caveMapType); + $.each(config.maps, function(name, mapType){ + map.mapTypes.set(name, mapType); + + var mapButton; + $('#maplist').append($('
') + .addClass('maprow') + .append(mapButton = $('') + .addClass('maptype_' + name) + .attr({ + type: 'radio', + name: 'map', + id: 'maptypebutton_' + name + }) + .attr('checked', config.defaultMap == name ? 'checked' : null) + ) + .append($('