This commit is contained in:
Alexander Popov 2022-03-29 23:50:58 +03:00
parent 7f1140f997
commit 64d99d7476
Signed by: iiiypuk
GPG Key ID: 3F76816AEE08F908
7 changed files with 104 additions and 52 deletions

7
TODO.md Normal file
View File

@ -0,0 +1,7 @@
## Plan
- [ ] - fog (draw distance)
- [ ] - покачивание камеры
## Complete
- [ ] `...`
## Dropped
- [ ] `...`

View File

@ -1,19 +1,19 @@
var raycast = raycast || {};
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(callback, element){
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;
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);
};

View File

@ -4,13 +4,15 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>JSRay</title>
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body bgcolor="999999">
<div id="canvasdiv">
<canvas id="viewport" width="800" height="600"></canvas>
<body>
<div class="container">
<canvas id="canvas" width="600" height="400"></canvas>
</div>
<script src="keyhandler.js"></script>
<script src="worldMap.js"></script>
<script src="keyHandler.js"></script>
<script src="texture.js"></script>
<script src="raycast.js"></script>
<script src="game.js"></script>

View File

@ -1,16 +1,22 @@
var raycast = raycast || {};
raycast.keyhandler = (function () {
raycast.keyHandler = (function() {
var codes = {
// forward
up: 38,
w: 87,
// backward
down: 40,
s: 83,
// turn left
left: 37,
a: 65,
// turn right
right: 39,
d: 68,
// special
space: 32,
ctrl: 17,
ctrl: 17, // change filtering type
esc: 27
};

View File

@ -1,13 +1,10 @@
// http://lodev.org/cgtutor/raycasting.html
var raycast = raycast || {};
raycast.engine = (function () {
var canvas = document.getElementById("viewport");
raycast.engine = (function() {
var canvas = document.getElementById("canvas");
var g = canvas.getContext("2d");
var filtering = false;
var mapWidth = 24,
mapHeight = 24,
texHeight = 64,
let texHeight = 64, // mapWidth = 24, mapHeight = 24
texWidth = 64;
var texture;
@ -24,24 +21,14 @@ raycast.engine = (function () {
}
}
}
/*
texture[0] = raycast.texture.load("ground");
texture[0] = raycast.texture.load("...");
texture[1] = raycast.texture.load("brick");
texture[2] = raycast.texture.load("sky");
texture[2] = raycast.texture.load("ground");
texture[3] = 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,
@ -54,7 +41,6 @@ raycast.engine = (function () {
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];
@ -67,20 +53,21 @@ raycast.engine = (function () {
imagedata = g.getImageData(0,0,w,h);
var buffer = imagedata.data;
var keys = raycast.keyhandler;
var keys = raycast.keyHandler;
function input() {
if (keys.isKeydown("up")) {
// player move forward
if (keys.isKeydown("up") || keys.isKeydown("w")) {
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")) {
// player move backwards if no wall behind you
if (keys.isKeydown("down") || keys.isKeydown("s")) {
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
if (keys.isKeydown("right") || keys.isKeydown("d")) {
// 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);
@ -88,8 +75,8 @@ raycast.engine = (function () {
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
if (keys.isKeydown("left") || keys.isKeydown("a")) {
// 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);
@ -97,7 +84,7 @@ raycast.engine = (function () {
planeX = planeX * Math.cos(rotSpeed) - planeY * Math.sin(rotSpeed);
planeY = oldPlaneX * Math.sin(rotSpeed) + planeY * Math.cos(rotSpeed);
}
if (keys.isKeypress("d"))
if (keys.isKeypress("ctrl"))
filtering = !filtering;
}
@ -158,10 +145,10 @@ raycast.engine = (function () {
else
perpWallDist = Math.abs((mapY - rayPosY + (1 - stepY) / 2) / rayDirY);
//Calculate height of line to draw on screen
// 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
// calculate lowest and highest pixel to fill in current stripe
var drawStart = ((h - lineHeight) / 2) | 0;
if(drawStart < 0)
drawStart = 0;
@ -247,7 +234,7 @@ raycast.engine = (function () {
var ceilTex = texture[2];
var floorTex = texture[1];
//draw the floor from drawEnd to the bottom of the screen
// 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
@ -286,7 +273,7 @@ raycast.engine = (function () {
color = floorTex[texWidth * (floorTexY|0) + (floorTexX|0)];
}
//floor
// floor
i = 4 * (w * y) + 4 * x;
buffer[i+0] = (color[0])/2;
@ -308,7 +295,7 @@ raycast.engine = (function () {
color = ceilTex[texWidth * (floorTexY|0) + (floorTexX|0)];
}
//ceiling (symmetrical!)
// ceiling (symmetrical!)
i = 4 * (w * (h - y - 1)) + 4 * x;
buffer[i+0] = color[0]/2;
@ -327,8 +314,8 @@ raycast.engine = (function () {
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);
g.font = "14pt Monospace";
g.fillText("FPS: " + ((1000 / (time - oldTime)) | 0), 5, 20);
};
function tick() {
@ -337,7 +324,6 @@ raycast.engine = (function () {
keys.tick();
window.requestAnimFrame(tick);
//window.setTimeout(tick, 1);
};
function start() {

20
src/styles.css Normal file
View File

@ -0,0 +1,20 @@
* { margin: 0; padding: 0; outline: 0; }
html, body {
height: 100%;
}
body {
background-color: #444;
}
.container {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
canvas {
border: 2px solid #000;
}

31
src/worldMap.js Normal file
View File

@ -0,0 +1,31 @@
/*let worldMap = [
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,1,1,1,0,0,0,0,0,0,0,0,1,0,0,1],
[1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1],
[1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1],
[1,0,0,1,0,1,0,0,0,0,0,0,0,0,1,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,1,1,1,0,1,0,0,0,0,0,0,0,0,1,1,1,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1],
[1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1],
[1,1,0,1,1,0,0,0,0,0,0,0,0,0,1,0,0,1],
[1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0,1],
[1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,1,0,1,0,0,0,0,0,0,0,0,1,0,1,1],
[1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
];*/
let worldMap = [
[1,1,1,1,1,1,1,1,1,1,1,1],
[1,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,1],
[1,0,0,1,1,1,0,0,1,0,0,1],
[1,0,0,0,0,0,0,0,0,0,0,1],
[1,1,1,1,1,1,1,1,1,1,1,1]
];