improve mouse lock and split up screen rendering into two canvas elements

This commit is contained in:
LabyStudio
2022-02-04 14:28:05 +01:00
parent a6f365225c
commit 039d799bed
5 changed files with 60 additions and 52 deletions
+38 -26
View File
@@ -9,8 +9,17 @@ window.GameWindow = class {
this.mouseMotionY = 0;
this.mouseLocked = false;
// Get canvas wrapper
this.wrapper = document.getElementById(this.canvasWrapperId);
// Create world renderer
this.canvas = document.createElement('canvas');
this.wrapper.appendChild(this.canvas);
// Create screen renderer
this.canvas2d = document.createElement('canvas');
this.wrapper.appendChild(this.canvas2d);
// Stats
this.stats = new Stats()
this.stats.showPanel(0);
@@ -30,7 +39,7 @@ window.GameWindow = class {
document.addEventListener('mousemove', event => this.onMouseMove(event), false);
// Losing focus event
window.addEventListener("mouseout", function () {
this.canvas.addEventListener("mouseout", function () {
if (minecraft.currentScreen === null) {
minecraft.displayScreen(new GuiIngameMenu());
}
@@ -76,28 +85,26 @@ window.GameWindow = class {
}
requestFocus() {
let scope = this;
window.focus();
this.canvas.requestPointerLock();
document.body.style.cursor = 'none';
this.mouseLocked = true;
}
setTimeout(function () {
window.focus();
scope.renderer.canvas.requestPointerLock();
}, 0);
exitFocus() {
document.exitPointerLock();
document.body.style.cursor = 'default';
}
loadRenderer(renderer) {
this.renderer = renderer;
let canvas = this.renderer.canvas;
// Add web renderer canvas to wrapper
this.wrapper.appendChild(canvas);
// Initialize window size
this.onResize();
// Request focus
let scope = this;
canvas.onclick = function () {
document.onclick = function () {
if (scope.minecraft.currentScreen === null) {
scope.requestFocus();
}
@@ -105,28 +112,33 @@ window.GameWindow = class {
}
updateWindowSize() {
this.scaleFactor = 1;
this.width = this.wrapper.offsetWidth;
this.height = this.wrapper.offsetHeight;
let wrapperWidth = this.wrapper.offsetWidth;
let wrapperHeight = this.wrapper.offsetHeight;
for (this.scaleFactor = 1; this.width / (this.scaleFactor + 1) >= 320 && this.height / (this.scaleFactor + 1) >= 240; this.scaleFactor++) {
let scale;
for (scale = 1; wrapperWidth / (scale + 1) >= 320 && wrapperHeight / (scale + 1) >= 240; scale++) {
// Empty
}
this.width = this.width / this.scaleFactor;
this.height = this.height / this.scaleFactor;
if (!(this.renderer === null)) {
this.renderer.webRenderer.setPixelRatio(/*this.minecraft.currentScreen === null ? 1 :*/ 1 / this.scaleFactor);
}
this.scaleFactor = scale;
this.width = wrapperWidth / scale;
this.height = wrapperHeight / scale;
}
onResize() {
this.updateWindowSize();
// Adjust camera
let wrapperWidth = this.width * this.scaleFactor;
let wrapperHeight = this.height * this.scaleFactor;
// Update world renderer size and camera
this.renderer.camera.aspect = this.width / this.height;
this.renderer.camera.updateProjectionMatrix();
this.renderer.webRenderer.setSize(this.width * this.scaleFactor, this.height * this.scaleFactor);
this.renderer.webRenderer.setSize(wrapperWidth, wrapperHeight);
// Update canvas 2d size
this.canvas2d.style.width = wrapperWidth + "px";
this.canvas2d.style.height = wrapperHeight + "px";
// Reinitialize gui
this.renderer.initializeGui();
@@ -138,7 +150,7 @@ window.GameWindow = class {
}
onFocusChanged() {
this.mouseLocked = document.pointerLockElement === this.renderer.canvas;
this.mouseLocked = document.pointerLockElement === this.canvas;
}
onMouseMove(event) {
@@ -148,7 +160,7 @@ window.GameWindow = class {
this.mouseX = event.clientX / this.scaleFactor;
this.mouseY = event.clientY / this.scaleFactor;
if (!this.mouseLocked && this.minecraft.currentScreen === null) {
if (document.pointerLockElement !== this.canvas && this.minecraft.currentScreen === null) {
this.requestFocus();
}
}
+1
View File
@@ -119,6 +119,7 @@ window.Minecraft = class {
if (screen === null) {
this.window.requestFocus();
} else {
this.window.exitFocus();
screen.setup(this, this.window.width, this.window.height);
}
}
@@ -30,7 +30,7 @@ window.IngameOverlay = class extends Gui {
this.textureHotbar,
0, 22,
24, 24,
x + this.minecraft.inventory.selectedSlotIndex * 20, y - 1,
x + this.minecraft.inventory.selectedSlotIndex * 20 - 1, y - 1,
24, 24
)
@@ -37,9 +37,8 @@ window.WorldRenderer = class {
this.scene.matrixAutoUpdate = false;
// Create web renderer
this.canvas = document.createElement('canvas')
this.webRenderer = new THREE.WebGLRenderer({
canvas: this.canvas,
canvas: this.window.canvas,
antialias: false
});
@@ -54,47 +53,44 @@ window.WorldRenderer = class {
}
initializeGui() {
// We will use 2D canvas element to render our HUD.
this.canvas2d = document.createElement('canvas')
// Update camera size
this.canvas2d.width = this.window.width;
this.canvas2d.height = this.window.height;
this.window.canvas2d.width = this.window.width;
this.window.canvas2d.height = this.window.height;
// Get context stack of 2d canvas
this.stack2d = this.canvas2d.getContext('2d');
this.stack2d = this.window.canvas2d.getContext('2d');
this.stack2d.webkitImageSmoothingEnabled = false;
this.stack2d.mozImageSmoothingEnabled = false;
this.stack2d.imageSmoothingEnabled = false;
// Create texture from rendered graphics.
this.frameBuffer = new THREE.Texture(this.canvas2d)
this.frameBuffer.needsUpdate = true;
this.frameBuffer.minFilter = THREE.LinearFilter;
this.frameBuffer.maxFilter = THREE.LinearFilter;
//this.frameBuffer = new THREE.Texture(this.canvas2d)
//this.frameBuffer.needsUpdate = true;
//this.frameBuffer.minFilter = THREE.LinearFilter;
//this.frameBuffer.maxFilter = THREE.LinearFilter;
// Create HUD material.
let material = new THREE.MeshBasicMaterial({
map: this.frameBuffer,
transparent: true
});
//let material = new THREE.MeshBasicMaterial({
// map: this.frameBuffer,
// transparent: true
//});
// Create plane to render the HUD. This plane fill the whole screen.
let geometry = new THREE.PlaneGeometry(this.canvas2d.width, this.canvas2d.height);
let plane = new THREE.Mesh(geometry, material);
//let geometry = new THREE.PlaneGeometry(this.canvas2d.width, this.canvas2d.height);
//let plane = new THREE.Mesh(geometry, material);
// Create also a custom scene for HUD.
this.scene2d = new THREE.Scene();
this.scene2d.add(plane);
//this.scene2d = new THREE.Scene();
//this.scene2d.add(plane);
// Create 2D camera
this.camera2d = new THREE.OrthographicCamera(0, 0, 0, 0, 0, 30);
/*this.camera2d = new THREE.OrthographicCamera(0, 0, 0, 0, 0, 30);
this.camera2d.aspect = this.window.width / this.window.height;
this.camera2d.left = -this.window.width / 2;
this.camera2d.right = this.window.width / 2;
this.camera2d.top = this.window.height / 2;
this.camera2d.bottom = -this.window.height / 2;
this.camera2d.updateProjectionMatrix();
this.camera2d.updateProjectionMatrix();*/
}
render(partialTicks) {
@@ -107,9 +103,8 @@ window.WorldRenderer = class {
let cameraChunkZ = Math.floor(player.z >> 4);
this.renderChunks(cameraChunkX, cameraChunkZ);
// Clear frame buffer for 2d screen
// Reset 2d canvas
this.stack2d.clearRect(0, 0, this.window.width, this.window.height);
this.frameBuffer.needsUpdate = true;
// Render in-game overlay
let mouseX = this.minecraft.window.mouseX;
@@ -123,7 +118,6 @@ window.WorldRenderer = class {
// Render actual scene and hud
this.webRenderer.render(this.scene, this.camera);
this.webRenderer.render(this.scene2d, this.camera2d);
}
orientCamera(partialTicks) {
+1
View File
@@ -8,6 +8,7 @@ body {
}
canvas {
position: absolute;
image-rendering: -moz-crisp-edges; /* Firefox */
image-rendering: -webkit-crisp-edges; /* Webkit (Safari) */
image-rendering: pixelated; /* Chrome */