diff --git a/public/static/css/styles.css b/public/static/css/styles.css index 0edf17e..ed68b28 100644 --- a/public/static/css/styles.css +++ b/public/static/css/styles.css @@ -12,3 +12,39 @@ body { overflow: hidden; } + +#gui { + color: #fff; +} + +#gui > .container { + position: fixed; +} + +#gui #chat { + bottom: 0; + left: 0; + width: 400px; + max-height: 300px; + overflow: hidden; + background-color: rgba(0, 0, 0, 0.55); +} + +#gui #chat span { + display: block; + margin-top: 5px; +} + +#gui #chat input { + font-family: inherit; + font-size: 16px; + border: 0; + display: block; + width: 100%; + padding: 2px 0 2px 0; + background-color: rgba(20, 20, 20, 0.5); +} + +#gui #chat input:focus { + background-color: #eee; +} diff --git a/public/static/js/wingbase/gui/chat.js b/public/static/js/wingbase/gui/chat.js new file mode 100644 index 0000000..503a967 --- /dev/null +++ b/public/static/js/wingbase/gui/chat.js @@ -0,0 +1,56 @@ +GUI.prototype.Chat = class { + constructor(gui) { + this.gui = gui; + + this.messageElement = this.gui.query('#chat-messages'); + this.inputElement = this.gui.query('#chat input'); + + this.inputElement.disabled = true; + + this.messages = []; + + this.typing = false; + } + + addMessage(messageData) { + let message = { + type: messageData.type, + player: messageData.player, + text: messageData.message, + createTime: Date.now() + }; + + let span = this.gui.createElement(this.messageElement, 'span', { + html: message.text + }); + + this.messages.push(message); + + setTimeout(_ => { + this.messageElement.removeChild(span); + this.messages.shift(); + }, 15000); + } + + tick() { + if (game.input.keys.pressed[13] || game.input.keys.pressed[27]) { + if (this.typing) { + if (game.input.keys.pressed[13]) { + let message = this.inputElement.value; + this.inputElement.value = ''; + game.net.send('chat', { msg: message }); + } + this.typing = false; + this.inputElement.blur(); + this.inputElement.disabled = true; + game.input.locked = false; + } else { + console.log(game.input.locked); + this.typing = true; + this.inputElement.disabled = false; + this.inputElement.focus(); + game.input.locked = true; + } + } + } +} diff --git a/public/static/js/wingbase/gui/gui.js b/public/static/js/wingbase/gui/gui.js new file mode 100644 index 0000000..a571e65 --- /dev/null +++ b/public/static/js/wingbase/gui/gui.js @@ -0,0 +1,29 @@ +//@10 + +class GUI { + constructor() { + this.guiElement = document.getElementById('gui'); + + this.chat = new this.Chat(this); + } + + createElement(parent, type, data) { + let el = document.createElement(type); + el.innerHTML = data.html; + parent.appendChild(el); + return el; + } + + query(selector) { + let result = this.guiElement.querySelectorAll(selector); + return result.length == 1 ? result[0] : result; + } + + tick() { + this.chat.tick(); + } + + set visible(visible) { + this.guiElement.style.display = visible ? 'block' : 'hidden'; + } +} diff --git a/public/static/js/wingbase/header.js b/public/static/js/wingbase/header.js new file mode 100644 index 0000000..3b0c766 --- /dev/null +++ b/public/static/js/wingbase/header.js @@ -0,0 +1,11 @@ +//@100000000 + +/* + * Wingbase version 0.0.1. + * + * Developer: Asraelite + * Subreddit: /r/wingbase + * Made with: Node.js, Socket.io, Box2D, HTML5 Canvas + */ + +'use strict'; diff --git a/public/static/js/wingbase/input.js b/public/static/js/wingbase/input.js index 3e867fc..3df8479 100644 --- a/public/static/js/wingbase/input.js +++ b/public/static/js/wingbase/input.js @@ -22,7 +22,7 @@ class Input { pressed: {} }; - this.mouse + this._locked = false; document.addEventListener('mousemove', this.mouseMove.bind(this)); document.addEventListener('mousedown', this.mouseDown.bind(this)); @@ -34,31 +34,42 @@ class Input { } mouseMove() { + if (this.locked) return; var rect = game.renderer.canvas.getBoundingClientRect(); this.mouse.x = event.clientX - rect.left; this.mouse.y = event.clientY - rect.top; }; mouseDown() { + if (this.locked) return; this.mouse.pressed[event.which] = true; this.mouse.held[event.which] = true; }; mouseUp() { + if (this.locked) return; this.mouse.held[event.which] = false; } keyDown() { + if (this.locked) { + if (event.which == '13' || event.which == '27') { + this.keys.pressed[event.which] = true; + } + return; + } if (!this.keys.held[event.which]) this.keys.pressed[event.which] = true; this.keys.held[event.which] = true; } keyUp() { + if (this.locked) return; this.keys.held[event.which] = false; } mouseAnyPressed() { + if (this.locked) return; var p = this.mouse.pressed; return p[1] || p[2] || p[3]; } @@ -67,4 +78,15 @@ class Input { for (var i in this.keys.pressed) this.keys.pressed[i] = false; for (var i in this.mouse.pressed) this.mouse.pressed[i] = false; }; + + get locked() { + return this._locked; + } + + set locked(value) { + this._locked = value; + if (!value) return; + this.keys.held = {}; + this.mouse.held = {}; + } } diff --git a/public/static/js/wingbase/main.js b/public/static/js/wingbase/main.js index f5ffd49..2f2205b 100644 --- a/public/static/js/wingbase/main.js +++ b/public/static/js/wingbase/main.js @@ -1,4 +1,4 @@ -'use strict'; +//@30 window.addEventListener('load', init); @@ -9,7 +9,7 @@ function init() { game.tick(); - //game.net.connect(); + game.net.connect(); } class Game { @@ -17,14 +17,16 @@ class Game { this.assets = this.loadAssets(); this.connected = false; - this.state = 'connecting'; this.pingMode = 'fast'; this.input = new Input(); + this.gui = new GUI(); this.net = new Net(); this.world = new World(); this.renderer = new Renderer(); this.player = new Player(); + + this.state = 'connecting'; } tick() { @@ -38,10 +40,26 @@ class Game { game.net.sendUpdate(delta); } - this.input.clear(); + this.gui.tick(); this.world.tick(); + this.input.clear(); + requestAnimationFrame(this.tick.bind(this)); } + + get state() { + return this._state; + } + + set state(state) { + this._state = state; + + if (state != 'connected') { + this.gui.visible = true; + } else { + this.gui.visible = false; + } + } } diff --git a/public/static/js/wingbase/net.js b/public/static/js/wingbase/net.js index 1c753d1..7d6b01c 100644 --- a/public/static/js/wingbase/net.js +++ b/public/static/js/wingbase/net.js @@ -42,7 +42,9 @@ class Net { game.renderer.addEffect(data); }); - this.socket.on('chat', data => console.log(data)); + this.socket.on('chat', data => { + game.gui.chat.addMessage(data); + }); }; sendUpdate(inputs) { diff --git a/public/static/js/wingbase/chat.js b/public/views/error/500.jade similarity index 100% rename from public/static/js/wingbase/chat.js rename to public/views/error/500.jade diff --git a/public/views/error/error.jade b/public/views/error/error.jade new file mode 100644 index 0000000..e226d86 --- /dev/null +++ b/public/views/error/error.jade @@ -0,0 +1,5 @@ +extends ../layout.jade + +block head + +block body diff --git a/public/views/game.jade b/public/views/game.jade index cebafe4..3872800 100644 --- a/public/views/game.jade +++ b/public/views/game.jade @@ -1,19 +1,16 @@ -doctype html -html(lang='en') - head - meta(charset="UTF-8") - link(rel="icon", type="image/png", href="img/favicon.png") - link(rel="stylesheet", type="text/css", href="css/styles.css") - title - | Wingbase - script(src="js/lib/dexie.min.js") - script(src="socket.io/socket.io.js") - script(src="js/lib/box2dweb.min.js") - script(src="https://rawgit.com/Asraelite/pallet.js/master/pallet.js") +extends layout.jade - script(src="wingbase.min.js") - body - canvas#wingbase_canvas - | Sorry, your browser does not currently support HTML5 Canvas. - #gui - include +block head + title + | Wingbase + script(src="js/lib/dexie.min.js") + script(src="socket.io/socket.io.js") + script(src="js/lib/box2dweb.min.js") + script(src="https://rawgit.com/Asraelite/pallet.js/master/pallet.js") + script(src="wingbase.min.js") + +block body + canvas#wingbase_canvas + | Sorry, your browser does not currently support HTML5 Canvas. + #gui + include gui/gui.jade diff --git a/public/views/gui/gui.jade b/public/views/gui/gui.jade new file mode 100644 index 0000000..bb61e5c --- /dev/null +++ b/public/views/gui/gui.jade @@ -0,0 +1,3 @@ +#chat.container + #chat-messages + input(type="text", maxLength="100")#chat-input diff --git a/public/views/layout.jade b/public/views/layout.jade new file mode 100644 index 0000000..55eac33 --- /dev/null +++ b/public/views/layout.jade @@ -0,0 +1,9 @@ +doctype html +html(lang='en') + head + meta(charset='UTF-8') + link(rel='icon', type='image/png', href='img/favicon.png') + link(rel='stylesheet', type='text/css', href='css/styles.css') + block head + body + block body diff --git a/server/game/net/connection.js b/server/game/net/connection.js index a1ac300..d65e844 100644 --- a/server/game/net/connection.js +++ b/server/game/net/connection.js @@ -34,13 +34,16 @@ class Connection { } chat(data) { - console.log(this.room); - if(this.chatCooldown > 5 || !this.room) return; + //if(this.chatCooldown > 5 || !this.room) return; + if(!data.msg) return; + + wingbase.log(`${this.room}/${this.player.name}: ${data.msg}`); this.chatCooldown++; this.io.to(this.room).emit('chat', { - name: this.player.name, - msg: data.msg.slice(0, 100) + type: 'player', + source: this.player.name, + message: data.msg.slice(0, 100) }); } diff --git a/server/game/room/world/index.js b/server/game/room/world/index.js index 33b82f8..cc5c5c0 100644 --- a/server/game/room/world/index.js +++ b/server/game/room/world/index.js @@ -108,7 +108,7 @@ class World { } populate() { - for (var i = 0; i < 40; i++) { + for (var i = 0; i < 5; i++) { let pos = { x: Math.random() * 2000 - 200, y: Math.random() * 500 - 250 diff --git a/server/web/index.js b/server/web/index.js index 8f9ffab..23b1630 100644 --- a/server/web/index.js +++ b/server/web/index.js @@ -28,7 +28,12 @@ class WebServer { }); app.get('/', (req, res) => { - res.render('index', {}); + try { + res.render('index', {}); + } catch(err) { + wingbase.error('Renderng error:' + err); + res.render('error/500', { error: err }); + } }); app.use(express.static('public/static')); diff --git a/server/web/minify.js b/server/web/minify.js index 6d65302..64e4355 100644 --- a/server/web/minify.js +++ b/server/web/minify.js @@ -26,12 +26,13 @@ function minifyJs(callback) { } scripts.sort((a, b) => getPriority(b) - getPriority(a)); + scripts = scripts.map(s => s.replace(/(\/\/@\d+\n)/, '')); let comment = ''; cache = scripts.join(''); - // Remove to re-enable minifying. + //Remove to re-enable minifying. callback(cache); return; try {