> show canvas only <


/* built with Studio Sketchpad: 
 *   https://sketchpad.cc
 * 
 * observe the evolution of this sketch: 
 *   https://studio.sketchpad.cc/sp/pad/view/ro.Z2GkEFkT2fl/rev.4467
 * 
 * authors: 
 *   Salvador Cueto
 *   

 * license (unless otherwise specified): 
 *   creative commons attribution-share alike 3.0 license.
 *   https://creativecommons.org/licenses/by-sa/3.0/ 
 */ 



// This sketch builds on a prior work, "cars", created by Daewon Lee
// http://studio.sketchpad.cc/sp/pad/view/ro.9civzkE0CyCy6/rev.8100

/////////////////////////////////////////////////////////////////
/////////////////       VARIABLES GENERALS   ////////////////////

int screen_x;
int screen_y;

int showKaboom = 0;
int kaboom_x, kaboom_y;
int showTomaa = 0;
int tomaa_x, tomaa_y;
int score=0;

float paddle_x = 150;
float paddle_y = 280;
float paddle_w = 100;
float paddle_h = 10;

boolean gameover = false;
boolean gotacc = false;

double ax = 12;
double ay = 54;


    /////////////////    INSTANCIACIO    /////////////////////////////

    Car[] cars = new Car[5];
    Car myCar = new Car();        
    Pantalla pant = new Pantalla();
    Object[] items = new Object[3 + 3]; // 3 for bonus items, 3 for weapons

    PImage[] images = new PImage[3];
    PImage kaboom = new PImage();
    PImage tomaa = new PImage();

    ArrayList projectiles = new ArrayList();

    PFont font = createFont("Arial", 13);



////////////////       CLASSES      /////////////////////////////
/////////////////////////////////////////////////////////////////
/////////////////      OBJECT      //////////////////////////////

class Object {

    float x;
    float y;
    float speed_x;
    float speed_y;
    float width;
    float height;
    string type;
    
    void draw() {
        
        fill(255,0,0);
        rect(x,y,width,height);
    }

    //********************

    void move() {
        x=x+speed_x;
        
        y=y+speed_y;
        
    }
    
    //********************

    void animate () {
    }

     //********************   

    boolean is_below_screen ()
    {
        if(y>screen_y) {
            return true;
        }
     
        return false;   
    }
    
    //********************

    boolean is_above_screen ()
    {
        if(y<0-height) {
            return true;
        }
        
        return false;
    }

    //********************

   
    boolean intersects (float _x, float _y, float _width, float _height, int border) {
         if (_x + border > x+width - border)
         {
             return false;
         }
         
         if (x + border > _x + _width - border)
         {
             return false;
         }
         
         if (_y + _height - border < y + border)
         {
             return false;
         }
         
         if (y+height - border < _y + border)
         {
             return false;
         }
         
                 
         return true;   
    }

    //********************
   
    boolean intersects (Object otherObject, int border)
    {
        return intersects (otherObject.x, otherObject.y, otherObject.width, otherObject.height, border);
    }
}

///////////////////     BONUSITEM     //////////////////////////////////////////

class BonusItem extends Object {
    
    int bonus_value;
    int diameter;

    //********************

    void draw() {
        
        fill(255,204,51);
        ellipse(x,y,width,height);
        
        fill(255,204,51,128);
        ellipse(x,y,diameter,diameter);
    }

    //********************
    
    void init () {
        
        type = "bonus";
        
        x = random(0,screen_x);
        y = random(0,screen_y*10) - screen_y*10;
        
        speed_x = 0;
        speed_y = random(2,20);
        
        bonus_value = random (5, 100);
        
        diameter = bonus_value;
        width = 25;
        height = 25;
    }
}

///////////////////      WEAPON     //////////////////////////////////////////////

class Weapon extends Object {
    
    string weapon_type;
    int  times_fired;
    
    //********************

    void draw() {
    
       fill (0,0,255);
       ellipse(x,y,25,25);
    }

    //********************

    void init() {
    
    type = "weapon";
    times_fired = 0;
    
    int n = (int)random(2.99);
    
    if (n == 0)
        weapon_type = "gun";    
    else if (n == 1)
        weapon_type = "cannon";
    else if (n == 2)
        weapon_type = "bomb";
    else if (n == 3){
        weapon_type = "ghost";    }
        
    x = random(0,screen_x);
    y = random(0,screen_y*10) - screen_y*10;
    
    speed_x = 0;
    speed_y = random (2,20);    
  }  
     //********************
       
    boolean out_of_ammo () {
        if (weapon_type == "bomb" && times_fired >= 5) {
            return true;
        }
        
        return false;
    }   
} 

/////////////////////     PROJECTILE     //////////////////////////////////////

class Projectile extends Object {
    
        
    void draw() {
        
        fill (255,0,0);
        ellipse(x,y,width,height);
    }    
 
    //********************
       
    void init() {
        
        type="bullet";
        
        width = 15;
        height = 15;
        
        x = -100;
        y = 0;
        
        speed_x = 0;
        speed_y = -12;
    }
    
}

/////////////////////      BOMB       //////////////////////////////////////

class Bomb extends Projectile{
    
    float radius;
    float radius_expansion_rate;
    boolean detonated;

    //********************

    void draw() {
        
        fill (255,0,0);
        ellipse(x,y,width,height);
        
        fill(255,0,0,128);
        ellipse(x,y,width+30+radius,width+30+radius);
    }

    //********************

    void init() {
        
        type="bomb";
        detonated = false;
        radius = 0;
        radius_expansion_rate = 0;
        
        speed_x = 0;
        speed_y = -3;
        
    }
    
    //********************

    void stop () {
        
        speed_y = 0;
        speed_x = 0;
    }
 
    //********************
   
    void explode() {
        
        if (detonated == true) {
            return;
        }
        
        radius_expansion_rate = 12;
        stop ();
        detonated = true;
    }
 
     //********************
  
    void animate() {
        
        radius += radius_expansion_rate;
        
        if (radius > 100) {
            radius = 100;
            radius_expansion_rate = -2;
        }
    }
 
     //********************
  
    boolean intersects (float _x, float _y, float _width, float _height, int border) {
         if (_x > x+width+radius)
         {
             return false;
         }
         
         if (x - radius > _x + _width)
         {
             return false;
         }
         
         if (_y + _height  < y - radius)
         {
             return false;
         }
         
         if (y+height+radius < _y )
         {
             return false;
         }
         
                 
         return true;   
    }
}


///////////////////////     CAR     ///////////////////////////////////////

class Car  extends BonusItem  {
    
    int health;
    
    PImage img;
    
    Weapon weapon;
    
    //********************      Car

    Car () {
        
         init();  
        
        width = 32;
        height = 48;     
    }

    //********************    take_damage
    
    void take_damage (int damage, boolean resetWhenDead)
    {
        health -= damage;
           
        if (resetWhenDead && health <= 0)
        {
            init ();
        }
    }

    //********************    fire_weapon
    
    void fire_weapon (){
        
        if (weapon){
            
            // create a projectile
            // initialize the projectile (position, velocity, etc...)
            // add it to the projectiles list
            
           Projectile p;
           
           if (weapon.weapon_type == "bomb") {
               p = new Bomb();                                                //new
           }
           else {
              p = new Projectile();                                            //new
           }
           
           p.init();
           p.x = x+width/2;
           p.y = y-height/2;
           
            projectiles.add (p);
            
            weapon.times_fired ++;
            
            if (weapon.out_of_ammo() == true) {
                weapon = null;
            }
        }
        
    }
    
    //********************      intersects
    
    boolean intersects (Car otherCar)
    {
         // x, y, width, height   &&   otherCar.x, otherCar.y, otherCar.width, otherCar.height
         
         int border = 5;
         
         if (otherCar.x + border > x+width - border)
         {
             return false;
         }
         
         if (x + border > otherCar.x + otherCar.width - border)
         {
             return false;
         }
         
         if (otherCar.y + otherCar.height - border < y + border)
         {
             return false;
         }
         
         if (y+height - border < otherCar.y + border)
         {
             return false;
         }
         
                 
         return true;   
    }

    //********************        init
    
    void init ()
    {
        x = random(0,screen_x);
        y = random(0,screen_y*2) - screen_y*2;
        diameter=60;
        speed_x=0;
        speed_y=random(2,20);   
        health=100;
    }

    //********************       draw
   
    void draw ()
    {
        image(img, x, y, width, height);
    }

    //********************       move
    
    void move ()
    { 
     
        if (y>paddle_y -diameter / 2 && x>paddle_x - paddle_w / 2  && x<paddle_x  + paddle_w / 2 )
        { 
           
        }
    
        if (y<0 + diameter / 2)
        {
   
        }
    
        y=y+speed_y;

        if (x>screen_x - diameter / 2)
        {
            x = screen_x - diameter / 2;
            speed_x = -speed_x;
        }
    
        if (x<0 + diameter / 2)
        {
            x = 0 + diameter / 2;
            speed_x = -speed_x;
        }
    
        x=x+speed_x;
    
        // if cars fall off the screen 
        if (y>screen_y + diameter) {
           
            
            init();
        }
    }
}

///////////////////////     PANTALLA     ///////////////////////////////////////

class Pantalla {
    
    PImage boom = new PImage();
    
    PImage toma = new PImage();
 
    Car Nau = new Car(); 
    

    //********************    Manegar Topis
    void mangTopis(){

        for (int i = 0; i < cars.length; i++)
        {
            cars[i].draw();
            cars[i].move();

            if (myCar.intersects ( cars[i] ))
            {
                showKaboom=20;//10
                kaboom_x=myCar.x;
                kaboom_y=myCar.y;


                myCar.take_damage(20,false);
                cars[i].take_damage(100,true);

                try
                {
                    playSound();
                }
                catch (err)
                {

                }
            }
        }
    }

    //********************     Manegar bonificacions i armes

    // handle bonus items and weapons (pickup)
    void mangArma(Car Nau){

        for (int i = 0; i < items.length; i++)
        {
            Object item = items[i];                                                 //

            item.draw();
            item.move();

            if (item.intersects(Nau.x,Nau.y,Nau.width,Nau.height,5) == true) {
               if (item.type == "bonus")
               { 
                   myCar.health += (BonusItem)item.bonus_value;

                       if (myCar.health>100) {
                       myCar.health=100;
                    } 
               }

               if (item.type == "weapon"){
                    myCar.weapon = (Weapon)item;
               }

               item.init();
            }

            if(item.is_below_screen() == true) {
                item.init();
            }
        }   
    }
       //********************                               Manegar Projectils

    void mangProjectils(int punts, int pantalla_y){       

        // handle projectiles
        for (int i = 0; i < projectiles.size(); i ++)
        {
            Projectile p = projectiles.get(i);

            p.draw();
            p.move();
            p.animate();

            if (p.type == "bomb" && p.y < pantalla_y  / 2) {
                Bomb b = p;
                b.explode();
            }

        // if (p intersects with any car) blow up car

            for (int ii = 0; ii < cars.length; ii++)
            {
                Car car = cars[ii];

                if (p.intersects(car.x,car.y,car.width,car.height,5)) {
                    car.init();

                    punts += 10000;///////
                    showTomaa=20;
                    tomaa_x=p.x;
                    tomaa_y=p.y;
                    image (tomaa,tomaa_x,tomaa_y -80,80,80);               
                }
            }

            if (p.is_above_screen() == true) {
                projectiles.remove(i);
                i --;
            }
        }
        return punts;
    }

    //********************        Mostrar Nau
    
    
   void mostraNau(Object Nau, boolean acc, int pantalla_x, int pantalla_y){

       if (acc == true) {
               Nau.x += ax * 5;
       }
        else {
           Nau.x = mouseX-Nau.width/2;
       }

        if (Nau.x < 0) {
            Nau.x = 0;
        }

        if (Nau.y > 450) {
            Nau.y = 450;
        }

        if (Nau.x > pantalla_x - Nau.width) {
            Nau.x = pantalla_x - Nau.width;
        }

        Nau.y=mouseY-Nau.height/2;

        Nau.draw();  

        return acc;
    }


     //********************            Mostrar armament

    void arma(Car Nau){
      if (Nau.weapon)
        {
            text("weapon: "+ Nau.weapon.weapon_type,100,20);
        }
    }
    
     //********************               Final

    void final(Car Nau, int pantalla_x, int pantalla_y){
       if (Nau.health<=0)
        {
            gameover = true;

            fill(0,0,0);
            PFont lletra=createFont("Arial", 32);
            textFont(lletra);
            textAlign(CENTER);
            text("game over", pantalla_x / 2, pantalla_y / 2);
        }
    }

     //********************         Mostrar Boom

    void boom(int showBoom, int boom_x, int boom_y, PImage boom){

        if (showBoom>0)
        {
            image (boom, boom_x, boom_y - 80,80,80);
            showBoom=showBoom-1;
            return showBoom;
        }
    }
    //********************          Mostrar Tomaa

    void toma(int showtoma,int toma_x, int toma_y, PImage toma){
        
        if (showtoma>0)
        {
           image (toma,toma_x,toma_y - 80,80,80);
           showtoma=showtoma-1;
           return showtoma;
        }
    }

    //********************       Mostrar puntuacio

    void punts(int punts, Car Nau, int pantalla_x, pantalla_y){

       text("score: "+punts, 10, 20);
       text("health: " + (int)(Nau.health), pantalla_x - 70, pantalla_y - 5);
       punts+=1;
       return punts;

       //fill(0,0,0);
    }
}

///////////////////////     GHOST     ///////////////////////////////////////

//class ghost{



   
//}

//////////////////////METODES  GENERALS//////////////////////////
/////////////////////////////////////////////////////////////////
//////////////////////    SETUP      ////////////////////////////

void setup() {  // this is run once. 


    // set the background color
    background(200);
    textFont(font);
    
    // canvas size (Variable aren't evaluated. Integers only, please.)
    size(300, 500); 
    
    screen_x = 300;
    screen_y = 500;
      
    // smooth edges
    smooth();
    
    // limit the number of frames per second
    frameRate(30);//30
    
    // set the width of the line. 
    strokeWeight(3);
    
    
    images[0] = loadImage("https://docs.google.com/drawings/pub?id=1TYLFmUuQAEOxOjHVjtVcWcApYmpx4comjtXQuPycqNQ&w=143&h=187");

    images[1] = loadImage("https://docs.google.com/drawings/pub?id=1E3L-BJboNOO7jVcLzCBP3jzwgnh5IxPr7UYGkeiNSfE&w=333&h=347");

    images[2] = loadImage("https://docs.google.com/drawings/pub?id=1WillIBH6Jvmk4rmnJinEf3-Lf1Suhnt2NazeBQ9lAD0&w=100&h=100");    

    kaboom = loadImage("https://docs.google.com/drawings/pub?id=1CLdOC8yp1Uscqh4zFMMBWZKAah9Mr3ugZSZfc2aO3E0&w=960&h=720");
    
 tomaa = loadImage("https://docs.google.com/drawings/pub?id=1SWffKW4Hibn6YaRqiuLQrsVWKrX2lSFEKUJBAwTrzm8&w=573&h=449");
    

    for (int i = 0; i < cars.length; i++)
    {
        cars[i] = new Car();                                                      //new
        
        int imageIndex = (int)random(0,images.length);
        
        cars[i].img = images[imageIndex];
    }

    myCar.img = loadImage("https://docs.google.com/drawings/pub?id=1VlE3PKvJsud2FHA8gOLjpVQU-_T9DoN1OHb3g_cDCp0&w=123&h=159");

    myCar.x = screen_x/2;                                                       //myCar,
    myCar.y = screen_y-50;                                                      //myCar,
    myCar.speed_x = 0;                                                          //myCar,
    myCar.speed_y = 0;                                                          //myCar,
    
    items[0] = new BonusItem();                                                   //new
    items[1] = new BonusItem();                                                   //new
    items[2] = new BonusItem();                                                   //new
    
    items[3] = new Weapon();                                                      //new
    items[4] = new Weapon();                                                      //new
    items[5] = new Weapon();                                                      //new
    
    for (int i = 0; i < items.length; i++)
    {   
        items[i].init();   
    }            
} 

////////////////////          SETACCELEROMETER    ////////////////////

void setaccelerometer(double _ax, double _ay) {
        ax=_ax;
        ay=_ay;
        
        gotacc=true;                                                             //gotacc
}

/////////////////////    DRAW    //////////////////////////////////

void draw() {  // this is run repeatedly.  

    if (gameover)
    {
        return;   
    }

    background(200);
        
    ellipseMode(CENTER);
    rectMode(CENTER);
        
    pant.mangTopis();//                                                      Manegar Topis

    pant.mangArma(myCar);//                                Manegar bonificacions i armes

    score=pant.mangProjectils(score,screen_y);//           anegar projectils i bombes

    gotacc=pant.mostraNau(myCar, gotacc,screen_x,screen_y);//           Mostra Nau
    
    showKaboom=pant.boom(showKaboom, kaboom_x,kaboom_y, kaboom);//   Mostra Boom

    showTomaa=pant.toma(showTomaa,tomaa_x,tomaa_y, tomaa);//    Mostra Tomaa

    score=pant.punts(score,myCar,screen_x,screen_y);//      Mostra punts

    pant.arma(myCar);//                                   Mostra arma

    pant.final(myCar,screen_x,screen_y);//    Final de la partida
}

//////////////////////     FIRE     ///////////////////////////////////////////

void fire()
{
        myCar.fire_weapon();
}

//////////////////////      MOUSEPRESSED      //////////////////////////////////

void mousePressed()
{
    fire();
}