Add start of ship editing grid
This commit is contained in:
parent
b88c0eb358
commit
2fbabc785e
16 changed files with 249 additions and 18 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
|||
.cache/
|
||||
*.min.js
|
||||
*.map
|
||||
|
|
1
dist/improcket.min.js.map
vendored
1
dist/improcket.min.js.map
vendored
File diff suppressed because one or more lines are too long
|
@ -18,9 +18,11 @@ export const MAX_ZOOM = 100;
|
|||
export const DEFAULT_ZOOM = 10;
|
||||
export const ZOOM_SPEED = 0.01;
|
||||
// Ship landing. Angle in radians.
|
||||
export const TIP_ANGLE = 30.3;
|
||||
export const TIP_ANGLE = 0.3;
|
||||
export const TIP_SPEED = 0.015;
|
||||
// Ship flight mechanics. Speed measured in units per tick.
|
||||
export const FUEL_BURN_RATE = 0.01;
|
||||
// Distance at which an orbited planet will not be considered a parent body.
|
||||
export const MAX_PARENT_CELESTIAL_DISTANCE = 120;
|
||||
// Ship editing.
|
||||
export const EDIT_MARGIN = 2;
|
||||
|
|
|
@ -1,10 +1,66 @@
|
|||
import * as game from './index.mjs';
|
||||
import * as graphics from '../graphics/index.mjs';
|
||||
import * as world from '../world/index.mjs';
|
||||
import * as consts from '../consts.mjs';
|
||||
|
||||
export let tiles = new Map();
|
||||
export let width = 0;
|
||||
export let height = 0;
|
||||
export let position = [0, 0];
|
||||
export let bounds = [0, 0, 0, 0];
|
||||
export let currentModule = null;
|
||||
|
||||
export function init() {
|
||||
graphics.setZoom(20);
|
||||
let ship = world.playerShip;
|
||||
let modules = ship.modules;
|
||||
let margin = consts.EDIT_MARGIN;
|
||||
|
||||
modules.forEach(m => {
|
||||
let pos = [m.x, m.y];
|
||||
tiles.set(posId(...pos), new Tile(...pos, m));
|
||||
});
|
||||
|
||||
let [sx, ex, sy, ey] = getBoundaries();
|
||||
[width, height] = [ex - sx + margin * 2 + 1, ey - sy + margin * 2 + 1];
|
||||
position = [sx - margin, sy - margin];
|
||||
let neededZoom = graphics.canvas.width / (Math.max(width, height) + 10);
|
||||
|
||||
graphics.changePerspective('planet', 0, -5);
|
||||
graphics.setZoom(neededZoom);
|
||||
}
|
||||
|
||||
export function end() {
|
||||
|
||||
}
|
||||
|
||||
export function getTile(x, y) {
|
||||
let id = posId(x, y);
|
||||
if (!tiles.has(id))
|
||||
tiles.set(id, new Tile(x, y, null));
|
||||
return tiles.get(id);
|
||||
}
|
||||
|
||||
function posId(x, y) {
|
||||
return `${x}.${y}`;
|
||||
}
|
||||
|
||||
function getBoundaries() {
|
||||
return [0, 0, 0, 2];
|
||||
}
|
||||
|
||||
class Tile {
|
||||
constructor(x, y, module) {
|
||||
this.module = module;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
get valid() {
|
||||
return true;
|
||||
}
|
||||
|
||||
get drawPos() {
|
||||
let [px, py] = pos;
|
||||
return [this.x + px, this.y + py];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,8 +22,6 @@ export function launchShip() {
|
|||
}
|
||||
|
||||
export function editShip() {
|
||||
console.log('a');
|
||||
graphics.changePerspective('parent', -5, 0);
|
||||
game.state.editing = true;
|
||||
edit.init();
|
||||
}
|
||||
|
|
16
js/graphics/edit.mjs
Normal file
16
js/graphics/edit.mjs
Normal file
|
@ -0,0 +1,16 @@
|
|||
import {context} from './index.mjs';
|
||||
import * as edit from '../game/edit.mjs';
|
||||
import * as world from '../world/index.mjs';
|
||||
|
||||
export function render() {
|
||||
let ship = world.playerShip;
|
||||
|
||||
context.save();
|
||||
context.translate(...ship.com);
|
||||
context.rotate(ship.r);
|
||||
let [cx, cy] = ship.localCom;
|
||||
|
||||
context.translate(-cx, -cy);
|
||||
|
||||
context.restore();
|
||||
}
|
|
@ -12,8 +12,12 @@ function renderElement(element) {
|
|||
if (element.type == 'frame') renderFrame(element);
|
||||
if (element.type == 'image') renderImage(element);
|
||||
if (element.type == 'button') renderButton(element);
|
||||
if (element.type == 'edit') renderEdit(element);
|
||||
if (element.type == 'itemButton') renderItemButton(element);
|
||||
}
|
||||
element.children.forEach(renderElement);
|
||||
|
||||
if (element.options.drawChildren)
|
||||
element.children.forEach(renderElement);
|
||||
}
|
||||
|
||||
function renderFrame(element) {
|
||||
|
@ -42,3 +46,40 @@ function renderButton(element) {
|
|||
context.font = '12pt Consolas';
|
||||
context.fillText(element.text, ...element.center);
|
||||
}
|
||||
|
||||
function renderItemButton(element) {
|
||||
context.globalAlpha = 0.5;
|
||||
if (element.mouseHeld) {
|
||||
context.fillStyle = '#080808';
|
||||
} else {
|
||||
context.fillStyle = element.mouseOver ? '#222' : '#0e0e0e';
|
||||
}
|
||||
|
||||
context.fillRect(...element.shape);
|
||||
context.strokeStyle = '#333';
|
||||
context.strokeWidth = 4;
|
||||
context.strokeRect(...element.shape);
|
||||
context.globalAlpha = 1;
|
||||
|
||||
if (element.image) {
|
||||
context.drawImage(element.image, ...element.shape);
|
||||
}
|
||||
}
|
||||
|
||||
function renderEdit(element) {
|
||||
/*
|
||||
element.tiles.forEach(t => {
|
||||
let tile = edit.getTile(x, y);
|
||||
let [dx, dy] = tile.drawPos;
|
||||
context.globalAlpha = 0.5;
|
||||
context.fillStyle = '#000';
|
||||
context.fillRect(dx, dy, 1, 1);
|
||||
context.globalAlpha = 1;
|
||||
|
||||
let module = tile.module;
|
||||
if (module !== null) {
|
||||
context.drawImage(module.currentImage, dx, dy, 1, 1);
|
||||
}
|
||||
});
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ import * as draw from './draw.mjs';
|
|||
import * as input from '../input.mjs';
|
||||
import {render as renderWorld} from './world.mjs';
|
||||
import {render as renderBackground} from './background.mjs';
|
||||
import {render as renderEdit} from './edit.mjs';
|
||||
import * as world from '../world/index.mjs';
|
||||
import * as consts from '../consts.mjs';
|
||||
|
||||
|
@ -77,7 +78,7 @@ class Perspective {
|
|||
}
|
||||
|
||||
changeRotationMode(mode) {
|
||||
this.oldTarget = this.targetRotation;
|
||||
this.oldTarget = this.currentRotation;
|
||||
this.rotationMode = mode;
|
||||
}
|
||||
|
||||
|
@ -181,7 +182,7 @@ class Perspective {
|
|||
|
||||
transformCanvas() {
|
||||
let [,,bw, bh] = this.bounds;
|
||||
let [sx, sy] = this.rotateVector(...this.currentShift, -this.rotation);
|
||||
let [sx, sy] = this.rotateVector(...this.currentShift, this.rotation);
|
||||
let tx = -(this.x + sx) * this.zoom;
|
||||
let ty = -(this.y + sy) * this.zoom;
|
||||
context.translate(tx + bw / 2, ty + bh / 2);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import {canvas, context} from './index.mjs';
|
||||
import {images as assets} from '../assets.mjs';
|
||||
import * as world from '../world/index.mjs';
|
||||
import * as edit from './edit.mjs';
|
||||
import {state} from '../game/index.mjs';
|
||||
|
||||
export function render() {
|
||||
world.particles.forEach(renderParticle);
|
||||
|
@ -20,6 +22,10 @@ function renderShip(ship) {
|
|||
let [cx, cy] = ship.localCom;
|
||||
context.translate(-cx, -cy);
|
||||
ship.modules.forEach(m => {
|
||||
let [mx, my] = [m.x, m.y];
|
||||
if (state.editing) {
|
||||
|
||||
}
|
||||
context.drawImage(m.currentImage, m.x, m.y, 1, 1);
|
||||
});
|
||||
context.restore();
|
||||
|
|
69
js/gui/edit.mjs
Normal file
69
js/gui/edit.mjs
Normal file
|
@ -0,0 +1,69 @@
|
|||
import * as gui from './index.mjs';
|
||||
import GuiElement from './element.mjs';
|
||||
import GuiItemButton from './item.mjs';
|
||||
import {state} from '../game/index.mjs';
|
||||
import * as edit from '../game/edit.mjs';
|
||||
|
||||
export default class GuiEdit extends GuiElement {
|
||||
constructor(x, y, w = 100, h = 30) {
|
||||
super(x, y, w, h);
|
||||
this.type = 'edit';
|
||||
this.tileWidth = 0;
|
||||
this.tileHeight = 0;
|
||||
this.active = false;
|
||||
}
|
||||
|
||||
updateTiles() {
|
||||
this.children.clear();
|
||||
|
||||
[this.tileWidth, this.tileHeight] = [edit.width, edit.height];
|
||||
|
||||
let tileRatio = this.tileWidth / this.tileHeight;
|
||||
let rectRatio = this.w / this.h;
|
||||
let tileSize;
|
||||
let [ox, oy] = [0, 0];
|
||||
|
||||
if (tileRatio < rectRatio) {
|
||||
tileSize = this.h / this.tileHeight;
|
||||
ox = (this.w - (tileSize * this.tileWidth)) / 2;
|
||||
} else {
|
||||
tileSize = this.w / this.tileWidth;
|
||||
oy = (this.h - (tileSize * this.tileHeight)) / 2;
|
||||
}
|
||||
|
||||
let spacing = 0.1 * tileSize;
|
||||
|
||||
for (let x = 0; x < this.tileWidth; x++)
|
||||
for (let y = 0; y < this.tileHeight; y++) {
|
||||
let tile = this.getTile(x, y);
|
||||
let ex = x * tileSize + spacing / 2 + ox + this.x;
|
||||
let ey = y * tileSize + spacing / 2 + oy + this.y;
|
||||
let [ew, eh] = [tileSize - spacing, tileSize - spacing];
|
||||
|
||||
let onclick = (button) => {
|
||||
this.tileClicked(x, y, button);
|
||||
};
|
||||
|
||||
let el = new GuiItemButton(tile.module, onclick, ex, ey, ew, eh);
|
||||
this.append(el);
|
||||
}
|
||||
}
|
||||
|
||||
tick() {
|
||||
if (state.editing && !this.active) this.updateTiles();
|
||||
this.active = state.editing;
|
||||
this.options.draw = this.options.drawChildren = this.active;
|
||||
if (!this.active) return;
|
||||
|
||||
[this.tileWidth, this.tileHeight] = [edit.width, edit.height];
|
||||
}
|
||||
|
||||
getTile(x, y) {
|
||||
let [px, py] = edit.position;
|
||||
return edit.getTile(x + px, y + py);
|
||||
}
|
||||
|
||||
tileClicked(x, y, button) {
|
||||
console.log(x, y, button);
|
||||
}
|
||||
}
|
0
js/gui/inventory.mjs
Normal file
0
js/gui/inventory.mjs
Normal file
18
js/gui/item.mjs
Normal file
18
js/gui/item.mjs
Normal file
|
@ -0,0 +1,18 @@
|
|||
import * as gui from './index.mjs';
|
||||
import GuiButton from './button.mjs';
|
||||
|
||||
export default class GuiItemButton extends GuiButton {
|
||||
constructor(module, onclick, x, y, w = 50, h = 50) {
|
||||
super(null, onclick, x, y, w, h);
|
||||
this.image = module === null ? null : module.currentImage;
|
||||
this.type = 'itemButton';
|
||||
}
|
||||
|
||||
click() {
|
||||
this.onclick('left');
|
||||
}
|
||||
|
||||
rightClick() {
|
||||
this.onclick('right');
|
||||
}
|
||||
}
|
|
@ -9,10 +9,15 @@ export class Rect {
|
|||
|
||||
this.onclick = null;
|
||||
this.mouseHeld = false;
|
||||
|
||||
this.rightMouseHeld = false;
|
||||
this.onRightClick = null;
|
||||
}
|
||||
|
||||
click() {}
|
||||
|
||||
rightClick() {}
|
||||
|
||||
tickMouse() {
|
||||
if (this.mouseHeld == true && !input.mouse.held[0] && this.mouseOver)
|
||||
this.click();
|
||||
|
@ -20,6 +25,14 @@ export class Rect {
|
|||
this.mouseHeld = true;
|
||||
if (!input.mouse.held[0])
|
||||
this.mouseHeld = false;
|
||||
|
||||
if (this.rightMouseHeld == true && !input.mouse.held[2]
|
||||
&&this.mouseOver)
|
||||
this.rightClick();
|
||||
if (!this.rightMouseHeld && input.mouse.pressed[2] && this.mouseOver)
|
||||
this.rightMouseHeld = true;
|
||||
if (!input.mouse.held[2])
|
||||
this.rightMouseHeld = false;
|
||||
}
|
||||
|
||||
get shape() {
|
||||
|
|
|
@ -4,6 +4,7 @@ import {canvas} from '../graphics/index.mjs';
|
|||
import GuiFrame from './frame.mjs';
|
||||
import GuiImage from './image.mjs';
|
||||
import GuiButton from './button.mjs';
|
||||
import GuiEdit from './edit.mjs';
|
||||
import * as events from '../game/events.mjs';
|
||||
import {state} from '../game/index.mjs';
|
||||
|
||||
|
@ -38,13 +39,19 @@ export function title() {
|
|||
export function game() {
|
||||
let shadow = root();
|
||||
|
||||
let edit = new GuiButton('Edit rocket', events.editShip, 0, 0, 200);
|
||||
shadow.append(edit);
|
||||
edit.posRelative({ x: 0.5, xc: 0.5, y: 1 });
|
||||
edit.y -= 45;
|
||||
edit.tick = () => {
|
||||
edit.options.draw = state.landed && !state.editing;
|
||||
let editButton = new GuiButton('Edit rocket', events.editShip, 0, 0, 200);
|
||||
shadow.append(editButton);
|
||||
editButton.posRelative({ x: 0.5, xc: 0.5, y: 1 });
|
||||
editButton.y -= 45;
|
||||
editButton.tick = () => {
|
||||
editButton.options.draw = state.landed && !state.editing;
|
||||
}
|
||||
|
||||
let edit = new GuiEdit(0, 0, 0, 0);
|
||||
shadow.append(edit);
|
||||
edit.posRelative({x: 0.45, y: 0, w: 0.55, h: 0.6});
|
||||
edit.x -= 10;
|
||||
edit.y += 10;
|
||||
|
||||
return shadow;
|
||||
}
|
||||
|
|
|
@ -48,4 +48,8 @@ export function init() {
|
|||
window.addEventListener('wheel', event => {
|
||||
mouse.scroll = event.deltaY;
|
||||
});
|
||||
|
||||
window.addEventListener('contextmenu', event => {
|
||||
event.preventDefault();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -40,9 +40,9 @@ export default class Ship extends Body {
|
|||
}
|
||||
|
||||
tick() {
|
||||
this.tickMotion();
|
||||
if (!state.editing) this.tickMotion();
|
||||
if (!this.landed) this.tickGravity(world.celestials);
|
||||
this.resolveCollisions();
|
||||
if (!state.editing) this.resolveCollisions();
|
||||
|
||||
this.modules.forEach(m => {
|
||||
if (m.type == 'thruster' && m.power !== 0) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue