> show canvas only <


/* built with Studio Sketchpad: 
 *   https://sketchpad.cc
 * 
 * observe the evolution of this sketch: 
 *   https://studio.sketchpad.cc/sp/pad/view/ro.Dp3MntjbWw0/rev.8100
 * 
 * authors: 
 *   Daewon Lee

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



int screen_x;
int screen_y;

float paddle_x=150;
float paddle_y=280;
float paddle_w=100;
float paddle_h=10;
boolean gameover = false;
int score=0;

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


class Object {

    float x;
    float y;
    float speed_x;
    float speed_y;
    float width;
    float height;
    //float health;
    
    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);
    }
}

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;
    }
}
class Weapon extends Object {
    
    string weapon_type;
    int  times_fired;
    
       
    boolean out_of_ammo () {
        if (weapon_type == "bomb" && times_fired >= 5) {
            return true;
        }
        
        return false;
    }

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 
        weapon_type = "ghost";
        
        //weapon_type = "bomb";
        
    x = random(0,screen_x);
    y = random(0,screen_y*10) - screen_y*10;
    
    speed_x = 0;
    speed_y = random (2,20);    
  }  
    
} 
class Projectile extends Object {
    
    string type;
    
    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;
    }
    
}

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;   
    }
}

class Car {
    
    float x;
    float y;
    float diameter;
    float speed_x;
    float speed_y;
    int   width;
    int   height;
    int health;
    
    PImage img;
    
    Weapon weapon;
    
    Car () {
        
         init();  
        
        width = 32;
        height = 48;     
    }
    
    void take_damage (int damage, boolean resetWhenDead)
    {
        health -= damage;
           
        if (resetWhenDead && health <= 0)
        {
            init ();
        }
    }
    
    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();
           }
           else {
              p = new Projectile();
           }
           
           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;
            }
        }
        
    }
    
    
    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;   
    }
    
    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;
    }
    
    void draw ()
    {
        image(img, x, y, width, height);
    }
    
    void move ()
    { 
        //if (y>300 - diameter / 2)
    //{
        //y = 300 - diameter / 2;
        //speed_y = -speed_y;
    //}
    
        if (y>paddle_y -diameter / 2 && x>paddle_x - paddle_w / 2  && x<paddle_x  + paddle_w / 2 )
        { 
           // y = paddle_y -diameter/ 2;
             //speed_y = -speed_y;
        }
    
        if (y<0 + diameter / 2)
        {
    //        y = 0 + diameter / 2;
    //        speed_y = -speed_y;
        }
    
        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();
        }
    }
}

Car[] cars = new Car[10];
Car myCar = new Car();


Object[] items = new Object[3 + 3]; // 3 for bonus items, 3 for weapons

ArrayList projectiles = new ArrayList();

PImage[] images = new PImage[3];
PImage kaboom = new PImage();
int showKaboom = 0;
int kaboom_x, kaboom_y;

void setup() {  // this is run once.   
    
    // set the background color
    background(255);
    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);
    
    // set the width of the line. 
    strokeWeight(3);
    
    
    images[0] = loadImage("http://www.velvetmatter.com/blah/car-a.png");

    images[1] = loadImage("http://www.velvetmatter.com/blah/car-big.png");

    images[2] = loadImage("http://www.velvetmatter.com/blah/car-dl.png");    

    kaboom = loadImage("http://t3.gstatic.com/images?q=tbn:ANd9GcQG0CEcNsW0uoTnl9x8siUf6J8FYzi56Al9jgPFxSrIcIT9BYjFMQ");

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

    myCar.img = loadImage("http://www.velvetmatter.com/blah/car-a.png");
    myCar.x = screen_x/2;
    myCar.y = screen_y-50;
    myCar.speed_x = 0;
    myCar.speed_y = 0;
    
    items[0] = new BonusItem();
    items[1] = new BonusItem();
    items[2] = new BonusItem();
    
    items[3] = new Weapon();
    items[4] = new Weapon();
    items[5] = new Weapon();
    
    for (int i = 0; i < items.length; i++)
    {   
        items[i].init();   
    }            
} 

boolean gotacc=false;

double ax = 12;
double ay = 54;


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

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

    if (gameover)
    {
        return;   
    }

    background(255);
        
    ellipseMode(CENTER);
    rectMode(CENTER);
        
    //partially erase background
    //fill(255,255,255,65);
    //rect(150,150,300,300);

    for (int i = 0; i < cars.length; i++)
    {
        cars[i].draw();
        cars[i].move();
        
        if (myCar.intersects ( cars[i] ))
        {
            showKaboom=10;
            kaboom_x=myCar.x;
            kaboom_y=myCar.y;
            
            
            myCar.take_damage(20,false);
            cars[i].take_damage(100,true);

            try
            {
                playSound();
            }
            catch (err)
            {
                
            }
        }
    }
    
    // handle bonus items and weapons (pickup)
    for (int i = 0; i < items.length; i++)
    {
        Object item = items[i];
        
        item.draw();
        item.move();
        
        if (item.intersects(myCar.x,myCar.y,myCar.width,myCar.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();
        }
    }   
    
    // 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 < screen_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();
                
                score += 100;
            }
        }
        
        
        
        if (p.is_above_screen() == true) {
            projectiles.remove(i);
            i --;
        }
    }
    
        if (gotacc == true) {
                myCar.x += ax * 5;
        }
        else {
            myCar.x = mouseX;
        }
    
    
    if (myCar.x < 10) {
        myCar.x = 10;
    }
    
    if (myCar.x > screen_x - myCar.width) {
        myCar.x = screen_x - myCar.width;
    }
    
    myCar.draw();
    
    if (showKaboom>0)
    {
        image (kaboom,kaboom_x,kaboom_y - 80,80,80);
        
        showKaboom=showKaboom-1;
    }
    
    score+=1;
    
    fill(0,0,0);
    
    if (myCar.weapon)
    {
        text("weapon: "+ myCar.weapon.weapon_type,100,20);
    }
    text("score: "+score, 10, 20);
    text("health: " + (int)(myCar.health), screen_x - 70,screen_y - 5);
        //text("ax: " + ax,100,20);
        //text("ay:" + ay,100,50);
    
    if (myCar.health<=0)
    {
        gameover = true;
            
        fill(0,0,0);
        font=createFont("Arial", 32);
        textFont(font);
        textAlign(CENTER);
        text("game over", screen_x / 2, screen_y / 2);
    }
}

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

void mousePressed()
{
    fire();
}