diff canvas3d/demo1/test/code.js @ 0:b67b790dcf4f

upload All File
author e085711@nobuyasuoshiro.local
date Mon, 24 May 2010 21:38:02 +0900
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/canvas3d/demo1/test/code.js	Mon May 24 21:38:02 2010 +0900
@@ -0,0 +1,385 @@
+/**
+ * Copyright (c) 2009, Benjamin Joffe
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+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.moveTo(tr[0], tr[1]);
+		canvas.lineTo(tr[0], tr[1]);//右上
+		canvas.lineTo(br[0], br[1]);//右下
+		canvas.lineTo(bl[0], bl[1]);//左下
+//		canvas.lineTo(0,0);
+		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;
+}
+
+var xOff = 0;
+var yOff = 0;
+function wobbleGun(){
+	var mag=playerVelY;
+    xOff = (10+Math.cos(total/6.23)*mag*90)
+    yOff = (10+Math.cos(total/5)*mag*90)
+	overlay.style.backgroundPosition = xOff + "px " + yOff + "px";
+}
+
+
+var jumpCycle=0;
+
+var audio = window.Audio && new Audio("shoot.wav");
+
+function shoot()
+{
+	audio && audio.play();
+	canvas.save();
+	canvas.strokeStyle = "#FFFF00";
+	canvas.beginPath();
+    
+	canvas.moveTo(190+xOff, 140+yOff);
+	canvas.lineTo(250+xOff, 200+yOff);
+	canvas.closePath();
+	canvas.stroke();
+	canvas.restore();
+	setTimeout('drawCanvas()',100);
+}
+
+
+function update(){
+
+	total++;
+
+	var change=false;
+
+	if (jumpCycle) {
+		jumpCycle--;
+		change=true;
+		playerPosZ = 1 + jumpCycle*(20-jumpCycle)/30;
+	}
+	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) playerVelY -= 0.02;
+	}
+	else {
+		if (playerVelY<-0.02) playerVelY += 0.015;
+		else if (playerVelY>0.02) playerVelY -= 0.015;
+		else playerVelY=0;
+	}
+	
+	
+	if (playerVelY!=0) {
+
+		var oldX=playerPos[0];;
+		var oldY=playerPos[1];		
+		var newX=oldX+Math.cos(playerDir)*playerVelY;
+		var newY=oldY+Math.sin(playerDir)*playerVelY;
+
+		if (!nearWall(newX, oldY)) {
+			playerPos[0]=newX;
+			oldX=newX;
+			change=true;
+		}
+		if (!nearWall(oldX, newY)) {
+			playerPos[1]=newY;
+			change=true;
+		}
+
+	}
+	
+	if (playerVelY) wobbleGun();
+	if (change) drawCanvas();
+
+}
+
+
+function changeKey(which, to){
+	switch (which){
+		case 65:case 37: key[0]=to; break; // left
+		case 87: case 38: key[2]=to; break; // up
+		case 68: case 39: key[1]=to; break; // right
+		case 83: case 40: key[3]=to; break;// down
+		case 32: key[4]=to; break; // space bar;
+		case 17: key[5]=to; break; // ctrl
+		case 66: if (to) { shoot() } break; // b
+	}
+}
+document.onkeydown=function(e){changeKey((e||window.event).keyCode, 1);}
+document.onkeyup=function(e){changeKey((e||window.event).keyCode, 0);}
+
+
+function initUnderMap(){
+	var underMap=document.getElementById("underMap").getContext("2d");
+	underMap.fillStyle="#FFF";
+	underMap.fillRect(0,0, 200, 200);
+	underMap.fillStyle="#444";
+	for (var i=0; i<arena.length; i++) {
+		for (var j=0; j<arena[i].length; j++) {
+			if (arena[i][j]) underMap.fillRect(i*8, j*8, 8, 8);
+		}	
+	}
+}
+
+
+window.onload=function(){
+	var ele = document.getElementById("map");
+	if (!ele.getContext)
+	{
+	  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.');
+	  return;
+	}
+	map=ele.getContext("2d");
+	canvas=document.getElementById("canvas").getContext("2d");
+	overlay=document.getElementById("overlay");
+	document.getElementById("sky").style.backgroundPosition=Math.floor(-playerDir/(2*pi)*2400)+"px 0";
+	drawCanvas();
+	initUnderMap();
+	setInterval(update, 35);
+}
\ No newline at end of file