xxxxxxxxxx
199
function Eye(x, y, z, angle) {
let eye = {
pos: createVector(x, y, z),
targetPos: createVector(x, y, z),
look: createVector(0, 0, 0),
angle: angle
};
eye.commitTarget = () => {
eye.pos = createVector(eye.targetPos.x, eye.targetPos.y, eye.targetPos.z);
}
return eye;
}
function Box(x, y, z, size, color) {
let box = {
pos: createVector(x, y, z),
size: size,
xmin: x - size / 2,
xmax: x + size / 2,
ymin: y - size / 2,
ymax: y + size / 2,
zmin: z - size / 2,
zmax: z + size / 2,
color: color
};
return box;
}
function Pickup(x, y, z, size, color) {
let pickup = Box(x, y, z, size, color);
pickup.angle1 = createVector(0, 0, 0);
pickup.angle2 = createVector(0, 0, 0);
// Handle collecting this pickup
pickup.collect = () => {
// Remove this pickup from the scene
pickups = pickups.filter(c => c !== pickup);
}
pickup.rotate = () => {
// Calculate a random angle change for each pole
let angleChange1 = random(-1, 1);
let angleChange2 = random(-1, 1);
// Update the angles of each pole
pickup.angle1.x += random(.15);
pickup.angle1.y += random(.15);
pickup.angle1.z += random(.15);
pickup.angle2.x += random(-.15);
pickup.angle2.y += random(-.15);
pickup.angle2.z += random(-.15);
}
return pickup;
}
// collide function
function collide(obj, vec) {
return vec.x > obj.xmin && vec.x < obj.xmax
&& vec.y > obj.ymin && vec.y < obj.ymax
&& vec.z > obj.zmin && vec.z < obj.zmax;
}
let eye, eyetarget, boxes, pickups,bgcolor;
function setup() {
createCanvas(400, 400);
scene = createGraphics(400, 400, WEBGL);
setClippingPlanes()
eye = new Eye(0, 0, 0, 0.2);
boxes = []
pickups = []
for (let i = 0; i < 200; i++) {
let x = random(-100, 100)*8+random(1);
let y = 0;
let z = random(-100, 100)*8+random(1);
let mass = 50;
let color = random(["orange", "darkgoldenrod", "sienna"]);
let box = new Box(x, y, z, mass, color);
if (!collide(box,eye.pos)) boxes.push (box);
}
for (let i = 0; i < 50; i++) {
let x = random(-100, 100)*8+random(1);
let y = 5;
let z = random(-100, 100)*8+random(1);
let mass = 25;
let color = random(["red", "darkmagenta", "orchid","greenyellow","deepskyblue","cyan"]);
let pickup = new Pickup(x, y, z, mass, color);
if (!collide(pickup,eye.pos)) pickups.push (pickup);
}
bgcolor = color(0)
}
function draw() {
if (keyIsDown(87)) { //d
eye.targetPos.x = eye.pos.x + cos(eye.angle) * 5;
eye.targetPos.z = eye.pos.z + sin(eye.angle) * 5;
}
if (keyIsDown(83)) { //a
eye.targetPos.x = eye.pos.x - cos(eye.angle) * 5;
eye.targetPos.z = eye.pos.z - sin(eye.angle) * 5;
}
if (keyIsDown(65)) //s
eye.angle = eye.angle - 0.1;
if (keyIsDown(68)) //w
eye.angle = eye.angle + 0.1;
// Set the camera's position and look vector
//if the target doesnt collide with any boxes
let hit = false;
for (let b of boxes) {
if (collide(b,eye.targetPos)) {
hit= true;
console.log("collide " +b.color)
break;
}
}
if (!hit) eye.commitTarget();
eye.look.x = eye.pos.x + cos(eye.angle);
eye.look.z = eye.pos.z + sin(eye.angle);
with (scene) {
//if(random(1)>.7)
clear()
noStroke()
bgcolor = lerpColor(color(bgcolor),color(0),0.2);
background(bgcolor);
pointLight(200, 200, 200, 0, 50, 40);
pointLight(100, 100, 100, 100, 10, 0);
pointLight(50, 50, 50, eye.pos.x, eye.pos.y, eye.pos.z);
camera(eye.pos.x, eye.pos.y, eye.pos.z, eye.look.x, eye.look.y, eye.look.z, 0, 1, 0);
//draw boxes
for (let b of boxes) {
push();
noStroke();
fill(b.color);
translate(b.pos.x, b.pos.y, b.pos.z);
box(b.size);
pop();
}
//collect or draw pickups
for (let c of pickups) {
if (collide(c,eye.pos)) {
console.log("collect " +c.color)
// Handle collecting the pickup
c.collect();
bgcolor = c.color;
} else {
push();
noStroke();
noLights();
c.rotate();
translate(c.pos.x, c.pos.y, c.pos.z);
push();
fill(255);
rotateX(c.angle1.x);
rotateY(c.angle1.y);
rotateZ(c.angle1.z);
translate(0,-c.size*.3,0);
sphere(c.size*.2);
translate(0,c.size*.6,0);
sphere(c.size*.15);
pop();
push();
fill(c.color)
rotateX(c.angle2.x);
rotateY(c.angle2.y);
rotateZ(c.angle2.z);
translate(0,-c.size*.25,0);
sphere(c.size*.2);
translate(0,c.size*.5,0);
sphere(c.size*.2);
pop();
fill(c.color);
sphere(c.size/3);
pop();
}
}
}
background(0)
image(scene,0,0)
rect(width/2-5,height/2-5,10,10)
}
function setClippingPlanes() {
//this replicates the default perspective, but with broader near/far clipping planes
let fov = PI/3.0;
let cameraZ = (height/2.0) / tan(fov/2.0);
let nearclip = cameraZ/100000.0;
let farclip = cameraZ*100.0;
scene.perspective(fov, float(width)/float(height), nearclip, farclip);
}