diff --git a/dist/img/celestials/green_0.svg b/dist/img/celestials/green_0.svg
index f0357e2..6d07600 100644
--- a/dist/img/celestials/green_0.svg
+++ b/dist/img/celestials/green_0.svg
@@ -25,9 +25,9 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="0.7"
- inkscape:cx="356.31215"
- inkscape:cy="358.21593"
+ inkscape:zoom="1.4"
+ inkscape:cx="249.24893"
+ inkscape:cy="380.139"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
@@ -44,7 +44,7 @@
image/svg+xml
-
+
@@ -54,52 +54,52 @@
id="layer1"
transform="translate(25.294481,-146.20324)">
-
+ id="g918"
+ style="stroke-width:0.5;stroke-miterlimit:4;stroke-dasharray:none">
+ style="stroke-width:0.5;stroke-miterlimit:4;stroke-dasharray:none">
+
diff --git a/dist/img/modules/light_thruster.svg b/dist/img/modules/light_thruster.svg
index 53f0088..1c0bf3b 100644
--- a/dist/img/modules/light_thruster.svg
+++ b/dist/img/modules/light_thruster.svg
@@ -25,11 +25,11 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="2.8"
- inkscape:cx="54.726513"
- inkscape:cy="10.343454"
+ inkscape:zoom="7.9195959"
+ inkscape:cx="59.772356"
+ inkscape:cy="7.3948782"
inkscape:document-units="mm"
- inkscape:current-layer="layer1"
+ inkscape:current-layer="g828"
showgrid="true"
inkscape:window-width="1366"
inkscape:window-height="714"
@@ -60,41 +60,44 @@
inkscape:groupmode="layer"
id="layer1"
transform="translate(-85.489576,-133.78125)">
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/dist/img/modules/light_thruster_on.svg b/dist/img/modules/light_thruster_on.svg
new file mode 100644
index 0000000..89ec80c
--- /dev/null
+++ b/dist/img/modules/light_thruster_on.svg
@@ -0,0 +1,103 @@
+
+
+
+
diff --git a/js/assets.mjs b/js/assets.mjs
index 18120a9..16da8cd 100644
--- a/js/assets.mjs
+++ b/js/assets.mjs
@@ -11,7 +11,10 @@ export const images = {
small: 'modules/small_fuel_tank.svg'
},
thruster: {
- light: 'modules/light_thruster.svg'
+ light: {
+ off: 'modules/light_thruster.svg',
+ on: 'modules/light_thruster_on.svg',
+ }
}
},
celestials: {
diff --git a/js/consts.mjs b/js/consts.mjs
index 6918296..5f9fa41 100644
--- a/js/consts.mjs
+++ b/js/consts.mjs
@@ -13,6 +13,6 @@ export const STAR_DENSITY = (SECTOR_SIZE ** 2) / 10000;
export const GRAVITATIONAL_CONSTANT = 0.01;
// Perspective constraints. Higher zoom value = closer.
export const MIN_ZOOM = 1;
-export const MAX_ZOOM = 30;
+export const MAX_ZOOM = 100;
export const DEFAULT_ZOOM = 10;
export const ZOOM_SPEED = 0.01;
diff --git a/js/data.mjs b/js/data.mjs
index 85039cc..734e948 100644
--- a/js/data.mjs
+++ b/js/data.mjs
@@ -5,6 +5,7 @@ export const modules = {
tooltip: 'A small, simple capsule. Provides just enough ' +
'rotational power for a small rocket.',
type: 'capsule',
+ id: 'small',
mass: 2,
rotation: 0.1
}
@@ -14,6 +15,7 @@ export const modules = {
name: 'Small Fuel Tank',
tooltip: 'A small flimsy tank with enough fuel for a short trip.',
type: 'fuel',
+ id: 'small',
mass: 1,
capacity: 3
}
@@ -24,6 +26,7 @@ export const modules = {
tooltip: 'Powerful enough to lift a small ship, but not much ' +
'more. Not very efficient.',
type: 'thruster',
+ id: 'light',
mass: 2,
thrust: 10,
isp: 200
diff --git a/js/game/control.mjs b/js/game/control.mjs
new file mode 100644
index 0000000..0267289
--- /dev/null
+++ b/js/game/control.mjs
@@ -0,0 +1,25 @@
+import * as input from '../input.mjs';
+import * as player from './player.mjs';
+
+export const mapping = {
+ thrust: 'KeyW',
+ left: 'KeyA',
+ right: 'KeyD'
+};
+
+export function tick() {
+ let held = input.keyCode.held;
+ let pressed = input.keyCode.pressed;
+
+ if (held[mapping.thrust]) {
+ player.ship.applyThrust({ forward: 1 });
+ }
+
+ if (held[mapping.left]) {
+ player.ship.applyThrust({ turnLeft: 1 });
+ }
+
+ if (held[mapping.right]) {
+ player.ship.applyThrust({ turnRight: 1 });
+ }
+}
diff --git a/js/game/events.mjs b/js/game/events.mjs
index 11a84c0..a3ba9f1 100644
--- a/js/game/events.mjs
+++ b/js/game/events.mjs
@@ -1,6 +1,7 @@
import * as game from './index.mjs';
import * as graphics from '../graphics/index.mjs';
import * as world from '../world/index.mjs';
+import * as player from './player.mjs';
export function startGame() {
game.changeView('game');
diff --git a/js/game/index.mjs b/js/game/index.mjs
index e614f8e..dc0cffb 100644
--- a/js/game/index.mjs
+++ b/js/game/index.mjs
@@ -4,6 +4,8 @@ import * as assets from '../assets.mjs';
import * as input from '../input.mjs';
import * as world from '../world/index.mjs';
import * as events from './events.mjs';
+import * as control from './control.mjs';
+import * as player from './player.mjs';
export let state;
@@ -35,11 +37,16 @@ export function changeView(view) {
if (view == 'game') {
world.init();
+ player.init();
}
}
async function tick() {
- if (state.view == 'game') world.tick();
+ if (state.view == 'game') {
+ world.tick();
+ control.tick();
+ }
+
gui.tick();
graphics.render();
input.tick();
diff --git a/js/game/player.mjs b/js/game/player.mjs
new file mode 100644
index 0000000..aeec9e0
--- /dev/null
+++ b/js/game/player.mjs
@@ -0,0 +1,7 @@
+import * as world from '../world/index.mjs';
+
+export let ship;
+
+export function init() {
+ ship = world.playerShip;
+}
diff --git a/js/graphics/world.mjs b/js/graphics/world.mjs
index 764cd7d..748b5b9 100644
--- a/js/graphics/world.mjs
+++ b/js/graphics/world.mjs
@@ -8,15 +8,14 @@ export function render() {
}
function renderShip(ship) {
- context.fillStyle = 'red';
- //context.fillRect(ship.x, ship.y, 10, 10);
- let size = 1;
- context.drawImage(assets.modules.capsule.small, ship.x, ship.y,
- size, size);
- context.drawImage(assets.modules.fuel.small, ship.x, ship.y + size,
- size, size);
- context.drawImage(assets.modules.thruster.light, ship.x,
- ship.y + size * 2, size, size);
+ context.save();
+ context.translate(ship.x, ship.y);
+ context.rotate(ship.r);
+ let [cx, cy] = ship.com;
+ ship.modules.forEach(m => {
+ context.drawImage(m.currentImage, m.x - cx, m.y - cy, 1, 1);
+ });
+ context.restore();
}
const celestialImages = {
diff --git a/js/world/body.mjs b/js/world/body.mjs
index d759eaa..09e5c72 100644
--- a/js/world/body.mjs
+++ b/js/world/body.mjs
@@ -8,12 +8,15 @@ export default class Body {
this.xvel = 0;
this.yvel = 0;
this.rvel = 0;
+ this.rfriction = 0.9;
this.mass = mass;
}
tickMotion() {
this.x += this.xvel;
this.y += this.yvel;
+ this.r += this.rvel;
+ this.rvel *= this.rfriction;
}
tickGravity(bodies) {
@@ -40,4 +43,10 @@ export default class Body {
this.xvel = 0;
this.yvel = 0;
}
+
+ applyDirectionalForce(x, y, r) {
+ this.xvel += (x * Math.cos(this.r) - y * Math.sin(this.r)) / this.mass;
+ this.yvel += (y * Math.cos(this.r) - x * Math.sin(this.r)) / this.mass;
+ this.rvel += r / this.mass;
+ }
}
diff --git a/js/world/module.mjs b/js/world/module.mjs
index 324ea29..053fbfd 100644
--- a/js/world/module.mjs
+++ b/js/world/module.mjs
@@ -1,7 +1,10 @@
+import {images as assets} from '../assets.mjs';
+
export default class Module {
constructor(x, y, {
name = 'Unnamed Module',
type = 'block',
+ id = 'unknown',
mass = 1,
// Fuel
filled = false,
@@ -13,7 +16,31 @@ export default class Module {
this.name = name;
this.type = type;
this.mass = mass;
+ this.id = id;
+ this.images = assets.modules[this.type][this.id];
// Fuel
- this.fuel = filled ? fuelCapacity : 0;
+ if (this.type == 'fuel') {
+ this.fuel = filled ? fuelCapacity : 0;
+ } else if (this.type == 'thruster') {
+ this.power = 0;
+ }
+ }
+
+ reset() {
+ if (this.type == 'thruster') {
+ this.power = 0;
+ }
+ }
+
+ get currentImage() {
+ if (this.type == 'thruster') {
+ return this.power > 0 ? this.images.on : this.images.off;
+ } else {
+ return this.images;
+ }
+ }
+
+ get com() {
+ return [this.x + 0.5, this.y + 0.5];
}
}
diff --git a/js/world/ship.mjs b/js/world/ship.mjs
index 046544f..3eb00be 100644
--- a/js/world/ship.mjs
+++ b/js/world/ship.mjs
@@ -14,6 +14,7 @@ export default class Ship extends Body {
this.tickMotion();
this.tickGravity(world.celestials);
this.resolveCollisions();
+ this.modules.forEach(m => m.reset());
}
addModule(x, y, properties, options) {
@@ -29,11 +30,12 @@ export default class Ship extends Body {
refreshShape() {
let points = [];
- this.modules.forEach(m => points.push([m.x, m.y, m.mass]));
+ this.modules.forEach(m => points.push([...m.com, m.mass]));
this.mass = points.reduce((a, [,,b]) => a + b, 0);
- this.com = points.reduce(([ax, ay], b) =>
- [ax + b.x * b.mass, ay + b.y * b.mass], [0, 0])
+ this.com = points.reduce(([ax, ay], [bx, by, bm]) =>
+ [ax + bx * bm, ay + by * bm], [0, 0])
.map(x => x / this.mass);
+ window.q = points;
}
resolveCollisions() {
@@ -45,4 +47,16 @@ export default class Ship extends Body {
}
})
}
+
+ applyThrust({ forward = 0, left = 0, right = 0, back = 0,
+ turnLeft = 0, turnRight = 0}) {
+ let turnForce = (turnRight - turnLeft) / 20;
+ this.applyDirectionalForce(0, -forward / 30, turnForce);
+
+ this.modules.forEach(m => {
+ if (m.type !== 'thruster') return;
+ m.power = forward;
+ });
+
+ }
}
diff --git a/js/world/spawn.mjs b/js/world/spawn.mjs
index 6d98dca..92cfa3f 100644
--- a/js/world/spawn.mjs
+++ b/js/world/spawn.mjs
@@ -5,7 +5,7 @@ import {modules} from '../data.mjs';
import * as world from './index.mjs';
export function player() {
- let ship = new Ship(0, 0);
+ let ship = new Ship(0, -45);
ship.addModule(0, 0, modules.capsule.small);
ship.addModule(0, 1, modules.fuel.small, { filled: true });
ship.addModule(0, 2, modules.thruster.light);
@@ -15,7 +15,7 @@ export function player() {
}
export function startPlanet() {
- return celestial(-40, 10, 40, {
+ return celestial(0, 0, 40, {
density: 1,
type: 'green'
});