3 <title>Tilerender</title>
5 </head><body onload="script()" style="width: 100%; max-height: 600px; overflow: hidden; padding: 0 auto;" >
6 <canvas id="view" width="1280" height="600" style="padding: 0 auto; max-height: 600px;">
7 Canvas not supported<br/>
8 <img id="maptiles" src="tileset.png" width="64" style="overflow: hidden;" />
10 <tile position="2" animated="1"></tile>
11 <tile position="3" elevation=".125"></tile>
12 <tile position="4" blocking="yes"></tile>
14 <img id="character" src="character.png" speed="2.75"/>
15 <div id="map" columns="18" rows="36">
16 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
17 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
18 5, 1, 1, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 5,
19 5, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,5,
20 5, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5,
21 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,5,
22 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5,
23 5, 2, 2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2,5,
24 5, 2, 2, 2, 2, 1, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5,
25 5, 2, 2, 2, 1, 1, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,5,
26 5, 2, 2, 2, 1, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5,
27 5, 2, 2, 1, 4, 4, 1, 2, 2, 2, 2, 2, 2, 4, 2, 2, 2,5,
28 5, 2, 2, 2, 1, 4, 1, 2, 2, 2, 4, 2, 2, 4, 4, 2, 2, 5,
29 5, 2, 2, 2, 1, 1, 2, 2, 2, 2, 4, 2, 4, 3, 4, 2, 2,5,
30 5, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 4, 4, 3, 3, 4, 2, 5,
31 5, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 4, 3, 3, 3, 4, 2,5,
32 5, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 3, 4, 3, 3, 3, 4, 5,
33 5, 2, 2, 2, 2, 2, 2, 1, 2, 2, 3, 3, 3, 3, 3, 4, 2,5,
34 5, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 3, 3, 4, 3, 4, 2, 5,
35 5, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 3, 3, 4, 4, 2, 2,5,
36 5, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 3, 3, 4, 2, 2, 5,
37 5, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 3, 3, 2, 2, 2,5,
38 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 3, 2, 2, 2, 5,
39 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2,5,
40 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 5,
41 5, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2,5,
42 5, 2, 2, 4, 4, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 5,
43 5, 2, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,5,
44 5, 2, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5,
45 5, 2, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,5,
46 5, 2, 2, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5,
47 5, 2, 2, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,5,
48 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5,
49 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,5,
50 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
51 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
53 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0,
54 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0,
55 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0,
56 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
57 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
58 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
59 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
60 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
61 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
62 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
63 0, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
64 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0,
65 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 4, 0, 0, 4, 4, 0, 0, 0,
66 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 0, 4, 0, 0, 0,
67 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 4, 0, 0,
68 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0,
69 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0,
70 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0,
71 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 0, 0,
72 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
73 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
74 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
75 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
76 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
77 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
78 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
79 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
80 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
81 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
82 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
83 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
84 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
85 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
86 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
87 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
88 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
92 view = document.getElementById("view");
93 canvas = document.getElementById("view").getContext("2d");
96 rows: document.getElementById("map").getAttribute("rows") * 1 || 1,
97 cols: document.getElementById("map").getAttribute("columns") * 1 || 1,
98 data: document.getElementById("map").textContent.split(',') || [],
99 tiles: document.getElementById("maptiles"),
101 default_props: {animated: false, elevation: 0, blocking: false},
103 tw: 32, th: 16, sw: 16, sh: 8,
104 offset_x: 0, offset_y: 0,
107 this.tw = this.tiles.getAttribute("width") * 1 || 32;
108 this.th = this.tiles.getAttribute("height") * 1 || this.tw / 2;
109 this.sw = this.tw / 2;
110 this.sh = this.th / 2;
114 for (i in this.data) this.data[i] = this.data[i] * 1 || 0; // make numeric
116 for (prop of document.querySelectorAll("tiles > tile")) {
117 i = prop.getAttribute("position") * 1;
119 this.tileprops[i] = {
120 animated: prop.getAttribute("animated") || this.default_props.animated,
121 elevation: prop.getAttribute("elevation") * 1 || this.default_props.elevation,
122 blocking: prop.getAttribute("blocking") || this.default_props.blocking
128 props_of: function(n) { return this.tileprops[this.data[n]] || this.default_props; },
130 tile_at: function(x, y) {
131 var my = (y / this.sh |0);
132 var mx = (x / this.sw |0);
134 switch(((my % 2) << 1) + mx % 2) {
135 case 0: my += o = (y % this.sh * 2 > this.sw - x % this.sw); break;
136 case 1: my += o = (y % this.sh * 2 > x % this.sw); mx -= o; break;
137 case 2: my += o = (y % this.sh * 2 > x % this.sw); break;
138 case 3: my += o = (y % this.sh * 2 > this.sw - x % this.sw); mx += o - 1; break;
140 mx -= x / this.tw |0;
142 return this.cols * my + mx;
145 draw: function(){ // map.draw
146 var py = player.n / this.cols % this.rows |0;
147 var px = player.n % this.cols;
148 var x, y, z, n, tile;
150 for (y = 0; y < this.rows; ++y) {
151 for (z = 0; z < this.data.length / (this.rows * this.cols); ++z)
152 for (x = 0; x < this.cols; ++x) {
153 n = x + y * map.cols + z * map.rows * map.cols;
154 tile = ( n == ptr ) ? 5 : this.data[n];
155 canvas.globalAlpha = ( y > py &&
156 (z > player.z || z == (player.z |0) && this.props_of(n).blocking) &&
162 canvas.drawImage( this.tiles,
163 this.tw * tile, 2 * this.th * ((frame / 16 |0) % 8),
164 this.tw, 2 * this.th,
165 x * this.tw + y % 2 * this.sw - this.sw - this.offset_x,
166 y * this.sh - z * this.th - 3 * this.sh - this.offset_y,
170 if (py == y) player.draw();
178 sprite: document.getElementById("character"),
181 this.w = this.sprite.getAttribute("width") * 1 || map.tw || 32;
182 this.h = this.sprite.getAttribute("height") * 1 || map.sh * 6 || this.w * 1.5;
183 this.o = this.sprite.getAttribute("offset") * 1 || map.sh || this.w / 4;
184 this.speed = this.sprite.getAttribute("speed") * 1|| this.w / 16;
185 this.n = map.tile_at(this.x, this.y) + this.z * map.rows * map.cols || 0;
186 map.offset_x = this.x - view.clientWidth / 2 |0;
187 map.offset_y = this.y - view.clientHeight / 2 |0;
194 case 'n': dy = -this.speed; break;
195 case 's': dy = this.speed; break;
196 case 'w': dx = -this.speed; break;
197 case 'e': dx = this.speed; break;
198 case 'nw': dy = -.45 * this.speed; dx = -.9 * this.speed; break;
199 case 'ne': dy = -.45 * this.speed; dx = .9 * this.speed; break;
200 case 'sw': dy = .45 * this.speed; dx = -.9 * this.speed; break;
201 case 'se': dy = .45 * this.speed; dx = .9 * this.speed; break;
204 if (player.frame % 6 > 2) {
212 var n = map.tile_at(this.x + dx, this.y + dy) + this.z * map.rows * map.cols;
213 if (!map.props_of(n).blocking &&
214 !map.props_of(n + map.rows * map.cols).blocking
215 ) { this.x += dx; this.y += dy; this.n = n; }
216 else if (!map.props_of(n + map.rows * map.cols).blocking &&
217 !map.props_of(n + 2 * map.rows * map.cols).blocking
218 ) { this.x += dx; this.y += dy; this.z += 1; this.n = n + map.rows * map.cols; }
220 this.frame += this.frame < 255 ? 1 : -127;
222 map.offset_x = this.x - view.clientWidth / 2 |0;
223 map.offset_y = this.y - view.clientHeight / 2 |0;
227 if (!this.fallspeed) this.fallspeed = 0;
228 if (!this.falloff) this.falloff = 0;
230 if(this.falloff > 0 ||
232 !map.props_of(this.n - map.cols * map.rows).blocking
233 ) this.fallspeed += 1.81 * .03;
234 else this.fallspeed = 0;
236 this.falloff -= this.fallspeed;
237 if (this.falloff < 0 &&
239 map.props_of(this.n - map.cols * map.rows).blocking)) {
240 this.fallspeed = this.falloff = 0;
241 } else if (this.falloff < 0) {
244 this.n -= map.rows * map.cols;
249 draw: function(){ // player.draw
250 var face = 0, state = 0;
253 case 's': face = 0; break;
254 case 'sw': face = 1; break;
255 case 'w': face = 2; break;
256 case 'nw': face = 3; break;
257 case 'n': face = 4; break;
258 case 'ne': face = 5; break;
259 case 'e': face = 6; break;
260 case 'se': face = 7; break;
264 (this.frame > 11) ? frame / 16 % 2 |0 :
265 (this.frame < 12) ? this.frame / 3 + 2 |0 :
268 canvas.drawImage( this.sprite, this.w * face, this.h * state,
270 this.x - this.w / 2 - map.offset_x,
271 this.y - (this.z |0) * map.th - this.h + this.o - map.offset_y - map.props_of(this.n).elevation * map.th - this.falloff * map.th,
282 function get_input(){
284 if ( keys[87] || keys[38] ) d = 'n';
285 if ( keys[83] || keys[40] ) d = 's';
286 if ( keys[65] || keys[37] ) d += 'w';
287 if ( keys[68] || keys[39] ) d += 'e';
289 if ( d == '' ) player.frame = 12
292 if ( player.frame > 11 ) player.frame = 0;
301 setInterval(function(){
305 frame += frame < 255 ? 1 : -255;
308 window.addEventListener('keydown', function(x){ keys[x.keyCode] = true; }, false );
309 window.addEventListener('keyup', function(x){ keys[x.keyCode] = false;}, false );
311 window.addEventListener('mousemove', function(e){
312 px = view.width * (e.clientX - view.offsetLeft) / view.clientWidth |0;
313 py = view.height * (e.clientY - view.offsetTop) / view.clientHeight |0;
315 ptr = map.tile_at(px + map.offset_x, py + map.offset_y);