# Need Game Idea help (ground mechanics already there)

**URL:** <https://discourse.processing.org/t/need-game-idea-help-ground-mechanics-already-there/31168>\
**Category:** Project Guidance\
**Created:** [July 11, 2021, 1:25pm UTC](https://discourse.processing.org/t/need-game-idea-help-ground-mechanics-already-there/31168 "2021-07-11T13:25:36Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Flolo](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/flolo/32/13874_2.png) [@Flolo](https://discourse.processing.org/u/Flolo)\
**Post date:** [July 11, 2021, 1:25pm UTC](https://discourse.processing.org/t/need-game-idea-help-ground-mechanics-already-there/31168/1 "2021-07-11T13:25:36Z")

</div>

Hey I want to build a little game for a pc.  
I already have the ground mechanics and now I dont have any Idea what the target of the game should be.  
So have you some Ideas?

Thank you in andvance 😃

Here is the code:

> **Click to see the code**
>
> **Main Code:**
> 
> ```auto
> /*
> Controlls:
> SPACE = JUMP
> W = CHANGE ROTATE DIRECTION
> */
> 
> final float GRAVITY = 500;
> 
> ArrayList<Gear> gears;
> 
> float deltaTime = 0;
> 
> Player player;
> 
> void setup() {
> rectMode(CENTER);
> 
> fullScreen();
> //size(600, 600);
> gears = new ArrayList<Gear>();
> gears.add(new Gear(width/2, height/2+300, 70, radians(40)));
> gears.add(new Gear(width/2+100, height/2, 100, radians(50)));
> gears.add(new Gear(width/2-300, height/2-200, 200, radians(50)));
> player = new Player(width/2, 0);
> }
> void draw() {
> //println("Framerate: " + frameRate + "\n" + player.pos);
> deltaTime = 1 / frameRate;
> background(0);
> for (int i = 0; i < gears.size(); i++) {
> Gear g = gears.get(i);
> g.show();
> g.upadte();
> }
> player.move();
> 
> player.update();
> player.show();
> }
> void mousePressed() {
> gears.add(new Gear(mouseX, mouseY, random(50, 150), radians(random(20, 80))));
> }
> void keyPressed() {
> if (key == ' ') {
> player.jump();
> } else if (key == 'w' || key == 'W') {
> player.currentGear.rotateSpeed *= -1;
> }
> }
> 
> ```
> 
> **Gear Class**
> 
> ```auto
> class Gear {
> PVector pos;
> float size;
> float rotation;
> float rotateSpeed;
> boolean playerOnGear;
> Gear(float x, float y, float r, float s) {
> pos = new PVector(x, y);
> size = r;
> rotation = 0;
> rotateSpeed = s;
> playerOnGear = false;
> }
> PVector getPlayerPosition(PVector p, float a) {
> float dir = a;
> 
> PVector v = PVector.fromAngle(dir);
> v.normalize();
> v.mult(size/2);
> v.add(pos);
> v.add(PVector.sub(p, pos).normalize().mult(player.size.y/2));
> return v;
> }
> float getPlayerDirection(PVector p) {
> PVector v = PVector.sub(p, pos);
> return v.heading();
> }
> void show() {
> noFill();
> stroke(255);
> strokeWeight(3);
> pushMatrix();
> translate(pos.x, pos.y);
> rotate(rotation);
> ellipse(0, 0, size, size);
> line(0, 0, size/2, 0);
> line(0, 0, -size/2, 0);
> line(0, 0, 0, size/2);
> line(0, 0, 0, -size/2);
> popMatrix();
> }
> void upadte() {
> rotation += rotateSpeed*deltaTime;
> }
> }
> 
> ```
> 
> **Player Class**
> 
> ```auto
> class Player {
> Gear currentGear;
> PVector pos, size, vel;
> float rotation, dirToGear;
> float speed;
> int pointHelpCount = 10;
> Player(float x, float y) {
> pos = new PVector(x, y);
> size = new PVector(30, 50);
> vel = new PVector(0, GRAVITY);
> speed = 700;
> rotation = 0;
> }
> void show() {
> noFill();
> stroke(255);
> strokeWeight(2);
> pushMatrix();
> translate(pos.x, pos.y);
> rotate(rotation);
> rect(0, 0, size.x, size.y, 15, 15, 0, 0);
> if (currentGear != null) {
> for (int i = pointHelpCount; i > 0; i--) {
> strokeWeight(i);
> point(0, -i*10);
> }
> }
> popMatrix();
> }
> void move() {
> PVector v = vel.copy();
> v.mult(deltaTime);
> rotation = vel.heading() + PI/2;
> pos.add(v);
> 
> if (pos.x > width) {
> pos.x = 0;
> currentGear = null;
> } 
> if (pos.x < 0) {
> pos.x = width;
> currentGear = null;
> }
> if (pos.y > height) {
> pos.y = 0;
> currentGear = null;
> }
> if (pos.y < 0) {
> pos.y = height; 
> currentGear = null;
> }
> 
> if (currentGear != null) {
> pos.set(currentGear.getPlayerPosition(pos, dirToGear)); 
> rotation = currentGear.getPlayerDirection(pos) + PI/2; 
> dirToGear += currentGear.rotateSpeed*deltaTime; 
> vel.set(0, 0);
> }
> }
> void update() {
> if (currentGear == null) {
> for (int i = 0; i < gears.size(); i++) {
> Gear g = gears.get(i);
> float d = PVector.dist(pos, g.pos);
> if (d < size.y/2+g.size/2) {
> println("On Gear");
> currentGear = g; 
> dirToGear = g.getPlayerDirection(pos); 
> vel.set(0, 0);
> }
> }
> }
> }
> void jump() {
> if (currentGear == null) return; 
> PVector dir = PVector.sub(pos, currentGear.pos); 
> dir.normalize(); 
> dir.mult(speed); 
> vel.set(dir);
> currentGear = null;
> println("JUMP");
> }
> }
> 
> ```

---

<div class="post-metadata">

**Author:** ![th75](https://avatars.discourse-cdn.com/v4/letter/t/ebca7d/32.png) [@th75](https://discourse.processing.org/u/th75)\
**Post date:** [July 16, 2021, 1:35am UTC](https://discourse.processing.org/t/need-game-idea-help-ground-mechanics-already-there/31168/2 "2021-07-16T01:35:51Z")

</div>

hi,

it’s already really great… i’m sure you will find how to gamify it  
moving targets, obstacles, gravity fields, time countdown, ordered paths, ressource bar filling each stop drawning on not moving, fading or blinking targets…  
anyhow, impressive code!

---

<div class="post-metadata">

**Author:** ![Pipo](https://avatars.discourse-cdn.com/v4/letter/p/8491ac/32.png) [@Pipo](https://discourse.processing.org/u/Pipo)\
**Post date:** [July 16, 2021, 6:38am UTC](https://discourse.processing.org/t/need-game-idea-help-ground-mechanics-already-there/31168/3 "2021-07-16T06:38:00Z")

</div>

Hi! Looks amazing!

The fist tipe of game that comes to my mind is this kind of game were the camera es going up and your are in a canyon narrow path and the main objective is to keep the player in the screen. So you could add a force wich alwais push the player down to make it more dificult, maybe hitting the walls make the player bounce and loss little bit of speed.

Or, another idea, the camera is fixed, and there are also some platforms that the player can not touch or that make the player bounce, and the final objective would be to cross from one place of the screen to the other.

Also you could add some object that give you axtra point if you hit them with the player avatar. In both cases. May be this extra points objects are not fixed, they are falling so you have to be quick.

And finally, it gave me an error when y press “w” while the player was in the middle of the air.

Good luck! Can’t wait to play it!

(not a native english speaker, sorry for any mistake I could have comited in my spelling or grammar)

---

<div class="post-metadata">

**Author:** ![Flolo](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/flolo/32/13874_2.png) [@Flolo](https://discourse.processing.org/u/Flolo)\
**Post date:** [July 16, 2021, 1:54pm UTC](https://discourse.processing.org/t/need-game-idea-help-ground-mechanics-already-there/31168/4 "2021-07-16T13:54:22Z")

</div>

Hey thanks for all the good ideas 😁  
First up I fixed the error:

```auto
void keyPressed() {
  if (key == ' ') {
    player.jump();
  } else if (key == 'w' || key == 'W') {
    if (player.currentGear != null) { // I forgot this if statement thanks for reminding me :)
      player.currentGear.rotateSpeed *= -1;
    }
  } 
}

```

> [@Pipo](#):
>
> The fist tipe of game that comes to my mind is this kind of game were the camera es going up and your are in a canyon narrow path and the main objective is to keep the player in the screen. So you could add a force wich alwais push the player down to make it more dificult, maybe hitting the walls make the player bounce and loss little bit of speed.

I liked you idea and I made a little example what do you mean?

> **Click to see code**
>
> **Main:**
> 
> ```auto
> /* //<>// //<>// //<>// //<>//
> Controlls:
> SPACE = JUMP
> W = CHANGE ROTATE DIRECTION
> */
> 
> final float GRAVITY = 500;
> 
> ArrayList<Obstacle> obstacles;
> ArrayList<Gear> gears;
> 
> float deltaTime = 0;
> 
> PVector moveDir = new PVector(0, 1);
> float moveSpeed = 100;
> 
> float gearSpawnTime = 2;//seconds
> float timeToSpawnGear = 0;
> 
> Player player;
> 
> void setup() {
> //rectMode(CENTER);
> 
> fullScreen();
> //size(600, 700);
> obstacles = new ArrayList<Obstacle>();
> gears = new ArrayList<Gear>();
> player = new Player(width/2, 0);
> addRandomGear(3);
> gears.add(new Gear(width/2, height/2, 80, radians(20)));
> }
> void draw() {
> //println("Framerate: " + frameRate + "\n" + player.pos);
> deltaTime = 1 / frameRate;
> background(0);
> for (int i = 0; i < gears.size(); i++) {
> Gear g = gears.get(i);
> g.show();
> g.update();
> }
> for (int i = 0; i < obstacles.size(); i++) {
> Obstacle o = obstacles.get(i);
> o.show();
> o.move();
> }
> player.move();
> 
> player.update();
> player.show();
> 
> showPlayerUI();
> updateGearSpawner();
> }
> void mousePressed() {
> gears.add(new Gear(mouseX, mouseY, random(50, 150), radians(random(20, 80))));
> }
> void keyPressed() {
> if (key == ' ') {
> player.jump();
> } else if (key == 'w' || key == 'W') {
> if (player.currentGear != null) {
> player.currentGear.rotateSpeed *= -1;
> }
> }
> }
> void updateGearSpawner() {
> timeToSpawnGear += deltaTime;
> if (!(timeToSpawnGear >= gearSpawnTime)) return;
> 
> timeToSpawnGear -= gearSpawnTime;
> addRandomGear();
> 
> if (random(1) > 0.25) obstacles.add(new Obstacle(random(width), 0, random(50, 150)));
> }
> void gameOver() {
> System.err.println("GAME OVER");//Just red println :)
> println("Score:", player.score);
> setup();
> }
> void addRandomGear(int count) {
> for (int i = 0; i < count; i++) {
> addRandomGear();
> }
> }
> void addRandomGear() {
> float size = random(50, 150);
> float speed = random(20, 80);
> gears.add(new Gear(random(size/2, width-size/2), -size, size, radians(speed)));
> }
> void showPlayerUI() {
> rectMode(CORNER);//This is because of the text() idk why but it is the same es the rect mode
> 
> fill(255);
> textAlign(LEFT, TOP);
> textSize(50);
> text("Score: " + round(player.score), 10, 10, width, height);
> }
> 
> ```
> 
> **Gear Class:**
> 
> ```auto
> class Gear {
> PVector pos;
> float size;
> float rotation;
> float rotateSpeed;
> boolean playerOnGear;
> Gear(float x, float y, float r, float s) {
> pos = new PVector(x, y);
> size = r;
> rotation = 0;
> rotateSpeed = s;
> playerOnGear = false;
> }
> PVector getPlayerPosition(PVector p, float a) {
> float dir = a;
> 
> PVector v = PVector.fromAngle(dir);
> v.normalize();
> v.mult(size/2);
> v.add(pos);
> v.add(PVector.sub(p, pos).normalize().mult(player.size.y/2));
> return v;
> }
> float getPlayerDirection(PVector p) {
> PVector v = PVector.sub(p, pos);
> return v.heading();
> }
> void show() {
> noFill();
> stroke(255);
> strokeWeight(3);
> pushMatrix();
> translate(pos.x, pos.y);
> rotate(rotation);
> ellipse(0, 0, size, size);
> line(0, 0, size/2, 0);
> line(0, 0, -size/2, 0);
> line(0, 0, 0, size/2);
> line(0, 0, 0, -size/2);
> popMatrix();
> }
> void move() {
> PVector v = moveDir.copy();
> v.mult(moveSpeed);
> v.mult(deltaTime);
> pos.add(v);
> 
> if (pos.x - size/2 > width || pos.x + size/2 < 0 || pos.y - size/2 > height) {
> gears.remove(this);
> }
> }
> void update() {
> rotation += rotateSpeed*deltaTime;
> move();
> }
> }
> 
> ```
> 
> **Obstacle Class:**
> 
> ```auto
> class Obstacle {
> PVector pos;
> float size;
> float bounceSpeed = 600;
> Obstacle(float x, float y, float s) {
> pos = new PVector(x, y);
> size = s;
> }
> PVector getPlayerPosition(PVector p, float a) {
> float dir = a;
> 
> PVector v = PVector.fromAngle(dir);
> v.normalize();
> v.mult(size/2);
> v.add(pos);
> v.add(PVector.sub(p, pos).normalize().mult(player.size.y/2));
> return v;
> }
> float getPlayerDirection(PVector p) {
> PVector v = PVector.sub(p, pos);
> return v.heading();
> }
> PVector getPlayerVelocity(PVector p) {
> PVector dir = PVector.sub(p, pos);
> dir.normalize();
> dir.mult(bounceSpeed);
> return dir;
> }
> void show() {
> fill(255);
> ellipse(pos.x, pos.y, size, size);
> }
> void move() {
> PVector v = moveDir.copy();
> v.mult(moveSpeed);
> v.mult(deltaTime);
> pos.add(v);
> 
> if (pos.x > width || pos.x < 0 || pos.y > height) {
> obstacles.remove(this);
> }
> }
> }
> 
> ```
> 
> **Player Class:**
> 
> ```auto
> class Player {
> Gear currentGear;
> PVector pos, size, vel;
> float rotation, dirToGear;
> float speed;
> float scorePerSec = 2;
> float score;
> int pointHelpCount = 10;
> Player(float x, float y) {
> pos = new PVector(x, y);
> size = new PVector(30, 50);
> vel = new PVector(0, GRAVITY);
> speed = 700;
> rotation = 0;
> score = 0;
> }
> void show() {
> rectMode(CENTER);
> noFill();
> stroke(255);
> strokeWeight(2);
> pushMatrix();
> translate(pos.x, pos.y);
> rotate(rotation);
> rect(0, 0, size.x, size.y, 15, 15, 0, 0);
> if (currentGear != null) {
> for (int i = pointHelpCount; i > 0; i--) {
> strokeWeight(i);
> point(0, -i*10);
> }
> }
> popMatrix();
> }
> void move() {
> PVector v = vel.copy();
> v.mult(deltaTime);
> rotation = vel.heading() + PI/2;
> pos.add(v);
> 
> if (pos.x > width) {
> pos.x = width;
> vel.x *= -1;
> } 
> if (pos.x < 0) {
> pos.x = 0;
> vel.x *= -1;
> }
> if (pos.y > height) {
> gameOver();
> }
> if (pos.y < 0) {
> pos.y = 0;
> vel.y *= -1;
> }
> 
> if (currentGear != null) {
> pos.set(currentGear.getPlayerPosition(pos, dirToGear)); 
> rotation = currentGear.getPlayerDirection(pos) + PI/2; 
> dirToGear += currentGear.rotateSpeed*deltaTime; 
> vel.set(0, 0);
> }
> }
> void update() {
> addScore();
> if (currentGear == null) {
> for (int i = 0; i < obstacles.size(); i++) {
> Obstacle o = obstacles.get(i);
> float d = PVector.dist(pos, o.pos);
> if (d < size.y/2+o.size/2) {
> println("On Obstacle");
> 
> //I know I should use another variable but iam just to lazy sry haha
> dirToGear = o.getPlayerDirection(pos);
> pos.set(o.getPlayerPosition(pos, dirToGear));
> vel.set(o.getPlayerVelocity(pos));
>           
> }
> }
> for (int i = 0; i < gears.size(); i++) {
> Gear g = (Gear) gears.get(i);
> float d = PVector.dist(pos, g.pos);
> if (d < size.y/2+g.size/2) {
> println("On Gear");
> currentGear = g; 
> dirToGear = g.getPlayerDirection(pos); 
> vel.set(0, 0);
> }
> }
> }
> }
> void addScore() {
> score += scorePerSec * deltaTime;
> }
> void jump() {
> if (currentGear == null) return; 
> PVector dir = PVector.sub(pos, currentGear.pos); 
> dir.normalize(); 
> dir.mult(speed); 
> vel.set(dir);
> currentGear = null;
> println("JUMP");
> }
> }
> 
> ```

I am happy about any advice 😃

---

<div class="post-metadata">

**Author:** ![noahbuddy](https://avatars.discourse-cdn.com/v4/letter/n/73ab20/32.png) [@noahbuddy](https://discourse.processing.org/u/noahbuddy)\
**Post date:** [July 16, 2021, 10:20pm UTC](https://discourse.processing.org/t/need-game-idea-help-ground-mechanics-already-there/31168/5 "2021-07-16T22:20:47Z")

</div>

The code you have provided is already entertaining, especially the “canyon” version.

I did have a couple game-type ideas:

**Word building game/hangman**  
See how many words the player can make (tested against a dictionary) or have the player build words from a list.  
Maybe more complicated words are built with trick-shots (fired through the edge of the display)

**Worms/Scorched Earth**  
I played around with some gravity and launching a ball.  
Based on your original code, the goal is to keep the ball from hitting a gear for as long as possible.  
Adding moving gears/planets could add more challenge (difficulty levels).  
This is not optimized for code structure or efficiency.

```auto
/*
Controlls:
 SPACE = JUMP
 W = CHANGE ROTATE DIRECTION
 F = fire a shot
 */

final float GRAVITY = 500;

ArrayList<Gear> gears;

float deltaTime = 0;

Player player;

void setup() {
  rectMode(CENTER);

  //fullScreen();
  size(1280, 900);
  gears = new ArrayList<Gear>();
  gears.add(new Gear(width/2, height/2+300, 70, radians(40)));
  gears.add(new Gear(width/2+100, height/2, 100, radians(50)));
  gears.add(new Gear(width/2-300, height/2-200, 200, radians(50)));
  player = new Player(width/2, 0);
}

void draw() {
  //println("Framerate: " + frameRate + "\n" + player.pos);
  deltaTime = 1 / frameRate;
  background(0);
  for (int i = 0; i < gears.size(); i++) {
    Gear g = gears.get(i);
    g.show();
    g.upadte();
  }
  
  player.move();
  player.update();
  player.show();
  
  textAlign(LEFT, TOP);
  textSize(50);
  fill(255);
  text("Longest shot: " + player.longestShot, 50, height-100); 
}

void mousePressed() {
  gears.add(new Gear(mouseX, mouseY, random(50, 150), radians(random(20, 80))));
}

void keyPressed() {
  if (key == ' ') {
    player.jump();
  } else if (key == 'w' || key == 'W') {
    if (player.currentGear != null) {
      player.currentGear.rotateSpeed *= -1;
    }
  } else if (key == 'f' || key == 'F') {
    player.fire();
  }
}

```

Ball class:

```auto
class Ball
{
  final float GRAV_FACTOR = 2.7; // "arcade" non-realistic gravity
  final int MAX_SPEED = 1000;
  PVector pos, velo;
  boolean active = false;
  int lifespan = 0;
  
  Ball(float x, float y, PVector v)
  {
    pos = new PVector(x, y);
    velo = new PVector(v.x, v.y);
    active = true;
  }
  
  void move()
  {
    lifespan++;
    PVector v = velo.copy();
    v.mult(deltaTime);
    pos.add(v);
    
    if (pos.x > width) {
      pos.x = 0;
    }
    if (pos.x < 0) {
      pos.x = width;
    }
    if (pos.y > height) {
      pos.y = 0;
    }
    if (pos.y < 0) {
      pos.y = height;
    }
  }
  
  void show()
  {
    stroke(255,0,0);
    pushMatrix();
    translate(pos.x, pos.y);
    ellipse(0,0, 10,10);
    popMatrix();
  }
  
  boolean update(Gear g, float d)
  {
    if (d > 0)
    {
      PVector v = PVector.sub(g.pos, pos);
      v.mult(GRAV_FACTOR / d);
      velo.add(v);
      if (velo.mag() > MAX_SPEED)
      {
        velo.normalize().mult(MAX_SPEED);
      }
    }
    else
    {
      active = false;
    }
    return active;
  }
}

```

Gear class:

```auto
class Gear {
  PVector pos;
  float size;
  float rotation;
  float rotateSpeed;
  boolean playerOnGear;
  Gear(float x, float y, float r, float s) {
    pos = new PVector(x, y);
    size = r;
    rotation = 0;
    rotateSpeed = s;
    playerOnGear = false;
  }
  PVector getPlayerPosition(PVector p, float a) {
    float dir = a;

    PVector v = PVector.fromAngle(dir);
    v.normalize();
    v.mult(size/2);
    v.add(pos);
    v.add(PVector.sub(p, pos).normalize().mult(player.size.y/2));
    return v;
  }
  float getPlayerDirection(PVector p) {
    PVector v = PVector.sub(p, pos);
    return v.heading();
  }
  void show() {
    noFill();
    stroke(255);
    strokeWeight(3);
    pushMatrix();
    translate(pos.x, pos.y);
    rotate(rotation);
    ellipse(0, 0, size, size);
    line(0, 0, size/2, 0);
    line(0, 0, -size/2, 0);
    line(0, 0, 0, size/2);
    line(0, 0, 0, -size/2);
    popMatrix();
  }
  void upadte() {
    rotation += rotateSpeed*deltaTime;
  }
}

```

Player class:

```auto
class Player {
  Gear currentGear;
  Ball shot;
  PVector pos, size, vel;
  float rotation, dirToGear;
  float speed;
  int pointHelpCount = 10;
  int longestShot = 0;
  
  Player(float x, float y) {
    pos = new PVector(x, y);
    size = new PVector(30, 50);
    vel = new PVector(0, GRAVITY);
    speed = 700;
    rotation = 0;
  }
  void show() {
    noFill();
    stroke(255);
    strokeWeight(2);
    pushMatrix();
    translate(pos.x, pos.y);
    rotate(rotation);
    rect(0, 0, size.x, size.y, 15, 15, 0, 0);
    if (currentGear != null) {
      for (int i = pointHelpCount; i > 0; i--) {
        strokeWeight(i);
        point(0, -i*10);
      }
    }
    popMatrix();
    if (shot != null)
    {
      shot.show();
    }
  }
  void move() {
    PVector v = vel.copy();
    v.mult(deltaTime);
    rotation = vel.heading() + PI/2;
    pos.add(v);

    if (pos.x > width) {
      pos.x = 0;
      currentGear = null;
    }
    if (pos.x < 0) {
      pos.x = width;
      currentGear = null;
    }
    if (pos.y > height) {
      pos.y = 0;
      currentGear = null;
    }
    if (pos.y < 0) {
      pos.y = height;
      currentGear = null;
    }

    if (currentGear != null) {
      pos.set(currentGear.getPlayerPosition(pos, dirToGear));
      rotation = currentGear.getPlayerDirection(pos) + PI/2;
      dirToGear += currentGear.rotateSpeed*deltaTime;
      vel.set(0, 0);
    }
  }
  void update() {
    if (currentGear == null) {
      for (int i = 0; i < gears.size(); i++) {
        Gear g = gears.get(i);
        float d = PVector.dist(pos, g.pos);
        if (d < size.y/2+g.size/2) {
          println("On Gear");
          currentGear = g;
          dirToGear = g.getPlayerDirection(pos);
          vel.set(0, 0);
        }
        
        if (shot != null)
        {
          float sd = PVector.dist(shot.pos, g.pos) - g.size/2;
          if (!shot.update(g, sd))
          {
            if (shot.lifespan > longestShot)
            {
              longestShot = shot.lifespan;
            }
            shot = null;
          }
        }
      }
      if (shot != null)
      {
        shot.move();
      }
    }
    else // don't redo the work if (currentGear == null) above was true
    {
      for (int i = 0; i < gears.size(); i++) {
        Gear g = gears.get(i);
        if (shot != null)
        {
          float sd = PVector.dist(shot.pos, g.pos) - g.size/2;
          if (!shot.update(g, sd))
          {
            if (shot.lifespan > longestShot)
            {
              longestShot = shot.lifespan;
            }
            shot = null;
          }
        }
      }
      if (shot != null)
      {
        shot.move();
      }
    }
  }
  
  void fire()
  {
    if (currentGear == null)
    {
      shot = new Ball(2*vel.x*deltaTime+pos.x, 2*vel.y*deltaTime+pos.y, vel);
    }
    else
    {
      PVector dir = PVector.sub(pos, currentGear.pos);
      dir.normalize();
      dir.mult(speed);
      shot = new Ball(dir.x*deltaTime+pos.x, dir.y*deltaTime+pos.y, dir);
    }
    
  }
  
  void jump() {
    if (currentGear == null) return;
    PVector dir = PVector.sub(pos, currentGear.pos);
    dir.normalize();
    dir.mult(speed);
    vel.set(dir);
    currentGear = null;
    println("JUMP");
  }
}

```
