let drawBuffer, miniMapBuffer;
asteroidImgs[0] = loadImage("1.png");
asteroidImgs[1] = loadImage("2.png");
asteroidImgs[2] = loadImage("3.png");
asteroidImgs[3] = loadImage("4.png");
asteroidImgs[4] = loadImage("test.png");
createCanvas(window.innerWidth, window.innerHeight);
drawBuffer = createGraphics(width/5.0, height/5.0);
miniMapBuffer = createGraphics(48, 48);
ship = new FlexableBody();
cockpit = ship.createPart(createVector(1200, 0), 10);
const driveA = ship.createPart(createVector(1190, -20), 5);
const driveB = ship.createPart(createVector(1175, 0), 5);
const driveC = ship.createPart(createVector(1190, 20), 5);
const laserDrill = ship.createPart(createVector(1225, 0), 8);
laserDrill.lable = "drill";
laserDrill.color = "red";
cockpit.addLink(laserDrill);
bodies.push(cockpit, driveA, driveB, driveC, laserDrill);
sun = new Body(createVector(0, 0), 500);
for (let i = 0; i < 25; i++) {
addAsteroid(createVector(random(800, 1100), 0).rotate(TWO_PI * i / 25), floor(random(0, 4.02)));
for (let i = 0; i < 25; i++) {
addAsteroid(createVector(random(1300, 1600), 0).rotate(TWO_PI * i / 25), floor(random(0, 4.02)));
function windowResized() {
resizeCanvas(window.innerWidth, window.innerHeight);
function addAsteroid(position, asteroidID) {
const asteroid = new ImageBody(asteroidImgs[asteroidID], position);
asteroid.velocity = position.copy().rotate(HALF_PI).setMag(sqrt(10));
drawBuffer.resetMatrix();
drawBuffer.background("#191970");
display(drawBuffer, screenZoom);
miniMapBuffer.resetMatrix();
miniMapBuffer.background(0);
miniMapBuffer.drawingContext.globalCompositeOperation = "destination-out";
display(miniMapBuffer, 0.025);
miniMapBuffer.stroke(0, 255, 0, 288 - (frameCount % 64) * 5);
miniMapBuffer.circle(24, 24, frameCount % 64);
miniMapBuffer.fill(0, 255, 0);
miniMapBuffer.noStroke();
miniMapBuffer.circle(24, 24, 4);
drawBuffer.rect(0, 0, 48, 48);
drawBuffer.image(miniMapBuffer, 0.5, -0.5, 48, 48);
image(drawBuffer, 0, 0, width, height)
function display(buffer, zoom, ) {
buffer.translate(buffer.width / 2, buffer.height / 2);
buffer.translate(floor(-cockpit.position.x), floor(-cockpit.position.y));
for (const body of bodies) body.predraw(buffer);
for (const body of bodies) body.draw(buffer);
let pixelAllowance = 32768;
for (const body of bodies) {
if (body.imageCacheValid !== false) continue;
pixelAllowance -= body.img.width * body.img.height;
if (pixelAllowance <= 0) break;
for (const part of ship.parts) {
const driveDirection = createVector();
if (keyIsDown(68) || keyIsDown(39)) {
if (keyIsDown(65) || keyIsDown(37)) {
if (keyIsDown(83) || keyIsDown(40)) {
if (keyIsDown(87) || keyIsDown(38)) {
driveDirection.limit(0.12);
part.velocity.add(driveDirection);
if (driveDirection.mag() > 0 && frameCount % 4 === 0) {
const engineExhaust = new ErodingBody(part.position.copy(), 3);
engineExhaust.color = "cyan";
engineExhaust.fadeAmount = 0.5;
driveDirection.setMag(-3);
driveDirection.add(part.velocity);
driveDirection.add(p5.Vector.random2D().mult(0.5));
engineExhaust.velocity = driveDirection;
bodies.push(engineExhaust);
const laserBeam = new ErodingBody(part.position.copy(), 5);
const velocity = screenToWorld(createVector(mouseX, mouseY)).sub(part.position).setMag(8);
velocity.add(part.velocity);
velocity.add(p5.Vector.random2D().mult(0.1));
laserBeam.velocity = velocity;
for (const body of bodies) {
if (!body.multiBody) body.gravityPull(sun.position, 10);
for (let i = 0; i < bodies.length; i++) {
for (let i = 0; i < bodies.length; i++) {
if (bodies[i].multiBody) continue;
for (let j = i + 1; j < bodies.length; j++) {
if (!bodies[j].multiBody) {
const maxDist = bodies[i].radius + bodies[j].radius;
if (Math.abs(bodies[i].position.x - bodies[j].position.x) > maxDist) continue;
if (Math.abs(bodies[i].position.y - bodies[j].position.y) > maxDist) continue;
bodies[i].collide(bodies[j]);
function screenToWorld(position) {
const worldPosition = position.copy();
worldPosition.div(width, height);
worldPosition.sub(0.5, 0.5);
worldPosition.mult(drawBuffer.width / screenZoom, drawBuffer.height / screenZoom);
worldPosition.add(cockpit.position);
return ((a % b) + b) % b;