basic viewport
HTML
<div>arrow keys to move</div>
CSS
body {
font-family: monospace;
font-size: 11px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
html, body {
height: 98%;
}
body > canvas {
margin: auto;
border: 4px solid #222;
}
body > div {
background: #222;
color: #fff;
padding: 2px;
}
JavaScript
/*
* assign the viewport to a target on each frame:
* viewport.x = -target.x + canvas.width / 2;
* viewport.y = -target.y + canvas.height / 2;
* ... and clamp it to the map if desired
*
* draw each entity relative to the viewport:
* entity.x + viewport.x
* entity.y + viewport.y
*/
"use strict";
const clamp = (n, lo, hi) => n < lo ? lo : n > hi ? hi : n;
const tau = Math.PI * 2;
const canvas = document.createElement("canvas");
canvas.style.background = "#eee";
const ctx = canvas.getContext("2d");
document.body.appendChild(canvas);
canvas.height = 400;
canvas.width = 400;
const map = {
height: 1000,
width: 2000
};
const viewport = {};
let kbd;
let ship;
const Ship = function (x, y, angle, size, color) {
this.x = x;
this.y = y;
this.vx = 0;
this.vy = 0;
this.ax = 0;
this.ay = 0;
this.rv = 0;
this.angle = angle;
this.accelerationAmount = 0.05;
this.decelerationAmount = 0.02;
this.friction = 0.9;
this.rotationSpd = 0.01;
this.size = size;
this.radius = size;
this.color = color;
};
Ship.prototype = {
accelerate: function (backwards) {
if (backwards) {
this.ax -= this.decelerationAmount;
this.ay -= this.decelerationAmount;
}
else {
this.ax += this.accelerationAmount;
this.ay += this.accelerationAmount;
}
},
move: function () {
this.angle += this.rv;
this.vx += this.ax;
this.vy += this.ay;
this.x += this.vx * Math.cos(this.angle);
this.y += this.vy * Math.sin(this.angle);
this.ax *= this.friction;
this.ay *= this.friction;
this.vx *= this.friction;
this.vy *= this.friction;
this.rv *= this.friction;
},
rotate: function (dir) {
if (dir === "left") {
this.rv -= this.rotationSpd;
}
else if (dir === "right") {
this.rv += this.rotationSpd;
}
},
draw: function (ctx, viewport) {
ctx.save();
ctx.translate(this.x + viewport.x,
this.y + viewport.y);
ctx.rotate(this.angle);
...