> show canvas only <


/* built with Studio Sketchpad: 
 *   https://sketchpad.cc
 * 
 * observe the evolution of this sketch: 
 *   https://sketchpad.cc/sp/pad/view/ro.K3Qtjdl0csA/rev.36
 * 
 * authors: 
 *   

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



    import controlP5.*;
    
    PImage bg, mycursor, ammo, heal; // Proměnné pro obrazky
    PFont f, Font2; // Proměnné pro Font.
    boolean upPressed, downPressed, leftPressed, rightPressed; // Proměnné pro pohyb.
    ArrayList<Bullet> arrayBullets = new ArrayList<Bullet>(); // Pole kulek.
    ArrayList<Zombies> arrayZombies = new ArrayList<Zombies>(); // Pole Zombíků.
    PVector mouse; // Pozice myši.
    color myColor; // Moje barvy.
    boolean reload; // Vrazí zda zrovna přebíjím nebo ne.
    boolean isLockedBecauseReloading; // Zakázaní střelby během nabíjení.
    boolean isPaused = false; // Kontroluje zda je hra pauznutá nebo ne.
    int lastSpawn = 0; // Počíta čas od posledního spawnu zombíka.
    int counter = 0; // Počítá počet vykreslených nepřátel.
    int pocetZombie = 5;
    int spawnTime = 1350; // Čas po jakém se spawne další zombík.
    //Classes
    Player p;
    Bullet b;
    Zombies z;
    
    //Functions
    
    void setup() {
      // size(1000, 700);
      fullScreen(1);
      loadStuff(); // Načtení obrázku, zvuků, atd..
      imageMode(CENTER);
      smooth();
      noCursor();
      cursor (mycursor, 0, 13);
      noStroke();
      isLockedBecauseReloading = false; // Povolení střelby po spuštění hry.
    
      print(p.location);
    } 
    void draw() {  
      background(0);
      mouse = new PVector(mouseX, mouseY);
      showFPS(); // Zobrazení FPS, života a ukazatele nábojů
      p.move(); // Pohyb hráče
      p.Display(); // Zobrazení hráče.
      giveBullets(); // Vykresluvání vystřelených kulek.
      p.reloadMagazine(); // Přebíjení
      image(ammo, width-92, height-89); // Ikonka nábojů
      image(heal, width-92, height-41); // Ikonka života.
      ZGenerate();
      zombieSpawn();
    
    
    
      p.checkHeal(); // Kontrola životů. => GAME OVER
    }
    
    
    
    void loadStuff() {
      mycursor = loadImage("Graphics/cursor2.png");
      Font2 = createFont("Fonts/Magazine.ttf", 32);
      ammo = loadImage("Graphics/ammo.png");
      heal = loadImage("Graphics/heal.png");
      heal.resize(30, 30);
      ammo.resize(50, 30);
      f = createFont("Arial", 16, true);
      p = new Player(width/2-28, height/2-20);
      bg=loadImage("Graphics/back.jpg");
      bg.resize(width, height);
    }
    
    
    void keyPressed(KeyEvent e) {
    
      if (key == 'w') {
        upPressed = true;
      } else if (key == 's') {
        downPressed = true;
      } else if (key == 'a') {
        leftPressed = true;
      } else if (key == 'd') {
        rightPressed = true;
      } else if (key == 'r') {
    
        reload = true; // gets main loop waiting for reload
        isLockedBecauseReloading = true;
        p.reloadStartTime = millis();
      }
    }
    
    
    void mousePressed() {
      p.shoot();
    }
    
    void keyReleased(KeyEvent e) {
    
      if (key == 'w') {
        upPressed = false;
      } else if (key == 's') {
        downPressed = false;
      } else if (key == 'a') {
        leftPressed = false;
      } else if (key == 'd') {
        rightPressed = false;
      } else if (key == 'p') {
        if (isPaused==false) {
          isPaused = true;
          noLoop();
          textFont(Font2, 200);
          fill(255, 11, 0);
          text("PAUSED", width/3.3, height/2-50);
        } else {
          isPaused = false;
          loop();
        }
      } else if (key =='o') {
        p.heal -= 13;
      }
    }
    
    
    
    void showFPS() {
      textFont(f, 19);
      fill(53, 247, 1);
      text("FPS: "+round(frameRate), 19, 40);
      textFont(Font2, 39);
      fill(255, 11, 0);
      text(p.zasobnik, width-50, height-71);
      setColor();
      fill(myColor);
      if (p.heal<0) {
        p.heal = 0;
      }
      text(p.heal, width-64, height-20);
    }
    
    void giveBullets() 
    {
    
      for (int i = 0; i < arrayBullets.size(); i++) {
        Bullet b = (Bullet) arrayBullets.get(i);
        b.move();
        b.Display();
      }
    }
    
    void zombieSpawn() { // First time i wanted to made this method in Class "Zombies" but when i tried to call it from draw => NullPointerException
    
      for (int i = 0; i < arrayZombies.size(); i++) {
        Zombies z = (Zombies) arrayZombies.get(i);
        //z.move();
    
        z.Display();
      }
    }
    
    void ZGenerate() { // Same problem like "zombieSpawn" => NullPointerException.
      if (millis() - lastSpawn >= spawnTime) {
        if (counter < pocetZombie) {
          z = new Zombies(int(random(0, width)), int(random(0, height)), 6, 200, 5, "Graphics/zombie.png");
          arrayZombies.add(z);
        }
        counter++;
        lastSpawn = millis();
      }
    }
    
    void setColor() {
      if (p.heal>=70) {
        myColor = color(0, 255, 0);
      } else if (p.heal<70 && p.heal>30) {
        myColor = color(255, 204, 0);
      } else if (p.heal<=30) {
        myColor = color(255, 0, 0);
      }
    }
    
    class Bullet {
      PImage bskin;
      float angle  = 0;
      float speed  = 3;
      float distance;
      PVector location, vel; 
    
      Bullet(float x, float y, PVector vel, float angel) {
        location = new PVector(x, y);
        this.angle = angel;
        this.vel = vel;
    
        bskin = loadImage("Graphics/bullet.png");
        bskin.resize(10, 5);
      }
    
      void Display() {
        pushMatrix();
        faceToMouse();
        image(bskin, 0, 0);
        popMatrix();
      }
    
      void faceToMouse() {
        translate(location.x, location.y);
        rotate(-angle-HALF_PI);
      }
    
      void move() {
        location.add(vel);
        if (location.y>height||location.y<0||location.x>width||location.x<0) {
          arrayBullets.remove(this);
          print("D:"+arrayBullets.size()+", ");
        }
      }
    }
    
    class Player{
      PImage skin;
      PVector location;
    
      int lastshot;
      int coolDown;
    
    
      float angle  = 0;
      float speed  = 4;
      int naboje = 15;
      int heal = 100;
      int zasobnik = naboje;
    
      // Timer pro reload
      long reloadStartTime;
      int wait = 2000;
      //Konec timeru pro reload------
    
    
    
      Bullet b;
      Player(float x, float y) {
        location = new PVector(x, y);
    
        skin = loadImage("Graphics/player.png");
        skin.resize(58, 40);
        lastshot = 0;
        coolDown = 10;
      } 
    
      void move() {
        if (upPressed) {
          location.y -= speed;
        }
        if (downPressed) {
          location.y += speed;
        }
    
        if (leftPressed) {
          location.x -= speed;
        }
        if (rightPressed) {
          location.x += speed;
        }
      }
    
      void Display() {
        pushMatrix();
    
        faceToMouse();
        image(skin, 0, 0);
    
        popMatrix();
      }
    
      void faceToMouse() {
        angle = atan2(location.x-mouse.x, location.y-mouse.y);
        translate(location.x, location.y);
        rotate(-angle-HALF_PI);
      }
      void shoot()
      {
        if (isLockedBecauseReloading!=true) {
          if (millis() - lastshot > coolDown )
          { 
            PVector dir = PVector.sub(mouse, p.location);
            dir.normalize();
            dir.mult(speed*3);
            if (p.zasobnik!=0) {  
              b = new Bullet(location.x, location.y, dir, angle);
              arrayBullets.add(b);
    
              zasobnik--;
            }
            print(arrayBullets.size()+", ");
            lastshot = millis();
          }
        }
      }
      void checkHeal() {
    
        if (heal<=0) {
          noLoop();
          background(0);
          textFont(Font2, 200);
          fill(255, 11, 0);
          text("GAME OVER", width/7, height/2-50);
        }
      }
      void reloadMagazine() {
        if (reload) {
          if (millis() > (reloadStartTime + wait)) { // more than 2 secs or whatever wait is set to
            zasobnik= 15;
            isLockedBecauseReloading = false;
            reload = false;
          }
        }
      } 
    } 
    
    class Zombies {
      PImage skin;
      String cesta;
      PVector location;
      int speed;
      int dmg;
      int heal;
      float angle  = 0;
      String obrazek;
    
    
    
      Bullet b;
      Player p;
    
      Zombies(float x, float y, int speed, int dmg, int heal, String obrazek) {
        location = new PVector(x, y);
        this.speed = speed;
        this.dmg = dmg;
        this.heal = heal;
        this.obrazek = obrazek;
        skin = loadImage(obrazek);
        skin.resize(58, 48);
      }
    
      void Display() {
        pushMatrix();
        faceToPlayer();
        image(skin, 0, 0);
        popMatrix();
      }
    
      void faceToPlayer() {
        
        angle = atan2(location.x-p.location.x, location.y-p.location.y); // HERE IS THE PROBLEM 
        translate(location.x, location.y);
        rotate(-angle-HALF_PI);
       
      }
    
    }// Konec CLASS ZOMBIE --------------------------