-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.js
128 lines (107 loc) · 4.21 KB
/
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(70, window.innerWidth/window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// White directional light used as 'sunlight'
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.75);
directionalLight.castShadow = true;
scene.add(directionalLight);
// Ambient lighting used to prevent total black-out for unlit faces
const light = new THREE.AmbientLight(0x404040); // soft white light
scene.add(light);
// Setup the camera
camera.position.x = 5;
camera.position.z = 5;
// Setup some basic world constants
const cellHeight = 5;
const cellWidth = 18;
// The renderer loop
let fFirstRender = true;
let nLastFrame = Date.now();
const arrFPS = [];
const render = function () {
// For the first render, initalize some stuff
if (fFirstRender) {
fFirstRender = false;
// Generate a simple 'cell' of 8x8x8 blocks
/*for (let y = 0; y < cellHeight; ++y) {
for (let z = 0; z < cellWidth; ++z) {
for (let x = 0; x < cellWidth; ++x) {
// Top-level blocks should be grass blocks!
addBlock(x, y, z, y === cellHeight - 1 ? blocks.grass : y <= cellHeight - 3 ? blocks.stone : blocks.dirt);
}
}
}
// Spawn a forest!
const nTrees = Math.random() * 15;
for (let i = 0; i<nTrees; i++)
addTree(Math.round(Math.random() * cellWidth), cellHeight, Math.round(Math.random() * cellWidth));*/
// Generate a terrain
generateTerrain();
// Sit the player on-top of the cell
camera.position.y = cellHeight + nPlayerHeight;
// Setup the FPS counter
setInterval(() =>
domStats.innerHTML = Math.round(arrFPS.reduce((a, b) => a + b) / 30) + ' FPS' +
'<br>Draw Calls: ' + renderer.info.render.calls +
'<br>Triangles: ' + renderer.info.render.triangles
, 250);
// Lastly, perform an initially-expensive optimization run by hiding meshes that have no visible faces.
checkWorldVisibility();
simulateWaterTick();
}
// Execute any key presses. holds, etc.
runPressedButtons();
// Check for any objects in view, highlighting and selecting in-advance, if possible.
checkObjectsInView();
// Check for + execute physical collisions
checkPlayerPhysics();
// Render the scene
renderer.render(scene, camera);
// Calculate and display engine stats
arrFPS.unshift(Math.round(1000 / (Date.now() - nLastFrame)));
if (arrFPS.length > 30) arrFPS.pop();
nLastFrame = Date.now();
// Queue another frame!
requestAnimationFrame(render);
};
// Keep track of player states
const cObjectInView = {
distance: 0,
object: {}
}
function handleClick() {
if (cObjectInView.distance > 0 && cObjectInView.distance <= 3) {
// Nuke that block!
removeBlock(cObjectInView.object.position.x,
cObjectInView.object.position.y,
cObjectInView.object.position.z
);
}
}
function placeBlock() {
if (cObjectInView.distance > 0 && cObjectInView.distance <= 3) {
const isWater = cObjectInView.object.userData.type === blocks.water;
// Add a block (or modify the existing Water block)
const cBlock = isWater ? cObjectInView.object : addBlock(cObjectInView.object.position.x,
cObjectInView.object.position.y + 1,
cObjectInView.object.position.z,
blocks.water
);
if (!cBlock) return;
cBlock.userData.nVolume = 1;
}
}
document.body.addEventListener('click', () => {
handleClick();
controls.lock();
});
// Fire off the first renderer tick once ALL page elements are loaded
window.onload = () => render();
// If the page/screen size changes, make sure to adjust the rendering too!
window.onresize = () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}