key event fixes, add canvas mode (default)
BIN
js/earth.png
Normal file
After Width: | Height: | Size: 219 B |
BIN
js/empty.png
Normal file
After Width: | Height: | Size: 73 B |
131
js/gui.js
@ -1,28 +1,31 @@
|
|||||||
var mineGui_mine, mineGui_curmap, mineGui_curndx, mineGui_moves = "";
|
var mineGui_mine, mineGui_curmap, mineGui_curndx, mineGui_moves = "";
|
||||||
var mineGui_movesBackup = [];
|
var mineGui_movesBackup = [];
|
||||||
var mineGui_customNdx = 1;
|
var mineGui_customNdx = 1;
|
||||||
|
var mineGui_canvas = true;
|
||||||
|
|
||||||
function mineGui_addCustomMap() {
|
var mineGui_imgSources = {
|
||||||
var map = document.getElementById("mineGui_data").value;
|
'R': 'robot.png',
|
||||||
var mine;
|
'#': 'wall.png',
|
||||||
var selMap = document.getElementById("mineGui_selectMap");
|
'*': 'rock.png',
|
||||||
document.getElementById("mineGui_addDataResult").textContent = "";
|
'\\': 'lambda.png',
|
||||||
try {
|
'L': 'liftclosed.png',
|
||||||
mine = new Mine(map);
|
'O': 'liftopen.png',
|
||||||
} catch (e) {
|
'.': 'earth.png',
|
||||||
document.getElementById("mineGui_addDataResult").textContent = "Adding map failed: " + e;
|
' ': 'empty.png'
|
||||||
return;
|
};
|
||||||
|
var mineGui_images = {};
|
||||||
|
var mineGui_imagesNeed = 0;
|
||||||
|
|
||||||
|
function mineGui_loadImg(key, src) {
|
||||||
|
var img;
|
||||||
|
++mineGui_imagesNeed;
|
||||||
|
mineGui_images[key] = img = new Image();
|
||||||
|
img.onload = function() {
|
||||||
|
if (0 == --mineGui_imagesNeed) {
|
||||||
|
mineGui_show();
|
||||||
}
|
}
|
||||||
mineMaps["custom" + mineGui_customNdx] = map;
|
};
|
||||||
var entry = document.createElement("option");
|
img.src = src;
|
||||||
entry.textContent = "custom" + mineGui_customNdx;
|
|
||||||
selMap.appendChild(entry);
|
|
||||||
mineGui_customNdx++;
|
|
||||||
|
|
||||||
window.setTimeout(function() {
|
|
||||||
selMap.selectedIndex = selMap.options.length - 1;
|
|
||||||
selMap.onchange();
|
|
||||||
}, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function mineGui_start() {
|
function mineGui_start() {
|
||||||
@ -31,6 +34,7 @@ function mineGui_start() {
|
|||||||
var inpMoves = document.getElementById("mineGui_moves");
|
var inpMoves = document.getElementById("mineGui_moves");
|
||||||
var customMapInput = document.getElementById("mineGui_data")
|
var customMapInput = document.getElementById("mineGui_data")
|
||||||
var validMoves = {L:1,U:1,R:1,D:1,A:1,W:1};
|
var validMoves = {L:1,U:1,R:1,D:1,A:1,W:1};
|
||||||
|
var k;
|
||||||
document.getElementById("mineGui_addData").onclick = mineGui_addCustomMap;
|
document.getElementById("mineGui_addData").onclick = mineGui_addCustomMap;
|
||||||
selMap.onchange = function() {
|
selMap.onchange = function() {
|
||||||
var k = selMap.options[selMap.selectedIndex].text;
|
var k = selMap.options[selMap.selectedIndex].text;
|
||||||
@ -54,21 +58,30 @@ function mineGui_start() {
|
|||||||
inpMoves.onpaste = delayInpValidate;
|
inpMoves.onpaste = delayInpValidate;
|
||||||
inpMoves.onkeypress = delayInpValidate;
|
inpMoves.onkeypress = delayInpValidate;
|
||||||
document.body.onkeydown = function (event) {
|
document.body.onkeydown = function (event) {
|
||||||
// console.log("body", event, event.type);
|
// console.log("body", event);
|
||||||
|
// console.log("isChar", event.isChar,
|
||||||
|
// "; char '"+String.fromCharCode(event.charCode)+
|
||||||
|
// "'; key '"+String.fromCharCode(event.keyCode)+"'")
|
||||||
if (document.activeElement === customMapInput) return;
|
if (document.activeElement === customMapInput) return;
|
||||||
if (event.ctrlKey || event.altKey || event.metaKey) return;
|
if (event.ctrlKey || event.altKey || event.metaKey) return;
|
||||||
var handled = true;
|
var handled = true;
|
||||||
var cmd = String.fromCharCode(event.charCode || event.keyCode).toUpperCase();
|
|
||||||
|
// ascii keys are reported as uppercase ascii code
|
||||||
|
var cmd = String.fromCharCode(event.keyCode);
|
||||||
if (validMoves[cmd]) {
|
if (validMoves[cmd]) {
|
||||||
mineGui_move(cmd);
|
mineGui_move(cmd);
|
||||||
} else if (cmd == 'C') { // clear
|
} else if (cmd == 'C') { // clear
|
||||||
mineGui_moves = "";
|
mineGui_moves = "";
|
||||||
mineGui_updateMine();
|
mineGui_updateMine();
|
||||||
} else if (event.keyCode == 8 || event.charCode == 8) {
|
} else if (cmd == 'T') { // toggle text/canvas
|
||||||
// backspace -> undo
|
mineGui_canvas = !mineGui_canvas;
|
||||||
|
console.log("canvas show", mineGui_canvas);
|
||||||
|
mineGui_show();
|
||||||
|
} else switch (event.keyCode) {
|
||||||
|
case 8: // backspace -> undo
|
||||||
mineGui_moves = mineGui_moves.slice(0,-1);
|
mineGui_moves = mineGui_moves.slice(0,-1);
|
||||||
mineGui_updateMine();
|
mineGui_updateMine();
|
||||||
} else switch (event.keyCode) {
|
break;
|
||||||
case 33: // page up
|
case 33: // page up
|
||||||
if (selMap.selectedIndex > 0) {
|
if (selMap.selectedIndex > 0) {
|
||||||
selMap.selectedIndex--;
|
selMap.selectedIndex--;
|
||||||
@ -82,16 +95,16 @@ function mineGui_start() {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 37: // left
|
case 37: // left
|
||||||
mineGui_move('L');
|
if (mineGui_mine.validMove('L')) mineGui_move('L');
|
||||||
break;
|
break;
|
||||||
case 38: // up
|
case 38: // up
|
||||||
mineGui_move('U');
|
if (mineGui_mine.validMove('U')) mineGui_move('U');
|
||||||
break;
|
break;
|
||||||
case 39: // right
|
case 39: // right
|
||||||
mineGui_move('R');
|
if (mineGui_mine.validMove('R')) mineGui_move('R');
|
||||||
break;
|
break;
|
||||||
case 40: // down
|
case 40: // down
|
||||||
mineGui_move('D');
|
if (mineGui_mine.validMove('D')) mineGui_move('D');
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
handled = false;
|
handled = false;
|
||||||
@ -103,6 +116,11 @@ function mineGui_start() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
for (k in mineGui_imgSources) {
|
||||||
|
if (mineGui_imgSources.hasOwnProperty(k)) {
|
||||||
|
mineGui_loadImg(k, mineGui_imgSources[k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
for (k in mineMaps) {
|
for (k in mineMaps) {
|
||||||
if (mineMaps.hasOwnProperty(k)) {
|
if (mineMaps.hasOwnProperty(k)) {
|
||||||
var entry = document.createElement("option");
|
var entry = document.createElement("option");
|
||||||
@ -115,6 +133,29 @@ function mineGui_start() {
|
|||||||
selMap.onchange();
|
selMap.onchange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function mineGui_addCustomMap() {
|
||||||
|
var map = document.getElementById("mineGui_data").value;
|
||||||
|
var mine;
|
||||||
|
var selMap = document.getElementById("mineGui_selectMap");
|
||||||
|
document.getElementById("mineGui_addDataResult").textContent = "";
|
||||||
|
try {
|
||||||
|
mine = new Mine(map);
|
||||||
|
} catch (e) {
|
||||||
|
document.getElementById("mineGui_addDataResult").textContent = "Adding map failed: " + e;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mineMaps["custom" + mineGui_customNdx] = map;
|
||||||
|
var entry = document.createElement("option");
|
||||||
|
entry.textContent = "custom" + mineGui_customNdx;
|
||||||
|
selMap.appendChild(entry);
|
||||||
|
mineGui_customNdx++;
|
||||||
|
|
||||||
|
window.setTimeout(function() {
|
||||||
|
selMap.selectedIndex = selMap.options.length - 1;
|
||||||
|
selMap.onchange();
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
|
||||||
function mineGui_move(cmd) {
|
function mineGui_move(cmd) {
|
||||||
for (i = 0; i < cmd.length; ++i) {
|
for (i = 0; i < cmd.length; ++i) {
|
||||||
if (mineGui_mine.state != Mine.ALIVE) break;
|
if (mineGui_mine.state != Mine.ALIVE) break;
|
||||||
@ -149,12 +190,42 @@ function mineGui_updateMine() {
|
|||||||
function mineGui_show() {
|
function mineGui_show() {
|
||||||
var waterLevel = Math.max(mineGui_mine.meta.Water, 0);
|
var waterLevel = Math.max(mineGui_mine.meta.Water, 0);
|
||||||
var map = mineGui_mine.toString().split(/\n/);
|
var map = mineGui_mine.toString().split(/\n/);
|
||||||
|
var canv = document.getElementById("mineGui_mineCanvas");
|
||||||
|
var mapNode = document.getElementById("mineGui_mineMap");
|
||||||
|
if (mineGui_canvas && 0 == mineGui_imagesNeed) {
|
||||||
|
canv.style.display = '';
|
||||||
|
canv.style.visibility = 'visible';
|
||||||
|
mapNode.style.display = 'none';
|
||||||
|
mapNode.style.visibility = 'hidden';
|
||||||
|
canv.width = 16*mineGui_mine.width;
|
||||||
|
canv.height = 16*mineGui_mine.height;
|
||||||
|
var ctx = canv.getContext("2d");
|
||||||
|
ctx.globalAlpha=1.0;
|
||||||
|
ctx.fillStyle = "black";
|
||||||
|
ctx.fillRect(0,0,canv.width, canv.height);
|
||||||
|
for (var y = 0; y < mineGui_mine.height; ++y) {
|
||||||
|
for (var x = 0; x < mineGui_mine.width; ++x) {
|
||||||
|
ctx.drawImage(mineGui_images[map[y][x]],16*x,16*y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.fillStyle = "#0000FF";
|
||||||
|
ctx.globalAlpha = 0.3;
|
||||||
|
y = 16*(mineGui_mine.height - waterLevel);
|
||||||
|
ctx.fillRect(0,y,canv.width, canv.height-y);
|
||||||
|
} else {
|
||||||
|
canv.style.display = 'none';
|
||||||
|
canv.style.visibility = 'hidden';
|
||||||
|
mapNode.style.display = '';
|
||||||
|
mapNode.style.visibility = 'visible';
|
||||||
|
}
|
||||||
|
|
||||||
if (waterLevel > 0) {
|
if (waterLevel > 0) {
|
||||||
document.getElementById("mineGui_mineMapWater").textContent = map.splice(-waterLevel).join("\n");
|
document.getElementById("mineGui_mineMapWater").textContent = map.splice(-waterLevel).join("\n");
|
||||||
} else {
|
} else {
|
||||||
document.getElementById("mineGui_mineMapWater").textContent = "";
|
document.getElementById("mineGui_mineMapWater").textContent = "";
|
||||||
}
|
}
|
||||||
document.getElementById("mineGui_mineMap").textContent = map.join("\n");
|
document.getElementById("mineGui_mineMapDry").textContent = map.join("\n");
|
||||||
|
|
||||||
document.getElementById("mineGui_moves").value = mineGui_moves;
|
document.getElementById("mineGui_moves").value = mineGui_moves;
|
||||||
var state = "";
|
var state = "";
|
||||||
switch (mineGui_mine.state) {
|
switch (mineGui_mine.state) {
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
<h2>ICFP Contest 2012 Simulator</h2>
|
<h2>ICFP Contest 2012 Simulator</h2>
|
||||||
Links: <a href="http://icfpcontest2012.wordpress.com/">contest page</a>.<br>
|
Links: <a href="http://icfpcontest2012.wordpress.com/">contest page</a>.<br>
|
||||||
<i>This simulator may or may not perform according to specs, who knows...</i><br/>
|
<i>This simulator may or may not perform according to specs, who knows...</i><br/>
|
||||||
|
<noscript><h3 style="color:red">This page needs javascript</h3></noscript>
|
||||||
|
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
@ -14,9 +15,9 @@
|
|||||||
Select Map: <select id="mineGui_selectMap"></select>
|
Select Map: <select id="mineGui_selectMap"></select>
|
||||||
<div style="white-space: pre">Moves: <input type="text" id="mineGui_moves" value="" style="width: 80%; font-weight: bold; border: 1px solid"></input></div>
|
<div style="white-space: pre">Moves: <input type="text" id="mineGui_moves" value="" style="width: 80%; font-weight: bold; border: 1px solid"></input></div>
|
||||||
<table align=top><tr><td style="padding-right: 50px;vertical-align:top">
|
<table align=top><tr><td style="padding-right: 50px;vertical-align:top">
|
||||||
<pre><span id="mineGui_mineMap" style="margin-bottom: 0px"></span>
|
<pre id="mineGui_mineMap"><span id="mineGui_mineMapDry" style="margin-bottom: 0px"></span>
|
||||||
<span id="mineGui_mineMapWater" style="margin-top: 0px; background: lightblue"></span>
|
<span id="mineGui_mineMapWater" style="margin-top: 0px; background: lightblue"></span>
|
||||||
</pre>
|
</pre><canvas id="mineGui_mineCanvas" width="0" height="0"></canvas>
|
||||||
</td><td style="vertical-align:top">
|
</td><td style="vertical-align:top">
|
||||||
<pre id="mineGui_meta"></pre>
|
<pre id="mineGui_meta"></pre>
|
||||||
</td></tr></table>
|
</td></tr></table>
|
||||||
@ -34,7 +35,7 @@
|
|||||||
|
|
||||||
<pre>Help:
|
<pre>Help:
|
||||||
(<b>L</b>)eft/(<b>U</b>)p/(<b>R</b>)ight/(<b>D</b>)own work as expected (letter and arrow keys), (<b>A</b>)bort and (<b>W</b>)ait too.
|
(<b>L</b>)eft/(<b>U</b>)p/(<b>R</b>)ight/(<b>D</b>)own work as expected (letter and arrow keys), (<b>A</b>)bort and (<b>W</b>)ait too.
|
||||||
Special keys: PageUp/PageDown for map select, Backspace for undo and (<b>C</b>)lear
|
Special keys: PageUp/PageDown for map select, Backspace for undo, (<b>C</b>)lear and (<b>T</b>)oggle text mode
|
||||||
Be careful: a reload looses all custom maps and saved moves.
|
Be careful: a reload looses all custom maps and saved moves.
|
||||||
Listed highscore can be outdated.
|
Listed highscore can be outdated.
|
||||||
</pre>
|
</pre>
|
||||||
|
BIN
js/lambda.png
Normal file
After Width: | Height: | Size: 592 B |
BIN
js/liftclosed.png
Normal file
After Width: | Height: | Size: 603 B |
BIN
js/liftopen.png
Normal file
After Width: | Height: | Size: 558 B |
BIN
js/robot.png
Normal file
After Width: | Height: | Size: 621 B |
BIN
js/rock.png
Normal file
After Width: | Height: | Size: 741 B |
BIN
js/wall.png
Normal file
After Width: | Height: | Size: 722 B |