/*****************************************************************************************************
__ __ __ __ ______ ________ _______ ________ ______ ______ _______ ________
| |__| || |__| || _ |_ | __| | ___| | ___|| _ |_ | __ | | ____|| __|
| __ ||__ __|| |_| _|| __| | _| | |___ | |_| _|| |__| || | | __|
| | | | | | | ___| | |_____ | | |____ || ___| | __ || |____ | |_____
| | | | |__| |__| |________||__| _____| ||__| |__| |__| |_______||________|
|__| |__| |_________|
by Klayton Cheuk
October, 2016
Experience quantum tunnelling!
Press space to travel forwards with increasing speed.
Press shift to travel in reverse with increasing speed.
Press the directional buttons while moving forward to
turn the tunnel, and the spaceship's direction.
******************************************************************************************************/
// declare variables for speed
float speed;
int acceleration;
// declare booleans for button inputs
boolean up, down, left, right, forward, backward;
// declare the ring array
ring[] rings;
// declare the ship
ship mainShip;
void setup() {
size(800, 600);
// initialization of variables
speed = 0;
acceleration = 0;
rings = new ring[7];
mainShip = new ship();
// initialize, place the rings
for (int i=0; i < rings.length; i++) {
rings[i] = new ring(color(random(100, 255), random(100, 255), random(100, 255)));
rings[i].grow((i+1)*150, false, false, false, false);
}
}
void draw() {
background(10, 10, 10);
// detect button inputs
detectInput();
// check current acceleration and modify speed accordingly
speed = speed + (checkAcceleration()) * 0.1;
// turn ship
mainShip.turn(right, left, up, down);
// grow and display rings
growRings();
displayRings();
// display ship
mainShip.display();
up = false;
down = false;
right = false;
left = false;
}
void detectInput() {
if (keyPressed) {
if (key == ' ') {
forward = true;
}
if (key == CODED) {
if (keyCode == UP) {
up = true;
}
if (keyCode == DOWN) {
down = true;
}
if (keyCode == RIGHT) {
right = true;
}
if (keyCode == LEFT) {
left = true;
}
if (keyCode == SHIFT) {
backward = true;
}
}
}
}
float checkAcceleration() {
// if the spacebar is pressed, increase the speed.
if (forward) {
acceleration += 2;
forward = false;
key = 'n';
return acceleration;
}
// if SHIFT is pressed, decrease the speed.
if (backward) {
acceleration =- 2;
backward = false;
key = 'n';
return acceleration;
}
// otherwise there is no acceleration.
return acceleration = 0;
}
void growRings () {
for (int i=0; i < rings.length; i++) {
rings[i].grow(speed, right, left, up, down);
}
}
void displayRings() {
for (int i=0; i < rings.length; i++) {
rings[i].display();
}
}class ring {
// declare class variables
color c;
float size;
float speed;
PVector position;
boolean right, left, up, down;
// constructor
ring (color c_) {
c = c_;
size = 0;
position = new PVector(width/2, height/2);
}
// function to calculate ring growth
void grow(float speed_, boolean right_, boolean left_, boolean up_, boolean down_) {
speed = speed_;
right = right_;
left = left_;
up = up_;
down = down_;
// add the speed to the size of the ring
size = size + speed;
// if the ring is too large
if (size > 1050) {
// reset it
size = 0;
c = color(random(100, 255), random(100, 255), random(100, 255));
position = new PVector(width/2, height/2);
// check for any turn inputs to spawn ring in correct position
if (right) {
position.x = -(size/1.75)+width;
}
if (left) {
position.x = size/1.75;
}
if (up) {
position.y = size/1.75;
}
if (down) {
position.y = -(size/1.75)+height;
}
}
// slide rings towards center.
if (position.x < width/2) {
position.x = size/1.75;
}
if (position.x > width/2) {
position.x = -(size/1.75)+width;
}
if (position.y < height/2) {
position.y = size/1.75;
}
if (position.y > height/2) {
position.y = -(size/1.75)+height;
}
// because of floats being inaccurate?? catch floats close to the center.
if (position.x < width/2+10 && position.x > width/2-10) {
position.x = width/2;
}
if (position.y < height/2+10 && position.y > height/2-10) {
position.y = height/2;
}
// if the ring becomes too small
if (size < 0) {
// reset it on the other end.
size = 1050;
c = color(random(100, 255), random(100, 255), random(100, 255));
position = new PVector(width/2, height/2);
}
}
// display the ring
void display() {
stroke(c);
strokeWeight(size/25);
noFill();
ellipse(position.x, position.y, size, size);
}
}class ship {
// declare variables
PVector position;
boolean right, left, up, down;
// constructor
ship () {
position = new PVector(width/2, height/2+75);
}
// check for a turn and modify position
void turn(boolean right_, boolean left_, boolean up_, boolean down_) {
right = right_;
left = left_;
up = up_;
down = down_;
// if right is pressed, move left
if (right && position.x >= width/2-200) {
position.x -= 25;
}
// if right is released, move back
else if (right == false && position.x < width/2) {
position.x += 25;
}
// if left is pressed, move right
if (left && position.x <= width/2+200) {
position.x += 25;
}
// if left is released, move back
else if (left == false && position.x > width/2) {
position.x -=25;
}
// if up is pressed, move down
if (up && position.y <= height/2+175) {
position.y += 25;
}
// if up is released, move back
else if (up == false && position.y > height/2+50) {
position.y -= 25;
}
//if down is pressed, move up
if (down && position.y >= height/2-150) {
position.y -= 25;
}
// if up is released, move back
else if (down == false && position.y < height/2+50) {
position.y += 25;
}
}
// display ship
void display() {
noStroke();
fill(255, 255, 255);
triangle((position.x)+10, (position.y)-10, (position.x)-10, (position.y)-10, (position.x/2)+200, ((position.y/2)+150));
triangle((position.x), (position.y)-10, (position.x), (position.y)-20, (position.x/2)+200, (position.y/2)+150);
fill(100, 100, 100);
triangle((position.x)+10, (position.y)-10, (position.x)-10, (position.y)-10, position.x, (position.y)-20);
fill(255, 255, 255);
ellipse(position.x, position.y-14, 5, 5);
}
}