<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<HTML>
<HEAD>
<TITLE>Canvascape - 3D walker</TITLE>
<!--
This game is copyright by Benjamin Joffe.
You may not reproduce or modify this without
written permission by the origional author.
Email him: CanvasGame@gmail.com for suggestions.
-->
<SCRIPT type="text/javascript" src="canvas.js"></SCRIPT>
<STYLE type="text/css"><!--
H1 {
padding: 5px;
font-size: 14pt;
font-style: italic;
}
BODY {
font-family: arial;
font-size: 10pt;
background-color: #000;
color: #CCC;
}
#holder {
position: relative;
width: 400px;
height:300px;
top: 10px;
left: 120px;
border: 2px solid #333;
}
#sky {
position: absolute;
left: 0;
top: 0;
height: 150px;
width: 400px;
background-color: #CCD;
background-image: url(sky.jpg);
}
#floor {
position: absolute;
left: 0;
top: 150px;
height: 150px;
width: 400px;
background-color: #565;
background-image: url(floor.png);
}
#canvas {
position: absolute;
top: 0;
left: 0;
}
#overlay {
position: absolute;
top: 0;
left: 0;
width: 400px;
height: 300px;
background-image: url(overlay.gif);
}
#map, #underMap {
top: 70px;
left: 20px;
position: absolute;
}
#copyright {
position: absolute;
top: 170px;
left: 15px;
}
A {
color: #66AACC;
}
A:hover {
color: lime;
}
--></STYLE>
</HEAD>
<BODY>
<H1>Canvascape - "3D Walker"</H1>
<CANVAS id="underMap" width="80" height="80"></CANVAS>
<CANVAS id="map" width="80" height="80"></CANVAS>
<DIV id="copyright">
© Benjamin Joffe<BR>
<A href="mailto:CanvasGame@gmail.com" style="font-size:7pt;">canvasGame@gmail.com</A>
</DIV>
<DIV id="holder" style="clear:both;">
<DIV id="sky"></DIV>
<DIV id="floor"></DIV>
<CANVAS id="canvas" width="400" height="300"></CANVAS>
<DIV id="overlay"></DIV>
</DIV>
<P>Use the arrow keys to walk around the map. Space bar = jump.</P>
<P>What you are seeing is a test using the new Canvas tag to demonstrate its capabilities, Internet Explorer support has recently been added thanks to Google's workaround code. See also: <A href="textures.htm">textured version</A>.</P>
<P><A href="http://www.studiocoast.com.au/">Web hosting provided by Studio Coast</A></P>
<SCRIPT type="text/javascript"><!--
/*
This code is copyright by Benjamin Joffe.
You may not reproduce or modify this without
written permission by the origional author.
Email him: CanvasGame@gmail.com for suggestions.
*/
var map;
var canvas;
var overlay;
//variables initiated at the bottom of the code...
var pi=Math.PI;
var total=0;
Number.prototype.range=function(){
return (this+2*pi)%(2*pi);
}
Number.prototype.roundC=function(){
return Math.round(this*100)/100;
}
var total=0;
var samples=200;
var arena=[];
arena[0]=[1,1,1,1,1,1,1,1,1,1]
arena[1]=[1,0,0,0,0,0,0,0,0,1]
arena[2]=[1,0,0,1,0,1,1,1,0,1]
arena[3]=[1,0,1,0,0,0,0,1,0,1]
arena[4]=[1,0,0,0,0,1,0,1,0,1]
arena[5]=[1,0,1,1,0,0,0,0,0,1]
arena[6]=[1,0,0,1,0,1,1,1,0,1]
arena[7]=[1,1,0,1,0,0,0,1,0,1]
arena[8]=[1,0,0,1,0,1,0,0,0,1]
arena[9]=[1,1,1,1,1,1,1,1,1,1]
var playerPos=[4,4]; // x,y (from top left)
var playerDir=0.4; // theta, facing right=0=2pi
var playerPosZ=1;
var key=[0,0,0,0,0]; // left, right, up, down
var playerVelY=0;
var face=[];
function wallDistance(theta){
var data=[];
face=[];
var x = playerPos[0], y = playerPos[1];
var deltaX, deltaY;
var distX, distY;
var stepX, stepY;
var mapX, mapY
var atX=Math.floor(x), atY=Math.floor(y);
var thisRow=-1;
var thisSide=-1;
var lastHeight=0;
for (var i=0; i<samples; i++) {
theta+=pi/(3*samples)+2*pi;
theta%=2*pi;
mapX = atX, mapY = atY;
deltaX=1/Math.cos(theta);
deltaY=1/Math.sin(theta);
if (deltaX>0) {
stepX = 1;
distX = (mapX + 1 - x) * deltaX;
}
else {
stepX = -1;
distX = (x - mapX) * (deltaX*=-1);
}
if (deltaY>0) {
stepY = 1;
distY = (mapY + 1 - y) * deltaY;
}
else {
stepY = -1;
distY = (y - mapY) * (deltaY*=-1);
}
for (var j=0; j<20; j++) {
if (distX < distY) {
mapX += stepX;
if (arena[mapX][mapY]) {
if (thisRow!=mapX || thisSide!=0) {
if (i>0) {
data.push(i);
data.push(lastHeight);
}
data.push(i);
data.push(distX);
thisSide=0;
thisRow=mapX;
face.push(1+stepX);
}
lastHeight=distX;
break;
}
distX += deltaX;
}
else {
mapY += stepY;
if (arena[mapX][mapY]) {
if (thisRow!=mapY || thisSide!=1) {
if (i>0) {
data.push(i);
data.push(lastHeight);
}
data.push(i);
data.push(distY);
thisSide=1;
thisRow=mapY;
face.push(2+stepY)
}
lastHeight=distY;
break;
}
distY += deltaY;
}
}
}
data.push(i);
data.push(lastHeight);
return data;
}
function drawCanvas(){
canvas.clearRect(0,0,400, 300);
var theta = playerDir-pi/6;
var wall=wallDistance(theta);
map.beginPath();
map.clearRect(0,0,80,80);
map.fillStyle="#3366CC";
map.arc(playerPos[0]*8, playerPos[1]*8, 3, 0, 2*pi, true);
map.fill();
map.beginPath();
map.moveTo(8*playerPos[0], 8*playerPos[1]);
var linGrad;
var tl,tr,bl,br;
var theta1,theta2,fix1,fix2;
for (var i=0; i<wall.length; i+=4) {
theta1=playerDir-pi/6 + pi*wall[i]/(3*samples);
theta2=playerDir-pi/6 + pi*wall[i+2]/(3*samples);
fix1 = Math.cos(theta1-playerDir);
fix2 = Math.cos(theta2-playerDir);
var h=2-playerPosZ;
var wallH1=100/(wall[i+1]*fix1);
var wallH2=100/(wall[i+3]*fix2);
tl=[wall[i]*2, 150-wallH1*h];
tr=[wall[i+2]*2, 150-wallH2*h]
br=[wall[i+2]*2, tr[1]+wallH2*2];
bl=[wall[i]*2, tl[1]+wallH1*2]
var shade1=Math.floor(wallH1*2+20); if (shade1>255) shade1=255;
var shade2=Math.floor(wallH2*2+20); if (shade2>255) shade2=255;
linGrad = canvas.createLinearGradient(tl[0],0,tr[0],0);
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)');
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)');
canvas.beginPath();
canvas.moveTo(tl[0], tl[1]);
canvas.lineTo(tr[0], tr[1]);
canvas.lineTo(br[0], br[1]);
canvas.lineTo(bl[0], bl[1]);
canvas.fillStyle = linGrad;
canvas.fill();
map.lineTo(playerPos[0]*8+Math.cos(theta1)*(wall[i+1])*8, playerPos[1]*8+Math.sin(theta1)*(wall[i+1])*8);
map.lineTo(playerPos[0]*8+Math.cos(theta2)*(wall[i+3])*8, playerPos[1]*8+Math.sin(theta2)*(wall[i+3])*8);
}
map.fillStyle="#FF0000"
map.fill();
}
function nearWall(x,y){
var xx,yy;
if (isNaN(x)) x=playerPos[0];
if (isNaN(y)) y=playerPos[1];
for (var i=-0.1; i<=0.1; i+=0.2) {
xx=Math.floor(x+i)
for (var j=-0.1; j<=0.1; j+=0.2) {
yy=Math.floor(y+j);
if (arena[xx][yy]) return true;
}
}
return false;
}
function wobbleGun(){
var mag=playerVelY;
overlay.style.backgroundPosition=(10+Math.cos(total/6.23)*mag*90)+"px "+(10+Math.cos(total/5)*mag*90)+"px";
}
var jumpCycle=0;
function update(){
total++;
var change=false;
if (jumpCycle) {
jumpCycle--;
change=true;
playerPosZ = 1 + jumpCycle*(20-jumpCycle)/110;
}
else if (key[4]) jumpCycle=20;
if (key[0]) {
if (!key[1]) {
playerDir-=0.07; //left
change=true;
}
}
else if (key[1]) {
playerDir+=0.07; //right
change=true;
}
if (change) {
playerDir+=2*pi;
playerDir%=2*pi;
document.getElementById("sky").style.backgroundPosition=Math.floor(1-playerDir/(2*pi)*2400)+"px 0";
}
if (key[2] && !key[3]) {
if (playerVelY<0.1) playerVelY += 0.02;
}
else if (key[3] && !key[2]) {
if (playerVelY>-0.1) playerV
评论0
最新资源