Add start of ship editing

This commit is contained in:
asraelite 2018-03-04 16:49:42 +00:00
parent d85338d9f2
commit b88c0eb358
18 changed files with 288 additions and 100 deletions

View file

@ -11,58 +11,23 @@ function init() {
};
}
export function render() {
export function render(angle) {
if (patterns === null) init();
renderLayer(patterns.back, 0.3, 1);
renderLayer(patterns.middle, 0.5, 0.3);
//renderLayer(patterns.front, 0.7, 0.3);
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) {
function renderLayer(pattern, speed = 1, scale = 1, angle = 0) {
context.save();
let outset = (Math.abs(Math.cos(angle)) + Math.abs(Math.sin(angle)));
outset = ((outset - 1) * canvas.width) / scale;
let [px, py] = [perspective.x * speed, perspective.y * speed];
context.translate(-px, -py);
context.scale(scale, scale);
context.fillStyle = pattern;
context.fillRect(px / scale, py / scale,
canvas.width / scale, canvas.height / scale);
context.fillRect(px / scale - outset / 2, py / scale - outset / 2,
canvas.width / scale + outset, canvas.height / scale + outset);
context.restore();
}
/*
function renderSectorStars(sector) {
let rand = new SeededRandom(sector.numId);
context.fillStyle = '#fff';
for (let i = 0; i < STAR_DENSITY; i++) {
let sx = rand.next() * sector.size + sector.wx;
let sy = rand.next() * sector.size + sector.wy;
context.fillRect(sx, sy, 1.5, 1.5);
}
}
function tile(img, x, y, dx = 0, dy = 0, scale = 1) {
let [sx, sy] = [x * scale, y * scale];
let [ex, ey] = [(x + canvas.width) * scale, (y + canvas.height) * scale];
for (let x = sx; x < ex;) {
let nx = (Math.floor(x / img.width) + 1) * img.width;
nx = Math.min(nx, ex);
let w = nx - x;
for (let y = sy; y < ey;) {
let ny = (Math.floor(y / img.height) + 1) * img.height;
ny = Math.min(ny, ey);
let h = ny - y;
context.drawImage(img, x % img.width, y % img.height, w, h,
dx + x, dy + y, w, h);
y = ny;
}
x = nx;
}
}
*/

View file

@ -29,10 +29,10 @@ export function render() {
context.fillStyle = '#000';
context.fillRect(0, 0, canvas.width, canvas.height);
renderBackground();
context.save();
perspective.tick();
perspective.transformRotate();
renderBackground(perspective.rotation);
perspective.transformCanvas();
renderWorld();
context.restore();
@ -44,41 +44,108 @@ export function getVisibleSectors() {
return world.getContainedSectors(...perspective.bounds);
}
export function changePerspective(rotationMode, shiftX = 0, shiftY = 0) {
perspective.changeRotationMode(rotationMode);
perspective.changeShift(shiftX, shiftY);
perspective.transition = 1;
}
export function changeZoom(delta) {
perspective.zoomDelta(delta);
}
export function setZoom(target) {
perspective.changeZoom(target);
}
class Perspective {
constructor() {
this.x = 0;
this.y = 0;
this.shiftX = 0;
this.shiftY = 0;
this.zoom = 0;
this.bounds = [0, 0, canvas.width, canvas.height];
this.rotationMode = 'universe';
this.targetZoom = consts.DEFAULT_ZOOM;
this.oldTarget = 0;
this.oldShift = [0, 0];
this.oldZoom = 0;
this.transition = 0;
this.zoomTransition = 0;
this.reset();
}
changeRotationMode(mode) {
this.oldTarget = this.targetRotation;
this.rotationMode = mode;
}
changeShift(x, y) {
this.oldShift = this.currentShift;
[this.shiftX, this.shiftY] = [x, y];
}
changeZoom(zoom) {
this.oldZoom = this.currentZoom;
this.targetZoom = zoom;
this.zoomTransition = 1;
}
get currentShift() {
let [ox, oy] = this.oldShift;
return [this.interpolate(this.shiftX, ox),
this.interpolate(this.shiftY, oy)];
}
get currentRotation() {
return this.interpolate(this.targetRotation, this.oldTarget);
}
get currentZoom() {
let t = this.zoomTransition;
return (this.oldZoom * t + this.targetZoom * (1 - t));
}
interpolate(cur, old, x = this.transition) {
return (old * x + cur * (1 - x));
}
tick() {
if (input.mouse.scroll !== 0) {
this.zoomDelta(-input.mouse.scroll);
}
if (this.focus !== null) {
if (this.focus !== null)
[this.x, this.y] = this.focus.com;
}
if (this.rotationFocus !== null) {
this.targetRotation = this.rotationFocus.r;
} else {
if (this.focus === null || this.rotationMode === 'universe') {
this.targetRotation = 0;
} else if (this.rotationMode === 'parent') {
let parent = this.focus.parentCelestial;
if (parent === null) {
this.targetRotation = 0;
} else {
let a = this.focus.angleTo(...this.focus.com, ...parent.com);
this.targetRotation = a - Math.PI / 2;
}
} else {
this.targetRotation = this.focus.r;
}
if (this.smoothRotation) {
this.rotation = (this.rotation * 0.9 + this.targetRotation * 0.1);
} else {
this.rotation = this.targetRotation;
}
let dif = Math.abs(this.targetRotation - this.rotation);
this.rotationMet = dif < (this.rotationMet ? 0.3 : 0.05);
this.rotation = this.currentRotation;
this.zoom = this.currentZoom;
this.transition *= 0.9;
this.zoomTransition *= 0.9;
this.normalize();
}
reset() {
this.rotation = 0;
this.targetRotation = 0;
this.smoothRotation = false;
this.zoom = consts.DEFAULT_ZOOM;
this.targetZoom = this.zoom;
this.focus = null;
this.rotationFocus = null;
}
@ -86,24 +153,37 @@ class Perspective {
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.targetZoom *= delta > 0 ? factor : 1 / factor;
this.normalize();
}
normalize() {
this.zoom = Math.max(consts.MIN_ZOOM,
Math.min(consts.MAX_ZOOM, this.zoom));
this.targetZoom = Math.max(consts.MIN_ZOOM,
Math.min(consts.MAX_ZOOM, this.targetZoom));
this.targetRotation %= (Math.PI * 2);
}
transformRotate() {
let [,,bw, bh] = this.bounds;
context.translate(bw / 2, bh / 2);
context.rotate(-this.rotation);
context.translate(-bw / 2, -bh / 2);
}
rotateVector(x, y, r = this.rotation) {
return [(x * Math.cos(r) - y * Math.sin(r)),
(y * Math.cos(r) - x * Math.sin(r))];
}
transformCanvas() {
let [,,bw, bh] = this.bounds;
let tx = -this.x * this.zoom;
let ty = -this.y * this.zoom;
let [sx, sy] = this.rotateVector(...this.currentShift, -this.rotation);
let tx = -(this.x + sx) * this.zoom;
let ty = -(this.y + sy) * this.zoom;
context.translate(tx + bw / 2, ty + bh / 2);
context.scale(this.zoom, this.zoom);
}