Your browser does not support the canvas tag.

previous        Show / Hide Source        Download        next
/******************************************************************
* Project Name: Toy Knife
* Author: Gabriel Duarte
* Student Number: 991433574
* Date: Oct 22, 2016
* Description: The user cuts the skin of a human by clicking the
left mouse button until that hooman dies *evil laugh*. There 
is a lot of blood (cool particle system).

Read the console.
******************************************************************/

//Knife object:
Knife myKnife;

//If the knife has cut once:
boolean hasCut;

//Group of cuts:
ArrayList<Cut> cuts;

//Group of Particle emitters:
ArrayList<ParticleSystem> p;

//Randomize skin color:
color bgColor;

//"Voice" of the person:
Voice voice;

void setup() {
  size(640, 480);
  noCursor();
  smooth(2);
  
  //Selects a skin color:
  bgColor = chooseColor();
  
  //Nothing has been cut yet:
  hasCut = false;
  
  //Creates a voice instance:
  voice = new Voice();
  
  createCutsArray();
  createKnife();
  createParticleSystems();
}

//Creates group of cuts:
void createCutsArray() {
  cuts = new ArrayList<Cut>();
}

//Creates knife:
void createKnife() {
  myKnife = new Knife(180);
}

//Creates group of particle emitters:
void createParticleSystems() {
  p = new ArrayList<ParticleSystem>();
}

void draw() {
  
  background(bgColor);

  drawEachCut();
  drawBlood();
  myKnife.drawKnife();
  
  noStroke();
  fill(149, 21, 21, p.size()*10);
  rect(0, 0, width, height);

}

//For each particle system, draw their blood:
void drawBlood() {
  for (int i = 0; i < p.size(); i++) {
    ParticleSystem ps = p.get(i);
    ps.addParticle();
    ps.run();
  }
}

//Draws each cut on the screen:
void drawEachCut() {
  for (int i = 0; i < cuts.size(); i++) {
    Cut c = cuts.get(i);
    c.drawCut();
  }
}

//Click interaction:
void mousePressed() {
  //If nothing was cut before, it is now:
  if (!hasCut) {
    hasCut = true;
  }
  
  //Add a cut:
  cuts.add(new Cut(mouseX, mouseY-myKnife.mySize));
  
  //Add a particle emitter:
  p.add(new ParticleSystem(mouseX, mouseY-myKnife.mySize));
  
  //If the person is dead:
  if (p.size()*10 >= 255) {
    println("*silence*");
  } else {
    //Say things:
    voice.shout();  
  }
}

//Reset by pressing "r":
void keyPressed() {
  if (key == 'r') {
    setup();
  }
}

//Choose a skin color:
color chooseColor() {
  if (random(-5, 5) > 0) {
    return color(126, 98, 70);
  } else {
    return color(235, 240, 201);
  }
}

class Cut {
  
  //Index of cut shape:
  int myIndex;
  
  //Position of cut:
  PVector pos;
  
  //Cut constructor:
  Cut(float x, float y) {
    
    //Choose a shape:
    myIndex = int(random(4));
    
    pos = new PVector(x, y);
    
  }
  
  void drawCut() {
    noStroke();
    fill(0);
    
    //Chooses between different shapes of cuts:
    switch (myIndex) {
      case 0:
        case1();
        break;
      case 1:
        case2();
        break;
      case 2:
        case3();
        break;
      case 3:
        case4();
        break;
      default:
        case1();
        break;
    }
  }
  
  //Shape 1:
  void case1() {
    triangle(pos.x+10, pos.y-5, pos.x-50, pos.y+10, pos.x+8, pos.y-15);
  }
  
  //Shape 2:
  void case2() {
    triangle(pos.x+80, pos.y-5, pos.x-50, pos.y+10, pos.x+8, pos.y-15);
  }
  
  //Shape 3:
  void case3() {
    triangle(pos.x+60, pos.y+5, pos.x-20, pos.y+10, pos.x+15, pos.y+15);
  }
  
  //Shape 4:
  void case4() {
    triangle(pos.x-30, pos.y-80, pos.x-20, pos.y+10, pos.x+15, pos.y+60);
  }

}
class Knife {
  
  //Size of the knife:
  float mySize;
  
  //Knife constructor:
  Knife(float sze) {
    mySize = sze;
  }
  
  //Drawing the knife at the mouse position:
  void drawKnife() {
    noStroke();
    fill(191, 189, 189);
    triangle(mouseX, mouseY, mouseX-mySize/2, mouseY, mouseX, mouseY-mySize);
    fill(175, 152, 115);
    rectMode(CORNERS);
    rect(mouseX-mySize/4, mouseY, mouseX, mouseY+mySize/1.2);
    ellipse(mouseX-(mySize/3)/2, mouseY+mySize/1.2, mySize/3, mySize/3);
    fill(219, 237, 84);
    ellipse(mouseX-(mySize/3)/2, mouseY+mySize/1.2, mySize/8, mySize/8);
    ellipse(mouseX-mySize/8, mouseY+mySize/10, mySize/10, mySize/10);
    
    //Draw blood stains if the knife has cut something:
    if (hasCut) {
      fill(185, 66, 66);
      noStroke();
      ellipse(mouseX-mySize/3, mouseY-mySize/6, 26, 32);
      ellipse(mouseX-mySize/6, mouseY-mySize/4, 16, 16);
      ellipse(mouseX-mySize/6.5, mouseY-mySize/2, 20, 15);
      ellipse(mouseX-mySize/18, mouseY-mySize/1.2, 8, 10);
      fill(185, 66, 66, 100);
      triangle(mouseX, mouseY, mouseX-mySize/2, mouseY, mouseX, mouseY-mySize);
    }
    
  }
  
}

class Particle {
  
  //Particle position:
  PVector position;
  
  //Particle speed:
  PVector speed;
  
  //Particle acceleration:
  PVector acceleration;
  
  //Particle lifeTime (alpha):
  float lifeTime = 255;
  
  float lifeSpeed;
  
  //Particle constructor:
  Particle(PVector l, float lSpd) {
    acceleration = new PVector(0, 0.5);
    speed = new PVector(random(-1, 1), random(-1, 1));
    position = l.get();
    
    lifeSpeed = lSpd;
    
  }
  
  //Update the position of each particle:
  void update() {
    speed.add(acceleration);
    position.add(speed);
    
    //Turn transparent over time:
    lifeTime -= lifeSpeed;
  }
  
  //Test if particle has gone completly transparent:
  boolean isDead() {
    if (lifeTime <= 0) {
      return true;
    } else {
      return false;
    }
  }
  
  //Draw particle:
  void display() {
    noStroke();
    fill(185, 66, 66, lifeTime);
    ellipse(position.x, position.y, 30, 25);
  }
}
class ParticleSystem {
  
  //Group of particels:
  ArrayList<Particle> particles;
  
  //Origin of particles:
  PVector origin;
  
  //System constructor:
  ParticleSystem(float x, float y) {
    origin = new PVector(x, y);
    particles = new ArrayList<Particle>();
  }
  
  //Adds particles to the system:
  void addParticle() {  
    particles.add(new Particle(origin, 2));
  }
  
  //Run particle system and render every particle:
  void run() {
    for (int i = 0; i < particles.size(); i++) {
      Particle p = particles.get(i);
      p.update();
      p.display();
      
      //Destroy them if they are "dead":
      if (p.isDead()) {
        particles.remove(i);
      }
      
    }
  }
  
}
class Voice {
  
  //Text displayed in the console:
  String text;
  
  //Voice constructor:
  Voice() {
  
  }
  
  //Display text:
  void shout() {
    
    //Choose a random number:
    int rand = int(random(1, 5));
    
    //Display text according to the number chosen:
    switch (rand) {
      case 1:
        text = "Stop it";
        break;
      case 2:
        text = "Baby don't hurt me";
        break;
      case 3:
        text = "I'd rather drink bleach";
        break;
      case 4:
        text = "Anakin you're breaking my heart";
        break;
      case 5:
        text = "This doesn't even hurt :(";
        break;
      default:
        //Gets
        text = "Hi human, If this appears on the console, something went horribly wrong...";
        break;
    }
    
    //Print selected text to console:
    println(text);
    
  }
  
}