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