Wednesday, October 10, 2018

Processing Classes Practice


Can be played here: https://www.openprocessing.org/sketch/605087


CODE:

//MAIN

//empty vector for using Vector functions
Vector useVector = new Vector();
Entity useEntity = new Entity(0);
//empty collision for using collision functions

//player Object
Entity player;//movement input
char[] moveKeys = {'d', 'a', 'w', 's'};
//movement values
int[] moveValues = new int[4];
//movement Vector
Vector moveVector = new Vector();
//movement Velocity
Vector moveVelocity = new Vector();
float playerSpeed = 5;

//Game Timeline
boolean startGame = false;
float gameTime;

//playerAttack
//bulletList
ArrayList <Bullet> bulletStack;
Vector playerBSpawn;
boolean attackPress;
float attackPause = 8;
float attackCycle;

//Enemies
Entity dummy;
//Enemy List
ArrayList <Entity> enemyList;
//enemy bulletList
ArrayList <Bullet> EBulletStack;
//Enemy Sequence
int ESequence;

void setup()
{
  size(1080, 720);
  //all colliders will be based on radius from the center of objects
  rectMode(CENTER);
  //set bullet stack to an empty ArrayList
  bulletStack = new ArrayList();
  //start position of the player
  player = new Entity(40, new Vector(width/2, height/1.2));

  //Enemies
  EBulletStack = new ArrayList();
  //
  enemyList = new ArrayList();
  //enemyList.add(dummy);
 
  //enemy Setup
  enemyTypes();
}

void draw()
{
  //background(255, 240, 200);
  fill(255, 240, 200, 150);
  rect(width/2, height/2, width, height);
 
  movePlayer();

  drawBullet();

  damageHit();

  enemySequence();
}

//
void mousePressed()
{
  attackPress = true;
}

void mouseReleased()
{
  attackPress = false;
}

void keyPressed()
{
  for (int a = 0; a < moveKeys.length; a++)
  {
    if (key == moveKeys[a])
    {
      moveValues[a] = 1;
    }

    if (key == ' ')
    {
      attackPress = true;
    }
  }
}

void keyReleased()
{
  for (int a = 0; a < moveKeys.length; a++)
  {
    if (key == moveKeys[a])
    {
      moveValues[a] = 0;
    }

    if (key == ' ')
    {
      attackPress = false;
    }
  }
}

void movePlayer()
{
  //direction input
  moveVector = new Vector(moveValues[0]- moveValues[1], moveValues[3] - moveValues[2]);
  moveVelocity = new Vector(moveVector.x * playerSpeed, moveVector.y * playerSpeed);
  //apply movement
  player.position = useVector.addVelocity(player.position, moveVelocity);

  //playerAttack
  //attack cooldown
  if (attackCycle > 0)
  {
    attackCycle--;
  }
  //attack when the attack cooldown is back at 0
  if (attackPress && attackCycle <= 0)
  {
    playerBSpawn = new Vector(player.position.x, player.position.y-35);
    //create a new bullet
    Bullet a = new Bullet(playerBSpawn, new Vector(0, -13));
    bulletStack.add(a);
    //start attack cooldown
    attackCycle = attackPause;
  }
  //draw the player
  player.drawCirc();
}


void drawBullet()
{
  //according to google "for(class : Arraylist){}" checks for every class in a array of classes,
  //useful but not my own work.
  /*for(Bullet stack: bulletStack)
   {
   stack.drawBullet();
   stack.moveBullet();
   }*/

  //move and draw each bullet in the stack
  for (int a = 0; a < bulletStack.size(); a++)
  { 
    fill(200,100,255);
    bulletStack.get(a).moveBullet();
    bulletStack.get(a).drawBullet();

    //delete the bullet if it's out of bounds
    if (bulletStack.get(a).deleteBullet())
    {
      bulletStack.remove(a);
    }
  }

}

//Damage
void damageHit()
{
  //HIT ENEMIES
  if (enemyList.size()>0)
  {
    for (int b = 0; b < enemyList.size(); b++)
    {
      //fix out of bounds bug
      if (bulletStack.size()>0)
      {
        for (int a = 0; a < bulletStack.size(); a++)
        {
          //attack test

          //use collision boolean method on bullets and target
          if (useEntity.attackCollision(bulletStack.get(a), enemyList.get(b)))
          {
            bulletStack.remove(a);
          }
        }
      }
      //if enemy has health
      if (enemyList.get(b).health > 0)
      {
        enemyList.get(b).drawCirc();
      } else
      {
        enemyList.remove(b);
      }
    }
  }

  //PLAYER damage
  if (EBulletStack.size() > 0)
  {
    for (int a = 0; a < EBulletStack.size(); a++)
    {
      //use collision boolean method on bullets and test dummy
      if (useEntity.attackCollision(EBulletStack.get(a), player))
      {
        EBulletStack.remove(a);
      }
    }
  }
}

boolean onEnemy;

//bugger type enemy
Entity bugger;

Entity skimmer;

Entity rusher;

Entity doozers;

void enemyTypes()
  {
    //
    dummy = new Entity(100, new Vector (width/2, 100));
    dummy.health = 25;
    dummy.lifeSpan = -10;
    dummy.moveSetup(new Vector(), 50, 20, .05);
   
    //
    bugger = new Entity(50, new Vector());
    bugger.lifeSpan = 600;
    //bugger.attackSetup(new Vector(0,3), 1);
    bugger.attackSetup(new Vector(1,2), 1);
    bugger.attackSetup(new Vector(-1,2), 1);
    bugger.moveSetup(new Vector(0,1), 70,0, .05);
    //
    skimmer = new Entity(70, new Vector());
    skimmer.health = 20;
    skimmer.lifeSpan = 600;
    skimmer.attackSetup(new Vector(2,2), 1);
    skimmer.moveSetup(new Vector(2,0), 0,0,1);
    //
    rusher = new Entity(60, new Vector());
    rusher.health = 5;
    rusher.lifeSpan = 600;
    rusher.attackSetup(new Vector(2,1), .5);
    rusher.attackSetup(new Vector(-2,1), .5);
    rusher.moveSetup(new Vector(0,3), 0,0,1);
    //
    doozers = new Entity(30, new Vector());
    doozers.health = 3;
    doozers.lifeSpan = 1200;
    doozers.attackSetup(new Vector(1,1), 1.25);
    doozers.attackSetup(new Vector(-1,1), 1.25);
    doozers.attackSetup(new Vector(-1,-1), 1.25);
    doozers.attackSetup(new Vector(1,-1), 1.25);
    doozers.moveSetup(new Vector(0,.5),20,20,.1);
  }

//the timeline for all enemy spawns
void enemySequence()
{
  //a bool to stop if conditions from crashing if the enemy list is empty/null.
  //must be first condition or array list will crash
  if (enemyList.size() >0)
  {
    onEnemy = true;
  } else
  {
    onEnemy = false;
  }

  //add enemies to the game on time when the game starts
 
  switch(int(gameTime))
  {
    //create the starting enemy
   
    /*case:
        //add enemy
        List.add(enemyObject);
        //starting position
        List.get(int).position = new Vector();
    */
   
  case 0:
    enemyList.add(dummy);
    gameTime++;
    break;
    //start the game once starting enemy is destroyed
  case 1:
    if (!onEnemy)
      startGame = true;
    break;
  case 2:
    bugger.position = new Vector(width/2, -60);
    enemyList.add(bugger);
    gameTime++;
    break;
  case 6:
  //must reset the classes to a new class(); to avoid double feedback
    enemyTypes();
    bugger.position = new Vector(width/2 + 100, -60);
    enemyList.add(bugger);
  //
    enemyTypes();
    bugger.position = new Vector(width/2 -100, -60);
    enemyList.add(bugger);
    gameTime++;
    break;
  case 15:
    enemyTypes();
    skimmer.position = new Vector(-50, 200);
    enemyList.add(skimmer);
    gameTime++;
    break;
  case 18:
    enemyTypes();
    skimmer.moveSetup(new Vector(-2,0), 0,0,-1);
    skimmer.position = new Vector(width+50, 200);
    skimmer.attackSetup(new Vector(-2,2), 1);
    enemyList.add(skimmer);
    gameTime++;
    break;
  case 25:
    enemyTypes();
    rusher.position = new Vector(width/2 - 300,-50);
    enemyList.add(rusher);
    //
    enemyTypes();
    rusher.position = new Vector(width/2 + 300,-50);
    enemyList.add(rusher);
    gameTime++;
    break;
  case 28:
    enemyTypes();
    doozers.position = new Vector(width/2 + 200, - 50);
    enemyList.add(doozers);
    //
    enemyTypes();
    doozers.position = new Vector(width/2, - 50);
    enemyList.add(doozers);
    //
    enemyTypes();
    doozers.position = new Vector(width/2 - 200, - 50);
    enemyList.add(doozers);
    //
    enemyTypes();
    doozers.position = new Vector(width/2 - 400, - 50);
    enemyList.add(doozers);
    //
    enemyTypes();
    doozers.position = new Vector(width/2 + 400, - 50);
    enemyList.add(doozers);
    gameTime++;
    break;
  }

  //out of bounds check
  if (onEnemy)
  {
    //all enemies
    for (int a = 0; a < enemyList.size(); a++)
    {
      //move all enemies
      enemyList.get(a).moveType();
      enemyList.get(a).attackCycle();
     
     
      //if the enemy has run out of time delete them
      if(!enemyList.get(a).lifeTime())
      {
        enemyList.remove(a);
      }
    }
  }
 
  //keep bullet stack below limit by removing the last one in the stack
  if (EBulletStack.size() > 200)
  {
    EBulletStack.remove(0);
  }
 
  //move and draw each bullet in the stack
  for (int a = 0; a < EBulletStack.size(); a++)
  { 
    fill(255,100,200);
    EBulletStack.get(a).moveBullet();
    EBulletStack.get(a).drawBullet();

    //delete the bullet if it's out of bounds
    if (EBulletStack.get(a).deleteBullet())
    {
      EBulletStack.remove(a);
    }
  }

  //start game time
  if (startGame)
  {
    //real seconds timer
    gameTime += 1/frameRate;
    //println(int(gameTime)+ "   " + ESequence);
  }
}

//BULLET CLASS

class Bullet
{
  //empty Vector class for using class functions
  Vector useVector = new Vector();
 
  //bullet position
  Vector bPos;
  //bullet Size
  float radius = 25;
  //bullet Velocity
  Vector bVelocity = new Vector();
  //bullet lifeTime
  float lifeTime = 1200;
 
  //constructor for spawning the bullet in canvas space
  Bullet(Vector position, Vector velocity)
  {
    bPos = position;
    bVelocity = velocity;
  }
 
  //draw the bullet
  void drawBullet()
  {
    noStroke();
    ellipse(bPos.x, bPos.y,radius, radius);
  }
 
  //translate the bullet via it's velocity
  void moveBullet()
  {
    bPos = useVector.addVelocity(bPos, bVelocity);
    lifeTime -= 1; 
  }
 
  //return true to delete bullet from arrayList
  boolean deleteBullet()
  {
    if(lifeTime <= 0)
    {
      return true;
    }
   
    return false;
  }

}

//ENTITY

class Entity
{
  Bullet useBullet = new Bullet(new Vector(), new Vector());
 
  float shape = 10;
  Vector position = new Vector(0, 0);
  //
  float healthChange;
  float health = 10;
  //
  float lifeSpan = 600;

  //empty box with a shape
  Entity(float a)
  {
    shape = a;
    attackVectors = new ArrayList();
  }

  //shape and position
  Entity(float a, Vector b)
  {
    shape = a;
    position = b;
    attackVectors = new ArrayList();
  }

  //
  void drawCirc()
  {
    noStroke();
    fill(200, 100, 100);
    ellipse(position.x, position.y, shape+health, shape+health);

    if (healthChange != health)
    {
      fill(255, 100, 100);
      healthChange = health;
    } else
    {
      fill(100, 100, 100);
    }

    stroke(0);
    ellipse(position.x, position.y, shape, shape);
  }

  boolean attackCollision(Bullet bullet, Entity target)
  {
    if (dist(bullet.bPos.x, bullet.bPos.y, target.position.x, target.position.y) < bullet.radius/2 + target.shape/2)
    {
      //remove health from target on collision
      target.health --;
      return true;
    }
    return false;
  }

  boolean lifeTime()
  {
    //return true if object has time left
    if (lifeSpan > 0)
    {
      return true;
    }
    //if lifespan is below 0 return false to delete enemy unless set below -10 for infinite lifetime;
    if (lifeSpan > -10 && lifeSpan <=0)
    {
      return false;
    }
    //return true for infinite life
    return true;
  }

  boolean mSetupOnce = false;

  Vector velocity = new Vector();
  float xMove;
  float yMove;
  float wSpeed;

  //setup all entity movement on initiation;
  void moveSetup(Vector lineMove, float xWave, float yWave, float waveSpeed)
  {
    //if (!mSetupOnce)
    {
      velocity = lineMove;
      xMove = xWave;
      yMove = yWave;
      wSpeed= waveSpeed;
      //mSetupOnce = true;
    }
  }

  void moveType()
  {
    //if (xMove !=0 || yMove !=0 || wSpeed !=0)
    {
      sinMove(xMove, yMove, wSpeed);
    }

    ///if (velocity.x != 0 || velocity.y != 0)
    {
      anchorPoint = useVector.addVelocity(anchorPoint, velocity);
    }
  }

  float wave;
  boolean anchorStop = true;
  Vector anchorPoint = new Vector();
  Vector waveMovement = new Vector();

  //adds a wave motion to the object
  void sinMove(float xWave, float yWave, float speed)
  {
    //find the anchor of the Object before wave movement starts
    if (anchorStop)
    {
      anchorPoint = position;
      anchorStop = false;
    }
    //create vector with wave motion
    waveMovement = new Vector(sin(wave) * xWave, cos(wave) * yWave);
    //apply motion
    position = useVector.addVelocity(anchorPoint, waveMovement);
    wave += speed;
  }

  ArrayList <Vector> attackVectors;

  float fireRate;
  float coolDown;

  void attackSetup(Vector direction, float rate)
  {
   
    attackVectors.add(direction);
    fireRate = rate;
  }

  Vector bulletSpawn;



  void attackCycle()
  {
    //check for out of bounds
    if (attackVectors.size()>0)
    {
      //if cycle is reset
      if (coolDown <= 0)
      {
        //use all attacks
        for (int a = 0; a < attackVectors.size(); a++)
        {
          bulletSpawn = useVector.addVelocity(position, attackVectors.get(a));
          EBulletStack.add(new Bullet(position, attackVectors.get(a)));
        }
        coolDown = fireRate;
      }

      //cycle interval
      if (coolDown>0)
      {
        coolDown -= 1/frameRate;
      }
    }
  }
}


//VECTORS

//physics class
class Vector
{
  //x and y values
  float x;
  float y;

  //empty new Vector(0,0)
  Vector()
  {
    x = 0;
    y = 0;
  }

  //new Vector(x,y)
  Vector(float a, float b)
  {
    x = a;
    y = b;
  }

  //function for adding movement using a velocity Vector
  Vector addVelocity(Vector position, Vector velocity)
  {
    return new Vector(position.x + velocity.x, position.y + velocity.y);
  }

}

No comments:

Post a Comment