implement ingame menu
This commit is contained in:
@@ -28,8 +28,23 @@ window.GameWindow = class {
|
|||||||
// Mouse motion
|
// Mouse motion
|
||||||
document.addEventListener('mousemove', event => this.onMouseMove(event), false);
|
document.addEventListener('mousemove', event => this.onMouseMove(event), false);
|
||||||
|
|
||||||
|
// Losing focus event
|
||||||
|
window.addEventListener("mouseout", function () {
|
||||||
|
if (minecraft.currentScreen === null) {
|
||||||
|
minecraft.displayScreen(new GuiIngameMenu());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Mouse buttons
|
// Mouse buttons
|
||||||
document.addEventListener('click', event => minecraft.onMouseClicked(event.button), false);
|
document.addEventListener('click', function (event) {
|
||||||
|
// Handle in-game mouse click
|
||||||
|
minecraft.onMouseClicked(event.button);
|
||||||
|
|
||||||
|
// Handle mouse click on screen
|
||||||
|
if (!(minecraft.currentScreen === null)) {
|
||||||
|
minecraft.currentScreen.mouseClicked(event.x, event.y, event.code);
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
|
||||||
// Keyboard interaction with screen
|
// Keyboard interaction with screen
|
||||||
window.addEventListener('keydown', function (event) {
|
window.addEventListener('keydown', function (event) {
|
||||||
@@ -41,6 +56,9 @@ window.GameWindow = class {
|
|||||||
// Cancel browser interaction
|
// Cancel browser interaction
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
|
} else if (event.code === 'Escape') {
|
||||||
|
event.preventDefault();
|
||||||
|
minecraft.displayScreen(new GuiIngameMenu());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -49,7 +67,12 @@ window.GameWindow = class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
requestFocus() {
|
requestFocus() {
|
||||||
this.renderer.canvasElement.requestPointerLock();
|
let scope = this;
|
||||||
|
|
||||||
|
setTimeout(function () {
|
||||||
|
window.focus();
|
||||||
|
scope.renderer.canvasElement.requestPointerLock();
|
||||||
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadRenderer(renderer) {
|
loadRenderer(renderer) {
|
||||||
@@ -64,10 +87,10 @@ window.GameWindow = class {
|
|||||||
this.onResize();
|
this.onResize();
|
||||||
|
|
||||||
// Request focus
|
// Request focus
|
||||||
let minecraft = this.minecraft;
|
let scope = this;
|
||||||
canvas.onclick = function () {
|
canvas.onclick = function () {
|
||||||
if (minecraft.currentScreen === null) {
|
if (scope.minecraft.currentScreen === null) {
|
||||||
canvas.requestPointerLock();
|
scope.requestFocus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -90,14 +113,13 @@ window.GameWindow = class {
|
|||||||
|
|
||||||
// Reinitialize current screen
|
// Reinitialize current screen
|
||||||
if (!(this.minecraft.currentScreen === null)) {
|
if (!(this.minecraft.currentScreen === null)) {
|
||||||
this.minecraft.currentScreen.init(this.minecraft, this.width, this.height);
|
this.minecraft.currentScreen.setup(this.minecraft, this.width, this.height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onFocusChanged() {
|
onFocusChanged() {
|
||||||
this.mouseLocked = document.pointerLockElement === this.renderer.canvasElement;
|
this.mouseLocked = document.pointerLockElement === this.renderer.canvasElement;
|
||||||
|
|
||||||
// Open in-game menu
|
|
||||||
if (!this.mouseLocked && this.minecraft.currentScreen === null) {
|
if (!this.mouseLocked && this.minecraft.currentScreen === null) {
|
||||||
this.minecraft.displayScreen(new GuiIngameMenu());
|
this.minecraft.displayScreen(new GuiIngameMenu());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ window.Minecraft = class {
|
|||||||
this.worldRenderer.scene.add(this.world.group);
|
this.worldRenderer.scene.add(this.world.group);
|
||||||
|
|
||||||
// Create player
|
// Create player
|
||||||
this.player = new Player(this.world);
|
this.player = new Player(this, this.world);
|
||||||
this.pickedBlock = 1;
|
this.pickedBlock = 1;
|
||||||
|
|
||||||
// Initialize
|
// Initialize
|
||||||
@@ -48,6 +48,10 @@ window.Minecraft = class {
|
|||||||
this.requestNextFrame();
|
this.requestNextFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasInGameFocus() {
|
||||||
|
return this.window.mouseLocked && this.currentScreen === null;
|
||||||
|
}
|
||||||
|
|
||||||
requestNextFrame() {
|
requestNextFrame() {
|
||||||
let scope = this;
|
let scope = this;
|
||||||
requestAnimationFrame(function () {
|
requestAnimationFrame(function () {
|
||||||
@@ -88,7 +92,7 @@ window.Minecraft = class {
|
|||||||
|
|
||||||
onRender(partialTicks) {
|
onRender(partialTicks) {
|
||||||
// Player rotation
|
// Player rotation
|
||||||
if (this.window.mouseLocked && !(this.currentScreen === "null")) {
|
if (this.hasInGameFocus()) {
|
||||||
this.player.turn(this.window.mouseMotionX, this.window.mouseMotionY);
|
this.player.turn(this.window.mouseMotionX, this.window.mouseMotionY);
|
||||||
|
|
||||||
this.window.mouseMotionX = 0;
|
this.window.mouseMotionX = 0;
|
||||||
@@ -112,7 +116,7 @@ window.Minecraft = class {
|
|||||||
if (screen === null) {
|
if (screen === null) {
|
||||||
this.window.requestFocus();
|
this.window.requestFocus();
|
||||||
} else {
|
} else {
|
||||||
screen.init(this, this.window.width, this.window.height);
|
screen.setup(this, this.window.width, this.window.height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
window.Player = class {
|
window.Player = class {
|
||||||
|
|
||||||
constructor(world) {
|
constructor(minecraft, world) {
|
||||||
|
this.minecraft = minecraft;
|
||||||
this.world = world;
|
this.world = world;
|
||||||
|
|
||||||
this.prevX = 0;
|
this.prevX = 0;
|
||||||
@@ -309,38 +310,40 @@ window.Player = class {
|
|||||||
let jumping = false;
|
let jumping = false;
|
||||||
let sneaking = false;
|
let sneaking = false;
|
||||||
|
|
||||||
if (Keyboard.isKeyDown("KeyR")) { // R
|
if (this.minecraft.hasInGameFocus()) {
|
||||||
this.respawn();
|
if (Keyboard.isKeyDown("KeyR")) { // R
|
||||||
}
|
this.respawn();
|
||||||
if (Keyboard.isKeyDown("KeyW")) { // W
|
|
||||||
moveForward++;
|
|
||||||
}
|
|
||||||
if (Keyboard.isKeyDown("KeyS")) { // S
|
|
||||||
moveForward--;
|
|
||||||
}
|
|
||||||
if (Keyboard.isKeyDown("KeyA")) { // A
|
|
||||||
moveStrafe++;
|
|
||||||
}
|
|
||||||
if (Keyboard.isKeyDown("KeyD")) { // D
|
|
||||||
moveStrafe--;
|
|
||||||
}
|
|
||||||
if (Keyboard.isKeyDown("Space")) { // Space
|
|
||||||
jumping = true;
|
|
||||||
}
|
|
||||||
if (Keyboard.isKeyDown("ShiftLeft")) { // Shift
|
|
||||||
if (this.moveForward > 0 && !this.sneaking && !this.sprinting && this.motionX !== 0 && this.motionZ !== 0) {
|
|
||||||
this.sprinting = true;
|
|
||||||
|
|
||||||
this.updateFOVModifier();
|
|
||||||
}
|
}
|
||||||
}
|
if (Keyboard.isKeyDown("KeyW")) { // W
|
||||||
if (Keyboard.isKeyDown("KeyQ")) { // Q
|
moveForward++;
|
||||||
sneaking = true;
|
}
|
||||||
}
|
if (Keyboard.isKeyDown("KeyS")) { // S
|
||||||
|
moveForward--;
|
||||||
|
}
|
||||||
|
if (Keyboard.isKeyDown("KeyA")) { // A
|
||||||
|
moveStrafe++;
|
||||||
|
}
|
||||||
|
if (Keyboard.isKeyDown("KeyD")) { // D
|
||||||
|
moveStrafe--;
|
||||||
|
}
|
||||||
|
if (Keyboard.isKeyDown("Space")) { // Space
|
||||||
|
jumping = true;
|
||||||
|
}
|
||||||
|
if (Keyboard.isKeyDown("ShiftLeft")) { // Shift
|
||||||
|
if (this.moveForward > 0 && !this.sneaking && !this.sprinting && this.motionX !== 0 && this.motionZ !== 0) {
|
||||||
|
this.sprinting = true;
|
||||||
|
|
||||||
if (sneaking) {
|
this.updateFOVModifier();
|
||||||
moveStrafe = moveStrafe * 0.3;
|
}
|
||||||
moveForward = moveForward * 0.3;
|
}
|
||||||
|
if (Keyboard.isKeyDown("KeyQ")) { // Q
|
||||||
|
sneaking = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sneaking) {
|
||||||
|
moveStrafe = moveStrafe * 0.3;
|
||||||
|
moveForward = moveForward * 0.3;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.moveForward = moveForward;
|
this.moveForward = moveForward;
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
window.Gui = class {
|
window.Gui = class {
|
||||||
|
|
||||||
|
static FONT = "normal 20px Minecraftia";
|
||||||
|
|
||||||
drawRect(stack, left, top, right, bottom, color, alpha = 1) {
|
drawRect(stack, left, top, right, bottom, color, alpha = 1) {
|
||||||
stack.save();
|
stack.save();
|
||||||
stack.fillStyle = color;
|
stack.fillStyle = color;
|
||||||
@@ -8,18 +10,28 @@ window.Gui = class {
|
|||||||
stack.restore();
|
stack.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
drawString(stack, string, x, y, color) {
|
drawCenteredString(stack, string, x, y, color = 'white') {
|
||||||
this._drawString(stack, string, x, y, color, 0, false);
|
this._drawString(stack, string, x + this.getStringWidth(stack, string) / 2, y, color, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
_drawString(stack, string, x, y, color, alignment, bold) {
|
drawString(stack, string, x, y, color = 'white') {
|
||||||
let size = 24;
|
this._drawString(stack, string, x, y, color, 0);
|
||||||
stack.font = (bold ? "bold" : "normal") + " " + size + "px Minecraftia";
|
}
|
||||||
stack.fillStyle = color;
|
|
||||||
|
_drawString(stack, string, x, y, color, alignment) {
|
||||||
|
stack.font = Gui.FONT;
|
||||||
|
stack.fillStyle = 'black';
|
||||||
stack.textAlign = alignment === 0 ? "center" : alignment < 0 ? "left" : "right";
|
stack.textAlign = alignment === 0 ? "center" : alignment < 0 ? "left" : "right";
|
||||||
|
stack.fillText(string, x + 2, y + 2);
|
||||||
|
stack.fillStyle = color;
|
||||||
stack.fillText(string, x, y);
|
stack.fillText(string, x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getStringWidth(stack, string) {
|
||||||
|
stack.font = Gui.FONT;
|
||||||
|
return stack.measureText(string).width;
|
||||||
|
}
|
||||||
|
|
||||||
drawTexture(stack, texture, x, y, width, height, alpha = 1.0) {
|
drawTexture(stack, texture, x, y, width, height, alpha = 1.0) {
|
||||||
this.drawSprite(stack, texture, 0, 0, 256, 256, x, y, width, height, alpha);
|
this.drawSprite(stack, texture, 0, 0, 256, 256, x, y, width, height, alpha);
|
||||||
}
|
}
|
||||||
@@ -42,7 +54,7 @@ window.Gui = class {
|
|||||||
stack.restore();
|
stack.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
loadTexture(path) {
|
static loadTexture(path) {
|
||||||
let img = new Image();
|
let img = new Image();
|
||||||
img.src = path;
|
img.src = path;
|
||||||
return img;
|
return img;
|
||||||
|
|||||||
@@ -1,13 +1,28 @@
|
|||||||
window.GuiScreen = class extends Gui {
|
window.GuiScreen = class extends Gui {
|
||||||
|
|
||||||
init(minecraft, width, height) {
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.buttonList = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
setup(minecraft, width, height) {
|
||||||
this.minecraft = minecraft;
|
this.minecraft = minecraft;
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
|
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this.buttonList = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
drawScreen(stack, mouseX, mouseY, partialTicks) {
|
drawScreen(stack, mouseX, mouseY, partialTicks) {
|
||||||
|
for (let i in this.buttonList) {
|
||||||
|
let button = this.buttonList[i];
|
||||||
|
button.render(stack, mouseX, mouseY, partialTicks);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
keyTyped(code) {
|
keyTyped(code) {
|
||||||
@@ -18,4 +33,14 @@ window.GuiScreen = class extends Gui {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mouseClicked(mouseX, mouseY, mouseButton) {
|
||||||
|
for (let i in this.buttonList) {
|
||||||
|
let button = this.buttonList[i];
|
||||||
|
|
||||||
|
if (button.isMouseOver(mouseX, mouseY)) {
|
||||||
|
button.mouseClicked(mouseX, mouseY, mouseButton);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,7 @@ window.IngameOverlay = class extends Gui {
|
|||||||
super();
|
super();
|
||||||
this.window = window;
|
this.window = window;
|
||||||
|
|
||||||
this.textureCrosshair = this.loadTexture("icons.png");
|
this.textureCrosshair = Gui.loadTexture("icons.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
render(stack, mouseX, mouseY, partialTicks) {
|
render(stack, mouseX, mouseY, partialTicks) {
|
||||||
|
|||||||
@@ -4,8 +4,23 @@ window.GuiIngameMenu = class extends GuiScreen {
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
drawScreen(stack, mouseX, mouseY, partialTicks) {
|
init() {
|
||||||
|
super.init();
|
||||||
|
|
||||||
|
let scope = this;
|
||||||
|
this.buttonList.push(new GuiButton("Back to game", this.width / 2 - 100 * 3, this.height / 2 - 50 * 3, 200 * 3, 20 * 3, function () {
|
||||||
|
scope.minecraft.displayScreen(null);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
drawScreen(stack, mouseX, mouseY, partialTicks) {
|
||||||
|
// Background
|
||||||
|
this.drawRect(stack, 0, 0, this.width, this.height, 'black', 0.6);
|
||||||
|
|
||||||
|
// Title
|
||||||
|
this.drawCenteredString(stack, "Game paused", this.width / 2, 100);
|
||||||
|
|
||||||
|
super.drawScreen(stack, mouseX, mouseY, partialTicks);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@ window.GuiLoadingScreen = class extends GuiScreen {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.textureBackground = this.loadTexture("background.png");
|
this.textureBackground = Gui.loadTexture("background.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
drawScreen(stack, mouseX, mouseY, partialTicks) {
|
drawScreen(stack, mouseX, mouseY, partialTicks) {
|
||||||
@@ -35,6 +35,8 @@ window.GuiLoadingScreen = class extends GuiScreen {
|
|||||||
this.height / 2 + progressHeight / 2,
|
this.height / 2 + progressHeight / 2,
|
||||||
'#80ff80',
|
'#80ff80',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
super.drawScreen(stack, mouseX, mouseY, partialTicks);
|
||||||
}
|
}
|
||||||
|
|
||||||
setTitle(title) {
|
setTitle(title) {
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
window.GuiButton = class extends Gui {
|
||||||
|
|
||||||
|
static textureGui = Gui.loadTexture("gui.png");
|
||||||
|
|
||||||
|
constructor(string, x, y, width, height, callback) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.string = string;
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
this.callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
render(stack, mouseX, mouseY, partialTicks) {
|
||||||
|
let mouseOver = this.isMouseOver(mouseX, mouseY);
|
||||||
|
this.drawSprite(stack, GuiButton.textureGui, 0, mouseOver ? 40 : 20, 200, 20, this.x, this.y, this.width, this.height);
|
||||||
|
this.drawCenteredString(stack, this.string, this.x + this.width / 2, this.y + this.height / 2 + 17);
|
||||||
|
}
|
||||||
|
|
||||||
|
mouseClicked(mouseX, mouseY, mouseButton) {
|
||||||
|
this.callback();
|
||||||
|
}
|
||||||
|
|
||||||
|
isMouseOver(mouseX, mouseY) {
|
||||||
|
return mouseX > this.x && mouseX < this.x + this.width && mouseY > this.y && mouseY < this.y + this.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -13,6 +13,16 @@ window.World = class {
|
|||||||
|
|
||||||
// Load world
|
// Load world
|
||||||
this.generator = new WorldGenerator(this, Date.now() % 100000);
|
this.generator = new WorldGenerator(this, Date.now() % 100000);
|
||||||
|
|
||||||
|
// Update lights async
|
||||||
|
let scope = this;
|
||||||
|
setInterval(function () {
|
||||||
|
let i = 1000;
|
||||||
|
while (scope.lightUpdateQueue.length >= 10 && i > 0) {
|
||||||
|
i--;
|
||||||
|
scope.lightUpdateQueue.shift().updateBlockLightning(scope);
|
||||||
|
}
|
||||||
|
}, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
onTick() {
|
onTick() {
|
||||||
@@ -83,22 +93,7 @@ window.World = class {
|
|||||||
updateLights() {
|
updateLights() {
|
||||||
let scope = this;
|
let scope = this;
|
||||||
|
|
||||||
if (this.lightUpdateQueue.length > 10) {
|
if (this.lightUpdateQueue.length < 10) {
|
||||||
// Update lights async
|
|
||||||
setTimeout(function () {
|
|
||||||
// Update lights in queue
|
|
||||||
let i = 5000;
|
|
||||||
while (scope.lightUpdateQueue.length > 0) {
|
|
||||||
if (i <= 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
let meta = scope.lightUpdateQueue.shift();
|
|
||||||
meta.updateBlockLightning(scope);
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}, 0);
|
|
||||||
} else {
|
|
||||||
// Update lights in queue
|
// Update lights in queue
|
||||||
let i = 10;
|
let i = 10;
|
||||||
while (scope.lightUpdateQueue.length > 0) {
|
while (scope.lightUpdateQueue.length > 0) {
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 8.4 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 7.4 KiB |
@@ -61,6 +61,7 @@ loadScripts([
|
|||||||
"src/js/net/minecraft/util/Keyboard.js",
|
"src/js/net/minecraft/util/Keyboard.js",
|
||||||
"src/js/net/minecraft/client/gui/Gui.js",
|
"src/js/net/minecraft/client/gui/Gui.js",
|
||||||
"src/js/net/minecraft/client/gui/GuiScreen.js",
|
"src/js/net/minecraft/client/gui/GuiScreen.js",
|
||||||
|
"src/js/net/minecraft/client/gui/widgets/GuiButton.js",
|
||||||
"src/js/net/minecraft/client/gui/IngameOverlay.js",
|
"src/js/net/minecraft/client/gui/IngameOverlay.js",
|
||||||
"src/js/net/minecraft/client/gui/screens/GuiLoadingScreen.js",
|
"src/js/net/minecraft/client/gui/screens/GuiLoadingScreen.js",
|
||||||
"src/js/net/minecraft/client/gui/screens/GuiIngameMenu.js",
|
"src/js/net/minecraft/client/gui/screens/GuiIngameMenu.js",
|
||||||
|
|||||||
Reference in New Issue
Block a user