diff --git a/js/data.mjs b/js/data.mjs index 52d98a5..c30ef00 100644 --- a/js/data.mjs +++ b/js/data.mjs @@ -4,9 +4,8 @@ export const modules = { capsule: { small: { name: 'Small Capsule', - tooltip: 'A small, simple capsule. Provides just enough ' + - 'rotational power for a small rocket and has a small ' + - 'amount of storage space.', + tooltip: 'A small, simple capsule. Provides a small amount ' + + 'of rotational power and storage space.', type: 'capsule', id: 'small', mass: 2, diff --git a/js/game/events.mjs b/js/game/events.mjs index 957d488..3785497 100644 --- a/js/game/events.mjs +++ b/js/game/events.mjs @@ -73,6 +73,7 @@ export function endEditing() { if (valid) { audio.play('endEdit'); + particle.createEndEditBurst(world.playerShip); graphics.changePerspective('universe'); game.state.editing = false; game.state.inventory = false; diff --git a/js/game/inventory.mjs b/js/game/inventory.mjs index d1f7f25..3819a4b 100644 --- a/js/game/inventory.mjs +++ b/js/game/inventory.mjs @@ -65,9 +65,26 @@ class Tile { this.mapId = toId(type, id); this.quantity = q; this.image = assets.modules[type][id]; + this.data = modules[type][id]; if (type === 'thruster') this.image = this.image.off; } + get textInfo() { + let text = this.data.name + '\n\n' + this.data.tooltip + '\n\n'; + text += 'Mass: ' + this.data.mass + '\n'; + + if (this.type === 'thruster') + text += 'Power: ' + this.data.thrust + '\n'; + if (this.type === 'fuel') + text += 'Fuel capacity: ' + this.data.fuelCapacity + '\n'; + if (this.type === 'capsule') { + text += 'Rotational power: ' + this.data.rotation + '\n'; + text += 'Cargo space: ' + this.data.capacity + '\n'; + } + + return text; + } + get ident() { return [this.type, this.id]; } diff --git a/js/graphics/gui.mjs b/js/graphics/gui.mjs index c8885c1..0e9b1d1 100644 --- a/js/graphics/gui.mjs +++ b/js/graphics/gui.mjs @@ -36,7 +36,9 @@ function renderText(element) { context.textAlign = element.align; context.textBaseline = element.valign; context.fillStyle = element.color; - context.fillText(element.text, element.x, element.y); + element.text.split('\n').forEach((line, i) => + context.fillText(line, element.x, element.y + i * element.spacing) + ); } function renderButton(element) { diff --git a/js/gui/button.mjs b/js/gui/button.mjs index 288004a..0a85267 100644 --- a/js/gui/button.mjs +++ b/js/gui/button.mjs @@ -10,7 +10,7 @@ export default class GuiButton extends GuiElement { } click() { - if (this.options.draw && !this.options.disabled) + if (this.drawn && !this.options.disabled) this.onclick(); } } diff --git a/js/gui/element.mjs b/js/gui/element.mjs index 71a793a..a5c3829 100644 --- a/js/gui/element.mjs +++ b/js/gui/element.mjs @@ -26,6 +26,12 @@ export default class GuiElement extends Rect { } + get drawn() { + if (!this.options.drawChildren) return false; + if (!this.parent) return true; + return this.parent.drawn; + } + append(element) { this.children.add(element); element.parent = this; diff --git a/js/gui/inventory.mjs b/js/gui/inventory.mjs index ba3cd7c..679cc34 100644 --- a/js/gui/inventory.mjs +++ b/js/gui/inventory.mjs @@ -12,6 +12,7 @@ export default class GuiInventory extends GuiElement { this.tileHeight = 5; this.currentPage = 0; inventory.setOnupdate(this.updateTiles.bind(this)); + this.guiInfo = null; } updateTiles() { @@ -35,14 +36,15 @@ export default class GuiInventory extends GuiElement { let offset = pageSize * this.currentPage; let tiles = inventory.getTiles().slice(offset); let tile; + let cur = inventory.currentItem; for (let y = 0; y < this.tileHeight; y++) for (let x = 0; x < this.tileWidth && tiles.length; x++) { let i = y * this.tileWidth + (x % this.tileWidth) + offset; tile = tiles.shift(); - let ex = x * tileSize + spacing / 2 + ox + this.x; - let ey = y * tileSize + spacing / 2 + oy + this.y; + let ex = x * tileSize + spacing / 2 + ox; + let ey = y * tileSize + spacing / 2 + oy; let [ew, eh] = [tileSize - spacing, tileSize - spacing]; let ident = tile.ident; @@ -51,7 +53,6 @@ export default class GuiInventory extends GuiElement { this.tileClicked(...ident, button); }; - let cur = inventory.currentItem; let selected = cur !== null && tile.type === cur.type && tile.id === cur.id; @@ -63,13 +64,18 @@ export default class GuiInventory extends GuiElement { this.append(el); } + + this.guiInfo.text = cur === null ? '' : cur.textInfo; + this.guiInfo.splitLines(); } tick() { if (state.inventory && !this.active) this.updateTiles(); this.active = state.inventory; - this.options.draw = this.options.drawChildren = this.active; + this.parent.options.drawChildren = this.active; if (!this.active) return; + + this.children } getTile(x, y) { diff --git a/js/gui/item.mjs b/js/gui/item.mjs index 3d72031..e7e67d5 100644 --- a/js/gui/item.mjs +++ b/js/gui/item.mjs @@ -17,10 +17,12 @@ export default class GuiItemButton extends GuiButton { } click() { - this.onclick('left'); + if (this.drawn) + this.onclick('left'); } rightClick() { - this.onclick('right'); + if (this.drawn) + this.onclick('right'); } } diff --git a/js/gui/modules.mjs b/js/gui/modules.mjs index 78914a1..f30e2a0 100644 --- a/js/gui/modules.mjs +++ b/js/gui/modules.mjs @@ -67,7 +67,7 @@ export function game() { edit.posRelative({w: 1, h: 1}); let editInfoText = new GuiText('', 0, 0, 0, 0, { - size: 10, + size: 12, align: 'center' }); editShadow.append(editInfoText); @@ -75,7 +75,7 @@ export function game() { editInfoText.y += 5; let editWarnText = new GuiText('', 0, 0, 0, 0, { - size: 10, + size: 12, align: 'center' }); editShadow.append(editWarnText); @@ -93,18 +93,27 @@ export function game() { invShadow.posRelative({x: 0, w: 0.4, h: 0.6}); invShadow.x += 10; invShadow.y += 10; - invShadow.h += 60; let inventory = new GuiInventory(0, 0, 0, 0); invShadow.append(inventory); inventory.posRelative({w: 1, h: 1}); - inventory.h -= 60; + + let moduleInfo = new GuiText('test\nline\n', 0, 0, 0, 0, { + size: 12, + align: 'left', + valign: 'top' + }); + invShadow.append(moduleInfo); + moduleInfo.posRelative({x: 0, y: 1, w: 1}); + moduleInfo.splitLines(); + moduleInfo.y += 5; + inventory.guiInfo = moduleInfo; edit.guiInventory = inventory; let notification = new GuiText('', 0, 0, 0, 0, { - size: 12, + size: 14, align: 'center', valign: 'top' }); diff --git a/js/gui/text.mjs b/js/gui/text.mjs index 52005af..bdc6eb1 100644 --- a/js/gui/text.mjs +++ b/js/gui/text.mjs @@ -1,5 +1,6 @@ import * as gui from './index.mjs'; import GuiElement from './element.mjs'; +import {context} from '../graphics/index.mjs'; export default class GuiText extends GuiElement { constructor(text = '', x, y, w, h, { @@ -14,8 +15,33 @@ export default class GuiText extends GuiElement { this.type = 'text'; this.color = color; this.text = text; - this.font = size + 'pt Consolas'; + this.spacing = size * 1.2; + this.font = size + 'px Consolas'; this.align = align; this.valign = valign; } + + splitLines() { + // Not very robust, but good enough for now. Mebe fix later? + context.font = this.font; + let maxLineLength = (this.w / context.measureText('A').width) | 0; + maxLineLength = Math.max(maxLineLength, 1); + + let lines = []; + let currentLine = ''; + + this.text.split('\n').forEach(l => { + currentLine = ''; + l.split(' ').forEach(word => { + if (word.length + currentLine.length > maxLineLength) { + lines.push(currentLine.slice(0, -1)); + currentLine = ''; + } + currentLine += word + ' '; + }); + lines.push(currentLine.slice(0, -1)); + }); + + this.text = lines.join('\n'); + } } diff --git a/js/world/particle.mjs b/js/world/particle.mjs index 0626902..b9f8d22 100644 --- a/js/world/particle.mjs +++ b/js/world/particle.mjs @@ -15,6 +15,18 @@ export function createThrustExhaust(thruster) { })); } +export function createEndEditBurst(ship) { + for (let i = 0; i < 20; i++) { + particles.add(new Particle(...ship.poc, { + color: '#ccc', + lifetime: Math.random() * 30 + 25, + size: Math.random() * 0.3 + 0.05, + spray: 0.3, + gravity: true + })); + } +} + export function createPickupBurst(ship, point) { for (let i = 0; i < 20; i++) { particles.add(new Particle(...point, { diff --git a/js/world/ship.mjs b/js/world/ship.mjs index bd1940c..1f8e598 100644 --- a/js/world/ship.mjs +++ b/js/world/ship.mjs @@ -16,6 +16,7 @@ export default class Ship extends Body { this.maxRadius = 0; this.landed = false; this.lastContactModule = null; + this.poc = this.com; } get com() { @@ -121,6 +122,7 @@ export default class Ship extends Body { this.halt(); this.resolveCelestialCollision(p, body, module); this.lastContactModule = module; + this.poc = p; } }