> show canvas only <


/* built with Studio Sketchpad: 
 *   https://sketchpad.cc
 * 
 * observe the evolution of this sketch: 
 *   https://studio.sketchpad.cc/sp/pad/view/ro.6xWASEeu2LF/rev.5278
 * 
 * authors: 
 *   Craig Kitchen
 *   

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



// Pressing Control-R will render this sketch.
public abstract class Picture{
    abstract void center();
    abstract void draw(int i);
}
public abstract class Brain{
    abstract PVector getvel(PVector pos, PVector oldvel);
}
public abstract class Sense{
    abstract boolean notices (PVector mepos, PVector mevel, PVector youpos);
}

PVector moveret = new PVector (70, 105);
int moveretrad = 70;

class DeadBrain extends Brain{
    PVector getvel (PVector pos, PVector oldvel){
        return (new PVector (0,0));
    }
}

public class Thing {
    private PVector pos, vel;
    private float speed, angle;
    private Picture pic;
    private Brain br;
    private int health = 255;
    public Thing (xi, yi, pici, bri){
        pos = new PVector(xi, yi);
        pic = pici;
        br = bri;
        vel = br.getvel(pos, vel);
    }
    
    public void hurt(){
        health -= 10;
        if (health < 0){
            health = 0;
        }
    }
    
    public int gethealth(){
        return health;
    }
    
    public void center(){
        translate (-pos.x + width/2, -pos.y + height/2);
    }
    
    public void setbrain(Brain bri){
        br = bri;
    }
    
    public PVector getpos(){
        return pos;
    }
    
    public void draw (){
        vel = br.getvel(pos, vel);
        pos.add(vel);
        if (pos.x < 10 || pos.x > width-10 || pos.y < 10 || pos.y > height - 10){
            this.hurt();
        }
        if (health <= 0){
            br = new DeadBrain;
        }
        
        //x = (x < 0 ? x + width : (x > width ? x - width : x));
        //y = (y < 0 ? y + height : (y > height ? y - height : y));
        //line (width/2,height/2,pos.x,pos.y);
        pushMatrix();
        translate (pos.x, pos.y);
        pic.draw(health);
        popMatrix();
    }
    
}

class PersonPicture extends Picture{
    void draw(int i){
        pushStyle();
        strokeWeight(2);
        fill(i == 0 ? 0 : 255,i,i);
        ellipse (0,0,10,10);
        strokeWeight(1);
        popStyle();
    }
}

class EnemyPicture extends Picture{
    void draw(int i){
        pushStyle();
        fill(i == 0 ? 0 : i,i,0);
        ellipse (0,0,10,10);
        popStyle();
    }
}

class PlayerBrain extends Brain{
    PVector vel = new PVector (0,0);
    Boolean move = false;
    PVector getvel(PVector pos, PVector oldvel){
        PVector mouse = new PVector (mouseX, mouseY);
        PVector s = PVector.sub(mouse, moveret);

        if (!mousePressed){
            move = false;
        }

        if ((s.mag() < moveretrad && mousePressed) || move) {
            vel = PVector.div(s,moveretrad/2);
            move = true;
        } else {
            vel.mult(.8);
        }
        
        if (vel.mag() < .3){
            vel.set(0,0);
        } else if (vel.mag() > 2){
            vel.mult(2/vel.mag());
        }
        return vel;
    }
}

class RandomBrain extends Brain{
    PVector vel = new PVector (1,0);
    int timer = 0;
    int change = 0;
    PVector getvel(PVector pos, PVector oldvel){
        timer++;
        
        if (pos.x >= width - 15){
            vel.set((random(6)-6)*.3, vel.y);
        } else if (pos.x <= 15){
            vel.set((random(6))*.3, vel.y)
        }
        
        if (pos.y >= height - 15){
            vel.set(vel.x, (random(6)-6)*.3);
        } else if (pos.y <= 15){
            vel.set(vel.x, (random(6))*.3);
        }
        
        if (timer > change){
            timer = 0;
            change = random(100);

            vel = new PVector ((random(11)-6)*.3, (random(11)-6)*.3);
        }
        return vel;
    }
}

float mydist(PVector p1, PVector p2){
    return Math.pow(Math.pow(p1.x - p2.x,2) + Math.pow(p1.y - p2.y,2),.5);
}

class CircleSight extends Sense{
    int sightrad = 30;
    public boolean notices (PVector mepos, PVector mevel, PVector youpos){
        PVector sightcenter = PVector.add(mepos,PVector.mult(PVector.normalize(mevel), sightrad));
        //ellipse(sightcenter.x, sightcenter.y,sightrad*2, sightrad*2);
        float distance = mydist(sightcenter, youpos);
        if (distance < sightrad){
            return true;
        } else {
            return false;
        }
    }
}

PlayerBrain p1 = new PlayerBrain();
Thing me = new Thing (210, 105, new PersonPicture, p1);


class FollowBrain extends Brain{ 
    PVector getvel (PVector pos, PVector oldvel){
        PVector tome = PVector.sub(me.getpos(),pos);
        
        if (tome.mag() == 0){
            return (new PVector (0,0));
        } else {
            return PVector.normalize(tome);
        }
    }
}

class SearchBrain extends Brain{
    Sense sight = new CircleSight;
    PVector vel = new PVector (1,0);
    int timer = 0;
    int change = 0;
    
    PVector getvel (PVector pos, PVector oldvel){
        if (oldvel == null){
            oldvel = new PVector (0,1)
        }
        if (sight.notices(pos, oldvel, me.getpos())){
            PVector tome = PVector.sub(me.getpos(),pos);
            timer = 0;
            change = 100;
            if (tome.mag() == 0){
                vel = (new PVector (0,0));
            } else {
                vel = PVector.mult(PVector.normalize(tome),1.2);
            }
        } else {
            timer++;
        
            if (pos.x >= width - 15){
                vel.set((random(6)-6)*.3, vel.y);
            } else if (pos.x <= 15){
                vel.set((random(6))*.3, vel.y)
            }
        
            if (pos.y >= height - 15){
                vel.set(vel.x, (random(6)-6)*.3);
            } else if (pos.y <= 15){
                vel.set(vel.x, (random(6))*.3);
            }
        
            if (timer > change){
                timer = 0;
                change = random(100);

                vel = new PVector ((random(11)-6)*.3, (random(11)-6)*.3);
            }
        }
        return vel;
    }
}

Thing[] others = new Thing[35];


void setup() {  // this is run once.   
    // set the background color
    background(255);
    // canvas size (Variable aren't evaluated. Integers only, please.)
    size(420, 210);
    // smooth edges
    smooth();
    // limit the number of frames per second
    frameRate(30);
    // set the width of the line. 
    strokeWeight(1);
    f = createFont("Arial",16,true); 
    noFill();
    for (int i = 0; i < others.length; i++){
        others[i] = new Thing (random(width/2-30)+15+((int)random(2))*width/2, random(height-30)+15, new EnemyPicture, new SearchBrain);
    }
} 
int score = 0;
void draw() {
    background (255);  
    
    if (me.gethealth() > 0) score++;
    

    
    pushMatrix();
    me.center();
    rect(10,10,width-20, height-20);
    for (int i = 0; i < others.length; i++){
        others[i].draw();
        if (mydist(others[i].getpos(), me.getpos()) < 8){
            me.hurt();
        }
    }

    me.draw();
    popMatrix();
    pushStyle();
    fill(0);
    text(score, width/2, height - 10);
    popStyle();
    ellipse (moveret.x, moveret.y, moveretrad*2, moveretrad*2);
    ellipse (moveret.x, moveret.y, 20, 20);
}

void keyPressed() {
  if (key == ((int) 'f') || key == ((int) 'F')) {
    //you.setbrain(new FollowBrain);
  } else if (key == 'R' || key == 'r') {
    //you.setbrain(new RandomBrain);
  } else if (key == 'P' || key == 'p') {
    //you.setbrain(new PlayerBrain);
  }

}