Wednesday, October 3, 2018

Processing - Procedural Motion



Code:

MAIN:

//useClass functions
//Vector class stores and manipulates floats x and y for horizontal and vertical
Vector useVector = new Vector();

//Player
//player size x and y
Vector playerSize = new Vector(20, 20);

//Vectors
//player position x and y
Vector playerPos = new Vector();
//player speed and direction as x and y
Vector playerVelocity = new Vector();
//input direction of the player x and y
Vector inputVector = new Vector();

//Input
//movement keys
char[] moveKeys = {'d', 'a', ' ', 's'};
//input axis for the movement
int[] moveValues = new int[4];

//Movement
//horizontal velocity
float moveSpeed = 5;

//Jump
//input for jumping
boolean jumpPress;
//locks the input so it only applies once per press
boolean singleJump;
//magnitude of jump velocity
float jumpForce = 7.5;
//is on the floor
boolean floorTouch;


//amount of platform to be drawn
int platformCount = 15;
//position of each platform
Vector[] platformStart;
//size of eachplatform
Vector[] platformEnd;


void setup()

  size(500, 700);
  //center the player
  playerPos = new Vector(width/2, 0);
  //build the platforms
  platformSetup();
}

void draw()
{
  background(240, 200, 200);
  //get player input
  moveInput();
  //get jump input
  jump();
  //apply physics
  playerPhysics();
  //draw platforms
  platform();
  //platform collisions
  collide();
  //draw player
  drawPlayer();

  saveFrame("output/gp_####.png");
}

void drawPlayer()
{
  fill(200, 200, 200);
  rect(playerPos.x, playerPos.y, playerSize.x, playerSize.y);
}

void moveInput()
{
  //set a directional vector based on the keyboard input directions pressed
  inputVector = new Vector(moveValues[0] - moveValues[1], moveValues[2] - moveValues[3]);
}

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

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

//gravity, drag, and movement
void playerPhysics()
{
  //gravity
  playerVelocity = useVector.gravity(playerVelocity);
  //drag
  playerVelocity = useVector.drag(playerVelocity);
  //movement
  playerVelocity.x = inputVector.x * moveSpeed;
  //add velocity
  playerPos = new Vector(playerPos.x + playerVelocity.x, playerPos.y+playerVelocity.y);
}

//jumping mechanics
void jump()
{
  //Jump Input when vertical input vector is positive
  if (inputVector.y > 0)
  {
    jumpPress = true;
  }
  else
  //turn off jump input and
  {
    jumpPress = false;
    singleJump = true;
  }

  //Add jump velocity
  //check if touching floor
  if (floorTouch)
  {
    //jump input
    if (jumpPress && singleJump)
    {
      //add velocity
      playerVelocity.y = -jumpForce;
      //fire once boolean
      singleJump = false;
    }
  }

  //accelerate faster if player releases jump input
  if (!jumpPress && playerVelocity.y < 0)
  {
    playerVelocity.y += 0.2;
  }
  //
  if (playerVelocity.y > 0)//!jumpPress && playerVelocity.y > 0)
  {
    playerVelocity.y += 0.1;
  }
}

void collide()
{
  //reset floor trigger;
  floorTouch = false;

  for (int a = 0; a < platformCount; a ++)
  {
    //only run if there is a platform
    if (platformStart[a] != null)
    {
      //check if the player is contacting floor collider;
      if (playerPos.y + playerSize.y >= platformStart[a].y)
      {
        //check if the player is on the platform from the left
        if (playerPos.x + playerSize.x >= platformStart[a].x)
        {
          //check if the player is on the collider from the right
          if (playerPos.x <= platformStart[a].x + platformEnd[a].x)
          {
            //check if the player is above the collider
            if (playerPos.y <= platformStart[a].y + platformEnd[a].y)
            {
              //enable jumping
              floorTouch = true;
              //stop downward velocity
              if(playerVelocity.y > 0)
              {
                playerVelocity.y = 0;
              }
              //keep the player above the platform
              playerPos.y = platformStart[a].y - (playerSize.y);
            }
          }
        }
      }
    }
  }
}

//create platforms
void platformSetup()
{
  //platform positions and dimensions
  platformStart = new Vector[platformCount];
  platformEnd = new Vector[platformCount];

  //first platform for the ground
  platformStart[0] = new Vector(0, height - 100);
  platformEnd[0] = new Vector(width, height);

  //make a bunch of random positions for platforms
  for (int a = 1; a < platformCount; a ++)
  {
    //random positions
    platformStart[a] = new Vector(random(0, width), random(0, height -100));
    //platforms with some random width
    platformEnd[a] = new Vector(random(50, 100), 10);
  }
}

//draw the platforms
void platform()
{
  fill(100, 100, 200);
  //draw each platform
  for (int a = 0; a < platformCount; a ++)
  {
    rect(platformStart[a].x, platformStart[a].y, platformEnd[a].x, platformEnd[a].y);
  }
}


VECTOR CLASS

//Vector class stores x and y positions but can also be used for manipulating velocity using the same Vector type;
//aka it handles basic 2D physics

class Vector
{
  //horizontal and vertical;
  float x;
  float y;
  
  //forces
  float gravity = 9.11/60;
  float drag = 0.01;
  
  //if empty statement make new Vectors(0,0)
  Vector()
  {
    x=0;
    y=0;
  }
  
  //declare a new vector with new values;
  Vector(float a, float b)
  {
    x = a;
    y = b;
  }
  
  //returns a velocity with gravity acceleration
  Vector gravity(Vector velocity)
  {
    return new Vector(velocity.x, velocity.y + gravity); 
  }
  
  //returns a velocity with drag deceleration
  Vector drag(Vector velocity)
  {
    return new Vector(velocity.x - velocity.x * drag, velocity.y - velocity.y * drag);
  }

}


No comments:

Post a Comment