Code viewer for World: where's my bike
// Cloned by Brendan McGrath on 16 Sep 2025 from World "One Cube World (P5)" by Starter user 
// Please leave this clone trail here.
 
const MUSICFILE = '/uploads/starter/SuspenseStrings.mp3';
AB.backgroundMusic ( MUSICFILE );
 
const objectsize    = 100;      // size of object   

const anglechange   = 0.01;     // how much the rotate angle changes each step 

var angle = 0;                  // rotate angle starts at 0  

var img;

//Particle class
class Particle {
  constructor(x, y, z) {
    this.pos = createVector(x, y, z);
    this.vel = p5.Vector.random3D().mult(random(1, 3));
    this.lifespan = 100 + random(50);
    this.size = random(5, 15);
    this.color = color(random(200,255), 0, 0, 200);
  }
  update() {
    this.pos.add(this.vel);
    this.lifespan -= 2;
  }
  isDead() { return this.lifespan < 0; }
  show() {
    push();
    translate(this.pos.x, this.pos.y, this.pos.z);
    noStroke();
    fill(this.color.levels[0], this.color.levels[1], this.color.levels[2], this.lifespan);
    sphere(this.size);
    pop();
  }
}

let particles = [];

const noboxes = 3000;
var a = new Array(noboxes);
for (var i = 0; i < noboxes; i++) {
  a[i] = [
    AB.randomIntAtoB(-500, 500),
    AB.randomIntAtoB(-500, 500),
    AB.randomIntAtoB(-500, 500)
  ];
}

// Add motorbike drawing helper
function drawMotorbike(s = 1) {
  push();
  scale(s);
  noStroke();

  // Wheels
  push(); fill(20); translate(-60, 40, 0); rotateZ(HALF_PI); torus(35, 7, 24, 16); pop();
  push(); fill(20); translate( 60, 40, 0); rotateZ(HALF_PI); torus(35, 7, 24, 16); pop();
  // Hubs
  push(); fill(150); translate(-60, 40, 0); rotateZ(HALF_PI); cylinder(6, 10, 12); pop();
  push(); fill(150); translate( 60, 40, 0); rotateZ(HALF_PI); cylinder(6, 10, 12, 12); pop();

  // Frame
  push(); fill(200, 0, 0); translate(0, 20, 0); rotateZ(-PI/18); box(120, 6, 6); pop();   // bottom tube
  push(); fill(200, 0, 0); translate(5, -5, 0); rotateZ(-PI/18); box(90, 6, 6);  pop();   // top tube

  // Seat
  push(); fill(50); translate(-20, -20, 0); box(40, 8, 20); pop();

  // Tank
  push(); fill(30, 120, 200); translate(10, -15, 0); ellipsoid(28, 14, 18, 12, 8); pop();

  // Fork + handlebar
  push(); fill(150); translate(50, 0, 0); rotateZ(-PI/6); box(8, 60, 8); pop();
  push(); fill(150); translate(80, -28, 0); box(30, 4, 4); pop();

  // Engine
  push(); fill(120); translate(0, 20, 0); box(30, 30, 20); pop();

  // Exhaust
  push(); fill(90); translate(-55, 5, -8); rotateZ(-PI/18); box(70, 6, 6); pop();

  pop();
}


function preload() 
{
   img = loadImage ( 'uploads/busa06/space_invader.png' );
}


function setup()        // "setup" is called once at start of run 
{
  createCanvas ( ABWorld.fullwidth(), ABWorld.fullheight(),  WEBGL );
}

function draw()         // "draw" is called every timestep during run 
{
    // background("lightblue");    // background color 
    background("green")
    // fill("navy");               // paint box with this color 
    // fill("orange");     
    texture(img);        	

           
    rotateX(angle);             // set each dimension rotation angle to "angle"
    rotateY(angle);
    rotateZ(angle);
    
    // Particle system: spawn new particles at the center
    for (let i = 0; i < 5; i++) {
      particles.push(new Particle(0, 0, 0));
    }

    // Update and display particles
    for (let i = particles.length - 1; i >= 0; i--) {
      particles[i].update();
      particles[i].show();
      if (particles[i].isDead()) {
        particles.splice(i, 1);
      }
    }

    // Draw a motorbike near the origin (will rotate with the scene)
    push();
    translate(-100, 0, 0);
    rotateY(PI/2);
    drawMotorbike(3);
    pop();

    translate(100, 100, 100);

    for ( var i=0; i < noboxes; i++ )
    {
      translate ( a[i][0], a[i][1], a[i][2] );		// get box position i 
      sphere(objectsize/2);             
    }
  
    angle = angle + anglechange ;       // change angle each step to get rotate movement
}