Add zooming

This commit is contained in:
asraelite 2018-03-03 13:29:14 +00:00
parent 56a09f98c5
commit b02675f4fb
12 changed files with 156 additions and 29 deletions

View file

@ -13,6 +13,11 @@ export const images = {
thruster: { thruster: {
light: 'modules/light_thruster.svg' light: 'modules/light_thruster.svg'
} }
},
celestials: {
green: {
"0": 'celestials/green_0.svg'
}
} }
}; };

View file

@ -1,11 +1,18 @@
/* /*
* Constants that do not change during gameplay. * Constants that do not change during gameplay.
* This can kind of be treated like a configuration file, I guess. * This can kind of be treated like a configuration file, I guess.
*
* All le
*/ */
// Pixel length of sector. // Unit length of sector. Only for internal representation.
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 // G, G-boy, The big G, Mr. G, g's big brother, G-dog
export const GRAVITATIONAL_CONSTANT = 0.01; export const GRAVITATIONAL_CONSTANT = 0.01;
// Perspective constraints. Higher zoom value = closer.
export const MIN_ZOOM = 2;
export const MAX_ZOOM = 30;
export const DEFAULT_ZOOM = 10;
export const ZOOM_SPEED = 0.01;

View file

@ -1,5 +1,8 @@
import * as game from './index.mjs'; import * as game from './index.mjs';
import * as graphics from '../graphics/index.mjs';
import * as world from '../world/index.mjs';
export function startGame() { export function startGame() {
game.changeView('game'); game.changeView('game');
graphics.perspective.focusPlayer();
} }

View file

@ -18,7 +18,9 @@ export async function init() {
gui.init(); gui.init();
input.init(); input.init();
//events.startGame(); events.startGame();
//tick(); return;
// Recursive `requestAnimationFrame` can cause problems with Parcel. // Recursive `requestAnimationFrame` can cause problems with Parcel.
while(true) { while(true) {

View file

@ -1,12 +1,13 @@
import {game} from '../game/index.mjs';
import {getContainedSectors} from '../world/index.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'; import * as input from '../input.mjs';
import {render as renderWorld} from './world.mjs';
import {render as renderBackground} from './background.mjs';
import * as world from '../world/index.mjs';
import * as consts from '../consts.mjs';
export let canvas, context, tempCanvas, tempContext; export let canvas, context, tempCanvas, tempContext;
export let view; export let perspective;
export function init() { export function init() {
canvas = document.querySelector('#main'); canvas = document.querySelector('#main');
@ -17,12 +18,7 @@ export function init() {
canvas.width = 600; canvas.width = 600;
canvas.height = 600; canvas.height = 600;
view = { perspective = new Perspective();
bounds: [0, 0, canvas.width, canvas.height],
x: 0,
y: 0,
zoom: 1
}
draw.text('Loading...', canvas.width / 2, canvas.height / 2, draw.text('Loading...', canvas.width / 2, canvas.height / 2,
{ align: 'center', valign: 'middle' }); { align: 'center', valign: 'middle' });
@ -32,18 +28,84 @@ export function render() {
context.clearRect(0, 0, canvas.width, canvas.height); context.clearRect(0, 0, canvas.width, canvas.height);
context.fillStyle = '#000'; context.fillStyle = '#000';
context.fillRect(0, 0, canvas.width, canvas.height); context.fillRect(0, 0, canvas.width, canvas.height);
renderBackground();
context.save(); context.save();
perspective.tick();
// TODO: Translate canvas. perspective.transformCanvas();
renderWorld();
background.render();
ship.render();
context.restore(); context.restore();
gui.render(); gui.render();
} }
export function getVisibleSectors() { export function getVisibleSectors() {
return getContainedSectors(...view.bounds); return world.getContainedSectors(...perspective.bounds);
}
class Perspective {
constructor() {
this.x = 0;
this.y = 0;
this.bounds = [0, 0, canvas.width, canvas.height];
this.reset();
}
tick() {
if (input.mouse.scroll !== 0) {
this.zoomDelta(-input.mouse.scroll);
}
if (this.focus !== null) {
this.x = this.focus.x;
this.y = this.focus.y;
}
if (this.rotationFocus !== null) {
this.targetRotation = this.rotationFocus.r;
} else {
this.targetRotation = 0;
}
if (this.smoothRotation) {
this.rotation = (this.rotation * 0.9 + this.targetRotation * 0.1);
} else {
this.rotation = this.targetRotation;
}
}
reset() {
this.rotation = 0;
this.targetRotation = 0;
this.smoothRotation = false;
this.zoom = consts.DEFAULT_ZOOM;
this.focus = null;
this.rotationFocus = null;
}
focusPlayer() {
this.focus = world.playerShip;
this.rotationFocus = world.playerShip;
this.smoothRotation = false;
}
zoomDelta(delta) {
let factor = 1 + (consts.ZOOM_SPEED * Math.abs(delta));
this.zoom *= delta > 0 ? factor : 1 / factor;
this.normalize();
}
normalize() {
this.zoom = Math.max(consts.MIN_ZOOM,
Math.min(consts.MAX_ZOOM, this.zoom));
}
transformCanvas() {
let [bx, by, bw, bh] = this.bounds;
let tx = -this.x + bw / 2;
let ty = -this.y + bh / 2;
context.translate(tx, ty);
context.scale(this.zoom, this.zoom);
}
} }

View file

@ -4,12 +4,13 @@ import * as world from '../world/index.mjs';
export function render() { export function render() {
world.ships.forEach(renderShip); world.ships.forEach(renderShip);
world.celestials.forEach(renderCelestial);
} }
function renderShip(ship) { function renderShip(ship) {
context.fillStyle = 'red'; context.fillStyle = 'red';
//context.fillRect(ship.x, ship.y, 10, 10); //context.fillRect(ship.x, ship.y, 10, 10);
let size = 100; let size = 1;
context.drawImage(assets.modules.capsule.small, ship.x, ship.y, context.drawImage(assets.modules.capsule.small, ship.x, ship.y,
size, size); size, size);
context.drawImage(assets.modules.fuel.small, ship.x, ship.y + size, context.drawImage(assets.modules.fuel.small, ship.x, ship.y + size,
@ -17,3 +18,11 @@ function renderShip(ship) {
context.drawImage(assets.modules.thruster.light, ship.x, context.drawImage(assets.modules.thruster.light, ship.x,
ship.y + size * 2, size, size); ship.y + size * 2, size, size);
} }
const celestialImages = {
green: Object.values(assets.celestials.green)
}
function renderCelestial(cel) {
context.drawImage(cel.image, cel.x, cel.y, cel.diameter, cel.diameter);
}

View file

@ -1,6 +1,6 @@
import {canvas} from './graphics/index.mjs'; import {canvas} from './graphics/index.mjs';
export const mouse = { pressed: {}, held: {}, x: 0, y: 0 }; export const mouse = { pressed: {}, held: {}, x: 0, y: 0, scroll: 0 };
export const keyCode = { pressed: {}, held: {} }; export const keyCode = { pressed: {}, held: {} };
export const key = { pressed: {}, held: {} }; export const key = { pressed: {}, held: {} };
export const action = {}; export const action = {};
@ -11,6 +11,7 @@ export function tick() {
mouse.pressed = {}; mouse.pressed = {};
keyCode.pressed = {}; keyCode.pressed = {};
key.pressed = {}; key.pressed = {};
mouse.scroll = 0;
} }
export function init() { export function init() {
@ -43,4 +44,8 @@ export function init() {
mouse.x = event.clientX - rect.left; mouse.x = event.clientX - rect.left;
mouse.y = event.clientY - rect.top; mouse.y = event.clientY - rect.top;
}); });
window.addEventListener('wheel', event => {
mouse.scroll = event.deltaY;
});
} }

View file

@ -10,7 +10,7 @@ export default class Body {
this.rvel = 0; this.rvel = 0;
this.mass = mass; this.mass = mass;
} }
tickGravity(bodies) { tickGravity(bodies) {
bodies.forEach(b => { bodies.forEach(b => {
let force = b.mass / this.mass / (distanceTo(b) ** 2) * G; let force = b.mass / this.mass / (distanceTo(b) ** 2) * G;

View file

@ -1,10 +1,29 @@
import {images as assets} from '../assets.mjs';
import Body from './body.mjs'; import Body from './body.mjs';
export default class Celestial extends Body { export default class Celestial extends Body {
constructor(x, y, radius, { constructor(x, y, radius, {
density = 1, density = 1,
mass = (radius ** 2) * density type = 'rock'
}) { }) {
let mass = (radius ** 2) * density
super(x, y, mass); super(x, y, mass);
this.radius = radius;
this.type = type;
let imageArr = Object.values(assets.celestials[this.type]);
this.image = imageArr[Math.random() * imageArr.length | 0];
}
tick() {
}
get center() {
return [this.x + this.radius / 2, this.y + this.radius / 2];
}
get diameter() {
return this.radius * 2;
} }
} }

View file

@ -17,6 +17,8 @@ export function init() {
entities.clear(); entities.clear();
celestials.clear(); celestials.clear();
spawn.player(); spawn.player();
spawn.startPlanet();
} }
export function tick() { export function tick() {

View file

@ -3,6 +3,9 @@ export default class Module {
name = 'Unnamed Module', name = 'Unnamed Module',
type = 'block', type = 'block',
mass = 1, mass = 1,
// Fuel
filled = false,
fuelCapacity = 0,
...properties ...properties
}) { }) {
this.x = x; this.x = x;
@ -10,6 +13,7 @@ export default class Module {
this.name = name; this.name = name;
this.type = type; this.type = type;
this.mass = mass; this.mass = mass;
// Fuel
this.fuel = filled ? fuelCapacity : 0;
} }
} }

View file

@ -1,6 +1,6 @@
import Ship from './ship.mjs'; import Ship from './ship.mjs';
import Module from './module.mjs'; import Module from './module.mjs';
import Celestial from './ship.mjs'; import Celestial from './celestial.mjs';
import {modules} from '../data.mjs'; import {modules} from '../data.mjs';
import * as world from './index.mjs'; import * as world from './index.mjs';
@ -11,9 +11,18 @@ export function player() {
ship.addModule(0, 2, modules.thruster.light); ship.addModule(0, 2, modules.thruster.light);
world.ships.add(ship); world.ships.add(ship);
world.setPlayerShip(ship); world.setPlayerShip(ship);
return ship;
} }
// Make module length = 1, define all other length off that. export function startPlanet() {
export function celestial() { return celestial(-40, 10, 40, {
let celestial = new Celestial(0, 50, 45) density: 1,
type: 'green'
});
}
export function celestial(x, y, radius, params) {
let celestial = new Celestial(x, y, radius, params);
world.celestials.add(celestial);
return celestial;
} }