initial commit
This commit is contained in:
commit
ed4fd2a1ac
21
game.js
Normal file
21
game.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
var raycast = raycast || {};
|
||||||
|
|
||||||
|
window.requestAnimFrame = (function(){
|
||||||
|
return window.requestAnimationFrame ||
|
||||||
|
window.webkitRequestAnimationFrame ||
|
||||||
|
window.mozRequestAnimationFrame ||
|
||||||
|
window.oRequestAnimationFrame ||
|
||||||
|
window.msRequestAnimationFrame ||
|
||||||
|
function(callback, element){
|
||||||
|
window.setTimeout(callback, 1000 / 60);
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
function start() {
|
||||||
|
document.onkeyup = raycast.keyhandler.onKeyup;
|
||||||
|
document.onkeydown = raycast.keyhandler.onKeydown;
|
||||||
|
var textureFiles = ["img/brick.png", "img/ground.png", "img/sky.png"];
|
||||||
|
raycast.texture.initiateLoad(textureFiles, raycast.engine.start);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.onload = start;
|
BIN
img/brick.png
Normal file
BIN
img/brick.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
BIN
img/ground.png
Normal file
BIN
img/ground.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.6 KiB |
BIN
img/sky.png
Normal file
BIN
img/sky.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 215 B |
65
keyhandler.js
Normal file
65
keyhandler.js
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
var raycast = raycast || {};
|
||||||
|
|
||||||
|
raycast.keyhandler = (function () {
|
||||||
|
var codes = {
|
||||||
|
up: 38,
|
||||||
|
w: 87,
|
||||||
|
down: 40,
|
||||||
|
left: 37,
|
||||||
|
a: 65,
|
||||||
|
right: 39,
|
||||||
|
d: 68,
|
||||||
|
space: 32,
|
||||||
|
ctrl: 17,
|
||||||
|
esc: 27
|
||||||
|
};
|
||||||
|
|
||||||
|
var state = new Array();
|
||||||
|
var lastState = new Array();
|
||||||
|
|
||||||
|
for (var i = 0; i < 255; i++) {
|
||||||
|
state[i] = false;
|
||||||
|
lastState[i] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
onKeyup = function (e) {
|
||||||
|
state[e.which] = false;
|
||||||
|
if (isUsedKey(e.which))
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
onKeydown = function (e) {
|
||||||
|
state[e.which] = true;
|
||||||
|
if (isUsedKey(e.which))
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
function isUsedKey(keycode) {
|
||||||
|
for (var key in codes) {
|
||||||
|
if (codes[key] == keycode) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
isKeydown = function(keyname) {
|
||||||
|
return state[codes[keyname]];
|
||||||
|
}
|
||||||
|
|
||||||
|
isKeypress = function(keyname) {
|
||||||
|
return state[codes[keyname]] && !lastState[codes[keyname]];
|
||||||
|
}
|
||||||
|
|
||||||
|
tick = function() {
|
||||||
|
lastState = state.slice();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
onKeyup: onKeyup,
|
||||||
|
onKeydown: onKeydown,
|
||||||
|
isKeydown: isKeydown,
|
||||||
|
isKeypress: isKeypress,
|
||||||
|
tick: tick
|
||||||
|
};
|
||||||
|
})();
|
17
raycast.html
Normal file
17
raycast.html
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body bgcolor="999999">
|
||||||
|
<div id="canvasdiv">
|
||||||
|
<canvas id="viewport" width="800" height="600"></canvas>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="keyhandler.js"></script>
|
||||||
|
<script src="texture.js"></script>
|
||||||
|
<script src="raycast.js"></script>
|
||||||
|
<script src="game.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
349
raycast.js
Normal file
349
raycast.js
Normal file
@ -0,0 +1,349 @@
|
|||||||
|
// http://lodev.org/cgtutor/raycasting.html
|
||||||
|
var raycast = raycast || {};
|
||||||
|
|
||||||
|
raycast.engine = (function () {
|
||||||
|
var canvas = document.getElementById("viewport");
|
||||||
|
var g = canvas.getContext("2d");
|
||||||
|
var filtering = false;
|
||||||
|
var mapWidth = 24,
|
||||||
|
mapHeight = 24,
|
||||||
|
texHeight = 64,
|
||||||
|
texWidth = 64;
|
||||||
|
|
||||||
|
var texture;
|
||||||
|
function initTexture() {
|
||||||
|
texture = raycast.texture.getTextures();
|
||||||
|
console.log(texture);
|
||||||
|
texture.push([]);
|
||||||
|
for(var x = 0; x < texWidth; x++) {
|
||||||
|
for(var y = 0; y < texHeight; y++) {
|
||||||
|
var xorcolor = (x * 256 / texWidth) ^ (y * 256 / texHeight);
|
||||||
|
var d = Math.sqrt((texWidth/2 - x)*(texWidth/2 - x) + (texHeight/2 - y)*(texHeight/2 - y));
|
||||||
|
var sincolor = 256 * (1 + Math.sin(d/2)) / 2;
|
||||||
|
texture[3][texWidth * y + x] = [xorcolor, 0, sincolor]; // blue sine pattern
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
texture[0] = raycast.texture.load("ground");
|
||||||
|
texture[1] = raycast.texture.load("brick");
|
||||||
|
texture[2] = raycast.texture.load("sky");
|
||||||
|
*/
|
||||||
|
|
||||||
|
var worldMap = [
|
||||||
|
[1,1,1,1,1,1,1,1,1,1],
|
||||||
|
[1,0,0,0,0,0,0,0,0,1],
|
||||||
|
[1,0,0,0,0,0,0,0,0,1],
|
||||||
|
[1,0,0,1,0,0,1,0,0,1],
|
||||||
|
[1,0,0,0,0,0,0,0,0,1],
|
||||||
|
[1,0,0,0,0,0,0,0,0,1],
|
||||||
|
[1,0,0,1,0,0,1,0,0,1],
|
||||||
|
[1,0,0,0,0,0,0,0,0,1],
|
||||||
|
[1,0,0,0,0,0,0,0,0,1],
|
||||||
|
[1,1,1,1,1,1,1,1,1,1]
|
||||||
|
];
|
||||||
|
|
||||||
|
var posX = 2, posY = 2,
|
||||||
|
dirX = -1, dirY = 0,
|
||||||
|
planeX = 0, planeY = 0.66,
|
||||||
|
time = Date.now(), oldTime = Date.now();
|
||||||
|
|
||||||
|
var moveSpeed, rotSpeed;
|
||||||
|
|
||||||
|
var w = canvas.width,
|
||||||
|
h = canvas.height;
|
||||||
|
|
||||||
|
function verLine(arr, x, yStart, yEnd, color){
|
||||||
|
//console.log(x, yStart, yEnd);
|
||||||
|
for (var y = yStart | 0; y < yEnd | 0; y++) {
|
||||||
|
var i = 4 * (w * y) + 4 * x;
|
||||||
|
arr[i + 0] = color[0];
|
||||||
|
arr[i + 1] = color[1];
|
||||||
|
arr[i + 2] = color[2];
|
||||||
|
arr[i + 3] = 255;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
imagedata = g.getImageData(0,0,w,h);
|
||||||
|
var buffer = imagedata.data;
|
||||||
|
|
||||||
|
var keys = raycast.keyhandler;
|
||||||
|
|
||||||
|
function input() {
|
||||||
|
if (keys.isKeydown("up")) {
|
||||||
|
if(worldMap[(posX + dirX * moveSpeed) | 0][posY | 0] == 0) posX += dirX * moveSpeed;
|
||||||
|
if(worldMap[posX | 0][(posY + dirY * moveSpeed) | 0] == 0) posY += dirY * moveSpeed;
|
||||||
|
}
|
||||||
|
//move backwards if no wall behind you
|
||||||
|
if (keys.isKeydown("down")) {
|
||||||
|
if(worldMap[(posX - dirX * moveSpeed) | 0][posY | 0] == 0) posX -= dirX * moveSpeed;
|
||||||
|
if(worldMap[posX | 0][(posY - dirY * moveSpeed) | 0] == 0) posY -= dirY * moveSpeed;
|
||||||
|
}
|
||||||
|
if (keys.isKeydown("right")) {
|
||||||
|
//both camera direction and camera plane must be rotated
|
||||||
|
var oldDirX = dirX;
|
||||||
|
dirX = dirX * Math.cos(-rotSpeed) - dirY * Math.sin(-rotSpeed);
|
||||||
|
dirY = oldDirX * Math.sin(-rotSpeed) + dirY * Math.cos(-rotSpeed);
|
||||||
|
var oldPlaneX = planeX;
|
||||||
|
planeX = planeX * Math.cos(-rotSpeed) - planeY * Math.sin(-rotSpeed);
|
||||||
|
planeY = oldPlaneX * Math.sin(-rotSpeed) + planeY * Math.cos(-rotSpeed);
|
||||||
|
}
|
||||||
|
if (keys.isKeydown("left")) {
|
||||||
|
//both camera direction and camera plane must be rotated
|
||||||
|
var oldDirX = dirX;
|
||||||
|
dirX = dirX * Math.cos(rotSpeed) - dirY * Math.sin(rotSpeed);
|
||||||
|
dirY = oldDirX * Math.sin(rotSpeed) + dirY * Math.cos(rotSpeed);
|
||||||
|
var oldPlaneX = planeX;
|
||||||
|
planeX = planeX * Math.cos(rotSpeed) - planeY * Math.sin(rotSpeed);
|
||||||
|
planeY = oldPlaneX * Math.sin(rotSpeed) + planeY * Math.cos(rotSpeed);
|
||||||
|
}
|
||||||
|
if (keys.isKeypress("d"))
|
||||||
|
filtering = !filtering;
|
||||||
|
}
|
||||||
|
|
||||||
|
function draw() {
|
||||||
|
for(var x = 0; x < w; x++) {
|
||||||
|
var cameraX = 2 * x / w - 1,
|
||||||
|
rayPosX = posX,
|
||||||
|
rayPosY = posY,
|
||||||
|
rayDirX = dirX + planeX * cameraX,
|
||||||
|
rayDirY = dirY + planeY * cameraX;
|
||||||
|
|
||||||
|
var mapX = rayPosX | 0,
|
||||||
|
mapY = rayPosY | 0;
|
||||||
|
|
||||||
|
var deltaDistX = Math.sqrt(1 + (rayDirY * rayDirY) / (rayDirX * rayDirX)),
|
||||||
|
deltaDistY = Math.sqrt(1 + (rayDirX * rayDirX) / (rayDirY * rayDirY));
|
||||||
|
|
||||||
|
var stepX,
|
||||||
|
stepY,
|
||||||
|
sideDistX,
|
||||||
|
sideDistY;
|
||||||
|
|
||||||
|
if (rayDirX < 0) {
|
||||||
|
stepX = -1;
|
||||||
|
sideDistX = (rayPosX - mapX) * deltaDistX;
|
||||||
|
} else {
|
||||||
|
stepX = 1;
|
||||||
|
sideDistX = (mapX + 1.0 - rayPosX) * deltaDistX;
|
||||||
|
}
|
||||||
|
if (rayDirY < 0) {
|
||||||
|
stepY = -1;
|
||||||
|
sideDistY = (rayPosY - mapY) * deltaDistY;
|
||||||
|
} else {
|
||||||
|
stepY = 1;
|
||||||
|
sideDistY = (mapY + 1.0 - rayPosY) * deltaDistY;
|
||||||
|
}
|
||||||
|
|
||||||
|
var side, hit = 0;
|
||||||
|
|
||||||
|
// DDA
|
||||||
|
while (hit == 0) {
|
||||||
|
side = sideDistX > sideDistY;
|
||||||
|
if (side == 0) {
|
||||||
|
sideDistX += deltaDistX;
|
||||||
|
mapX += stepX;
|
||||||
|
} else {
|
||||||
|
sideDistY += deltaDistY;
|
||||||
|
mapY += stepY;
|
||||||
|
}
|
||||||
|
if (worldMap[mapX][mapY] > 0) {
|
||||||
|
hit = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var perpWallDist;
|
||||||
|
if (side == 0)
|
||||||
|
perpWallDist = Math.abs((mapX - rayPosX + (1 - stepX) / 2) / rayDirX);
|
||||||
|
else
|
||||||
|
perpWallDist = Math.abs((mapY - rayPosY + (1 - stepY) / 2) / rayDirY);
|
||||||
|
|
||||||
|
//Calculate height of line to draw on screen
|
||||||
|
var lineHeight = Math.abs((h / perpWallDist) | 0);
|
||||||
|
|
||||||
|
//calculate lowest and highest pixel to fill in current stripe
|
||||||
|
var drawStart = ((h - lineHeight) / 2) | 0;
|
||||||
|
if(drawStart < 0)
|
||||||
|
drawStart = 0;
|
||||||
|
var drawEnd = ((h + lineHeight) / 2) | 0;
|
||||||
|
if(drawEnd >= h)
|
||||||
|
drawEnd = h - 1;
|
||||||
|
|
||||||
|
var wallX; // the exact value where the wall was hit
|
||||||
|
if (side == 1)
|
||||||
|
wallX = rayPosX + ((mapY - rayPosY + (1 - stepY) / 2) / rayDirY) * rayDirX;
|
||||||
|
else
|
||||||
|
wallX = rayPosY + ((mapX - rayPosX + (1 - stepX) / 2) / rayDirX) * rayDirY;
|
||||||
|
wallX -= wallX | 0;
|
||||||
|
|
||||||
|
var texX = (wallX * texWidth)/* | 0*/;
|
||||||
|
if(side == 0 && rayDirX > 0)
|
||||||
|
texX = texWidth - texX - 1;
|
||||||
|
if(side == 1 && rayDirY < 0)
|
||||||
|
texX = texWidth - texX - 1;
|
||||||
|
|
||||||
|
var shade = (side == 1 ? 0.6: 1);
|
||||||
|
|
||||||
|
var wallTex = texture[worldMap[mapX][mapY] - 1];
|
||||||
|
|
||||||
|
for (var y = drawStart; y < drawEnd; y++) {
|
||||||
|
var d = (y * 256 - h * 128 + lineHeight * 128) | 0;
|
||||||
|
var texY = ((d * texHeight) / (lineHeight * 256))/* | 0*/;
|
||||||
|
if (texY < 0) texY = 0;
|
||||||
|
|
||||||
|
var color;
|
||||||
|
if (filtering) {
|
||||||
|
var ty1 = texY | 0;
|
||||||
|
var ty2 = (ty1 + 1) % texHeight;
|
||||||
|
var tx1 = texX | 0;
|
||||||
|
var tx2 = (tx1 + 1) % texWidth;
|
||||||
|
var xf = texX - (texX | 0);
|
||||||
|
var yf = texY - (texY | 0);
|
||||||
|
|
||||||
|
color = [0,0,0];
|
||||||
|
var c1 = wallTex[texWidth * ty1 + tx1];
|
||||||
|
var c2 = wallTex[texWidth * ty1 + tx2];
|
||||||
|
var c3 = wallTex[texWidth * ty2 + tx1];
|
||||||
|
var c4 = wallTex[texWidth * ty2 + tx2];
|
||||||
|
|
||||||
|
color[0] = (c1[0]*(1-xf)*(1-yf) + c2[0]*xf*(1-yf) + c3[0]*(1-xf)*yf + c4[0]*xf*yf) | 0;
|
||||||
|
color[1] = (c1[1]*(1-xf)*(1-yf) + c2[1]*xf*(1-yf) + c3[1]*(1-xf)*yf + c4[1]*xf*yf) | 0;
|
||||||
|
color[2] = (c1[2]*(1-xf)*(1-yf) + c2[2]*xf*(1-yf) + c3[2]*(1-xf)*yf + c4[2]*xf*yf) | 0;
|
||||||
|
} else {
|
||||||
|
texX |= 0;
|
||||||
|
texY |= 0;
|
||||||
|
color = wallTex[texHeight * texY + texX];
|
||||||
|
}
|
||||||
|
var i = 4 * (w * y) + 4 * x;
|
||||||
|
|
||||||
|
buffer[i + 0] = color[0] * shade;
|
||||||
|
buffer[i + 1] = color[1] * shade;
|
||||||
|
buffer[i + 2] = color[2] * shade;
|
||||||
|
buffer[i + 3] = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
var floorXWall, floorYWall; //x, y position of the floor texel at the bottom of the wall
|
||||||
|
//4 different wall directions possible
|
||||||
|
if (side == 0 && rayDirX > 0) {
|
||||||
|
floorXWall = mapX;
|
||||||
|
floorYWall = mapY + wallX;
|
||||||
|
} else if (side == 0 && rayDirX < 0) {
|
||||||
|
floorXWall = mapX + 1.0;
|
||||||
|
floorYWall = mapY + wallX;
|
||||||
|
} else if (side == 1 && rayDirY > 0) {
|
||||||
|
floorXWall = mapX + wallX;
|
||||||
|
floorYWall = mapY;
|
||||||
|
} else /* side == 1 && rayDirY > 0*/{
|
||||||
|
floorXWall = mapX + wallX;
|
||||||
|
floorYWall = mapY + 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentDist;
|
||||||
|
var distWall = perpWallDist;
|
||||||
|
var distPlayer = 0.0;
|
||||||
|
|
||||||
|
if (drawEnd < 0) drawEnd = h; //becomes < 0 when the integer overflows
|
||||||
|
|
||||||
|
var ceilTex = texture[2];
|
||||||
|
var floorTex = texture[1];
|
||||||
|
|
||||||
|
//draw the floor from drawEnd to the bottom of the screen
|
||||||
|
for(var y = drawEnd; y < h; y++)
|
||||||
|
{
|
||||||
|
currentDist = h / (2.0 * y - h); //you could make a small lookup table for this instead
|
||||||
|
|
||||||
|
var weight = (currentDist - distPlayer) / (distWall - distPlayer);
|
||||||
|
var nextWeight = (h / (2.0 * (y+1) - h)) / distWall;
|
||||||
|
|
||||||
|
var currentFloorX = weight * floorXWall + (1.0 - weight) * posX;
|
||||||
|
var currentFloorY = weight * floorYWall + (1.0 - weight) * posY;
|
||||||
|
|
||||||
|
var floorTexX = (currentFloorX * texWidth) % texWidth;
|
||||||
|
var floorTexY = (currentFloorY * texHeight) % texHeight;
|
||||||
|
|
||||||
|
if (floorTexX < 0) floorTexX = 0;
|
||||||
|
if (floorTexY < 0) floorTexY = 0;
|
||||||
|
|
||||||
|
var color;
|
||||||
|
if (filtering) {
|
||||||
|
ty1 = floorTexY | 0;
|
||||||
|
ty2 = (ty1 + 1) % texHeight;
|
||||||
|
tx1 = floorTexX | 0;
|
||||||
|
tx2 = (tx1 + 1) % texWidth;
|
||||||
|
xf = floorTexX - (floorTexX | 0);
|
||||||
|
yf = floorTexY - (floorTexY | 0);
|
||||||
|
|
||||||
|
color = [0,0,0];
|
||||||
|
c1 = floorTex[texWidth * ty1 + tx1];
|
||||||
|
c2 = floorTex[texWidth * ty1 + tx2];
|
||||||
|
c3 = floorTex[texWidth * ty2 + tx1];
|
||||||
|
c4 = floorTex[texWidth * ty2 + tx2];
|
||||||
|
|
||||||
|
color[0] = (c1[0]*(1-xf)*(1-yf) + c2[0]*xf*(1-yf) + c3[0]*(1-xf)*yf + c4[0]*xf*yf) | 0;
|
||||||
|
color[1] = (c1[1]*(1-xf)*(1-yf) + c2[1]*xf*(1-yf) + c3[1]*(1-xf)*yf + c4[1]*xf*yf) | 0;
|
||||||
|
color[2] = (c1[2]*(1-xf)*(1-yf) + c2[2]*xf*(1-yf) + c3[2]*(1-xf)*yf + c4[2]*xf*yf) | 0;
|
||||||
|
} else {
|
||||||
|
color = floorTex[texWidth * (floorTexY|0) + (floorTexX|0)];
|
||||||
|
}
|
||||||
|
|
||||||
|
//floor
|
||||||
|
i = 4 * (w * y) + 4 * x;
|
||||||
|
|
||||||
|
buffer[i+0] = (color[0])/2;
|
||||||
|
buffer[i+1] = (color[1])/2;
|
||||||
|
buffer[i+2] = (color[2])/2;
|
||||||
|
buffer[i+3] = 255;
|
||||||
|
|
||||||
|
if (filtering) {
|
||||||
|
color = [0,0,0];
|
||||||
|
c1 = ceilTex[texWidth * ty1 + tx1];
|
||||||
|
c2 = ceilTex[texWidth * ty1 + tx2];
|
||||||
|
c3 = ceilTex[texWidth * ty2 + tx1];
|
||||||
|
c4 = ceilTex[texWidth * ty2 + tx2];
|
||||||
|
|
||||||
|
color[0] = (c1[0]*(1-xf)*(1-yf) + c2[0]*xf*(1-yf) + c3[0]*(1-xf)*yf + c4[0]*xf*yf) | 0;
|
||||||
|
color[1] = (c1[1]*(1-xf)*(1-yf) + c2[1]*xf*(1-yf) + c3[1]*(1-xf)*yf + c4[1]*xf*yf) | 0;
|
||||||
|
color[2] = (c1[2]*(1-xf)*(1-yf) + c2[2]*xf*(1-yf) + c3[2]*(1-xf)*yf + c4[2]*xf*yf) | 0;
|
||||||
|
} else {
|
||||||
|
color = ceilTex[texWidth * (floorTexY|0) + (floorTexX|0)];
|
||||||
|
}
|
||||||
|
|
||||||
|
//ceiling (symmetrical!)
|
||||||
|
i = 4 * (w * (h - y - 1)) + 4 * x;
|
||||||
|
|
||||||
|
buffer[i+0] = color[0]/2;
|
||||||
|
buffer[i+1] = color[1]/2;
|
||||||
|
buffer[i+2] = color[2]/2;
|
||||||
|
buffer[i+3] = 255;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
oldTime = time;
|
||||||
|
time = Date.now()
|
||||||
|
var frameTime = (time - oldTime) / 1000.0; //frameTime is the time this frame has taken, in seconds
|
||||||
|
|
||||||
|
//speed modifiers
|
||||||
|
moveSpeed = frameTime * 5.0; //the constant value is in squares/second
|
||||||
|
rotSpeed = frameTime * 3.0; //the constant value is in radians/second
|
||||||
|
|
||||||
|
g.putImageData(imagedata, 0, 0);
|
||||||
|
g.font = "bold 30pt Monospace";
|
||||||
|
g.fillText(""+((1000 / (time - oldTime))|0), 0, 30);
|
||||||
|
};
|
||||||
|
|
||||||
|
function tick() {
|
||||||
|
draw();
|
||||||
|
input();
|
||||||
|
keys.tick();
|
||||||
|
|
||||||
|
window.requestAnimFrame(tick);
|
||||||
|
//window.setTimeout(tick, 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
function start() {
|
||||||
|
initTexture();
|
||||||
|
tick();
|
||||||
|
}
|
||||||
|
|
||||||
|
return {start: start}
|
||||||
|
}());
|
BIN
screenshot.png
Normal file
BIN
screenshot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 157 KiB |
63
texture.js
Normal file
63
texture.js
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
var raycast = raycast || {};
|
||||||
|
|
||||||
|
raycast.texture = (function () {
|
||||||
|
function load(id) {
|
||||||
|
var canvas = document.createElement('canvas');
|
||||||
|
var image = document.getElementById(id);
|
||||||
|
canvas.width = image.width;
|
||||||
|
canvas.height = image.height;
|
||||||
|
var ctx = canvas.getContext('2d');
|
||||||
|
ctx.drawImage(image, 0, 0);
|
||||||
|
var imagedata = ctx.getImageData(0, 0, image.width, image.height);
|
||||||
|
var rgbArray = new Array(image.width * image.height);
|
||||||
|
for( var i = 0; i < image.width * image.height; i++) {
|
||||||
|
rgbArray[i] = [imagedata.data[4*i], imagedata.data[4*i+1], imagedata.data[4*i+2]];
|
||||||
|
}
|
||||||
|
image.width = 0;
|
||||||
|
image.height = 0;
|
||||||
|
return rgbArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
var images = [];
|
||||||
|
|
||||||
|
function initiateLoad(textures, onSuccess) {
|
||||||
|
var n = textures.length;
|
||||||
|
var counter = 0;
|
||||||
|
|
||||||
|
var callback = function() {
|
||||||
|
counter++;
|
||||||
|
console.log(counter+" of "+n+" textures received")
|
||||||
|
if (counter == n) onSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < n; i++) {
|
||||||
|
var image = new Image()
|
||||||
|
image.onload = callback;
|
||||||
|
image.src = textures[i];
|
||||||
|
images.push(image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTextures() {
|
||||||
|
var n = images.length;
|
||||||
|
var textures = [];
|
||||||
|
for (var i = 0; i < n; i++) {
|
||||||
|
var canvas = document.createElement('canvas');
|
||||||
|
var image = images[i];
|
||||||
|
canvas.width = image.width;
|
||||||
|
canvas.height = image.height;
|
||||||
|
var ctx = canvas.getContext('2d');
|
||||||
|
ctx.drawImage(image, 0, 0);
|
||||||
|
var imagedata = ctx.getImageData(0, 0, image.width, image.height);
|
||||||
|
var rgbArray = new Array(image.width * image.height);
|
||||||
|
for(var j = 0; j < image.width * image.height; j++) {
|
||||||
|
rgbArray[j] = [imagedata.data[4*j], imagedata.data[4*j+1], imagedata.data[4*j+2]];
|
||||||
|
}
|
||||||
|
textures.push(rgbArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
return textures;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {load: load, initiateLoad: initiateLoad, getTextures: getTextures};
|
||||||
|
}());
|
Loading…
Reference in New Issue
Block a user