Created
March 16, 2012 16:26
-
-
Save zzandy/2050874 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> | |
<html xmlns="http://www.w3.org/1999/xhtml"> | |
<head> | |
<title></title> | |
<style type="text/css"> | |
* | |
{ | |
background-color: #131510; | |
color: #aaa6a0; | |
font: 10pt/14pt monospace; | |
} | |
#out div | |
{ | |
float: left; | |
width: 1em; | |
text-align: center; | |
} | |
#out div.odd | |
{ | |
margin-top: .6em; | |
} | |
.hidden | |
{ | |
color: #333; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="out"> | |
</div> | |
<script type="text/javascript"> | |
var rnd = function(){ | |
var i = Math.floor(Math.random() * arguments.length); | |
return arguments[i]; | |
} | |
if (!('map' in Array.prototype)) | |
Array.prototype.map = function (fn) { | |
var res = []; | |
var i = -1, n = this.length; | |
while (++i < n) { | |
res.push(fn(this[i], i)); | |
} | |
return res; | |
} | |
if (!('filter' in Array.prototype)) | |
Array.prototype.filter = function (fn) { | |
var res = []; | |
var i = -1, n = this.length; | |
while (++i < n) { | |
if (fn(this[i], i)) | |
res.push(this[i]); | |
} | |
return res; | |
} | |
if (!('any' in Array.prototype)) | |
Array.prototype.any = function (fn) { | |
var i = -1, n = this.length; | |
while (++i < n) { | |
if (fn(this[i], i)) | |
return true; | |
} | |
return false; | |
} | |
var sqrt = Math.sqrt; | |
/* | |
* TODO: | |
* 3. FOV | |
* 4. Chunks | |
* 5. Line | |
* 6. Circles | |
* 7. Voiw rotation | |
*/ | |
/* | |
* Screen coordinates (y,x): | |
* | |
* 0,0 0,2 | |
* 0,1 0,3 | |
* 1,0 1,2 | |
* 1,1 1,3 | |
* | |
* | |
* World coordinates (y,x): | |
* | |
* 2-2 1,0 0,2 | |
* 1-1 0,1 | |
* 1-2 0,0 -1,2 | |
* 0-1 -1,1 | |
* 0-2 -1,0 -2,2 | |
* | |
* | |
* Storage coordinate (s): | |
* | |
* 11 2 7 | |
* 3 1 | |
* 12 0 18 | |
* 4 6 | |
* 13 5 17 | |
*/ | |
var D_URIGHT = 0; | |
var D_UP = 1; | |
var D_ULEFT = 2; | |
var D_DLEFT = 3; | |
var D_DOWN = 4; | |
var D_DRIGHT = 5; | |
/* Possible directions in world space | |
* UP | |
* 1 | |
* ULEFT 2 0 URIGHT | |
* DLEFT 3 5 DRIGHT | |
* 4 | |
* DOWN | |
*/ | |
var dirw = [[0, 1], [1, 0], [1, -1], [0, -1], [-1, 0], [-1, 1]]; | |
// World to screen | |
function w2sc(y0, x0, yw, xw) { | |
return [y0 - Math.floor((xw + (x0 + 1) % 2) / 2) - yw, xw + x0]; | |
} | |
// Screen to world | |
function sc2w(y0, x0, ys, xs) { | |
var x = xs - x0; | |
return [y0 - Math.floor((x + (x0 + 1) % 2) / 2) - ys, x]; | |
} | |
// World to geometry | |
function w2g(y, x) { | |
return [y + x / 2, x * .866]; | |
} | |
// Geometry to world | |
function g2w(y, x) { | |
var a = x / .866; | |
return [Math.round(y - a / 1), Math.round(a)]; | |
} | |
function wd(gc, gp) { | |
var dy = gc[0] - gp[0]; | |
var dx = gc[1] - gp[1]; | |
return sqrt(dx * dx + dy * dy); | |
} | |
// World coordinates distance | |
function d(a, b) { | |
var y = a[0] - b[0]; | |
var x = a[1] - b[1]; | |
return (x * y < 0) | |
? (Math.max(Math.abs(y), Math.abs(x))) | |
: (Math.abs(y) + Math.abs(x)); | |
} | |
function ring2st(r) { | |
return 3 * r * (r + 1); | |
} | |
function st2ring(st) { | |
return Math.ceil((Math.sqrt(12 * st + 9) - 3) / 6); | |
} | |
// Storage to world | |
function st2w(s) { | |
if (s == 0) return [0, 0]; | |
var r = st2ring(s); | |
var d = s - ring2st(r - 1) - 1; | |
var sx = Math.floor(d / r); | |
var sn = d % r; | |
var an = [ | |
[[0, 1], [1, -1]], | |
[[1, 0], [0, -1]], | |
[[1, -1], [-1, 0]], | |
[[0, -1], [-1, 1]], | |
[[-1, 0], [0, 1]], | |
[[-1, 1], [1, 0]] | |
]; | |
var q = [r, sn] | |
var o = an[sx] | |
return [q[0] * o[0][0] + q[1] * o[0][1], q[0] * o[1][0] + q[1] * o[1][1]]; | |
} | |
// World to storage | |
function w2st(y, x) { | |
if (y == 0 && x == 0) return 0; | |
var ax = Math.abs(x); | |
var ay = Math.abs(y); | |
var axy = Math.abs(x + y); | |
// ring | |
var r = (ay + ax + axy) / 2; | |
// hextant | |
var s = (y >= 0 && x > 0) ? 0 | |
: (x <= 0 && y > 0) ? (ax < y ? 1 : 2) | |
: (y <= 0 && x < 0) ? 3 | |
: (ay > x ? 4 : 5); | |
var n = s % 3; | |
n = n == 0 ? ay : n == 1 ? ax : axy; | |
var a0 = ring2st(r); | |
var a1 = ring2st(r - 1); | |
return n + a1 + 1 + s * (a0 - a1) / 6; | |
} | |
function ring(y, x) { | |
var ax = Math.abs(x); | |
var ay = Math.abs(y); | |
var axy = Math.abs(x + y); | |
return (ay + ax + axy) / 2; | |
} | |
// Get world coordinates of hexes visible from (y,x) within radius. | |
function visible(y, x, r) { | |
r = r || 8; | |
// Current ring | |
var rn = 0; | |
var v = []; | |
var i = -1; | |
var n = ring2st(r); | |
while(++i <= n) { | |
var c = st2w(i); | |
v.push([c[0] + y, c[1] + x]); | |
} | |
return v; | |
} | |
var out = document.getElementById('out'); | |
var w = 73; | |
var h = 21; | |
var radius = 5; | |
var y0 = Math.floor(h / 2); | |
var x0 = Math.floor(w / 4); | |
// screen coordinates of world origin (0,0) -> (y,x) | |
var originscreen = [y0, x0]; | |
var map = []; | |
var len = ring2st(Math.ceil(h)) + 1; | |
for (var n = 0; n < len; ++n) { | |
//⬡ | |
map.push(Math.random() < 2 ? '#' : '·'); | |
} | |
// Overlay a.k.a. HUD | |
var ovr = [] | |
for (var i = 0; i < h; ++i) { | |
ovr.push([]); | |
for (var j = 0; j < w; ++j) | |
ovr[i].push(''); | |
} | |
ovr[1][1] = '7'; | |
ovr[1][2] = '8'; | |
ovr[1][3] = '9'; | |
ovr[2][2] = '*' | |
ovr[2][1] = '4'; | |
ovr[3][2] = '5'; | |
ovr[2][3] = '6'; | |
ovr[1][5] = 'h'; | |
ovr[1][6] = 'k'; | |
ovr[1][7] = 'u'; | |
ovr[2][5] = 'b'; | |
ovr[2][6] = '*'; | |
ovr[3][6] = 'j'; | |
ovr[2][7] = 'l'; | |
// player | |
var p = [0, 0] | |
function text(i, j, s) { | |
var n = s.length; | |
var k = -1; | |
while (++k < n) { | |
ovr[i - Math.floor((k + 1) / 2)][k] = s[k]; | |
} | |
} | |
function valid(world) { | |
var x = world[1]; | |
var y = world[0]; | |
return y >= 0 && x >= 0 && y < map.length && x < map[y].length; | |
} | |
var bg = []; | |
for(var j=0; j<w; ++j){ | |
var row = []; | |
for(var i=0; i<h; ++i) { | |
row.push(rnd(',', '`', ' ', ' ', ' ', ' ')); | |
} | |
bg.push(row); | |
} | |
function print() { | |
function hidden(str) { | |
return '<span class="hidden">' + str + '</span>'; | |
} | |
var text = []; | |
var v = visible(p[0], p[1], radius); | |
var screen = []; | |
for(var j=0; j<w; ++j){ | |
var row = []; | |
for(var i=0; i<h; ++i) { | |
row.push(hidden(bg[j][i])); | |
} | |
screen.push(row); | |
} | |
var screenp = w2sc(y0, x0, p[0], p[1]); | |
screen[screenp[1]][screenp[0]] = '@'; | |
var showall = true; | |
if (showall) { | |
for (var j = 0; j < w; ++j) { | |
for (var i = 0; i < h; ++i) { | |
var c = sc2w(y0, x0, i, j); | |
screen[j][i] = map[w2st(c[0], c[1])]; | |
} | |
} | |
} | |
else { | |
var vis = visible(p[0], p[1]); | |
for (var k = 0; k < vis.length; ++k) { | |
var c = vis[k]; | |
var sc = w2sc(y0, x0, c[0], c[1]); | |
var s = w2st(c[0], c[1]); | |
if (sc[0] >= 0 && sc[1] >= 0 && sc[1] < w && sc[0] < h) | |
screen[sc[1]][sc[0]] = map[s]; | |
} | |
} | |
for (var j = 0; j < w; ++j) { | |
text.push((j % 2 == 0) ? '<div>' : '<div class="odd">'); | |
for (var i = 0; i < h; ++i) { | |
var char = ' '; | |
if (ovr[i][j] != '') { | |
char = ovr[i][j]; | |
} | |
else if (i==screenp[0] && j==screenp[1]) | |
{ | |
char = '@'; | |
} | |
else { | |
char = screen[j][i]; | |
} | |
text.push(char + '</br>'); | |
} | |
text.push('</div>'); | |
} | |
out.innerHTML = text.join(''); | |
} | |
print(); | |
document.onkeydown = function (e) { | |
var char = window.event.keyCode; | |
switch (char) { | |
case 72: case 103: app(p, dirw[D_ULEFT]); break; | |
case 75: case 104: app(p, dirw[D_UP]); break; | |
case 85: case 105: app(p, dirw[D_URIGHT]); break; | |
case 66: case 100: app(p, dirw[D_DLEFT]); break; | |
case 74: case 101: app(p, dirw[D_DOWN]); break; | |
case 76: case 102: app(p, dirw[D_DRIGHT]); break; | |
case 97: /*screen left */s = w2sc(y0, x0, p[0], p[1]); set(p, sc2w(y0, x0, s[0], s[1] - 1)); break; | |
case 99: /*screen right*/s = w2sc(y0, x0, p[0], p[1]); set(p, sc2w(y0, x0, s[0], s[1] + 1)); break; | |
case 96: --radius; break; | |
case 110: ++radius; break; | |
case 32: | |
var x = w2st(p[0], p[1]); | |
map[x] = map[x] == '#' ? ' ' : '#'; | |
break; | |
} | |
text(h - 1, 0, char.toString()); | |
print(); | |
} | |
function set(a, b) { | |
a[0] = b[0]; | |
a[1] = b[1]; | |
return a; | |
} | |
function app(a, b) { | |
a[0] += b[0]; | |
a[1] += b[1]; | |
return a; | |
} | |
function add(a, b) { | |
return [a[0] + b[0], a[1] + b[1]]; | |
} | |
// same jubject | |
// your dog barks. your dog barks. your dog barks. your dog barks. | |
// => | |
// your dog barks four times. | |
// different subjects | |
// jakal bites. jakal bites. jakal bites. jakal bites. | |
// => | |
// Four jackals bite. | |
// or | |
// Jackals bite four times. | |
// same subject different actions | |
// jackal bites, jackal misses, jackal is hit | |
// => | |
// jackal bites, misses and is hit | |
// you hit the dar blademster; something missed the dar blademaster; | |
// something missed the dar blademaster; something missed the dar blademaster. | |
// The dar blademsater slashes you. | |
// => | |
// You hit the dar blademaster, something misses him thrice, then it shashes you. | |
function msg(object, verb) { | |
return { object: object, verb: verb, toString: function () { return } } | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment