Add ship movement
This commit is contained in:
parent
09b3df649c
commit
4959519f39
15 changed files with 278 additions and 77 deletions
|
@ -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: {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
25
js/game/control.mjs
Normal file
25
js/game/control.mjs
Normal file
|
@ -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 });
|
||||
}
|
||||
}
|
|
@ -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');
|
||||
|
|
|
@ -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();
|
||||
|
|
7
js/game/player.mjs
Normal file
7
js/game/player.mjs
Normal file
|
@ -0,0 +1,7 @@
|
|||
import * as world from '../world/index.mjs';
|
||||
|
||||
export let ship;
|
||||
|
||||
export function init() {
|
||||
ship = world.playerShip;
|
||||
}
|
|
@ -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 = {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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'
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue