Your browser does not support the canvas tag.

previous        Show / Hide Source        Download        next
/////////////////////////////////////////////////////////////////////////
/////                    HURRICANE SIMULATOR                       //////
/////                                                              //////
/////             Consume rain clouds to grow larger!              //////
/////               Normal Clouds make you weaker!                 //////
///// The special cloud will cut your strength down significantly! //////
/////                                                              //////
/////      Gain strength and become the strongest hurricane!       //////
/////                                                              //////
/////      W,A,S,D to move, Space to print score & category.       //////
/////                                                              //////
/////                        Special Controls:                     ////// 
/////                     "1" will increase score                  //////
/////                     "2" will decrease score                  //////
/////                                                              //////
/////                   Made by : Alexandre Bujold                 //////
/////////////////////////////////////////////////////////////////////////

//Player Variables
  float playerX;
  float playerY;
  float playerSpeed = 4;
  int playerCategory = 1; //Category of Hurricane the player has achieved
  int playerScore = 300; //Generic Score to determine Category 
  float playerRadius = 20; //Used to draw player & check collisions
 
  //Control Variables
  boolean playerGoLeft;
  boolean playerGoRight;
  boolean playerGoUp;
  boolean playerGoDown;
  boolean showScore;
  boolean increaseScore;
  boolean decreaseScore;
  
//Global Variables
  float gameDifficulty = 1; //Set to 1 by default
  boolean gameStarted;
  
//Cloud Variables
  //Normal Clouds
    float normalCloud_X_1; //Position X
    float normalCloud_Y_1; //Position Y
    float normalCloudSpeed_1 = 1; //Cloud's movement speed
     
    float normalCloud_X_2;
    float normalCloud_Y_2;
    float normalCloudSpeed_2 = 1;
      
    float normalCloud_X_3;
    float normalCloud_Y_3;
    float normalCloudSpeed_3 = 1;
      
  //Rain Clouds  
    float rainCloud_X_1;
    float rainCloud_Y_1;
    float rainCloudSpeed_1 = 1;
      
    float rainCloud_X_2;
    float rainCloud_Y_2;
    float rainCloudSpeed_2 = 1;
      
    float rainCloud_X_3;
    float rainCloud_Y_3;
    float rainCloudSpeed_3 = 1;
    
  //Special Cloud
    float specialCloud_X;
    float specialCloud_Y;
    float specialCloudSpeed;
    int specialCloudDirection = 1; //Left to right by default

  //General
    float cloudRadius = 12.5; //Needed to calculate collisions & draw clouds
      
void setup()
{
  size(400,400);
  smooth();
  frameRate(60);
  gameStarted = false;
}

void draw()
{
  background(125); //Set background to gray
  
  //Initialize Game
  if (gameStarted == false)
  {  
    for (int i = 0; i < 7; i++)
      {
        resetCloud(i);
      }
   gameStarted = true;
   playerScore = 300;
   playerX = width/2;
   playerY = height/2;
  }
  
  //Game Functions
    checkCollisions();
    scoreManager();
    playerMovement();
    moveClouds();
  
  //Draw Functions
    drawBackground();
    drawClouds();
    drawPlayer();
}



void checkCollisions() //Checks for collisions between player & clouds
{
  if (playerCategory >= 4)
  {
    //Special Cloud (#0)
      //get distance between circle's centers (player circle / cloud circle)
      float distanceX_0 = playerX - specialCloud_X;
      float distanceY_0 = playerY - specialCloud_Y;
      float distance_0 = sqrt( (distanceX_0 * distanceX_0) + (distanceY_0 * distanceY_0) );
       
      if (distance_0 <= playerRadius + cloudRadius) //if distance is inferior to radius of player & cloud added, circles are touching
      {
        resetCloud(0); //Reset cloud
        playerScore-=5000; //Lower score by 5000
        
        rectMode(CORNER);
        fill(255,255,255,150);
        rect(0,0,400,400); //Make the screen flash white to indicate player collided with special cloud
      }
  }
  
  
  //Cloud #1
    float distanceX_1 = playerX - normalCloud_X_1; 
    float distanceY_1 = playerY - normalCloud_Y_1; 
    float distance_1 = sqrt( (distanceX_1*distanceX_1) + (distanceY_1*distanceY_1)); 
    
    if (distance_1 <= playerRadius + cloudRadius) 
    { 
      resetCloud(1);
      playerScore-=100;
    }
  
  //Cloud #2
    float distanceX_2 = playerX - normalCloud_X_2; 
    float distanceY_2 = playerY - normalCloud_Y_2; 
    float distance_2 = sqrt( (distanceX_2*distanceX_2) + (distanceY_2*distanceY_2)); 
    
    if (distance_2 <= playerRadius + cloudRadius) 
    {
      resetCloud(2);
      playerScore-=100;
    }
  
  //Cloud #3
    float distanceX_3 = playerX - normalCloud_X_3; 
    float distanceY_3 = playerY - normalCloud_Y_3; 
    float distance_3 = sqrt( (distanceX_3*distanceX_3) + (distanceY_3*distanceY_3)); 
    
    if (distance_3 <= playerRadius + cloudRadius) 
    {
      resetCloud(3);
      playerScore-=100;
    }
  
  //Cloud #4
    float distanceX_4 = playerX - rainCloud_X_1; 
    float distanceY_4 = playerY - rainCloud_Y_1; 
    float distance_4 = sqrt( (distanceX_4*distanceX_4) + (distanceY_4*distanceY_4)); 
    
    if (distance_4 <= playerRadius + cloudRadius) 
    {
      resetCloud(4);
      playerScore+=200;
    }
  
  //Cloud #5
    float distanceX_5 = playerX - rainCloud_X_2; 
    float distanceY_5 = playerY - rainCloud_Y_2; 
    float distance_5 = sqrt( (distanceX_5*distanceX_5) + (distanceY_5*distanceY_5)); 
    
    if (distance_5 <= playerRadius + cloudRadius) 
    {
      resetCloud(5);
      playerScore+=200;
    }
  
  //Cloud #6
    float distanceX_6 = playerX - rainCloud_X_3; 
    float distanceY_6 = playerY - rainCloud_Y_3; 
    float distance_6 = sqrt( (distanceX_6*distanceX_6) + (distanceY_6*distanceY_6)); 
    
    if (distance_6 <= playerRadius + cloudRadius) 
    {
      resetCloud(6);
      playerScore+=200;
    }
}

void playerMovement() //Actually moves player
{
    if (playerGoLeft == true) //Left (Key = A)
    {
      if (playerX > 0)
      {
          playerX-=playerSpeed;
      }
    }
    
    if (playerGoRight == true) //Right (Key = D)
    {
      if (playerX < width)
      {
        playerX+=playerSpeed;
      }
    }
    
    if (playerGoUp == true) //Up (Key = W)
    {
      if (playerY > 0)
      {
        playerY-=playerSpeed;
      }
    }
    
    if (playerGoDown == true) //Down (Key = S)
    {
      if (playerY < height)
      {
        playerY+=playerSpeed;
      }
    }
    
    if (showScore == true) //Score (Key = Spacebar)
    {
        println("Player Score = " ,playerScore, "     Player Category =" ,playerCategory);
    }
}

void moveClouds() //Cloud Movement controller. Clouds slowly move from left or right to the opposite side
{
  //Special Cloud (#0)
  if (playerCategory >= 4)
  {
    //If cloud's X is inferior to value, increase or decrease until it reaches value.
    //Determine if it's moving (left to right) or (right to left)
    if (specialCloudDirection == 1) //left to right
    {
       if (specialCloud_X <= 450) 
       {
        specialCloud_X += specialCloudSpeed; 
       }
       else if (specialCloud_X > 450)
       {
        resetCloud(0); 
       }
    }
    else if (specialCloudDirection == 2) //right to left
    {
        if (specialCloud_X >= -50) 
        {
         specialCloud_X -= specialCloudSpeed; 
        }
        else if (specialCloud_X < -50)
        {
          resetCloud(0);
        }
    }
  }
  
  
  //Normal Cloud (#1)
    if (normalCloud_X_1 <= 450) //left to right
    {
      normalCloud_X_1 += normalCloudSpeed_1;
    } 
    else if (normalCloud_X_1 > 450)
    {
      resetCloud(1);
    }
  
  //Normal Cloud (#2)
    if (normalCloud_X_2 >= -50) //right to left
    {
      normalCloud_X_2 -= normalCloudSpeed_2;
    } 
    else if (normalCloud_X_2 < -50)
    {
      resetCloud(2);
    }
  
  //Normal Cloud (#3)
    if (normalCloud_X_3 <= 450) //left to right
    {
     normalCloud_X_3 += normalCloudSpeed_3; 
    }
    else if (normalCloud_X_3 > 450)
    {
     resetCloud(3); 
    }
    
  //Rain Cloud (#4)
    if (rainCloud_X_1 >= -50) // right to left
    {
      rainCloud_X_1 -= rainCloudSpeed_1;
    }
    else if (rainCloud_X_1 < - 50) 
    {
      resetCloud(4);
    }
  //Rain Cloud (#5)
    if (rainCloud_X_2 <= 450) // left to right
    {
      rainCloud_X_2 += rainCloudSpeed_2;
    }
    else if (rainCloud_X_2 > 450) 
    {
      resetCloud(5);
    }
  
  //Rain Cloud (#6)
    if (rainCloud_X_3 >= -50) // right to left
    {
      rainCloud_X_3 -= rainCloudSpeed_3;
    }
    else if (rainCloud_X_3 < - 50) 
    {
      resetCloud(6);
    }
}

void resetCloud(int cloudNumber) //Reset Clouds once off screen or collided with
{
  //Special Cloud 
  if (cloudNumber == 0) // (#0)
  {
     if (specialCloudDirection == 1)
     {
       specialCloud_X = -50; //Reset Cloud back to start X position
       specialCloud_Y = random(50,375); //Reset & randomize Y position
       specialCloudSpeed = (random(2,4) * gameDifficulty) + 1; //Randomize speed based on difficulty player is currently at
       specialCloudDirection = (int)random(1,3);
     }
     else if (specialCloudDirection == 2)
     {
       specialCloud_X = 450;
       specialCloud_Y = random(50,375);
       specialCloudSpeed = (random(2,4) * gameDifficulty) + 1;
       specialCloudDirection = (int)random(1,3);
     }
  }
  
  //Normal Cloud
  else if (cloudNumber == 1) // (#1)
  {
   normalCloud_X_1 = -50; 
   normalCloud_Y_1 = random(50, 375); 
   normalCloudSpeed_1 = random(2,4)*gameDifficulty; //Randomize speed based on difficulty player is currently at
  }
  else if (cloudNumber == 2) // (#2)
  {
   normalCloud_X_2 = 450;
   normalCloud_Y_2 = random(50, 375); 
   normalCloudSpeed_2 = random(2,4)*gameDifficulty;
  }
  else if (cloudNumber == 3) // (#3)
  {
   normalCloud_X_3 = -50;
   normalCloud_Y_3 = random(50,375);
   normalCloudSpeed_3 = random(2,4)*gameDifficulty;
  }
  else if (cloudNumber == 4) // (#4)
  {
   rainCloud_X_1 = 450;
   rainCloud_Y_1 = random(50,375);
   rainCloudSpeed_1 = random(1,3)*gameDifficulty;
  }
  else if (cloudNumber == 5) // (#5)
  {
   rainCloud_X_2 = -50;
   rainCloud_Y_2 = random(50,375);
   rainCloudSpeed_2 = random(1,3)*gameDifficulty;
  }
  else if (cloudNumber == 6) // (#6)
  {
   rainCloud_X_3 = 450;
   rainCloud_Y_3 = random(50,375);
   rainCloudSpeed_3 = random(1,3)*gameDifficulty;
  }
  else if (cloudNumber > 6)
  {
   println("cloud number exceeds 6"); 
  }
}

void scoreManager() //Determines Category, playerSpeed & Difficulty (which changes Cloud's speeds)
{
  
//Score Manager 
  if (playerScore <= 0)
  {
   println("YOU ARE JUST A TROPICAL STORM NOW! BETTER LUCK NEXT TIME!");
   playerCategory = 0;
   
   rectMode(CORNER);
   fill(255,0,0);
   rect(0,0,400,400); //Screen Flashes Red
   gameStarted = false; //Game will reset itself
  }
  else if (playerScore > 0 && playerScore < 1500)
  {
   gameDifficulty = 1;
   playerCategory = 1;
   playerSpeed = 5;
  }
  else if (playerScore >= 1500 && playerScore < 5000)
  {
   gameDifficulty = 1.5;
   playerCategory = 2;
   playerSpeed = 5.5;
  }
  else if (playerScore >= 5000 && playerScore < 10000)
  {
   gameDifficulty = 2;
   playerCategory = 3;
   playerSpeed = 6;
  }
  else if (playerScore >= 10000 && playerScore < 25000)
  {
   gameDifficulty = 2.2;
   playerCategory = 4;
   playerSpeed = 6.5;
  }
  else if (playerScore >= 25000)
  {
   gameDifficulty = 2.5;
   playerCategory = 5;
   playerSpeed = 7;
  }
  
  //Special Controls to adjust score
    if (increaseScore == true)
    {
     playerScore += 1000; 
    }
    else if (decreaseScore == true)
    {
     playerScore -=1000; 
    }
}

void drawBackground() //Draw Sky background
{
//Draw Sky (TOP to BOTTOM)
  //Top
    rectMode(CENTER);
    noStroke();
    fill(36,163,224,255-(playerCategory * 35)); //Lower Alpha level the higher category a player achieves
    rect(200,50,400,100);
    
  //Middle #2
    rectMode(CENTER);
    noStroke();
    fill(72,175,224,255-(playerCategory * 35));
    rect(200,150,400,100);
    
  //Middle #1
    rectMode(CENTER);
    noStroke();
    fill(143,208,240,255-(playerCategory * 35));
    rect(200,250,400,100);
    
  //Bottom
    rectMode(CENTER);
    noStroke();
    fill(175,224,247,255-(playerCategory * 35));
    rect(200,350,400,100);
  
//Draw Background Clouds
  rectMode(CENTER);
  noStroke();
  
  fill(255,255,255,150);
  rect(100,100,150,30,25);
    
  fill(255,255,255,110);
  rect(230,340,100,30,15);
    
  fill(255,255,255,200);
  rect(350,150,75,15,10);
}

void drawClouds() //Draw moving clouds (3 ellipses compose body of single cloud)
{
  ellipseMode(CENTER);
  float cloudDiameter = cloudRadius * 2;
  noStroke();
  
  if (playerCategory >= 4) //Only draw special cloud if player has reached minimum category
  {
    //Special Cloud
      fill(222,65,65);
      ellipse(specialCloud_X, specialCloud_Y - 5, cloudDiameter,cloudDiameter);
      ellipse(specialCloud_X + 12, specialCloud_Y, cloudDiameter,cloudDiameter);
      ellipse(specialCloud_X - 12, specialCloud_Y, cloudDiameter,cloudDiameter);
  }
  
  //Normal Cloud (#1)
    fill(175);
    ellipse(normalCloud_X_1, normalCloud_Y_1 - 5, cloudDiameter,cloudDiameter);
    ellipse(normalCloud_X_1 + 12, normalCloud_Y_1, cloudDiameter,cloudDiameter);
    ellipse(normalCloud_X_1 - 12, normalCloud_Y_1, cloudDiameter,cloudDiameter);
    
  //Normal Cloud (#2)
    fill(175);
    ellipse(normalCloud_X_2, normalCloud_Y_2 - 5, cloudDiameter,cloudDiameter);
    ellipse(normalCloud_X_2 + 12, normalCloud_Y_2, cloudDiameter,cloudDiameter);
    ellipse(normalCloud_X_2 - 12, normalCloud_Y_2, cloudDiameter,cloudDiameter);
    
  //Normal Cloud (#3)
    fill(175);
    ellipse(normalCloud_X_3, normalCloud_Y_3 - 5, cloudDiameter,cloudDiameter);
    ellipse(normalCloud_X_3 + 12, normalCloud_Y_3, cloudDiameter,cloudDiameter);
    ellipse(normalCloud_X_3 - 12, normalCloud_Y_3, cloudDiameter,cloudDiameter);
    
  //Rain Cloud (#4)
    fill(0,0,175);
    ellipseMode(CENTER);
    ellipse(rainCloud_X_1, rainCloud_Y_1 - 5, cloudDiameter,cloudDiameter);
    ellipse(rainCloud_X_1 + 12, rainCloud_Y_1, cloudDiameter,cloudDiameter);
    ellipse(rainCloud_X_1 - 12, rainCloud_Y_1, cloudDiameter,cloudDiameter);
  //Rain Cloud (#5)
    fill(0,0,175);
    ellipse(rainCloud_X_2, rainCloud_Y_2 - 5, cloudDiameter,cloudDiameter);
    ellipse(rainCloud_X_2 + 12, rainCloud_Y_2, cloudDiameter,cloudDiameter);
    ellipse(rainCloud_X_2 - 12, rainCloud_Y_2, cloudDiameter,cloudDiameter);
  //Rain Cloud (#6)
    fill(0,0,175);
    ellipse(rainCloud_X_3, rainCloud_Y_3 - 5, cloudDiameter,cloudDiameter);
    ellipse(rainCloud_X_3 + 12, rainCloud_Y_3, cloudDiameter,cloudDiameter);
    ellipse(rainCloud_X_3 - 12, rainCloud_Y_3, cloudDiameter,cloudDiameter);
}

void drawPlayer() //Draw player (hurricane)
{
  float playerDiameter = (playerRadius * 2) + playerCategory * 3; //Player grows as category increases
  ellipseMode(CENTER);
  noStroke();
  
  //Body
    fill(20  - (playerCategory * 15),152  - (playerCategory * 15),216  + (playerCategory * 15)); //Player gets increasing blue as category increases
    ellipse(playerX,playerY,playerDiameter,playerDiameter);
    ellipse(playerX + 10,playerY,playerDiameter,playerDiameter);
    ellipse(playerX - 10,playerY,playerDiameter,playerDiameter);
    ellipse(playerX - 5,playerY + 10,playerDiameter,playerDiameter);
    ellipse(playerX + 5,playerY + 10,playerDiameter,playerDiameter);
    ellipse(playerX,playerY + 18,playerDiameter,playerDiameter);
  
  //Eyes
    if (playerCategory == 5) //Eyes glow red at category 5
    {
     fill(225,0,0); 
    }
    else
    {
     fill(0); 
    }
      if (playerCategory != 0) //If player is category 0, don't draw eyes
      {
       ellipse(playerX - 8, playerY + 3, playerDiameter/5, playerDiameter/5); //Left
       ellipse(playerX + 8, playerY + 3, playerDiameter/5, playerDiameter/5); //Right
      }
  
  //Eyebrows
    if (playerCategory >= 3) //Add eyebrows if above category 3
    {
      fill(0);
      stroke(0);
      line(playerX - 12, playerY - 8, playerX - 6, playerY - 5);
      line(playerX + 12, playerY - 8, playerX + 6, playerY - 5);
    }
    
  //Mouth
    if (playerCategory >= 4) //Add mouth if above category 4
    {
     fill(0);
     noStroke();
     ellipse(playerX,playerY + 20, playerDiameter/4.5, playerDiameter/4.5);
    }
}

void keyPressed() //Register a key is pressed
{
    if (key == 'a' || key == 'A')
    {
      playerGoLeft = true;
    }
    else if (key == 'd' || key == 'D')
    {
     playerGoRight = true;
    }
    else if (key == 'w' || key == 'W')
    {
     playerGoUp = true; 
    }
    else if (key == 's' || key == 'S')
    {
     playerGoDown = true; 
    }
    else if (keyCode == ' ')
    {
     showScore = true;
    }
    else if (keyCode == '1')
    {
     increaseScore = true;
    }
    else if (keyCode == '2')
    {
     decreaseScore = true;
    }
}

void keyReleased() //Register a key has been released
{
  if (key == 'a' || key == 'A')
    {
      playerGoLeft = false;
    }
    else if (key == 'd' || key == 'D')
    {
     playerGoRight = false;
    }
    else if (key == 'w' || key == 'W')
    {
     playerGoUp = false; 
    }
    else if (key == 's' || key == 'S')
    {
     playerGoDown = false; 
    }
    else if (keyCode == ' ')
    {
      showScore = false;
    }
    else if (keyCode == '1')
    {
     increaseScore = false;
    }
    else if (keyCode == '2')
    {
     decreaseScore = false;
    }
}