Skip to content

Instantly share code, notes, and snippets.

@kdrnic
Created September 11, 2016 23:11
Show Gist options
  • Save kdrnic/aae31af82bcab7df32e1b4d29b3f57fa to your computer and use it in GitHub Desktop.
Save kdrnic/aae31af82bcab7df32e1b4d29b3f57fa to your computer and use it in GitHub Desktop.
var _map = new Array();
_map[0] = new Array(2, 1, 2, 4, 4, 4, 4, 4, 4, 4, 4, 1);
_map[1] = new Array(2, 0, 2, 0, 0, 6, 0, 0, 0, 0, 4, 1);
_map[2] = new Array(2, 0, 2, 0, 0, 6, 0, 8, 8, 0, 4, 1);
_map[3] = new Array(2, 0, 0, 0, 0, 6, 0, 8, 8, 0, 4, 1);
_map[4] = new Array(2, 2, 2, 0, 0, 6, 0, 0, 0, 0, 4, 1);
_map[5] = new Array(4, 0, 0, 0, 0, 6, 0, 0, 8, 8, 4, 1);
_map[6] = new Array(4, 0, 7, 7, 0, 6, 0, 0, 8, 8, 4, 1);
_map[7] = new Array(4, 0, 7, 0, 0, 0, 0, 0, 0, 0, 4, 1);
_map[8] = new Array(4, 0, 7, 7, 0, 6, 0, 0, 0, 0, 4, 1);
_map[9] = new Array(4, 0, 0, 0, 0, 6, 0, 0, 0, 0, 4, 1);
_map[10] = new Array(4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1);
_map[11] = new Array(1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4);
var cameraX = 5.5;
var cameraY = 5.5;
var cameraAngle = Math.PI / 5;
var viewingAngle = Math.PI / 3;
var halfViewingAngleTan = Math.tan(viewingAngle / 2);
var aspectRatioMultiplier = (screenWidth / 2) / screenHeight;
var screenWidth = 320;
var screenHeight = 240;
var points = new Array();
var projectedPoints = new Array();
var walls;
CreateWalls(_map);
function Point(x, y)
{
this.x = x;
this.y = y;
this.Translate = function(x, y)
{
this.x += x;
this.y += y;
}
this.Rotate = function(angle)
{
var oldX, oldY;
oldX = this.x;
oldY = this.y;
this.x = oldX * Math.cos(angle) - oldY * Math.sin(angle);
this.y = oldX * Math.sin(angle) + oldY * Math.cos(angle);
}
}
function PointIndex(x, y)
{
for(var i = 0; i < points.length; i++)
{
if((points[i].x == x) && (points[i].y == y)) return i;
}
var oldL = points.length;
points[points.length] = new Point(x, y);
return oldL;
}
function Wall(i1, i2, c)
{
this.pointA = i1;
this.pointB = i2;
this.color = c;
}
function CreateWalls(map)
{
walls = new Array();
for(var x = 0; x < map.length; x++)
{
for(var y = 0; y < map[x].length; y++)
{
if(map[x][y] != 0)
{
if(x > 0)
{
if(map[x - 1][y] == 0)
{
walls[walls.length] = new Wall(PointIndex(x, y), PointIndex(x, y + 1), "rgb(255, 0, 0)");
}
}
if(y > 0)
{
if(map[x][y - 1] == 0)
{
walls[walls.length] = new Wall(PointIndex(x, y), PointIndex(x + 1, y), "rgb(0, 0, 255)");
}
}
if(x < map.length - 1)
{
if(map[x + 1][y] == 0)
{
walls[walls.length] = new Wall(PointIndex(x + 1, y), PointIndex(x + 1, y + 1), "rgb(255, 0, 0)");
}
}
if(y < map[x].length - 1)
{
if(map[x][y + 1] == 0)
{
walls[walls.length] = new Wall(PointIndex(x, y + 1), PointIndex(x + 1, y + 1), "rgb(0, 0, 255)");
}
}
}
}
}
}
function ProjectPoints()
{
for(var i = 0; i < points.length; i++)
{
projectedPoints[i] = new Point(points[i].x, points[i].y);
projectedPoints[i].Translate(-cameraX, -cameraY);
projectedPoints[i].Rotate(-cameraAngle);
var xBissectTanProd = projectedPoints[i].x * halfViewingAngleTan;
projectedPoints[i].y /= xBissectTanProd;
projectedPoints[i].x = projectedPoints[i].y;
projectedPoints[i].y = 0.5 / xBissectTanProd;
projectedPoints[i].x *= screenWidth / 2;
projectedPoints[i].y *= screenWidth / 2;
}
}
function DrawWalls()
{
var screen = document.getElementById("screenCanvas").getContext("2d");
document.getElementById("screenCanvas").width = document.getElementById("screenCanvas").width;
walls.sort((w1,w2)=>Math.max(projectedPoints[w1.pointB].y,projectedPoints[w1.pointA].y) - Math.max(projectedPoints[w2.pointA].y, projectedPoints[w2.pointB].y));
for(var i = 0; i < walls.length; i++)
{
var a, b;
a = projectedPoints[walls[i].pointA];
b = projectedPoints[walls[i].pointB];
if(a.y < 0) continue;
if(b.y < 0) continue;
if((Math.abs(a.x) < screenWidth / 2) || (Math.abs(b.x) < screenWidth / 2))
{
screen.beginPath();
screen.moveTo(a.x + (screenWidth / 2), (screenHeight / 2) - a.y);
screen.lineTo(b.x + (screenWidth / 2), (screenHeight / 2) - b.y);
screen.lineTo(b.x + (screenWidth / 2), (screenHeight / 2) + b.y);
screen.lineTo(a.x + (screenWidth / 2), (screenHeight / 2) + a.y);
screen.closePath();
screen.strokeStyle = "rgb(255, 255, 255)";
screen.fillStyle = walls[i].color;
screen.fill();
screen.stroke();
}
}
}
var up = 0;
var left;
var right;
var down;
setInterval(function(){if(up){ cameraX += Math.cos(cameraAngle) * 0.25; cameraY += Math.sin(cameraAngle) * 0.25; ProjectPoints(); DrawWalls()}}, 1000/60);
setInterval(function(){if(down){ cameraX -= Math.cos(cameraAngle) * 0.25; cameraY -= Math.sin(cameraAngle) * 0.25; ProjectPoints(); DrawWalls()}}, 1000/60);
setInterval(function(){if(left){ cameraAngle -= 0.0785398163; ProjectPoints(); DrawWalls()}}, 1000/60);
setInterval(function(){if(right){ cameraAngle += 0.0785398163; ProjectPoints(); DrawWalls()}}, 1000/60);
window.addEventListener("keydown", function(event){
if(event.keyCode == 38) up = true;
if(event.keyCode == 40) down = true;
if(event.keyCode == 37) left = true;
if(event.keyCode == 39) right = true;
});
window.addEventListener("keyup", function(event){
if(event.keyCode == 38) up = false;
if(event.keyCode == 40) down = false;
if(event.keyCode == 37) left = false;
if(event.keyCode == 39) right = false;
});
<html>
<head>
<script src="3D.js"></script>
</head>
<body onload="ProjectPoints(); DrawWalls()">
<canvas id="screenCanvas" width="320" height="240">
</canvas>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment