Add start of ship rendering
This commit is contained in:
parent
4a253b0184
commit
704c82838a
15 changed files with 199 additions and 13 deletions
|
@ -7,3 +7,5 @@
|
||||||
export const SECTOR_SIZE = 512;
|
export const SECTOR_SIZE = 512;
|
||||||
// Star count per sector.
|
// Star count per sector.
|
||||||
export const STAR_DENSITY = (SECTOR_SIZE ** 2) / 10000;
|
export const STAR_DENSITY = (SECTOR_SIZE ** 2) / 10000;
|
||||||
|
// G, G-boy, The big G, Mr. G, g's big brother, G-dog
|
||||||
|
export const GRAVITATIONAL_CONSTANT = 0.01;
|
||||||
|
|
32
js/data.mjs
Normal file
32
js/data.mjs
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
export const modules = {
|
||||||
|
capsule: {
|
||||||
|
small: {
|
||||||
|
name: 'Small Capsule',
|
||||||
|
tooltip: 'A small, simple capsule. Provides just enough ' +
|
||||||
|
'rotational power for a small rocket.',
|
||||||
|
type: 'capsule',
|
||||||
|
mass: 2,
|
||||||
|
rotation: 0.1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fuel: {
|
||||||
|
small: {
|
||||||
|
name: 'Small Fuel Tank',
|
||||||
|
tooltip: 'A small flimsy tank with enough fuel for a short trip.',
|
||||||
|
type: 'fuel',
|
||||||
|
mass: 1,
|
||||||
|
capacity: 3
|
||||||
|
}
|
||||||
|
},
|
||||||
|
thruster: {
|
||||||
|
light: {
|
||||||
|
name: 'Light Main Thruster',
|
||||||
|
tooltip: 'Powerful enough to lift a small ship, but not much ' +
|
||||||
|
'more. Not very efficient.',
|
||||||
|
type: 'thruster',
|
||||||
|
mass: 2,
|
||||||
|
thrust: 10,
|
||||||
|
isp: 200
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
import * as game from './index.mjs';
|
import * as game from './index.mjs';
|
||||||
|
|
||||||
export function startGame() {
|
export function startGame() {
|
||||||
console.log('started');
|
game.changeView('game');
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,15 +2,15 @@ import * as graphics from '../graphics/index.mjs';
|
||||||
import * as gui from '../gui/index.mjs';
|
import * as gui from '../gui/index.mjs';
|
||||||
import * as assets from '../assets.mjs';
|
import * as assets from '../assets.mjs';
|
||||||
import * as input from '../input.mjs';
|
import * as input from '../input.mjs';
|
||||||
|
import * as world from '../world/index.mjs';
|
||||||
|
import * as events from './events.mjs';
|
||||||
|
|
||||||
export let game;
|
export let state;
|
||||||
|
|
||||||
export async function init() {
|
export async function init() {
|
||||||
game = {
|
state = {
|
||||||
state: {
|
view: 'menu',
|
||||||
room: 'menu',
|
paused: false
|
||||||
paused: false
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
graphics.init();
|
graphics.init();
|
||||||
|
@ -18,6 +18,8 @@ export async function init() {
|
||||||
gui.init();
|
gui.init();
|
||||||
input.init();
|
input.init();
|
||||||
|
|
||||||
|
//events.startGame();
|
||||||
|
|
||||||
// Recursive `requestAnimationFrame` can cause problems with Parcel.
|
// Recursive `requestAnimationFrame` can cause problems with Parcel.
|
||||||
while(true) {
|
while(true) {
|
||||||
await tick();
|
await tick();
|
||||||
|
@ -25,7 +27,17 @@ export async function init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function changeView(view) {
|
||||||
|
state.view = view;
|
||||||
|
gui.changeView(view);
|
||||||
|
|
||||||
|
if (view == 'game') {
|
||||||
|
world.init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function tick() {
|
async function tick() {
|
||||||
|
if (state.view == 'game') world.tick();
|
||||||
gui.tick();
|
gui.tick();
|
||||||
graphics.render();
|
graphics.render();
|
||||||
input.tick();
|
input.tick();
|
||||||
|
|
|
@ -3,6 +3,7 @@ import {getContainedSectors} from '../world/index.mjs';
|
||||||
import * as background from './background.mjs';
|
import * as background from './background.mjs';
|
||||||
import * as gui from './gui.mjs';
|
import * as gui from './gui.mjs';
|
||||||
import * as draw from './draw.mjs';
|
import * as draw from './draw.mjs';
|
||||||
|
import * as ship from './ship.mjs';
|
||||||
|
|
||||||
export let canvas, context, tempCanvas, tempContext;
|
export let canvas, context, tempCanvas, tempContext;
|
||||||
export let view;
|
export let view;
|
||||||
|
@ -36,6 +37,7 @@ export function render() {
|
||||||
// TODO: Translate canvas.
|
// TODO: Translate canvas.
|
||||||
|
|
||||||
background.render();
|
background.render();
|
||||||
|
ship.render();
|
||||||
|
|
||||||
context.restore();
|
context.restore();
|
||||||
|
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
import {canvas, context} from './index.mjs';
|
|
||||||
import * as assets from '../assets.mjs';
|
|
||||||
|
|
||||||
export function render() {
|
|
||||||
|
|
||||||
}
|
|
12
js/graphics/ship.mjs
Normal file
12
js/graphics/ship.mjs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import {canvas, context} from './index.mjs';
|
||||||
|
import * as assets from '../assets.mjs';
|
||||||
|
import * as world from '../world/index.mjs';
|
||||||
|
|
||||||
|
export function render() {
|
||||||
|
world.ships.forEach(renderShip);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderShip(ship) {
|
||||||
|
context.fillStyle = 'red';
|
||||||
|
context.fillRect(ship.x, ship.y, 10, 10);
|
||||||
|
}
|
|
@ -20,6 +20,10 @@ export function changeView(view) {
|
||||||
if (view == 'title') {
|
if (view == 'title') {
|
||||||
root.append(modules.title());
|
root.append(modules.title());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (view == 'game') {
|
||||||
|
root.append(modules.game());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function measureText(msg, font) {
|
export function measureText(msg, font) {
|
||||||
|
|
|
@ -33,3 +33,9 @@ export function title() {
|
||||||
|
|
||||||
return shadow;
|
return shadow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function game() {
|
||||||
|
let shadow = root();
|
||||||
|
|
||||||
|
return shadow;
|
||||||
|
}
|
||||||
|
|
26
js/world/body.mjs
Normal file
26
js/world/body.mjs
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import {GRAVITATIONAL_CONSTANT as G} from '../consts.mjs';
|
||||||
|
|
||||||
|
export default class Body {
|
||||||
|
constructor(x, y, mass) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.r = 0;
|
||||||
|
this.xvel = 0;
|
||||||
|
this.yvel = 0;
|
||||||
|
this.rvel = 0;
|
||||||
|
this.mass = mass;
|
||||||
|
}
|
||||||
|
|
||||||
|
tickGravity(bodies) {
|
||||||
|
bodies.forEach(b => {
|
||||||
|
let force = b.mass / this.mass / (distanceTo(b) ** 2) * G;
|
||||||
|
let angle = Math.atan2(b.y - this.y, b.x - this.x);
|
||||||
|
this.xvel += Math.cos(angle) * force;
|
||||||
|
this.yvel += Math.sin(angle) * force;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
distanceTo(body) {
|
||||||
|
return Math.sqrt(((body.x - this.x) ** 2) + ((body.y - this.y) ** 2));
|
||||||
|
}
|
||||||
|
}
|
10
js/world/celestial.mjs
Normal file
10
js/world/celestial.mjs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import Body from './body.mjs';
|
||||||
|
|
||||||
|
export default class Celestial extends Body {
|
||||||
|
constructor(x, y, radius, {
|
||||||
|
density = 1,
|
||||||
|
mass = (radius ** 2) * density
|
||||||
|
}) {
|
||||||
|
super(x, y, mass);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,26 @@
|
||||||
import * as sector from './sector.mjs';
|
import * as sector from './sector.mjs';
|
||||||
|
import * as spawn from './spawn.mjs';
|
||||||
|
|
||||||
export {getSectorFromWorld, getContainedSectors} from './sector.mjs';
|
export {getSectorFromWorld, getContainedSectors} from './sector.mjs';
|
||||||
|
|
||||||
|
export const entities = new Set();
|
||||||
|
export const celestials = new Set();
|
||||||
|
export const ships = new Set();
|
||||||
|
|
||||||
|
export let playerShip = null;
|
||||||
|
|
||||||
|
export function setPlayerShip(ship) {
|
||||||
|
playerShip = ship;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function init() {
|
||||||
|
entities.clear();
|
||||||
|
celestials.clear();
|
||||||
|
spawn.player();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function tick() {
|
||||||
|
celestials.forEach(c => c.tick());
|
||||||
|
entities.forEach(e => e.tick());
|
||||||
|
ships.forEach(s => s.tick());
|
||||||
|
}
|
||||||
|
|
15
js/world/module.mjs
Normal file
15
js/world/module.mjs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
export default class Module {
|
||||||
|
constructor(x, y, {
|
||||||
|
name = 'Unnamed Module',
|
||||||
|
type = 'block',
|
||||||
|
mass = 1,
|
||||||
|
...properties
|
||||||
|
}) {
|
||||||
|
this.x = x;
|
||||||
|
this.y = y;
|
||||||
|
this.name = name;
|
||||||
|
this.type = type;
|
||||||
|
this.mass = mass;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
35
js/world/ship.mjs
Normal file
35
js/world/ship.mjs
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import Module from './module.mjs';
|
||||||
|
import Body from './body.mjs';
|
||||||
|
|
||||||
|
export default class Ship extends Body {
|
||||||
|
constructor(x, y) {
|
||||||
|
super(x, y, 0);
|
||||||
|
|
||||||
|
this.com = [0, 0];
|
||||||
|
this.modules = new Set();
|
||||||
|
}
|
||||||
|
|
||||||
|
tick() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
addModule(x, y, properties, options) {
|
||||||
|
let module = new Module(x, y, {...properties, ...options});
|
||||||
|
this.modules.add(module);
|
||||||
|
this.refreshShape();
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteModule(module) {
|
||||||
|
this.modules.delete(module);
|
||||||
|
this.refreshShape();
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshShape() {
|
||||||
|
let points = [];
|
||||||
|
this.modules.forEach(m => points.push([m.x, m.y, 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])
|
||||||
|
.map(x => x / this.mass);
|
||||||
|
}
|
||||||
|
}
|
13
js/world/spawn.mjs
Normal file
13
js/world/spawn.mjs
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import Ship from './ship.mjs';
|
||||||
|
import Module from './module.mjs';
|
||||||
|
import {modules} from '../data.mjs';
|
||||||
|
import * as world from './index.mjs';
|
||||||
|
|
||||||
|
export function player() {
|
||||||
|
let ship = new Ship(0, 0);
|
||||||
|
ship.addModule(0, 0, modules.capsule.small);
|
||||||
|
ship.addModule(0, 1, modules.fuel.small, { filled: true });
|
||||||
|
ship.addModule(0, 2, modules.thruster.light);
|
||||||
|
world.ships.add(ship);
|
||||||
|
world.setPlayerShip(ship);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue