]> git.plutz.net Git - isotilejs/blob - index.html
ea0f3dfc0df9278da1c53ab475f89e5dba7803c1
[isotilejs] / index.html
1 <!DOCTYPE XHTML>
2 <html><head>
3   <title>Tilerender</title>
4   <meta charset="utf8">
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;"  />
9     <tiles>
10       <tile position="2" animated="1"></tile>
11       <tile position="3" elevation=".125"></tile>
12       <tile position="4" blocking="yes"></tile>
13     </tiles>
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,
52
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
89     </div>
90   </canvas>
91 </body><script>
92 view = document.getElementById("view");
93 canvas = document.getElementById("view").getContext("2d");
94
95 map = {
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"),
100
101   default_props: {animated: false, elevation: 0, blocking: false},
102   tileprops: [],
103   tw: 32, th: 16, sw: 16, sh: 8,
104   offset_x: 0, offset_y: 0,
105
106   init: function(){
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;
111
112     var prop, i;
113
114     for (i in this.data) this.data[i] = this.data[i] * 1 || 0; // make numeric
115
116     for (prop of document.querySelectorAll("tiles > tile")) {
117       i = prop.getAttribute("position") * 1;
118       if (i) {
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
123         }
124       }
125     }
126   },
127
128   props_of: function(n) { return this.tileprops[this.data[n]] || this.default_props; },
129
130   tile_at: function(x, y) {
131     var my = (y / this.sh |0);
132     var mx = (x / this.sw |0);
133     
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;
139     }
140     mx -= x / this.tw |0;
141   
142     return this.cols * my + mx;
143   },
144
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;
149   
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) &&
157                                y < py + 6 &&
158                                x > px - 2 &&
159                                x < px + 2
160                              ) ? .25 : 1;
161   
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,
167                           this.tw, 2 * this.th
168                         );
169       }
170       if (py == y) player.draw();
171     }
172   } // end map.draw
173 } // end map
174
175 player = {
176   frame: 0, d: 's',
177   x: 40, y: 40, z: 0,
178   sprite: document.getElementById("character"),
179
180   init: function(){
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;
188   },
189
190   move: function(){
191     var dx = 0, dy = 0;
192   
193     switch(this.d){
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;
202     }
203
204     if (player.frame % 6 > 2) {
205       dx *= 1.375;
206       dy *= 1.375
207     } else {
208       dx *= .625;
209       dy *= .625;
210     }
211   
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; }
219   
220     this.frame += this.frame < 255 ? 1 : -127;
221
222     map.offset_x = this.x - view.clientWidth / 2 |0;
223     map.offset_y = this.y - view.clientHeight / 2 |0;
224   },
225
226   fall: function(){
227     if (!this.fallspeed) this.fallspeed = 0;
228     if (!this.falloff) this.falloff = 0;
229
230     if(this.falloff > 0 ||
231        !map.data[this.n] &&
232        !map.props_of(this.n - map.cols * map.rows).blocking
233       ) this.fallspeed += 1.81 * .03;
234     else this.fallspeed = 0;
235
236     this.falloff -= this.fallspeed;
237     if (this.falloff < 0 &&
238         (map.data[this.n] ||
239          map.props_of(this.n - map.cols * map.rows).blocking)) {
240       this.fallspeed = this.falloff = 0;
241     } else if (this.falloff < 0) {
242       this.falloff += 1;
243       this.z -= 1;
244       this.n -= map.rows * map.cols;
245     }
246   },
247
248
249   draw: function(){ // player.draw
250     var face = 0, state = 0;
251   
252     switch (this.d){
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;
261     }
262   
263     state = 
264       (this.frame > 11) ? frame / 16 % 2 |0 :
265       (this.frame < 12) ? this.frame / 3 + 2 |0 :
266       0;
267   
268     canvas.drawImage( this.sprite, this.w * face, this.h * state,
269                       this.w, this.h,
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,
272                       this.w, this.h );
273    
274   } // end player.draw
275 };
276
277 frame = 0;
278 move = true;
279 keys = [];
280 ptr = 0;
281
282 function get_input(){
283   d = '';
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';
288
289   if ( d == '' ) player.frame = 12
290   else {
291     player.d = d;
292     if ( player.frame > 11 ) player.frame = 0;
293     player.move();
294   }
295 }
296
297 function script(){
298   map.init();
299   player.init();
300
301   setInterval(function(){
302     get_input();
303     player.fall();
304     map.draw();
305     frame += frame < 255 ? 1 : -255;
306   }, 33)
307
308   window.addEventListener('keydown', function(x){ keys[x.keyCode] = true; }, false );
309   window.addEventListener('keyup',   function(x){ keys[x.keyCode] = false;}, false );
310
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;
314
315     ptr = map.tile_at(px + map.offset_x, py + map.offset_y);
316   })
317 }
318 </script></html>