Need Game Idea help (ground mechanics already there)

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 :smiley:

Here is the code:

Click to see the code

Main Code:

/*
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

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

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");
  }
}

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!

1 Like

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)

2 Likes

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

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;
    }
  } 
}

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

Click to see code

Main:

/* //<>// //<>// //<>// //<>//
 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:

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:

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:

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 :smiley:

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.

/*
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:

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:

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:

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");
  }
}
2 Likes