improve performance of chat rendering
This commit is contained in:
@@ -52,6 +52,7 @@ export default class GameWindow {
|
||||
// Create render layers
|
||||
this.canvasWorld = document.createElement('canvas');
|
||||
this.canvasDebug = document.createElement('canvas');
|
||||
this.canvasChat = document.createElement('canvas');
|
||||
this.canvasPlayerList = document.createElement('canvas');
|
||||
this.canvasItems = document.createElement('canvas');
|
||||
|
||||
@@ -381,6 +382,11 @@ export default class GameWindow {
|
||||
this.canvasDebug.height = this.canvas.height;
|
||||
}
|
||||
|
||||
if (this.canvasChat.width !== this.canvas.width || this.canvasChat.height !== this.canvas.height) {
|
||||
this.canvasChat.width = this.canvas.width;
|
||||
this.canvasChat.height = this.canvas.height;
|
||||
}
|
||||
|
||||
if (this.canvasPlayerList.width !== this.canvas.width || this.canvasPlayerList.height !== this.canvas.height) {
|
||||
this.canvasPlayerList.width = this.canvas.width;
|
||||
this.canvasPlayerList.height = this.canvas.height;
|
||||
@@ -394,6 +400,8 @@ export default class GameWindow {
|
||||
this.minecraft.currentScreen.setup(this.minecraft, this.width, this.height);
|
||||
}
|
||||
|
||||
this.minecraft.ingameOverlay.chatOverlay.setDirty();
|
||||
|
||||
// Render first frame
|
||||
if (this.minecraft.isInGame()) {
|
||||
this.minecraft.worldRenderer.render(0);
|
||||
|
||||
@@ -32,8 +32,7 @@ export default class Minecraft {
|
||||
|
||||
// TODO Add to settings
|
||||
static PROXY = {
|
||||
"address": "localhost",
|
||||
"port": 30023
|
||||
"url": "wss://socket.labystudio.de/minecraft/"
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -350,7 +349,8 @@ export default class Minecraft {
|
||||
|
||||
// Open chat
|
||||
if (button === this.settings.keyOpenChat) {
|
||||
this.displayScreen(new GuiChat());
|
||||
this.displayScreen(new GuiChat(this));
|
||||
this.ingameOverlay.chatOverlay.setDirty();
|
||||
}
|
||||
|
||||
// Toggle debug overlay
|
||||
|
||||
@@ -3,7 +3,7 @@ import Command from "../Command.js";
|
||||
export default class TeleportCommand extends Command {
|
||||
|
||||
constructor() {
|
||||
super("tp", "<x> <y> <y>", "Teleport to a position")
|
||||
super("tp", "<x> <y> <z>", "Teleport to a position")
|
||||
}
|
||||
|
||||
execute(minecraft, args) {
|
||||
|
||||
@@ -8,8 +8,11 @@ export default class ChatOverlay extends Gui {
|
||||
constructor(minecraft) {
|
||||
super(minecraft);
|
||||
|
||||
this.chatWidth = 320;
|
||||
|
||||
this.messages = [];
|
||||
this.sentHistory = [];
|
||||
this.dirty = true;
|
||||
}
|
||||
|
||||
render(stack, mouseX, mouseY, partialTicks) {
|
||||
@@ -30,25 +33,43 @@ export default class ChatOverlay extends Gui {
|
||||
if (alpha > 0) {
|
||||
let y = this.minecraft.window.height - 40 - i * 9;
|
||||
|
||||
this.drawRect(stack, 2, y - 1, 2 + 320, y + 8, '#000000', alpha / 2 / 255);
|
||||
this.drawRect(stack, 2, y - 1, 2 + this.chatWidth, y + 8, '#000000', alpha / 2 / 255);
|
||||
this.drawString(stack, message.message, 2, y, 0xffffff + (alpha << 24));
|
||||
}
|
||||
}
|
||||
this.dirty = false;
|
||||
}
|
||||
|
||||
onTick() {
|
||||
for (let i = 0; i < this.messages.length; i++) {
|
||||
let message = this.messages[i];
|
||||
message.updateCounter++;
|
||||
|
||||
// Fade out animation
|
||||
if (message.updateCounter >= 180 && message.updateCounter <= 200) {
|
||||
this.dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addMessage(message) {
|
||||
this.messages.splice(0, 0, new ChatLine(message));
|
||||
for (let line of this.minecraft.fontRenderer.listFormattedStringToWidth(message, this.chatWidth)) {
|
||||
this.messages.splice(0, 0, new ChatLine(line));
|
||||
}
|
||||
this.dirty = true;
|
||||
}
|
||||
|
||||
addMessageToSentHistory(message) {
|
||||
this.sentHistory.splice(0, 0, message);
|
||||
this.dirty = true;
|
||||
}
|
||||
|
||||
isDirty() {
|
||||
return this.dirty;
|
||||
}
|
||||
|
||||
setDirty() {
|
||||
this.dirty = true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -34,8 +34,8 @@ export default class IngameOverlay extends Gui {
|
||||
// Render hotbar
|
||||
this.renderHotbar(stack, this.window.width / 2 - 91, this.window.height - 22);
|
||||
|
||||
// Render chat
|
||||
this.chatOverlay.render(stack, mouseX, mouseY, partialTicks);
|
||||
// Render chat canvas
|
||||
stack.drawImage(this.window.canvasChat, 0, 0);
|
||||
|
||||
// Render debug canvas on stack
|
||||
if (this.minecraft.settings.debugOverlay) {
|
||||
@@ -70,6 +70,13 @@ export default class IngameOverlay extends Gui {
|
||||
|
||||
this.ticksRendered++;
|
||||
}
|
||||
|
||||
// Render chat on tick if dirty
|
||||
if (this.chatOverlay.isDirty()) {
|
||||
let stack = this.window.canvasChat.getContext('2d');
|
||||
stack.clearRect(0, 0, this.window.width, this.window.height);
|
||||
this.chatOverlay.render(stack, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
renderCrosshair(stack, x, y) {
|
||||
|
||||
@@ -3,9 +3,11 @@ import GuiTextField from "../widgets/GuiTextField.js";
|
||||
|
||||
export default class GuiChat extends GuiScreen {
|
||||
|
||||
constructor() {
|
||||
constructor(minecraft) {
|
||||
super();
|
||||
|
||||
this.minecraft = minecraft;
|
||||
|
||||
this.inputField = new GuiTextField(0, 0, 0, 0);
|
||||
this.inputField.renderBackground = false;
|
||||
|
||||
@@ -24,6 +26,11 @@ export default class GuiChat extends GuiScreen {
|
||||
this.buttonList.push(this.inputField);
|
||||
}
|
||||
|
||||
onClose() {
|
||||
super.onClose();
|
||||
this.minecraft.ingameOverlay.chatOverlay.setDirty();
|
||||
}
|
||||
|
||||
drawScreen(stack, mouseX, mouseY, partialTicks) {
|
||||
this.drawRect(stack, 2, this.height - 14, this.width - 2, this.height - 2, '#000000', 0.5);
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ export default class NetworkManager {
|
||||
}
|
||||
|
||||
connect(address, port, proxy) {
|
||||
this.socket = new WebSocket("ws://" + proxy.address + ":" + proxy.port);
|
||||
this.socket = new WebSocket(proxy.url);
|
||||
this.socket.binaryType = "arraybuffer";
|
||||
|
||||
this.socket.onopen = e => this._onOpen(e);
|
||||
|
||||
@@ -20,7 +20,7 @@ export default class ServerJoinGamePacket extends Packet {
|
||||
}
|
||||
|
||||
read(buffer) {
|
||||
this.entityId = buffer.readVarInt();
|
||||
this.entityId = buffer.readInt();
|
||||
let bits = buffer.readByte();
|
||||
this.hardcoreMode = (bits & 8) === 8;
|
||||
this.gameType = bits & -9;
|
||||
|
||||
@@ -140,7 +140,6 @@ export default class FontRenderer {
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
createBitMap(img) {
|
||||
let canvas = document.createElement('canvas');
|
||||
canvas.width = img.width;
|
||||
@@ -178,6 +177,54 @@ export default class FontRenderer {
|
||||
}
|
||||
|
||||
listFormattedStringToWidth(text, wrapWidth) {
|
||||
return text.split("\n"); // TODO Implement wrap logic
|
||||
let lines = [];
|
||||
let currentColorCharacter = "r";
|
||||
for (let line of text.split('\n')) {
|
||||
let currentLine = '';
|
||||
let currentLineWidth = 0;
|
||||
|
||||
// Split the text into words
|
||||
for (let word of line.split(' ')) {
|
||||
const wordWidth = this.getStringWidth(word + " ");
|
||||
|
||||
// If adding the word exceeds the wrap width, start a new line
|
||||
if (currentLineWidth + wordWidth > wrapWidth) {
|
||||
lines.push(FontRenderer.COLOR_PREFIX + currentColorCharacter + currentLine.trim());
|
||||
currentColorCharacter = this.getLastColorCharacterOfText(currentLine);
|
||||
|
||||
currentLine = '';
|
||||
currentLineWidth = 0;
|
||||
}
|
||||
|
||||
// Add the word to the current line
|
||||
currentLine += word + ' ';
|
||||
currentLineWidth += wordWidth;
|
||||
}
|
||||
|
||||
// Push the last line
|
||||
if (currentLine.length > 0) {
|
||||
lines.push(FontRenderer.COLOR_PREFIX + currentColorCharacter + currentLine.trim());
|
||||
currentColorCharacter = this.getLastColorCharacterOfText(currentLine);
|
||||
}
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
getLastColorCharacterOfText(text) {
|
||||
let character = "r";
|
||||
let isColorCode = false;
|
||||
|
||||
// For each character
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
if (text[i] === FontRenderer.COLOR_PREFIX) {
|
||||
isColorCode = true;
|
||||
} else {
|
||||
if (isColorCode) {
|
||||
character = text[i];
|
||||
isColorCode = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return character;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user