PageRenderTime 57ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/uupaa-excanvas.js/demo/3Dwalker.htm

http://uupaa-js-spinoff.googlecode.com/
HTML | 613 lines | 127 code | 36 blank | 450 comment | 0 complexity | 47a2c02ed74f07e2b50aef47e8c81740 MD5 | raw file
Possible License(s): Apache-2.0
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
  2. <html><head>
  3. <meta http-equiv="content-type" content="text/html; charset=Shift_JIS">
  4. <title>Canvascape - 3D walker</title>
  5. <!--
  6. This game is copyright by Benjamin Joffe.
  7. You may not reproduce or modify this without
  8. written permission by the origional author.
  9. Email him: CanvasGame@gmail.com for suggestions.
  10. -->
  11. <script type="text/xaml" id="xaml"><?xml version="1.0"?>
  12. <Canvas xmlns="http://schemas.microsoft.com/client/2007"></Canvas></script>
  13. <script type="text/javascript" src="../uupaa-excanvas.js"></script>
  14. <style type="text/css"><!--
  15. H1 {
  16. padding: 5px;
  17. font-size: 14pt;
  18. font-style: italic;
  19. }
  20. BODY {
  21. font-family: arial;
  22. font-size: 10pt;
  23. background-color: #000;
  24. color: #CCC;
  25. }
  26. #holder {
  27. position: relative;
  28. width: 400px;
  29. height:300px;
  30. top: 10px;
  31. left: 120px;
  32. border: 2px solid #333;
  33. }
  34. #sky {
  35. position: absolute;
  36. left: 0;
  37. top: 0;
  38. height: 150px;
  39. width: 400px;
  40. background-color: #CCD;
  41. background-image: url(images/sky.jpg);
  42. }
  43. #floor {
  44. position: absolute;
  45. left: 0;
  46. top: 150px;
  47. height: 150px;
  48. width: 400px;
  49. background-color: #565;
  50. background-image: url(images/floor.png);
  51. }
  52. #canvas {
  53. position: absolute;
  54. top: 0;
  55. left: 0;
  56. }
  57. #overlay {
  58. position: absolute;
  59. top: 0;
  60. left: 0;
  61. width: 400px;
  62. height: 300px;
  63. background-image: url(images/overlay.gif);
  64. }
  65. #map, #underMap {
  66. top: 70px;
  67. left: 20px;
  68. position: absolute;
  69. }
  70. #copyright {
  71. position: absolute;
  72. top: 170px;
  73. left: 15px;
  74. }
  75. A {
  76. color: #66AACC;
  77. }
  78. A:hover {
  79. color: lime;
  80. }
  81. --></style>
  82. <style type="text/css" charset="utf-8">/* See license.txt for terms of usage */
  83. .firebugHighlight {
  84. z-index: 2147483647;
  85. position: absolute;
  86. background-color: #3875d7;
  87. }
  88. .firebugLayoutBoxParent {
  89. z-index: 2147483647;
  90. position: absolute;
  91. background-color: transparent;
  92. border-right: 1px dashed #BBBBBB;
  93. border-bottom: 1px dashed #BBBBBB;
  94. }
  95. .firebugRulerH {
  96. position: absolute;
  97. top: -15px;
  98. left: 0;
  99. width: 100%;
  100. height: 14px;
  101. background: url(chrome://firebug/skin/rulerH.png) repeat-x;
  102. border-top: 1px solid #BBBBBB;
  103. border-right: 1px dashed #BBBBBB;
  104. border-bottom: 1px solid #000000;
  105. }
  106. .firebugRulerV {
  107. position: absolute;
  108. top: 0;
  109. left: -15px;
  110. width: 14px;
  111. height: 100%;
  112. background: url(chrome://firebug/skin/rulerV.png) repeat-y;
  113. border-left: 1px solid #BBBBBB;
  114. border-right: 1px solid #000000;
  115. border-bottom: 1px dashed #BBBBBB;
  116. }
  117. .overflowRulerX > .firebugRulerV {
  118. left: 0;
  119. }
  120. .overflowRulerY > .firebugRulerH {
  121. top: 0;
  122. }
  123. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  124. .firebugLayoutBoxOffset {
  125. z-index: 2147483647;
  126. position: absolute;
  127. opacity: 0.8;
  128. }
  129. .firebugLayoutBoxMargin {
  130. background-color: #EDFF64;
  131. }
  132. .firebugLayoutBoxBorder {
  133. background-color: #666666;
  134. }
  135. .firebugLayoutBoxPadding {
  136. background-color: SlateBlue;
  137. }
  138. .firebugLayoutBoxContent {
  139. background-color: SkyBlue;
  140. }
  141. /*.firebugHighlightGroup .firebugLayoutBox {
  142. background-color: transparent;
  143. }
  144. .firebugHighlightBox {
  145. background-color: Blue !important;
  146. }*/
  147. .firebugLayoutLine {
  148. z-index: 2147483647;
  149. background-color: #000000;
  150. opacity: 0.4;
  151. }
  152. .firebugLayoutLineLeft,
  153. .firebugLayoutLineRight {
  154. position: fixed;
  155. width: 1px;
  156. height: 100%;
  157. }
  158. .firebugLayoutLineTop,
  159. .firebugLayoutLineBottom {
  160. position: absolute;
  161. width: 100%;
  162. height: 1px;
  163. }
  164. .firebugLayoutLineTop {
  165. margin-top: -1px;
  166. border-top: 1px solid #999999;
  167. }
  168. .firebugLayoutLineRight {
  169. border-right: 1px solid #999999;
  170. }
  171. .firebugLayoutLineBottom {
  172. border-bottom: 1px solid #999999;
  173. }
  174. .firebugLayoutLineLeft {
  175. margin-left: -1px;
  176. border-left: 1px solid #999999;
  177. }
  178. </style></head><body>
  179. <h1>Canvascape - "3D Walker"</h1>
  180. <canvas id="underMap" width="80" height="80"></canvas>
  181. <canvas id="map" width="80" height="80"></canvas>
  182. <div id="copyright">
  183. &#169; Benjamin Joffe<br>
  184. <a href="mailto:CanvasGame@gmail.com" style="font-size: 7pt;">canvasGame@gmail.com</a>
  185. </div>
  186. <div id="holder" style="clear: both;">
  187. <div style="background-position: -153px 0pt;" id="sky"></div>
  188. <div id="floor"></div>
  189. <canvas id="canvas" width="400" height="300"></canvas>
  190. <div id="overlay"></div>
  191. </div>
  192. <p>Use the arrow keys to walk around the map. Space bar = jump.</p>
  193. <p>What you are seeing is a test using the new Canvas tag to
  194. demonstrate its capabilities, Internet Explorer support has recently
  195. been added thanks to Google's workaround code. See also: <a href="http://abrahamjoffe.com.au/ben/canvascape/textures.htm">textured version</a>.</p>
  196. <p><a href="http://www.studiocoast.com.au/">Web hosting provided by Studio Coast</a></p>
  197. <script type="text/javascript"><!--
  198. /*
  199. This code is copyright by Benjamin Joffe.
  200. You may not reproduce or modify this without
  201. written permission by the origional author.
  202. Email him: CanvasGame@gmail.com for suggestions.
  203. */
  204. var map;
  205. var canvas;
  206. var overlay;
  207. //variables initiated at the bottom of the code...
  208. var pi=Math.PI;
  209. var total=0;
  210. Number.prototype.range=function(){
  211. return (this+2*pi)%(2*pi);
  212. }
  213. Number.prototype.roundC=function(){
  214. return Math.round(this*100)/100;
  215. }
  216. var total=0;
  217. var samples=200;
  218. var arena=[];
  219. arena[0]=[1,1,1,1,1,1,1,1,1,1]
  220. arena[1]=[1,0,0,0,0,0,0,0,0,1]
  221. arena[2]=[1,0,0,1,0,1,1,1,0,1]
  222. arena[3]=[1,0,1,0,0,0,0,1,0,1]
  223. arena[4]=[1,0,0,0,0,1,0,1,0,1]
  224. arena[5]=[1,0,1,1,0,0,0,0,0,1]
  225. arena[6]=[1,0,0,1,0,1,1,1,0,1]
  226. arena[7]=[1,1,0,1,0,0,0,1,0,1]
  227. arena[8]=[1,0,0,1,0,1,0,0,0,1]
  228. arena[9]=[1,1,1,1,1,1,1,1,1,1]
  229. var playerPos=[4,4]; // x,y (from top left)
  230. var playerDir=0.4; // theta, facing right=0=2pi
  231. var playerPosZ=1;
  232. var key=[0,0,0,0,0]; // left, right, up, down
  233. var playerVelY=0;
  234. var face=[];
  235. function wallDistance(theta){
  236. var data=[];
  237. face=[];
  238. var x = playerPos[0], y = playerPos[1];
  239. var deltaX, deltaY;
  240. var distX, distY;
  241. var stepX, stepY;
  242. var mapX, mapY
  243. var atX=Math.floor(x), atY=Math.floor(y);
  244. var thisRow=-1;
  245. var thisSide=-1;
  246. var lastHeight=0;
  247. for (var i=0; i<samples; i++) {
  248. theta+=pi/(3*samples)+2*pi;
  249. theta%=2*pi;
  250. mapX = atX, mapY = atY;
  251. deltaX=1/Math.cos(theta);
  252. deltaY=1/Math.sin(theta);
  253. if (deltaX>0) {
  254. stepX = 1;
  255. distX = (mapX + 1 - x) * deltaX;
  256. }
  257. else {
  258. stepX = -1;
  259. distX = (x - mapX) * (deltaX*=-1);
  260. }
  261. if (deltaY>0) {
  262. stepY = 1;
  263. distY = (mapY + 1 - y) * deltaY;
  264. }
  265. else {
  266. stepY = -1;
  267. distY = (y - mapY) * (deltaY*=-1);
  268. }
  269. for (var j=0; j<20; j++) {
  270. if (distX < distY) {
  271. mapX += stepX;
  272. if (arena[mapX][mapY]) {
  273. if (thisRow!=mapX || thisSide!=0) {
  274. if (i>0) {
  275. data.push(i);
  276. data.push(lastHeight);
  277. }
  278. data.push(i);
  279. data.push(distX);
  280. thisSide=0;
  281. thisRow=mapX;
  282. face.push(1+stepX);
  283. }
  284. lastHeight=distX;
  285. break;
  286. }
  287. distX += deltaX;
  288. }
  289. else {
  290. mapY += stepY;
  291. if (arena[mapX][mapY]) {
  292. if (thisRow!=mapY || thisSide!=1) {
  293. if (i>0) {
  294. data.push(i);
  295. data.push(lastHeight);
  296. }
  297. data.push(i);
  298. data.push(distY);
  299. thisSide=1;
  300. thisRow=mapY;
  301. face.push(2+stepY)
  302. }
  303. lastHeight=distY;
  304. break;
  305. }
  306. distY += deltaY;
  307. }
  308. }
  309. }
  310. data.push(i);
  311. data.push(lastHeight);
  312. return data;
  313. }
  314. function drawCanvas(){
  315. canvas.clearRect(0,0,400, 300);
  316. var theta = playerDir-pi/6;
  317. var wall=wallDistance(theta);
  318. map.beginPath();
  319. map.clearRect(0,0,80,80);
  320. map.fillStyle="#3366CC";
  321. map.arc(playerPos[0]*8, playerPos[1]*8, 3, 0, 2*pi, true);
  322. map.fill();
  323. map.beginPath();
  324. map.moveTo(8*playerPos[0], 8*playerPos[1]);
  325. var linGrad;
  326. var tl,tr,bl,br;
  327. var theta1,theta2,fix1,fix2;
  328. for (var i=0; i<wall.length; i+=4) {
  329. theta1=playerDir-pi/6 + pi*wall[i]/(3*samples);
  330. theta2=playerDir-pi/6 + pi*wall[i+2]/(3*samples);
  331. fix1 = Math.cos(theta1-playerDir);
  332. fix2 = Math.cos(theta2-playerDir);
  333. var h=2-playerPosZ;
  334. var wallH1=100/(wall[i+1]*fix1);
  335. var wallH2=100/(wall[i+3]*fix2);
  336. tl=[wall[i]*2, 150-wallH1*h];
  337. tr=[wall[i+2]*2, 150-wallH2*h]
  338. br=[wall[i+2]*2, tr[1]+wallH2*2];
  339. bl=[wall[i]*2, tl[1]+wallH1*2]
  340. var shade1=Math.floor(wallH1*2+20); if (shade1>255) shade1=255;
  341. var shade2=Math.floor(wallH2*2+20); if (shade2>255) shade2=255;
  342. linGrad = canvas.createLinearGradient(tl[0],0,tr[0],0);
  343. linGrad.addColorStop(0, 'rgba('+(face[i/4]%2==0 ? shade1 : 0)+','+(face[i/4]==1 ? shade1 : 0)+','+(face[i/4]==2 ? 0 : shade1)+',1.0)');
  344. linGrad.addColorStop(1, 'rgba('+(face[i/4]%2==0 ? shade2 : 0)+','+(face[i/4]==1 ? shade2 : 0)+','+(face[i/4]==2 ? 0 : shade2)+',1.0)');
  345. canvas.beginPath();
  346. canvas.moveTo(tl[0], tl[1]);
  347. canvas.lineTo(tr[0], tr[1]);
  348. canvas.lineTo(br[0], br[1]);
  349. canvas.lineTo(bl[0], bl[1]);
  350. canvas.fillStyle = linGrad;
  351. canvas.fill();
  352. map.lineTo(playerPos[0]*8+Math.cos(theta1)*(wall[i+1])*8, playerPos[1]*8+Math.sin(theta1)*(wall[i+1])*8);
  353. map.lineTo(playerPos[0]*8+Math.cos(theta2)*(wall[i+3])*8, playerPos[1]*8+Math.sin(theta2)*(wall[i+3])*8);
  354. }
  355. map.fillStyle="#FF0000"
  356. map.fill();
  357. }
  358. function nearWall(x,y){
  359. var xx,yy;
  360. if (isNaN(x)) x=playerPos[0];
  361. if (isNaN(y)) y=playerPos[1];
  362. for (var i=-0.1; i<=0.1; i+=0.2) {
  363. xx=Math.floor(x+i)
  364. for (var j=-0.1; j<=0.1; j+=0.2) {
  365. yy=Math.floor(y+j);
  366. if (arena[xx][yy]) return true;
  367. }
  368. }
  369. return false;
  370. }
  371. function wobbleGun(){
  372. var mag=playerVelY;
  373. overlay.style.backgroundPosition=(10+Math.cos(total/6.23)*mag*90)+"px "+(10+Math.cos(total/5)*mag*90)+"px";
  374. }
  375. var jumpCycle=0;
  376. function update(){
  377. total++;
  378. var change=false;
  379. if (jumpCycle) {
  380. jumpCycle--;
  381. change=true;
  382. playerPosZ = 1 + jumpCycle*(20-jumpCycle)/110;
  383. }
  384. else if (key[4]) jumpCycle=20;
  385. if (key[0]) {
  386. if (!key[1]) {
  387. playerDir-=0.07; //left
  388. change=true;
  389. }
  390. }
  391. else if (key[1]) {
  392. playerDir+=0.07; //right
  393. change=true;
  394. }
  395. if (change) {
  396. playerDir+=2*pi;
  397. playerDir%=2*pi;
  398. document.getElementById("sky").style.backgroundPosition=Math.floor(1-playerDir/(2*pi)*2400)+"px 0";
  399. }
  400. if (key[2] && !key[3]) {
  401. if (playerVelY<0.1) playerVelY += 0.02;
  402. }
  403. else if (key[3] && !key[2]) {
  404. if (playerVelY>-0.1) playerVelY -= 0.02;
  405. }
  406. else {
  407. if (playerVelY<-0.02) playerVelY += 0.015;
  408. else if (playerVelY>0.02) playerVelY -= 0.015;
  409. else playerVelY=0;
  410. }
  411. if (playerVelY!=0) {
  412. var oldX=playerPos[0];;
  413. var oldY=playerPos[1];
  414. var newX=oldX+Math.cos(playerDir)*playerVelY;
  415. var newY=oldY+Math.sin(playerDir)*playerVelY;
  416. if (!nearWall(newX, oldY)) {
  417. playerPos[0]=newX;
  418. oldX=newX;
  419. change=true;
  420. }
  421. if (!nearWall(oldX, newY)) {
  422. playerPos[1]=newY;
  423. change=true;
  424. }
  425. }
  426. if (playerVelY) wobbleGun();
  427. if (change) drawCanvas();
  428. }
  429. function changeKey(which, to){
  430. switch (which){
  431. case 65:case 37: key[0]=to; break; // left
  432. case 87: case 38: key[2]=to; break; // up
  433. case 68: case 39: key[1]=to; break; // right
  434. case 83: case 40: key[3]=to; break;// down
  435. case 32: key[4]=to; break; // space bar;
  436. case 17: key[5]=to; break; // ctrl
  437. }
  438. }
  439. /*
  440. document.onkeydown=function(e){changeKey((e||window.event).keyCode, 1);}
  441. document.onkeyup=function(e){changeKey((e||window.event).keyCode, 0);}
  442. */
  443. document.onkeydown=function(e){
  444. e = e||window.event;
  445. changeKey(e.keyCode, 1);
  446. if (document.uniqueID) {
  447. e.cancelBubble=true;
  448. e.returnValue=false;
  449. } else {
  450. e.stopPropagation();
  451. e.preventDefault();
  452. }
  453. return false;
  454. }
  455. document.onkeyup=function(e){
  456. e = e||window.event;
  457. changeKey(e.keyCode, 0);
  458. if (document.uniqueID) {
  459. e.cancelBubble=true;
  460. e.returnValue=false;
  461. } else {
  462. e.stopPropagation();
  463. e.preventDefault();
  464. }
  465. return false;
  466. }
  467. function initUnderMap(){
  468. var underMap=document.getElementById("underMap").getContext("2d");
  469. underMap.fillStyle="#FFF";
  470. underMap.fillRect(0,0, 200, 200);
  471. underMap.fillStyle="#444";
  472. for (var i=0; i<arena.length; i++) {
  473. for (var j=0; j<arena[i].length; j++) {
  474. if (arena[i][j]) underMap.fillRect(i*8, j*8, 8, 8);
  475. }
  476. }
  477. }
  478. window.onerror=function(){
  479. alert('An error has occured, the most likely reason is because you are using an incompatible browser.\nYou must be using one of the following browsers or a newer version:\n\n- Internet Explorer 6\n- Firefox 1.5\n- Safari 1.3\n- Opera 9');
  480. window.onerror=function(){};
  481. return true;
  482. }
  483. uuCanvas.ready(function() {
  484. map=document.getElementById("map").getContext("2d");
  485. canvas=document.getElementById("canvas").getContext("2d");
  486. overlay=document.getElementById("overlay");
  487. document.getElementById("sky").style.backgroundPosition=Math.floor(-playerDir/(2*pi)*2400)+"px 0";
  488. drawCanvas();
  489. initUnderMap();
  490. setInterval(update, 35);
  491. });
  492. //--></script>
  493. </body></html>