diff --git a/.gitignore b/.gitignore index 0f6f9cf..b6183af 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .cache/ *.map +dist/improcket.min.js diff --git a/dist/img/background_small.png b/dist/img/background_small.png new file mode 100644 index 0000000..1a5fe90 Binary files /dev/null and b/dist/img/background_small.png differ diff --git a/dist/img/modules/small_navigation.svg b/dist/img/modules/small_navigation.svg new file mode 100644 index 0000000..1c20bb2 --- /dev/null +++ b/dist/img/modules/small_navigation.svg @@ -0,0 +1,140 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/dist/improcket.min.js b/dist/improcket.min.js index e0460cd..608e08f 100644 --- a/dist/improcket.min.js +++ b/dist/improcket.min.js @@ -11,8 +11,9 @@ const modules = { mass: 2, value: 5, connectivity: [false, false, true, false], - capacity: 2, - rotation: 1 + capacity: 3, + rotation: 1, + computation: 100, }, large: { name: 'Large Capsule', @@ -24,7 +25,8 @@ const modules = { value: 10, connectivity: [false, false, true, false], capacity: 5, - rotation: 4 + rotation: 4, + computation: 130, }, advanced: { name: 'Advanced Capsule', @@ -36,7 +38,8 @@ const modules = { value: 30, connectivity: [false, false, true, false], capacity: 4, - rotation: 5 + rotation: 5, + computation: 150, } }, fuel: { @@ -111,7 +114,7 @@ const modules = { 'heavy', type: 'connector', id: 'xheavy', - mass: 5, + mass: 2, value: 3, connectivity: [true, true, true, true] }, @@ -127,7 +130,7 @@ const modules = { }, gyroscope: { small: { - name: 'Small gyroscope', + name: 'Small Gyroscope', tooltip: 'Provides a small amount of rotational power to the ship.', type: 'gyroscope', id: 'small', @@ -137,7 +140,7 @@ const modules = { rotation: 2 }, large: { - name: 'Large gyroscope', + name: 'Large Gyroscope', tooltip: 'Provides a lot of rotational force for large ships.', type: 'gyroscope', id: 'large', @@ -147,6 +150,18 @@ const modules = { rotation: 4 } }, + navigation: { + small: { + name: 'Navigational Computer', + tooltip: 'Increases the length of your predicted orbital path.', + type: 'navigation', + id: 'small', + mass: 1, + value: 10, + connectivity: [true, false, true, false], + computation: 150, + }, + }, cargo: { small: { name: 'Cargo bay', @@ -167,7 +182,7 @@ const images = { logoSvg: 'logo2.svg' }, background: { - back: 'background.png', + back: 'background_small.png', middle: 'stars_back.png', front: 'stars_front.png' }, @@ -207,6 +222,9 @@ const images = { small: 'modules/small_gyroscope.svg', large: 'modules/large_gyroscope.svg' }, + navigation: { + small: 'modules/small_navigation.svg', + }, fuelcan: 'modules/fuelcan.svg' }, celestials: { @@ -233,7 +251,7 @@ const audio = { pause: 'swoosh1.mp3' }; -async function init() { +async function init$9() { let parse = (obj, convert) => Object.entries(obj).forEach(([k, v]) => { typeof v == 'object' ? parse(v, convert) : obj[k] = convert(v); }); @@ -318,7 +336,7 @@ class Module { // For fixing floating point rounding errors. const EPSILON = 1e-8; // Don't change these. -const TAU = Math.PI * 2; +const TAU$1 = Math.PI * 2; // Unit length of sector. May affect spawning a bit. const SECTOR_SIZE = 512; // G, G-boy, The big G, Mr. G, g's big brother, G-dog @@ -346,7 +364,9 @@ const ENTITY_ROTATION_RATE = 0.01; const PLANET_SPAWN_RATE = 100; const ENTITY_SPAWN_RATE = 8; const MIN_CELESTIAL_SPACING = 15; -const FUEL_CAN_AMOUNT = 4; +const FUEL_CAN_AMOUNT = 10000; + +const PLANET_IMAGE_SIZE = 250; class Body { constructor(x, y, mass) { @@ -377,7 +397,7 @@ class Body { } normalizeAngle(a = this.r) { - return ((a % TAU) + TAU) % TAU; + return ((a % TAU$1) + TAU$1) % TAU$1; } getCelestialCollision(celestials) { @@ -420,13 +440,15 @@ class Body { } tickGravity(bodies, speed = 1) { - bodies.forEach(b => { - let force = b.mass / (this.distanceTo(b) ** 2) * GRAVITATIONAL_CONSTANT; - let [[ax, ay], [bx, by]] = [this.com, b.com]; + for (let body of bodies) { + const distanceSquared = this.distanceToSquared(body); + if (distanceSquared > (1000 ** 2)) continue; + let force = body.mass / distanceSquared * GRAVITATIONAL_CONSTANT; + let [[ax, ay], [bx, by]] = [this.com, body.com]; let angle = Math.atan2(by - ay, bx - ax); this.xvel += Math.cos(angle) * force * speed; this.yvel += Math.sin(angle) * force * speed; - }); + } } distanceTo(body) { @@ -435,6 +457,12 @@ class Body { ((by - ay) ** 2)), 1); } + distanceToSquared(body) { + let [[ax, ay], [bx, by]] = [this.com, body.com]; + return Math.max(((bx - ax) ** 2) + + ((by - ay) ** 2), 1); + } + angleTo(ax, ay, bx, by) { return Math.atan2(by - ay, bx - ax); } @@ -606,7 +634,7 @@ let usedSpace = 0; let onupdate = () => {}; -function init$1() { +function init$8() { items.clear(); update(); } @@ -625,7 +653,7 @@ function getTiles() { function addItem(type, id) { let mapId = toId(type, id); - if (!items.has(mapId)) items.set(mapId, new Tile(type, id)); + if (!items.has(mapId)) items.set(mapId, new Tile$1(type, id)); let tile = items.get(mapId); tile.increase(); update(); @@ -664,7 +692,7 @@ function toId(type, id) { return `${type}.${id}`; } -class Tile { +class Tile$1 { constructor(type, id, q = 0) { this.type = type; this.id = id; @@ -748,7 +776,7 @@ let notLife = 0; let landedPlanets = new Set(); -function init$2() { +function init$7() { score = 0; shipLanded = false; } @@ -762,13 +790,13 @@ function playMusic() { volume('music', 0.4); } -function notify(message$$1, time = 80) { +function notify(message, time = 80) { if (notification === null) return; - notification.text = message$$1; + notification.text = message; notLife = time; } -function tick() { +function tick$6() { if (notification === null) return; if ((notLife-- <= 0 || state.gameOver) && !state.paused) notification.text = ''; @@ -779,15 +807,15 @@ function setNotificationElement(el) { } function startGame() { - init$2(); + init$7(); state.gameOver = false; - changeView$1('game'); + changeView('game'); perspective.reset(); perspective.focusPlayer(); } function toMenu() { - changeView$1('menu'); + changeView('menu'); } function togglePause() { @@ -808,7 +836,7 @@ function landShip(planet) { } function howToPlay() { - changeView$1('instructions'); + changeView('instructions'); } function newPlanet(planet) { @@ -858,27 +886,27 @@ function toggleEdit() { } state.editing = true; state.inventory = true; - init$4(); + init$5(); } -function toggleTrace() { - let trace$$1 = toggleTrace$1(); - notify('Path prediction: ' + (trace$$1 ? 'on' : 'off')); +function toggleTrace$1() { + let trace = toggleTrace(); + notify('Path prediction: ' + (trace ? 'on' : 'off')); } -function toggleMarkers() { - let markers$$1 = toggleMarkers$1(); - notify('Item markers: ' + (markers$$1 ? 'on' : 'off')); +function toggleMarkers$1() { + let markers = toggleMarkers(); + notify('Item markers: ' + (markers ? 'on' : 'off')); } -function cycleRotationMode() { - let message$$1 = { +function cycleRotationMode$1() { + let message = { parent: 'planet', local: 'ship', universe: 'universe' - }[cycleRotationMode$1()]; + }[cycleRotationMode()]; - notify('Rotation view: ' + message$$1); + notify('Rotation view: ' + message); } function endEditing() { @@ -906,7 +934,7 @@ function collectItem(type, id, name) { notify('Collected fuel: +10'); return true; } else { - if (usedSpace > capacity) { + if (usedSpace >= capacity) { notify('No space left in inventory', 60); return false; } @@ -951,7 +979,7 @@ class Tracer extends Body { } tick() { - this.run(100); + this.run(this.ship.computation); } tickPath(speed) { @@ -976,6 +1004,7 @@ class Ship extends Body { this.rotationPower = 0; this.cargoCapacity = 0; this.thrust = 0; + this.computation = 0; this.crashed = false; this.timeWithoutFuel = 0; } @@ -1067,6 +1096,7 @@ class Ship extends Body { this.rotationPower = 0; this.cargoCapacity = 0; this.thrust = 0; + this.computation = 0; this.modules.forEach(m => { if (m.type === 'fuel') { @@ -1074,12 +1104,15 @@ class Ship extends Body { } else if (m.type === 'capsule') { this.rotationPower += m.data.rotation; this.cargoCapacity += m.data.capacity; + this.computation += m.data.computation; } else if (m.type === 'thruster') { this.thrust += m.data.thrust; } else if (m.type === 'gyroscope') { this.rotationPower += m.data.rotation; } else if (m.type === 'cargo') { this.cargoCapacity += m.data.capacity; + } else if (m.type === 'navigation') { + this.computation += m.data.computation; } }); } @@ -1198,8 +1231,15 @@ class Celestial extends Body { this.radius = radius; this.type = type; - let imageArr = Object.values(images.celestials[this.type]); - this.image = imageArr[Math.random() * imageArr.length | 0]; + const imageArr = Object.values(images.celestials[this.type]); + const svgImage = imageArr[Math.random() * imageArr.length | 0]; + tempCanvas.width = PLANET_IMAGE_SIZE; + tempCanvas.height = PLANET_IMAGE_SIZE; + tempContext.clearRect(0, 0, PLANET_IMAGE_SIZE, PLANET_IMAGE_SIZE); + tempContext.drawImage(svgImage, 0, 0, PLANET_IMAGE_SIZE, PLANET_IMAGE_SIZE); + this.image = new Image(); + this.image.src = tempCanvas.toDataURL(); + // this.image = tempContext.getImageData(0, 0, PLANET_IMAGE_SIZE, PLANET_IMAGE_SIZE); } get com() { @@ -1287,7 +1327,7 @@ let spawnedSectors = new Map(); const visibleRadius = (400 / MIN_ZOOM) + SECTOR_SIZE; -function tick$1() { +function tick$5() { let [px, py] = playerShip.com; for (let x = px - visibleRadius; x < px + visibleRadius; x += SECTOR_SIZE) @@ -1350,7 +1390,7 @@ function randomPlanet(x, y, { if (cel !== null && dis < Math.max(radius, cel.radius) * mcs) return; - let planet = celestial(x, y, radius, { + let planet = celestial$1(x, y, radius, { density: density, type: type }); @@ -1425,7 +1465,7 @@ function startPlanet() { return planet; } -function celestial(x, y, radius, params) { +function celestial$1(x, y, radius, params) { let celestial = new Celestial(x - radius, y - radius, radius, params); celestials.add(celestial); return celestial; @@ -1439,15 +1479,17 @@ const tracers = new Set(); let playerShip = null; +let speed = 1; + function setPlayerShip(ship) { playerShip = ship; } -function init$3() { +function init$6() { clear(); player(); - let p = startPlanet(); - tick$1(); + startPlanet(); + tick$5(); } function clear() { @@ -1463,13 +1505,24 @@ function remove(object) { celestials.delete(object); } -function tick$2() { - particles.forEach(p => p.tick()); - celestials.forEach(c => c.tick()); - entities.forEach(e => e.tick()); - ships.forEach(s => s.tick()); +function increaseSpeed() { + if (speed < 5) speed += 1; +} + +function decreaseSpeed() { + if (speed > 1) speed -= 1; +} + +function tick$4() { + for (let i = 0; i < speed; i++) { + particles.forEach(p => p.tick()); + celestials.forEach(c => c.tick()); + entities.forEach(e => e.tick()); + ships.forEach(s => s.tick()); + } + + tick$5(); if (trace) tracers.forEach(t => t.tick()); - tick$1(); } let tiles = new Map(); @@ -1479,22 +1532,26 @@ let position = [0, 0]; let message = ''; let info = ''; -function init$4() { +function init$5() { let ship = playerShip; - let modules$$1 = ship.modules; + let modules = ship.modules; tiles.clear(); - modules$$1.forEach(m => { + modules.forEach(m => { let pos = [m.x, m.y]; - tiles.set(posId(...pos), new Tile$1(...pos, m)); + tiles.set(posId(...pos), new Tile(...pos, m)); }); message = ''; adjustSize(); + adjustGraphics(); +} + +function adjustGraphics() { let neededZoom = canvas.width / (Math.max(width, height) + 10); - changePerspective('planet', 0, -5); + changePerspective('planet', 0, -3); setZoom(neededZoom); } @@ -1526,6 +1583,9 @@ function end() { let [dx, dy] = [nx - ox, ny - oy]; ship.x -= dx; ship.y -= dy; + const [rdx, rdy] = ship.rotateVector(dx, dy); + ship.x -= rdx; + ship.y -= rdy; } return result; @@ -1537,6 +1597,7 @@ function getAttributes() { let rotation = 0; let mass = 0; let thrust = 0; + let computation = 0; tiles.forEach(t => { if (t.type === null) return; @@ -1545,12 +1606,15 @@ function getAttributes() { } else if (t.type === 'capsule') { rotation += t.module.rotation; cargo += t.module.capacity; + computation += t.module.computation; } else if (t.type === 'thruster') { thrust += t.module.thrust; } else if (t.type === 'gyroscope') { rotation += t.module.rotation; } else if (t.type === 'cargo') { cargo += t.module.capacity; + } else if (t.type === 'nafivation') { + computation += t.module.computation; } mass += t.module.mass; }); @@ -1560,7 +1624,8 @@ function getAttributes() { 'Thrust/mass ratio: ' + (thrust / Math.max(mass, 1)).toFixed(1) + '\n' + 'Rotation speed: ' + (rotation / Math.max(mass, 1) * 100).toFixed(1) + '\n' + - 'Cargo capacity: ' + cargo; + 'Cargo capacity: ' + cargo + '\n' + + 'Navigational computation: ' + computation; } function validate() { @@ -1627,12 +1692,11 @@ function clickTile(x, y) { let current = getTile(x, y).source; if (current.type !== null) { return; - } else { } let pos = positionAdjust(x, y); let id = posId(...pos); - tiles.set(id, new Tile$1(...pos, currentItem)); + tiles.set(id, new Tile(...pos, currentItem)); removeItem(...currentItem.ident); adjustSize(); validate(); @@ -1643,7 +1707,7 @@ function rightClickTile(x, y) { if (current.type === null) return; let { x: tx, y: ty } = current; let id = posId(tx, ty); - tiles.set(id, new Tile$1(tx, ty, null)); + tiles.set(id, new Tile(tx, ty, null)); addItem(current.type, current.id); adjustSize(); validate(); @@ -1657,7 +1721,7 @@ function getTile(x, y) { function getRawTile(x, y) { let id = posId(x, y); if (!tiles.has(id)) - tiles.set(id, new Tile$1(x, y, null)); + tiles.set(id, new Tile(x, y, null)); return tiles.get(id); // TODO: Get linked tiles. } @@ -1678,7 +1742,7 @@ function getBoundaries() { return [sx, ex, sy, ey]; } -class Tile$1 { +class Tile { constructor(x, y, module) { if (module === null) { this.module = null; @@ -1726,7 +1790,7 @@ function tick$3() { mouse.scroll = 0; } -function init$5() { +function init$4() { window.addEventListener('keydown', event => { keyCode.pressed[event.code] = !keyCode.held[event.code]; keyCode.held[event.code] = true; @@ -1757,7 +1821,7 @@ function init$5() { window.addEventListener('wheel', event => { mouse.scroll = event.deltaY; - event.preventDefault(); + // event.preventDefault(); }); window.addEventListener('contextmenu', event => { @@ -1990,7 +2054,7 @@ class GuiInventory extends GuiElement { 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; + y * this.tileWidth + (x % this.tileWidth) + offset; tile = tiles.shift(); let ex = x * tileSize + spacing / 2 + ox; @@ -2133,7 +2197,7 @@ class GuiText extends GuiElement { this.color = color; this.text = text; this.spacing = size * 1.2; - this.font = size + 'px Consolas'; + this.font = size + 'px Courier New'; this.align = align; this.valign = valign; } @@ -2163,14 +2227,14 @@ class GuiText extends GuiElement { } } -function root() { +function root$1() { return new GuiFrame(0, 0, canvas.width, canvas.height, { draw: false }); } function title() { - let shadow = root(); + let shadow = root$1(); let logo = new GuiImage(images.title.logo); shadow.append(logo); logo.scaleImage({ w: shadow.w * 0.7 }); @@ -2222,7 +2286,7 @@ running out of fuel. `; function instructions() { - let shadow = root(); + let shadow = root$1(); let frame = new GuiFrame(); shadow.append(frame); @@ -2246,7 +2310,7 @@ function instructions() { } function game() { - let shadow = root(); + let shadow = root$1(); let editButton = new GuiButton('Edit rocket', toggleEdit, 0, 0, 200); shadow.append(editButton); @@ -2279,21 +2343,35 @@ function game() { ship.maxFuel.toFixed(1); }; - let score$$1 = new GuiText('', 0, 0, 0, 0, { + let speed$1 = new GuiText('', 0, 0, 0, 0, { + size: 14, + align: 'right', + valign: 'bottom', + + }); + shadow.append(speed$1); + speed$1.posRelative({x: 1, y: 1}); + speed$1.y -= 30; + speed$1.x -= 10; + speed$1.tick = () => { + speed$1.text = 'Speed: ' + speed.toFixed(1) + 'x'; + }; + + let score$1 = new GuiText('', 0, 0, 0, 0, { size: 14, align: 'left', valign: 'bottom' }); - shadow.append(score$$1); - score$$1.posRelative({x: 0, y: 1}); - score$$1.y -= 10; - score$$1.x += 10; - score$$1.tick = () => { - score$$1.text = 'Score: ' + score; + shadow.append(score$1); + score$1.posRelative({x: 0, y: 1}); + score$1.y -= 10; + score$1.x += 10; + score$1.tick = () => { + score$1.text = 'Score: ' + score; }; - let editShadow = root(); + let editShadow = root$1(); shadow.append(editShadow); editShadow.posRelative({x: 0.45, y: 0, w: 0.55, h: 0.6}); editShadow.x -= 10; @@ -2326,7 +2404,7 @@ function game() { }; - let invShadow = root(); + let invShadow = root$1(); shadow.append(invShadow); invShadow.posRelative({x: 0, w: 0.4, h: 0.6}); invShadow.x += 10; @@ -2375,32 +2453,32 @@ function game() { setNotificationElement(notification); - let gameOver$$1 = root(); - shadow.append(gameOver$$1); - gameOver$$1.posRelative({x: 0.2, y: 0.2, w: 0.6, h: 0.6}); + let gameOver = root$1(); + shadow.append(gameOver); + gameOver.posRelative({x: 0.2, y: 0.2, w: 0.6, h: 0.6}); let gameOverMain = new GuiText('Game over', 0, 0, 0, 0, { size: 48, align: 'center', valign: 'top' }); - gameOver$$1.append(gameOverMain); + gameOver.append(gameOverMain); gameOverMain.posRelative({x: 0.5}); gameOverMain.y += 10; - gameOver$$1.tick = () => { - gameOver$$1.options.drawChildren = state.gameOver; + gameOver.tick = () => { + gameOver.options.drawChildren = state.gameOver; }; - let gameOverReason$$1 = new GuiText('', 0, 0, 0, 0, { + let gameOverReason$1 = new GuiText('', 0, 0, 0, 0, { size: 14, align: 'center', valign: 'top' }); - gameOver$$1.append(gameOverReason$$1); - gameOverReason$$1.posRelative({x: 0.5}); - gameOverReason$$1.y += 100; - gameOverReason$$1.tick = () => { - gameOverReason$$1.text = gameOverReason; + gameOver.append(gameOverReason$1); + gameOverReason$1.posRelative({x: 0.5}); + gameOverReason$1.y += 100; + gameOverReason$1.tick = () => { + gameOverReason$1.text = gameOverReason; }; let gameOverScore = new GuiText('', 0, 0, 0, 0, { @@ -2408,7 +2486,7 @@ function game() { align: 'center', valign: 'top' }); - gameOver$$1.append(gameOverScore); + gameOver.append(gameOverScore); gameOverScore.posRelative({x: 0.5}); gameOverScore.y += 200; gameOverScore.tick = () => { @@ -2416,7 +2494,7 @@ function game() { }; let gameOverExit = new GuiButton('Main menu', toMenu, 0, 0, 200); - gameOver$$1.append(gameOverExit); + gameOver.append(gameOverExit); gameOverExit.posRelative({ x: 0.5, xc: 0.5, y: 1 }); gameOverExit.y -= 10; @@ -2424,36 +2502,36 @@ function game() { } const elements = new Set(); -let root$1; +let root; -function init$6() { +function init$3() { elements.clear(); - root$1 = root(); - changeView('menu'); + root = root$1(); + changeView$1('menu'); } -function tick$4() { - root$1.tickElement(); +function tick$2() { + root.tickElement(); } -function changeView(view) { - root$1.clear(); +function changeView$1(view) { + root.clear(); if (view === 'menu') { - root$1.append(title()); + root.append(title()); } if (view === 'game') { - root$1.append(game()); + root.append(game()); } if (view === 'instructions') { - root$1.append(instructions()); + root.append(instructions()); } } -function render() { - renderElement(root$1); +function render$3() { + renderElement(root); } function renderElement(element) { @@ -2461,7 +2539,7 @@ 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 === 'edit') ; if (element.type === 'itemButton') renderItemButton(element); if (element.type === 'inventory') renderInventory(element); if (element.type === 'text') renderText(element); @@ -2530,7 +2608,7 @@ function renderButton(element) { context.textAlign = 'center'; context.textBaseline = 'middle'; context.fillStyle = '#fff'; - context.font = '12pt Consolas'; + context.font = '12pt Courier New'; context.fillText(element.text, ...element.center); context.globalAlpha = 1; @@ -2567,16 +2645,12 @@ function renderItemButton(element) { context.textAlign = 'right'; context.textBaseline = 'bottom'; context.fillStyle = '#fff'; - context.font = 'bold 10pt Consolas'; + context.font = 'bold 10pt Courier New'; let [ex, ey] = element.end; context.fillText('x' + element.quantity, ex - 2, ey - 2); } } -function renderEdit(element) { - -} - function renderInventory(element) { context.globalAlpha = 0.1; context.fillStyle = '#541'; @@ -2584,12 +2658,12 @@ function renderInventory(element) { context.globalAlpha = 1; } -function render$1() { - particles.forEach(renderParticle); - celestials.forEach(renderCelestial); - if (trace) tracers.forEach(renderTracer); - ships.forEach(renderShip); - entities.forEach(renderEntity); +function render$2() { + for (particle of particles) renderParticle(particle); + for (celestial of celestials) if (isVisible(celestial)) renderCelestial(celestial); + if (trace) for (tracer of tracers) renderTracer(tracer); + for (ship of ships) renderShip(ship); + for (entity of entities) if (isVisible(entity)) renderEntity(entity); /* if (typeof window.q === 'undefined') window.q = []; @@ -2600,6 +2674,16 @@ function render$1() { */ } +function isVisible(body) { + const [bx, by] = body.com; + const [px, py] = [perspective.x, perspective.y]; + perspective.bounds; + const [centerX, centerY] = [px, py]; + const margin = 1000; + return bx > centerX - margin && bx < centerX + margin && + by > centerY - margin && by < centerY + margin; +} + function renderParticle(particle) { context.fillStyle = particle.color; context.fillRect(...particle.com, particle.size, particle.size); @@ -2633,18 +2717,16 @@ 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) { - - } + [m.x, m.y]; + if (state.editing) ; context.drawImage(m.currentImage, m.x, m.y, 1, 1); }); context.restore(); } -const celestialImages = { +({ green: Object.values(images.celestials.green) -}; +}); function renderCelestial(cel) { context.drawImage(cel.image, cel.x, cel.y, @@ -2671,7 +2753,7 @@ function renderTracer(tracer) { let patterns = null; -function init$7() { +function init$2() { patterns = { back: context.createPattern(images.background.back, 'repeat'), middle: context.createPattern(images.background.middle, 'repeat'), @@ -2679,55 +2761,44 @@ function init$7() { }; } -function render$2(angle) { - if (patterns === null) init$7(); - - renderLayer(patterns.back, 0.3, 1, angle); - renderLayer(patterns.middle, 0.5, 0.3, angle); - //renderLayer(patterns.front, 0.7, 0.3, angle); +function render$1(angle) { + if (patterns === null) init$2(); + // renderLayer(patterns.back, 0.3, 1, angle); + // renderLayer(patterns.middle, 0.5, 0.3, angle); + // renderLayer(patterns.front, 0.7, 0.3, angle); } -function renderLayer(pattern, speed = 1, scale = 1, angle = 0) { - context.save(); - let outset = (Math.abs(Math.cos(angle)) + Math.abs(Math.sin(angle))); - outset = ((outset - 1) * canvas.width) / scale; - let [px, py] = [perspective.x * speed, perspective.y * speed]; - context.translate(-px, -py); - context.scale(scale, scale); - context.fillStyle = pattern; - context.fillRect(px / scale - outset / 2, py / scale - outset / 2, - canvas.width / scale + outset, canvas.height / scale + outset); - context.restore(); -} - -const TAU$1 = TAU; +const TAU = TAU$1; let canvas, context, tempCanvas, tempContext; let perspective; let trace = true; let markers = true; -function init$8() { +function init$1() { canvas = document.querySelector('#main'); context = canvas.getContext('2d'); tempCanvas = document.querySelector('#temp'); tempContext = tempCanvas.getContext('2d'); - canvas.width = 600; - canvas.height = 600; + canvas.width = window.innerWidth; + canvas.height = window.innerHeight; + + canvas.style.width = canvas.width + 'px'; + canvas.style.height = canvas.height + 'px'; perspective = new Perspective(); context.fillStyle = '#000'; context.fillRect(0, 0, canvas.width, canvas.height); - context.font = '36px Consolas'; + context.font = '36px Courier New'; context.textAlign = 'center'; context.textBaseline = 'middle'; context.fillStyle = '#fff'; context.fillText('Loading...', canvas.width / 2, canvas.height / 2); } -function render$3() { +function render() { context.clearRect(0, 0, canvas.width, canvas.height); context.fillStyle = '#000'; context.fillRect(0, 0, canvas.width, canvas.height); @@ -2739,12 +2810,12 @@ function render$3() { context.save(); perspective.tick(); perspective.transformRotate(); - render$2(perspective.rotation); + render$1(perspective.rotation); perspective.transformCanvas(); - render$1(); + render$2(); context.restore(); - render(); + render$3(); } function changePerspective(rotationMode, shiftX = 0, shiftY = 0) { @@ -2753,7 +2824,7 @@ function changePerspective(rotationMode, shiftX = 0, shiftY = 0) { perspective.transition = 1; } -function cycleRotationMode$1() { +function cycleRotationMode() { if (perspective.rotationMode === 'parent') { perspective.changeRotationMode('local'); } else if (perspective.rotationMode === 'local') { @@ -2765,12 +2836,12 @@ function cycleRotationMode$1() { return perspective.rotationMode; } -function toggleTrace$1() { +function toggleTrace() { trace = !trace; return trace; } -function toggleMarkers$1() { +function toggleMarkers() { markers = !markers; return markers; } @@ -2903,7 +2974,7 @@ class Perspective { normalize() { this.targetZoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, this.targetZoom)); - this.targetRotation %= TAU$1; + this.targetRotation %= TAU; } transformRotate() { @@ -2928,11 +2999,11 @@ class Perspective { } normalizeAngle(a = this.r) { - return ((a % TAU$1) + TAU$1) % TAU$1; + return ((a % TAU) + TAU) % TAU; } } -const mapping$1 = { +const mapping = { thrust: 'KeyW', left: 'KeyA', right: 'KeyD', @@ -2945,12 +3016,14 @@ const mapping$1 = { toggleMusic: 'KeyM', togglePause: 'KeyP', zoomIn: 'KeyZ', - zoomOut: 'KeyX' + zoomOut: 'KeyX', + increaseSpeed: 'Period', + decreaseSpeed: 'Comma', }; let held, pressed; -function tick$5() { +function tick$1() { held = keyCode.held; pressed = keyCode.pressed; @@ -2967,32 +3040,40 @@ function tick$5() { changeZoom(delta); } - if (held[mapping$1.zoomIn]) { + if (held[mapping.zoomIn]) { changeZoom(-10); } - if (held[mapping$1.zoomOut]) { + if (held[mapping.zoomOut]) { changeZoom(10); } - if (pressed[mapping$1.togglePause] && !state.gameOver) { + if (pressed[mapping.togglePause] && !state.gameOver) { togglePause(); } + + if (pressed[mapping.increaseSpeed]) { + increaseSpeed(); + } + + if (pressed[mapping.decreaseSpeed]) { + decreaseSpeed(); + } } if (state.gameOver) { stop('engine'); } - if (pressed[mapping$1.toggleMusic]) { + if (pressed[mapping.toggleMusic]) { toggle('music'); } } function tickPlaying() { - let power = held[mapping$1.reduce] ? 0.3 : 1; + let power = held[mapping.reduce] ? 0.3 : 1; - if (held[mapping$1.thrust] && playerShip.fuel !== 0) { + if (held[mapping.thrust] && playerShip.fuel !== 0) { playerShip.applyThrust({ forward: power }); let vol = Math.min(0.7, perspective.zoom / 10); volume('engine', vol); @@ -3000,7 +3081,7 @@ function tickPlaying() { stop('engine'); } - if (pressed[mapping$1.thrust]) { + if (pressed[mapping.thrust]) { if (playerShip.fuel !== 0) { start('engine'); } else { @@ -3008,40 +3089,40 @@ function tickPlaying() { } } - if (held[mapping$1.left]) { + if (held[mapping.left]) { playerShip.applyThrust({ turnLeft: power }); } - if (held[mapping$1.right]) { + if (held[mapping.right]) { playerShip.applyThrust({ turnRight: power }); } - if (pressed[mapping$1.inventory]) { + if (pressed[mapping.inventory]) { state.inventory = !state.inventory; } - if (pressed[mapping$1.cycleRotation]) { - cycleRotationMode(); + if (pressed[mapping.cycleRotation]) { + cycleRotationMode$1(); } - if (pressed[mapping$1.toggleTrace]) { - toggleTrace(); + if (pressed[mapping.toggleTrace]) { + toggleTrace$1(); } - if (pressed[mapping$1.toggleMarkers]) { - toggleMarkers(); + if (pressed[mapping.toggleMarkers]) { + toggleMarkers$1(); } } function tickEditing() { - if (pressed[mapping$1.exitEdit]) { + if (pressed[mapping.exitEdit]) { endEditing(); } } let state; -async function init$9() { +async function init() { state = { view: 'menu', playing: false, @@ -3051,68 +3132,59 @@ async function init$9() { gameOver: false }; - init$8(); - await init(); - init$6(); - init$5(); + init$1(); + await init$9(); + init$3(); + init$4(); playMusic(); //events.startGame(); - loop(tick$6); + loop(tick); } -function changeView$1(view) { +function changeView(view) { state.view = view; - changeView(view); + changeView$1(view); if (view === 'game') { state.playing = true; state.editing = false; state.paused = false; - init$3(); - init$4(); + init$6(); + init$5(); perspective.reset(); - init$1(); + init$8(); } else if (view === 'instructions') { state.playing = false; - changeView('instructions'); + changeView$1('instructions'); } else if (view === 'menu') { - changeView('menu'); + changeView$1('menu'); clear(); } } function loop(fn, fps = 60) { - let then = Date.now(); - let interval = 1000 / fps; (function loop(time) { + fn(); + requestAnimationFrame(loop); - - // again, Date.now() if it's available - let now = Date.now(); - let delta = now - then; - - if (delta > interval) { - then = now - (delta % interval); - fn(); - } - })(0); + })(); } -function tick$6() { - tick(); +function tick() { + tick$6(); if (state.view == 'game' && !state.paused) { - tick$2(); + tick$4(); } - tick$5(); + tick$1(); - tick$4(); - render$3(); + tick$2(); + render(); tick$3(); } -window.addEventListener('load', init$9); +window.addEventListener('load', init); //# sourceMappingURL=improcket.min.js.map diff --git a/dist/styles.css b/dist/styles.css index 6ff196f..3fb065e 100644 --- a/dist/styles.css +++ b/dist/styles.css @@ -13,8 +13,8 @@ body { } #main { - width: 600px; - height: 600px; + width: 1300px; + height: 900px; margin: 50px auto; border: 2px solid #111; background-color: #fff; diff --git a/js/assets.mjs b/js/assets.mjs index 64c416f..aff05ae 100644 --- a/js/assets.mjs +++ b/js/assets.mjs @@ -4,7 +4,7 @@ export const images = { logoSvg: 'logo2.svg' }, background: { - back: 'background.png', + back: 'background_small.png', middle: 'stars_back.png', front: 'stars_front.png' }, @@ -44,6 +44,9 @@ export const images = { small: 'modules/small_gyroscope.svg', large: 'modules/large_gyroscope.svg' }, + navigation: { + small: 'modules/small_navigation.svg', + }, fuelcan: 'modules/fuelcan.svg' }, celestials: { diff --git a/js/consts.mjs b/js/consts.mjs index 5240da8..4024c6f 100644 --- a/js/consts.mjs +++ b/js/consts.mjs @@ -37,4 +37,6 @@ export const ENTITY_ROTATION_RATE = 0.01; export const PLANET_SPAWN_RATE = 100; export const ENTITY_SPAWN_RATE = 8; export const MIN_CELESTIAL_SPACING = 15; -export const FUEL_CAN_AMOUNT = 4; +export const FUEL_CAN_AMOUNT = 10000; + +export const PLANET_IMAGE_SIZE = 250; diff --git a/js/data.mjs b/js/data.mjs index 151e8cb..176818f 100644 --- a/js/data.mjs +++ b/js/data.mjs @@ -11,8 +11,9 @@ export const modules = { mass: 2, value: 5, connectivity: [false, false, true, false], - capacity: 2, - rotation: 1 + capacity: 3, + rotation: 1, + computation: 100, }, large: { name: 'Large Capsule', @@ -24,7 +25,8 @@ export const modules = { value: 10, connectivity: [false, false, true, false], capacity: 5, - rotation: 4 + rotation: 4, + computation: 130, }, advanced: { name: 'Advanced Capsule', @@ -36,7 +38,8 @@ export const modules = { value: 30, connectivity: [false, false, true, false], capacity: 4, - rotation: 5 + rotation: 5, + computation: 150, } }, fuel: { @@ -111,7 +114,7 @@ export const modules = { 'heavy', type: 'connector', id: 'xheavy', - mass: 5, + mass: 2, value: 3, connectivity: [true, true, true, true] }, @@ -127,7 +130,7 @@ export const modules = { }, gyroscope: { small: { - name: 'Small gyroscope', + name: 'Small Gyroscope', tooltip: 'Provides a small amount of rotational power to the ship.', type: 'gyroscope', id: 'small', @@ -137,7 +140,7 @@ export const modules = { rotation: 2 }, large: { - name: 'Large gyroscope', + name: 'Large Gyroscope', tooltip: 'Provides a lot of rotational force for large ships.', type: 'gyroscope', id: 'large', @@ -147,6 +150,18 @@ export const modules = { rotation: 4 } }, + navigation: { + small: { + name: 'Navigational Computer', + tooltip: 'Increases the length of your predicted orbital path.', + type: 'navigation', + id: 'small', + mass: 1, + value: 10, + connectivity: [true, false, true, false], + computation: 150, + }, + }, cargo: { small: { name: 'Cargo bay', diff --git a/js/game/control.mjs b/js/game/control.mjs index 950e2d8..279b588 100644 --- a/js/game/control.mjs +++ b/js/game/control.mjs @@ -3,6 +3,7 @@ import * as events from './events.mjs'; import * as graphics from '../graphics/index.mjs'; import * as inventory from './inventory.mjs'; import * as audio from './audio.mjs'; +import * as world from '../world/index.mjs'; import {playerShip} from '../world/index.mjs'; import {state} from './index.mjs'; @@ -19,7 +20,9 @@ export const mapping = { toggleMusic: 'KeyM', togglePause: 'KeyP', zoomIn: 'KeyZ', - zoomOut: 'KeyX' + zoomOut: 'KeyX', + increaseSpeed: 'Period', + decreaseSpeed: 'Comma', }; let held, pressed; @@ -52,6 +55,14 @@ export function tick() { if (pressed[mapping.togglePause] && !state.gameOver) { events.togglePause(); } + + if (pressed[mapping.increaseSpeed]) { + world.increaseSpeed(); + } + + if (pressed[mapping.decreaseSpeed]) { + world.decreaseSpeed(); + } } if (state.gameOver) { diff --git a/js/game/edit.mjs b/js/game/edit.mjs index 4270154..d7564e0 100644 --- a/js/game/edit.mjs +++ b/js/game/edit.mjs @@ -29,8 +29,12 @@ export function init() { message = ''; adjustSize(); + adjustGraphics(); +} + +function adjustGraphics() { let neededZoom = graphics.canvas.width / (Math.max(width, height) + 10); - graphics.changePerspective('planet', 0, -5); + graphics.changePerspective('planet', 0, -3); graphics.setZoom(neededZoom); } @@ -62,6 +66,9 @@ export function end() { let [dx, dy] = [nx - ox, ny - oy]; ship.x -= dx; ship.y -= dy; + const [rdx, rdy] = ship.rotateVector(dx, dy); + ship.x -= rdx; + ship.y -= rdy; } return result; @@ -73,6 +80,7 @@ function getAttributes() { let rotation = 0; let mass = 0; let thrust = 0; + let computation = 0; tiles.forEach(t => { if (t.type === null) return; @@ -81,12 +89,15 @@ function getAttributes() { } else if (t.type === 'capsule') { rotation += t.module.rotation; cargo += t.module.capacity; + computation += t.module.computation; } else if (t.type === 'thruster') { thrust += t.module.thrust; } else if (t.type === 'gyroscope') { rotation += t.module.rotation; } else if (t.type === 'cargo') { cargo += t.module.capacity; + } else if (t.type === 'nafivation') { + computation += t.module.computation; } mass += t.module.mass; }); @@ -96,7 +107,8 @@ function getAttributes() { 'Thrust/mass ratio: ' + (thrust / Math.max(mass, 1)).toFixed(1) + '\n' + 'Rotation speed: ' + (rotation / Math.max(mass, 1) * 100).toFixed(1) + '\n' + - 'Cargo capacity: ' + cargo; + 'Cargo capacity: ' + cargo + '\n' + + 'Navigational computation: ' + computation; } export function validate() { diff --git a/js/game/events.mjs b/js/game/events.mjs index 21b8035..2875e2f 100644 --- a/js/game/events.mjs +++ b/js/game/events.mjs @@ -187,7 +187,7 @@ export function collectItem(type, id, name) { notify('Collected fuel: +10'); return true; } else { - if (inventory.usedSpace > inventory.capacity) { + if (inventory.usedSpace >= inventory.capacity) { notify('No space left in inventory', 60); return false; } diff --git a/js/game/index.mjs b/js/game/index.mjs index 65ff12e..0ea70cf 100644 --- a/js/game/index.mjs +++ b/js/game/index.mjs @@ -57,16 +57,9 @@ function loop(fn, fps = 60) { let interval = 1000 / fps; (function loop(time) { + fn(); + requestAnimationFrame(loop); - - // again, Date.now() if it's available - let now = Date.now(); - let delta = now - then; - - if (delta > interval) { - then = now - (delta % interval); - fn(); - } })(0); }; diff --git a/js/graphics/background.mjs b/js/graphics/background.mjs index 8e4f9e7..38dc3b9 100644 --- a/js/graphics/background.mjs +++ b/js/graphics/background.mjs @@ -13,10 +13,9 @@ function init() { export function render(angle) { if (patterns === null) init(); - - renderLayer(patterns.back, 0.3, 1, angle); - renderLayer(patterns.middle, 0.5, 0.3, angle); - //renderLayer(patterns.front, 0.7, 0.3, angle); + // renderLayer(patterns.back, 0.3, 1, angle); + // renderLayer(patterns.middle, 0.5, 0.3, angle); + // renderLayer(patterns.front, 0.7, 0.3, angle); } function renderLayer(pattern, speed = 1, scale = 1, angle = 0) { diff --git a/js/graphics/gui.mjs b/js/graphics/gui.mjs index 44c83fc..67a6b13 100644 --- a/js/graphics/gui.mjs +++ b/js/graphics/gui.mjs @@ -80,7 +80,7 @@ function renderButton(element) { context.textAlign = 'center'; context.textBaseline = 'middle'; context.fillStyle = '#fff'; - context.font = '12pt Consolas'; + context.font = '12pt Courier New'; context.fillText(element.text, ...element.center); context.globalAlpha = 1; @@ -117,7 +117,7 @@ function renderItemButton(element) { context.textAlign = 'right'; context.textBaseline = 'bottom'; context.fillStyle = '#fff'; - context.font = 'bold 10pt Consolas'; + context.font = 'bold 10pt Courier New'; let [ex, ey] = element.end; context.fillText('x' + element.quantity, ex - 2, ey - 2); } diff --git a/js/graphics/index.mjs b/js/graphics/index.mjs index 1cc6d5f..f94f44a 100644 --- a/js/graphics/index.mjs +++ b/js/graphics/index.mjs @@ -19,14 +19,17 @@ export function init() { tempCanvas = document.querySelector('#temp'); tempContext = tempCanvas.getContext('2d'); - canvas.width = 600; - canvas.height = 600; + canvas.width = window.innerWidth; + canvas.height = window.innerHeight; + + canvas.style.width = canvas.width + 'px'; + canvas.style.height = canvas.height + 'px'; perspective = new Perspective(); context.fillStyle = '#000'; context.fillRect(0, 0, canvas.width, canvas.height); - context.font = '36px Consolas'; + context.font = '36px Courier New'; context.textAlign = 'center'; context.textBaseline = 'middle'; context.fillStyle = '#fff'; @@ -54,7 +57,7 @@ export function render() { } export function getVisibleSectors() { - return world.getContainedSectors(...perspective.bounds); + // return world.getContainedSectors(...perspective.bounds); } export function changePerspective(rotationMode, shiftX = 0, shiftY = 0) { diff --git a/js/graphics/world.mjs b/js/graphics/world.mjs index 941c44e..532be54 100644 --- a/js/graphics/world.mjs +++ b/js/graphics/world.mjs @@ -1,15 +1,15 @@ -import {canvas, context} from './index.mjs'; +import { canvas, context } from './index.mjs'; import * as graphics from './index.mjs'; -import {images as assets} from '../assets.mjs'; +import { images as assets } from '../assets.mjs'; import * as world from '../world/index.mjs'; -import {state} from '../game/index.mjs'; +import { state } from '../game/index.mjs'; export function render() { - world.particles.forEach(renderParticle); - world.celestials.forEach(renderCelestial); - if (graphics.trace) world.tracers.forEach(renderTracer); - world.ships.forEach(renderShip); - world.entities.forEach(renderEntity); + for (particle of world.particles) renderParticle(particle); + for (celestial of world.celestials) if (isVisible(celestial)) renderCelestial(celestial); + if (graphics.trace) for (tracer of world.tracers) renderTracer(tracer); + for (ship of world.ships) renderShip(ship); + for (entity of world.entities) if (isVisible(entity)) renderEntity(entity); /* if (typeof window.q === 'undefined') window.q = []; @@ -20,6 +20,16 @@ export function render() { */ } +function isVisible(body) { + const [bx, by] = body.com; + const [px, py] = [graphics.perspective.x, graphics.perspective.y]; + const [, , w, h] = graphics.perspective.bounds; + const [centerX, centerY] = [px, py]; + const margin = 1000; + return bx > centerX - margin && bx < centerX + margin && + by > centerY - margin && by < centerY + margin; +} + function renderParticle(particle) { context.fillStyle = particle.color; context.fillRect(...particle.com, particle.size, particle.size); @@ -64,7 +74,7 @@ function renderShip(ship) { const celestialImages = { green: Object.values(assets.celestials.green) -} +}; function renderCelestial(cel) { context.drawImage(cel.image, cel.x, cel.y, diff --git a/js/gui/modules.mjs b/js/gui/modules.mjs index b77bb3d..67ba050 100644 --- a/js/gui/modules.mjs +++ b/js/gui/modules.mjs @@ -132,6 +132,20 @@ export function game() { ship.maxFuel.toFixed(1); }; + let speed = new GuiText('', 0, 0, 0, 0, { + size: 14, + align: 'right', + valign: 'bottom', + + }); + shadow.append(speed); + speed.posRelative({x: 1, y: 1}); + speed.y -= 30; + speed.x -= 10; + speed.tick = () => { + speed.text = 'Speed: ' + world.speed.toFixed(1) + 'x'; + }; + let score = new GuiText('', 0, 0, 0, 0, { size: 14, align: 'left', diff --git a/js/gui/text.mjs b/js/gui/text.mjs index bdc6eb1..2cadfe6 100644 --- a/js/gui/text.mjs +++ b/js/gui/text.mjs @@ -16,7 +16,7 @@ export default class GuiText extends GuiElement { this.color = color; this.text = text; this.spacing = size * 1.2; - this.font = size + 'px Consolas'; + this.font = size + 'px Courier New'; this.align = align; this.valign = valign; } diff --git a/js/input.mjs b/js/input.mjs index f72694e..3ca77a3 100644 --- a/js/input.mjs +++ b/js/input.mjs @@ -45,7 +45,7 @@ export function init() { window.addEventListener('wheel', event => { mouse.scroll = event.deltaY; - event.preventDefault(); + // event.preventDefault(); }); window.addEventListener('contextmenu', event => { diff --git a/js/world/body.mjs b/js/world/body.mjs index d45f3ef..86d126c 100644 --- a/js/world/body.mjs +++ b/js/world/body.mjs @@ -72,13 +72,15 @@ export default class Body { } tickGravity(bodies, speed = 1) { - bodies.forEach(b => { - let force = b.mass / (this.distanceTo(b) ** 2) * G; - let [[ax, ay], [bx, by]] = [this.com, b.com]; + for (let body of bodies) { + const distanceSquared = this.distanceToSquared(body); + if (distanceSquared > (1000 ** 2)) continue; + let force = body.mass / distanceSquared * G; + let [[ax, ay], [bx, by]] = [this.com, body.com]; let angle = Math.atan2(by - ay, bx - ax); this.xvel += Math.cos(angle) * force * speed; this.yvel += Math.sin(angle) * force * speed; - }); + } } distanceTo(body) { @@ -87,6 +89,12 @@ export default class Body { ((by - ay) ** 2)), 1); } + distanceToSquared(body) { + let [[ax, ay], [bx, by]] = [this.com, body.com]; + return Math.max(((bx - ax) ** 2) + + ((by - ay) ** 2), 1); + } + angleTo(ax, ay, bx, by) { return Math.atan2(by - ay, bx - ax); } diff --git a/js/world/celestial.mjs b/js/world/celestial.mjs index beafa4e..0bfe0c7 100644 --- a/js/world/celestial.mjs +++ b/js/world/celestial.mjs @@ -1,5 +1,7 @@ +import {tempCanvas, tempContext} from '../graphics/index.mjs'; import {images as assets} from '../assets.mjs'; import Body from './body.mjs'; +import { PLANET_IMAGE_SIZE } from '../consts.mjs'; export default class Celestial extends Body { constructor(x, y, radius, { @@ -11,8 +13,15 @@ export default class Celestial extends Body { this.radius = radius; this.type = type; - let imageArr = Object.values(assets.celestials[this.type]); - this.image = imageArr[Math.random() * imageArr.length | 0]; + const imageArr = Object.values(assets.celestials[this.type]); + const svgImage = imageArr[Math.random() * imageArr.length | 0]; + tempCanvas.width = PLANET_IMAGE_SIZE; + tempCanvas.height = PLANET_IMAGE_SIZE; + tempContext.clearRect(0, 0, PLANET_IMAGE_SIZE, PLANET_IMAGE_SIZE); + tempContext.drawImage(svgImage, 0, 0, PLANET_IMAGE_SIZE, PLANET_IMAGE_SIZE); + this.image = new Image(); + this.image.src = tempCanvas.toDataURL(); + // this.image = tempContext.getImageData(0, 0, PLANET_IMAGE_SIZE, PLANET_IMAGE_SIZE); } get com() { diff --git a/js/world/index.mjs b/js/world/index.mjs index 902498d..3c4504c 100644 --- a/js/world/index.mjs +++ b/js/world/index.mjs @@ -9,6 +9,8 @@ export const tracers = new Set(); export let playerShip = null; +export let speed = 1; + export function setPlayerShip(ship) { playerShip = ship; } @@ -33,11 +35,22 @@ export function remove(object) { celestials.delete(object); } -export function tick() { - particles.forEach(p => p.tick()); - celestials.forEach(c => c.tick()); - entities.forEach(e => e.tick()); - ships.forEach(s => s.tick()); - if (graphics.trace) tracers.forEach(t => t.tick()); - spawn.tick(); +export function increaseSpeed() { + if (speed < 5) speed += 1; +} + +export function decreaseSpeed() { + if (speed > 1) speed -= 1; +} + +export function tick() { + for (let i = 0; i < speed; i++) { + particles.forEach(p => p.tick()); + celestials.forEach(c => c.tick()); + entities.forEach(e => e.tick()); + ships.forEach(s => s.tick()); + } + + spawn.tick(); + if (graphics.trace) tracers.forEach(t => t.tick()); } diff --git a/js/world/ship.mjs b/js/world/ship.mjs index e10b7e9..b975b2a 100644 --- a/js/world/ship.mjs +++ b/js/world/ship.mjs @@ -22,6 +22,7 @@ export default class Ship extends Body { this.rotationPower = 0; this.cargoCapacity = 0; this.thrust = 0; + this.computation = 0; this.crashed = false; this.timeWithoutFuel = 0; } @@ -113,6 +114,7 @@ export default class Ship extends Body { this.rotationPower = 0; this.cargoCapacity = 0; this.thrust = 0; + this.computation = 0; this.modules.forEach(m => { if (m.type === 'fuel') { @@ -120,12 +122,15 @@ export default class Ship extends Body { } else if (m.type === 'capsule') { this.rotationPower += m.data.rotation; this.cargoCapacity += m.data.capacity; + this.computation += m.data.computation; } else if (m.type === 'thruster') { this.thrust += m.data.thrust; } else if (m.type === 'gyroscope') { this.rotationPower += m.data.rotation; } else if (m.type === 'cargo') { this.cargoCapacity += m.data.capacity; + } else if (m.type === 'navigation') { + this.computation += m.data.computation; } }); } diff --git a/js/world/tracer.mjs b/js/world/tracer.mjs index d55c64f..704cb53 100644 --- a/js/world/tracer.mjs +++ b/js/world/tracer.mjs @@ -40,7 +40,7 @@ export default class Tracer extends Body { } tick() { - this.run(100); + this.run(this.ship.computation); } tickPath(speed) { diff --git a/rollup b/rollup index 992f786..a39094c 100755 --- a/rollup +++ b/rollup @@ -1,2 +1,2 @@ #!/bin/bash -rollup js/index.mjs --o dist/improcket.min.js -m --silent --f es --watch +npx rollup js/index.mjs --o dist/improcket.min.js -m --f es --watch