001.
002.
003.
004.
005.
006.
007.
008.
009.
010.
011.
012.
013.
014.
015.
016.
017.
018.
019.
020.
021.
022.
023.
024.
025.
var
map;
026.
var
canvas;
027.
var
overlay;
028.
029.
030.
var
pi=Math.PI;
031.
032.
var
total=0;
033.
034.
Number.prototype.range=
function
(){
035.
return
(
this
+2*pi)%(2*pi);
036.
}
037.
Number.prototype.roundC=
function
(){
038.
return
Math.round(
this
*100)/100;
039.
}
040.
041.
var
total=0;
042.
043.
var
samples=200;
044.
045.
046.
var
arena=[];
047.
arena[0]=[1,1,1,1,1,1,1,1,1,1]
048.
arena[1]=[1,0,0,0,0,0,0,0,0,1]
049.
arena[2]=[1,0,0,1,0,1,1,1,0,1]
050.
arena[3]=[1,0,1,0,0,0,0,1,0,1]
051.
arena[4]=[1,0,0,0,0,1,0,1,0,1]
052.
arena[5]=[1,0,1,1,0,0,0,0,0,1]
053.
arena[6]=[1,0,0,1,0,1,1,1,0,1]
054.
arena[7]=[1,1,0,1,0,0,0,1,0,1]
055.
arena[8]=[1,0,0,1,0,1,0,0,0,1]
056.
arena[9]=[1,1,1,1,1,1,1,1,1,1]
057.
058.
059.
var
playerPos=[4,4];
060.
var
playerDir=0.4;
061.
var
playerPosZ=1;
062.
var
key=[0,0,0,0,0];
063.
064.
var
playerVelY=0;
065.
066.
067.
var
face=[];
068.
069.
function
wallDistance(theta){
070.
071.
var
data=[];
072.
face=[];
073.
074.
var
x = playerPos[0], y = playerPos[1];
075.
var
deltaX, deltaY;
076.
var
distX, distY;
077.
var
stepX, stepY;
078.
var
mapX, mapY
079.
080.
var
atX=Math.floor(x), atY=Math.floor(y);
081.
082.
var
thisRow=-1;
083.
var
thisSide=-1;
084.
085.
var
lastHeight=0;
086.
087.
for
(
var
i=0; i<samples; i++) {
088.
theta+=pi/(3*samples)+2*pi;
089.
theta%=2*pi;
090.
091.
mapX = atX, mapY = atY;
092.
093.
deltaX=1/Math.cos(theta);
094.
deltaY=1/Math.sin(theta);
095.
096.
if
(deltaX>0) {
097.
stepX = 1;
098.
distX = (mapX + 1 - x) * deltaX;
099.
}
100.
else
{
101.
stepX = -1;
102.
distX = (x - mapX) * (deltaX*=-1);
103.
}
104.
if
(deltaY>0) {
105.
stepY = 1;
106.
distY = (mapY + 1 - y) * deltaY;
107.
}
108.
else
{
109.
stepY = -1;
110.
distY = (y - mapY) * (deltaY*=-1);
111.
}
112.
113.
114.
for
(
var
j=0; j<20; j++) {
115.
if
(distX < distY) {
116.
mapX += stepX;
117.
if
(arena[mapX][mapY]) {
118.
if
(thisRow!=mapX || thisSide!=0) {
119.
if
(i>0) {
120.
data.push(i);
121.
data.push(lastHeight);
122.
}
123.
data.push(i);
124.
data.push(distX);
125.
thisSide=0;
126.
thisRow=mapX;
127.
face.push(1+stepX);
128.
}
129.
lastHeight=distX;
130.
break
;
131.
}
132.
distX += deltaX;
133.
}
134.
else
{
135.
mapY += stepY;
136.
if
(arena[mapX][mapY]) {
137.
if
(thisRow!=mapY || thisSide!=1) {
138.
if
(i>0) {
139.
data.push(i);
140.
data.push(lastHeight);
141.
}
142.
data.push(i);
143.
data.push(distY);
144.
thisSide=1;
145.
thisRow=mapY;
146.
face.push(2+stepY)
147.
}
148.
lastHeight=distY;
149.
break
;
150.
}
151.
distY += deltaY;
152.
}
153.
}
154.
}
155.
data.push(i);
156.
data.push(lastHeight);
157.
158.
return
data;
159.
}
160.
161.
162.
function
drawCanvas(){
163.
164.
canvas.clearRect(0,0,400, 300);
165.
166.
var
theta = playerDir-pi/6;
167.
168.
var
wall=wallDistance(theta);
169.
170.
map.beginPath();
171.
map.clearRect(0,0,80,80);
172.
map.fillStyle=
"#3366CC"
;
173.
map.arc(playerPos[0]*8, playerPos[1]*8, 3, 0, 2*pi,
true
);
174.
map.fill();
175.
map.beginPath();
176.
map.moveTo(8*playerPos[0], 8*playerPos[1]);
177.
178.
179.
var
linGrad;
180.
181.
var
tl,tr,bl,br;
182.
183.
var
theta1,theta2,fix1,fix2;
184.
185.
for
(
var
i=0; i<wall.length; i+=4) {
186.
187.
theta1=playerDir-pi/6 + pi*wall[i]/(3*samples);
188.
theta2=playerDir-pi/6 + pi*wall[i+2]/(3*samples);
189.
190.
fix1 = Math.cos(theta1-playerDir);
191.
fix2 = Math.cos(theta2-playerDir);
192.
193.
var
h=2-playerPosZ;
194.
195.
var
wallH1=100/(wall[i+1]*fix1);
196.
var
wallH2=100/(wall[i+3]*fix2);
197.
198.
tl=[wall[i]*2, 150-wallH1*h];
199.
tr=[wall[i+2]*2, 150-wallH2*h]
200.
br=[wall[i+2]*2, tr[1]+wallH2*2];
201.
bl=[wall[i]*2, tl[1]+wallH1*2]
202.
203.
var
shade1=Math.floor(wallH1*2+20);
if
(shade1>255) shade1=255;
204.
var
shade2=Math.floor(wallH2*2+20);
if
(shade2>255) shade2=255;
205.
206.
linGrad = canvas.createLinearGradient(tl[0],0,tr[0],0);
207.
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)'
);
208.
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)'
);
209.
210.
canvas.beginPath();
211.
canvas.moveTo(tl[0], tl[1]);
212.
canvas.lineTo(tr[0], tr[1]);
213.
canvas.lineTo(br[0], br[1]);
214.
canvas.lineTo(bl[0], bl[1]);
215.
canvas.fillStyle = linGrad;
216.
canvas.fill();
217.
218.
219.
map.lineTo(playerPos[0]*8+Math.cos(theta1)*(wall[i+1])*8, playerPos[1]*8+Math.sin(theta1)*(wall[i+1])*8);
220.
map.lineTo(playerPos[0]*8+Math.cos(theta2)*(wall[i+3])*8, playerPos[1]*8+Math.sin(theta2)*(wall[i+3])*8);
221.
222.
223.
}
224.
map.fillStyle=
"#FF0000"
225.
map.fill();
226.
227.
}
228.
229.
function
nearWall(x,y){
230.
var
xx,yy;
231.
if
(isNaN(x)) x=playerPos[0];
232.
if
(isNaN(y)) y=playerPos[1];
233.
for
(
var
i=-0.1; i<=0.1; i+=0.2) {
234.
xx=Math.floor(x+i)
235.
for
(
var
j=-0.1; j<=0.1; j+=0.2) {
236.
yy=Math.floor(y+j);
237.
if
(arena[xx][yy])
return
true
;
238.
}
239.
}
240.
return
false
;
241.
}
242.
243.
var
xOff = 0;
244.
var
yOff = 0;
245.
function
wobbleGun(){
246.
var
mag=playerVelY;
247.
xOff = (10+Math.cos(total/6.23)*mag*90)
248.
yOff = (10+Math.cos(total/5)*mag*90)
249.
overlay.style.backgroundPosition = xOff +
"px "
+ yOff +
"px"
;
250.
}
251.
252.
253.
var
jumpCycle=0;
254.
255.
var
audio = window.Audio &&
new
Audio(
"shoot.wav"
);
256.
257.
function
shoot()
258.
{
259.
audio && audio.play();
260.
canvas.save();
261.
canvas.strokeStyle =
"#FFFF00"
;
262.
canvas.beginPath();
263.
264.
canvas.moveTo(190+xOff, 140+yOff);
265.
canvas.lineTo(250+xOff, 170+yOff);
266.
canvas.closePath();
267.
canvas.stroke();
268.
canvas.restore();
269.
setTimeout(
'drawCanvas()'
,100);
270.
}
271.
272.
273.
function
update(){
274.
275.
total++;
276.
277.
var
change=
false
;
278.
279.
if
(jumpCycle) {
280.
jumpCycle--;
281.
change=
true
;
282.
playerPosZ = 1 + jumpCycle*(20-jumpCycle)/110;
283.
}
284.
else
if
(key[4]) jumpCycle=20;
285.
286.
if
(key[0]) {
287.
if
(!key[1]) {
288.
playerDir-=0.07;
289.
change=
true
;
290.
}
291.
}
292.
else
if
(key[1]) {
293.
playerDir+=0.07;
294.
change=
true
;
295.
}
296.
297.
if
(change) {
298.
playerDir+=2*pi;
299.
playerDir%=2*pi;
300.
document.getElementById(
"sky"
).style.backgroundPosition=Math.floor(1-playerDir/(2*pi)*2400)+
"px 0"
;
301.
}
302.
303.
if
(key[2] && !key[3]) {
304.
if
(playerVelY<0.1) playerVelY += 0.02;
305.
}
306.
else
if
(key[3] && !key[2]) {
307.
if
(playerVelY>-0.1) playerVelY -= 0.02;
308.
}
309.
else
{
310.
if
(playerVelY<-0.02) playerVelY += 0.015;
311.
else
if
(playerVelY>0.02) playerVelY -= 0.015;
312.
else
playerVelY=0;
313.
}
314.
315.
316.
if
(playerVelY!=0) {
317.
318.
var
oldX=playerPos[0];;
319.
var
oldY=playerPos[1];
320.
var
newX=oldX+Math.cos(playerDir)*playerVelY;
321.
var
newY=oldY+Math.sin(playerDir)*playerVelY;
322.
323.
if
(!nearWall(newX, oldY)) {
324.
playerPos[0]=newX;
325.
oldX=newX;
326.
change=
true
;
327.
}
328.
if
(!nearWall(oldX, newY)) {
329.
playerPos[1]=newY;
330.
change=
true
;
331.
}
332.
333.
}
334.
335.
if
(playerVelY) wobbleGun();
336.
if
(change) drawCanvas();
337.
338.
}
339.
340.
341.
function
changeKey(ev, which, to){
342.
343.
var
userAgent = navigator.userAgent.toLowerCase();
344.
345.
if
( ev.ctrlKey ) {
346.
switch
(which){
347.
case
65:
case
37: key[0]=to;
break
;
348.
case
87:
case
38: key[2]=to;
break
;
349.
case
68:
case
39: key[1]=to;
break
;
350.
case
83:
case
40: key[3]=to;
break
;
351.
case
32: key[4]=to;
break
;
352.
case
17: key[5]=to;
break
;
353.
case
66:
if
(to) { shoot() }
break
;
354.
}
355.
356.
if
(userAgent.indexOf(
"msie"
) > -1) {
357.
ev.returnValue =
false
;
358.
}
359.
else
{
360.
ev.preventDefault();
361.
}
362.
363.
}
364.
}
365.
document.onkeydown=
function
(e){changeKey((e||window.event),(e||window.event).keyCode, 1);}
366.
document.onkeyup=
function
(e){changeKey((e||window.event),(e||window.event).keyCode, 0);}
367.
368.
369.
function
initUnderMap(){
370.
var
underMap=document.getElementById(
"underMap"
).getContext(
"2d"
);
371.
underMap.fillStyle=
"#FFF"
;
372.
underMap.fillRect(0,0, 200, 200);
373.
underMap.fillStyle=
"#444"
;
374.
for
(
var
i=0; i<arena.length; i++) {
375.
for
(
var
j=0; j<arena[i].length; j++) {
376.
if
(arena[i][j]) underMap.fillRect(i*8, j*8, 8, 8);
377.
}
378.
}
379.
}
380.
381.
382.
window.onload=
function
(){
383.
var
ele = document.getElementById(
"map"
);
384.
if
(!ele.getContext)
385.
{
386.
alert(
'An error occured creating a Canvas 2D context. This may be because you are using an old browser, if not please contact me and I\'ll see if I can fix the error.'
);
387.
return
;
388.
}
389.
map=ele.getContext(
"2d"
);
390.
canvas=document.getElementById(
"canvas"
).getContext(
"2d"
);
391.
overlay=document.getElementById(
"overlay_html5"
);
392.
document.getElementById(
"sky"
).style.backgroundPosition=Math.floor(-playerDir/(2*pi)*2400)+
"px 0"
;
393.
drawCanvas();
394.
initUnderMap();
395.
setInterval(update, 35);
396.
}