General improvements

I forgot what I actually changed. It may not even be playable, I just want to get this up there.
This commit is contained in:
Asraelite 2023-03-31 11:43:56 +02:00
parent 8a0bf0ada9
commit c73130e3ff
25 changed files with 584 additions and 274 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
.cache/
*.map
dist/improcket.min.js

BIN
dist/img/background_small.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

140
dist/img/modules/small_navigation.svg vendored Normal file
View file

@ -0,0 +1,140 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="22.166674mm"
height="22.16667mm"
viewBox="0 0 22.166674 22.16667"
version="1.1"
id="svg8"
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
sodipodi:docname="small_navigation.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs
id="defs2">
<linearGradient
id="linearGradient895"
inkscape:swatch="solid">
<stop
style="stop-color:#515151;stop-opacity:1;"
offset="0"
id="stop893" />
</linearGradient>
<linearGradient
gradientTransform="matrix(3.7795276,0,0,3.7795276,-358.11024,-520.62993)"
inkscape:collect="always"
xlink:href="#linearGradient895"
id="linearGradient897-2"
x1="94.75"
y1="140.23438"
x2="98.395836"
y2="140.23438"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="3.959798"
inkscape:cx="-3.9143411"
inkscape:cy="62.250651"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:window-width="1920"
inkscape:window-height="1028"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:showpageshadow="2"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1">
<inkscape:grid
type="xygrid"
id="grid815"
originx="-85.489575"
originy="-141.05208" />
</sodipodi:namedview>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-85.489576,-133.78125)">
<path
style="fill:#3d473d;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 105.83333,135.60417 0,18.52083 h -2.64583 l 0,-18.52083 z"
id="rect908-5-6-53-0-9-3-0-6-1-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
style="fill:#3d473d;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="M 89.958331,135.60417 V 154.125 h -2.64583 v -18.52083 z"
id="rect908-5-6-53-0-9-3-0-6-1-2-0"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
style="opacity:1;fill:#909f99;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="m 85.989583,134.28125 h 10.583332 10.583335 v 1.32292 h -2.64583 l -3.96875,3.96875 v 10.58333 l 3.96875,3.96875 h 2.64583 v 1.32292 H 85.989583 V 154.125 h 2.645835 l 3.96875,-3.96875 0,-10.58333 -3.96875,-3.96875 h -2.645835 z"
id="rect821"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccccccccccc" />
<circle
style="vector-effect:none;fill:#5c734d;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:fill markers stroke"
id="path15-6"
cy="144.86459"
cx="91.281258"
r="2.6458402" />
<circle
style="vector-effect:none;fill:#5c734d;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:fill markers stroke"
id="path15-6-7"
cy="144.86458"
cx="101.86459"
r="2.6458402" />
<path
style="fill:#3d473d;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 97.895834,147.51042 v 5.29167 h -2.645833 v -5.29167 z"
id="rect908-5-6-53-0-9-3-0-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
style="fill:#3d473d;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 97.895833,136.92708 v 5.29167 h -2.645832 v -5.29167 z"
id="rect908-5-6-53-0-9-3-0-6-1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
style="fill:#686868;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 101.86458,139.57292 0,10.58333 H 91.281255 l 10e-7,-10.58333 z"
id="rect908-5-6-53-0"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
style="fill:#607d63;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;paint-order:fill markers stroke"
d="m 100.54166,140.89584 v 7.9375 h -7.937493 l 10e-7,-7.9375 z"
id="rect908-5-6-53-0-9"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 6 KiB

500
dist/improcket.min.js vendored

File diff suppressed because it is too large Load diff

4
dist/styles.css vendored
View file

@ -13,8 +13,8 @@ body {
}
#main {
width: 600px;
height: 600px;
width: 1300px;
height: 900px;
margin: 50px auto;
border: 2px solid #111;
background-color: #fff;

View file

@ -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: {

View file

@ -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;

View file

@ -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',

View file

@ -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) {

View file

@ -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() {

View file

@ -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;
}

View file

@ -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);
};

View file

@ -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) {

View file

@ -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);
}

View file

@ -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) {

View file

@ -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,

View file

@ -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',

View file

@ -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;
}

View file

@ -45,7 +45,7 @@ export function init() {
window.addEventListener('wheel', event => {
mouse.scroll = event.deltaY;
event.preventDefault();
// event.preventDefault();
});
window.addEventListener('contextmenu', event => {

View file

@ -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);
}

View file

@ -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() {

View file

@ -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());
}

View file

@ -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;
}
});
}

View file

@ -40,7 +40,7 @@ export default class Tracer extends Body {
}
tick() {
this.run(100);
this.run(this.ship.computation);
}
tickPath(speed) {

2
rollup
View file

@ -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