# Obstacle game in 3d (with 2d obstacles), unable to add more than 1 obstacle

**URL:** <https://discourse.processing.org/t/obstacle-game-in-3d-with-2d-obstacles-unable-to-add-more-than-1-obstacle/15110>\
**Category:** Coding Questions\
**Created:** [November 1, 2019, 12:02pm UTC](https://discourse.processing.org/t/obstacle-game-in-3d-with-2d-obstacles-unable-to-add-more-than-1-obstacle/15110 "2019-11-01T12:02:40Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![D.Signer](https://avatars.discourse-cdn.com/v4/letter/d/ba8739/32.png) [@D.Signer](https://discourse.processing.org/u/D.Signer)\
**Post date:** [November 1, 2019, 12:02pm UTC](https://discourse.processing.org/t/obstacle-game-in-3d-with-2d-obstacles-unable-to-add-more-than-1-obstacle/15110/1 "2019-11-01T12:02:40Z")

</div>

I am trying to make an obstacle game where you are supposedly driving and there are trees you need to avoid (for now those are just rectangles). Since I am pretty new to processing, I tried some stuff out, and it all seemed to work (kinda), but when I added more that one obstacle (obst1), the translation I do at the beginning of the setup gets changed to a value that is lower that what I want (the translation should be -2000 on the z axis, but when I add obst2, it suddenly is only 1000). I really can’t find the problem.

If you have any other tips on how I should actually handle the overall game, in terms of how it functions, I would really appreciate that.

Code:

```auto
boolean moving = false;
boolean restart = false;
int amount = 4;
int numberWaves = 10;
int wave = 0;
int size = 100;

//Obstacle obst[][] = new Obstacle[numberWaves][amount];
Obstacle obst1, obst2, obst3;

void setup() {
  size(1000, 1000, P3D);
  background(200);
  rectMode(CENTER);

  //for (int w = 0; w < numberWaves; w++) {
  // for (int i = 0; i < amount; i++) {
  // //obst[w][i] = new Obstacle(size, ((int) random((width*5) / size)) * (2 * size));
  // obst[w][i] = new Obstacle(size, -width + (i * (5*size)));
  // }
  //}
  
  obst1 = new Obstacle(size, 100);
  obst2 = new Obstacle(size, 900);
  obst3 = new Obstacle(size, 1300);

  //translate(0, 0, -2000);
  pushMatrix();
}

void draw() {
  background(200);
  
  popMatrix();

  //for (int i = 0; i < amount; i++) {
  // obst[wave][i].moveCar(8);
  // obst[wave][i].obstacleInteract();
  // obst[wave][i].nextWave();
  //}
  
  obst1.moveCar(8);
  obst1.obstacleInteract();
  obst1.nextWave();
  
  obst2.moveCar(8);
  obst2.obstacleInteract();
  obst2.nextWave();
  
  obst3.moveCar(8);
  obst3.obstacleInteract();
  obst3.nextWave();

  pushMatrix();

  //println(obst[0].xCar , obst[1].xCar, obst[2].xCar, obst[3].xCar, obst[4].xCar);
}

class Obstacle {

  float size, speed, xCar;
  float distance = 0;
  float z = 0;
  boolean wavePassed = false;

  Obstacle(float s, float x) {
    size = s;
    xCar = x;
  }

  void moveCar(float speed) {

    if (mousePressed && mousePressed == (mouseButton == LEFT) && restart == false) { //Let's you drive when you hold a mousebutton
      moving = true;
    } else {
      moving = false;
    }

    if (moving == true && restart == false) { //This part gives you the ability to move left and right while driving
      if (keyPressed && keyPressed == (keyCode == LEFT)) {
        xCar += speed;
      }
      if (keyPressed && keyPressed == (keyCode == RIGHT)) {
        xCar -= speed;
      }
    }

    if (moving == true && restart == false) { //Moves the objects towards you with translate, as if you are driving towards them
      translate(0, 0, z);
      z += 0.1;
    } else {
      z = 0;
    }
  }

  void obstacleInteract() {
    //for (int i = 0; i < amount; i++) {
      distance += z;

      translate(0, 0, -2000);
      rect(xCar, -500, size, height*3); //draws the obstacles

      if (distance > 2000 && moving == true) { //checks if the obstacle is hit (when it is still in screen) and gives a notification that you died or survived
        if (dist(width/2, 0, xCar, 0) < 500) {
          moving = false;
          restart = true;
          println("you are dead, not big suprise");
        } else {
          wavePassed = true;
          translate(0,0,-distance);
        //}
      }
    }
  }

  void nextWave() {
    if (wavePassed == true && wave < numberWaves -1) {
      wave += 1;
      wavePassed = false;
      distance = 0;
    }
  
  
    println("distance = ", distance );
    println("z = ", z );
  }

}

```

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [November 1, 2019, 12:05pm UTC](https://discourse.processing.org/t/obstacle-game-in-3d-with-2d-obstacles-unable-to-add-more-than-1-obstacle/15110/2 "2019-11-01T12:05:05Z")

</div>

> [@D.Signer](#):
>
> obstacleInteract()

This function also has translate in it

Please write pushMatrix and popMatrix at the beginning and at the end of the function too

---

<div class="post-metadata">

**Author:** ![D.Signer](https://avatars.discourse-cdn.com/v4/letter/d/ba8739/32.png) [@D.Signer](https://discourse.processing.org/u/D.Signer)\
**Post date:** [November 1, 2019, 1:01pm UTC](https://discourse.processing.org/t/obstacle-game-in-3d-with-2d-obstacles-unable-to-add-more-than-1-obstacle/15110/3 "2019-11-01T13:01:41Z")

</div>

Thanks for the help, but unfortunately this change didn’t affect the program at all. The translation is still affected by the number of obstacles that I want to spawn in.

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [November 1, 2019, 4:00pm UTC](https://discourse.processing.org/t/obstacle-game-in-3d-with-2d-obstacles-unable-to-add-more-than-1-obstacle/15110/4 "2019-11-01T16:00:15Z")

</div>

Also in draw() :

PushMatrix(); must come first, popMatrix(); last?

[https://processing.org/reference/pushMatrix\_.html](https://processing.org/reference/pushMatrix_.html)

---

<div class="post-metadata">

**Author:** ![D.Signer](https://avatars.discourse-cdn.com/v4/letter/d/ba8739/32.png) [@D.Signer](https://discourse.processing.org/u/D.Signer)\
**Post date:** [November 1, 2019, 4:05pm UTC](https://discourse.processing.org/t/obstacle-game-in-3d-with-2d-obstacles-unable-to-add-more-than-1-obstacle/15110/5 "2019-11-01T16:05:49Z")

</div>

I found a way to implement a 3d camera, so luckily I don’t need to use translate anymore. Thanks anyway.

> [@Chrisir](#):
>
> Also in draw() :
> 
> PushMatrix(); must come first, popMatrix(); last?

Well, normally yes, but when you want to execute a translation just once (that doesn’t change back to its origin afterwards) , I had read that you would have to do:

```auto
setup() {
pushMatrix();
}

draw() {
popMatrix();
(some code)
pushMatrix();
}

```

It worked, but it was very limited, so luckily I found an alternative.

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [November 1, 2019, 4:08pm UTC](https://discourse.processing.org/t/obstacle-game-in-3d-with-2d-obstacles-unable-to-add-more-than-1-obstacle/15110/6 "2019-11-01T16:08:09Z")

</div>

In this scenario pushMatrix and popMatrix don’t do anything

At the start of draw() the Matrix is resetted anyway

---

<div class="post-metadata">

**Author:** ![D.Signer](https://avatars.discourse-cdn.com/v4/letter/d/ba8739/32.png) [@D.Signer](https://discourse.processing.org/u/D.Signer)\
**Post date:** [November 1, 2019, 4:10pm UTC](https://discourse.processing.org/t/obstacle-game-in-3d-with-2d-obstacles-unable-to-add-more-than-1-obstacle/15110/7 "2019-11-01T16:10:02Z")

</div>

sorry, I actually meant:

```auto
setup() {
pushMatrix();
translation();
}

draw() {
popMatrix();
(some code)
translation();
pushMatrix();
}

```

Not that this is a good thing to use though

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [November 1, 2019, 4:23pm UTC](https://discourse.processing.org/t/obstacle-game-in-3d-with-2d-obstacles-unable-to-add-more-than-1-obstacle/15110/8 "2019-11-01T16:23:30Z")

</div>

> [@D.Signer](#):
>
> pushMatrix();  
> translation();

This doesn’t make sense in setup ()

The matrix gets resetted at start of draw

---

<div class="post-metadata">

**Author:** ![quark](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/quark/32/26_2.png) [@quark](https://discourse.processing.org/u/quark)\
**Post date:** [November 1, 2019, 4:29pm UTC](https://discourse.processing.org/t/obstacle-game-in-3d-with-2d-obstacles-unable-to-add-more-than-1-obstacle/15110/9 "2019-11-01T16:29:55Z")

</div>

`pushMatrix` and `popMatrix` should be used in pairs in that order - it is bad programming practice to split them across two functions as you have done in your code. It makes it confusing if you need other drawing functions to use them in the same sketch.

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [November 5, 2019, 8:59pm UTC](https://discourse.processing.org/t/obstacle-game-in-3d-with-2d-obstacles-unable-to-add-more-than-1-obstacle/15110/10 "2019-11-05T20:59:35Z")

</div>

> [@D.Signer](#):
>
> If you have any other tips on how I should actually handle the overall game

**Remark 1**

I understand that you made big progress here because you use a 3D camera now that gives you the view from the car. Well done.

When you click the mouse or w (as in wasd) you should move the camera.

The obstacles should be in fixed position. So they don’t move but the camera moves.

**Remark 2**

Don’t make car stuff part of the class Obstacle. This is confusing. Keep your class clean.

Either make a new class Car or Camera and treat it separately.

**Remark 3**

It’s good that you have a class of obstacles.

But better put the obstacles obst1,obst2,obst3 in an array (1D array, not 2D) and for loop over it.

So you can shorten these lines:

```auto
  obst1.moveCar(8);
  obst1.obstacleInteract();
  obst1.nextWave();

  obst2.moveCar(8);
  obst2.obstacleInteract();
  obst2.nextWave();

  obst3.moveCar(8);
  obst3.obstacleInteract();
  obst3.nextWave();

```

But I might say, you achieved a lot already. Well done!

Regards, Chrisir

---

<div class="post-metadata">

**Author:** ![Chrisir](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/chrisir/32/45_2.png) [@Chrisir](https://discourse.processing.org/u/Chrisir)\
**Post date:** [November 5, 2019, 10:12pm UTC](https://discourse.processing.org/t/obstacle-game-in-3d-with-2d-obstacles-unable-to-add-more-than-1-obstacle/15110/11 "2019-11-05T22:12:28Z")

</div>

Here is an example with wasd keys:

```auto

final int GENERAL_Y_HEIGHT = 300; 

Obstacle obstacles[] = new Obstacle[22];
Car car = new Car(); 

void setup() {
  size(1000, 1000, P3D);
  background(200);

  for (int i=0; i<obstacles.length; i++) {
    obstacles[i] = new Obstacle(random(30, 211), random(-1500, 1555)); // size, x-pos
  }
}

void draw() {
  background(200);

  lights();

  // Car 
  car.carCamera();  

  for (Obstacle obst : obstacles) {
    obst.obstacleDisplay();
  }

  // floor
  floor1() ;

  keyPressedThroughout();

  camera(); 
  fill(255); 
  text("Use wasd", 13, 13);
}

// --------------------------------------------------------------------
// Inputs 

void keyPressedThroughout() {
  switch (key) {

    // these letters we pass to car
  case 'w':
  case 's':
  case 'a':
  case 'd':
    car.keyPressedThroughoutCar();
    break;
    //
  }//switch
}//func 

// --------------------------------------------------------------------
// Tools 

void floor1() {
  // decoration: the floor  
  float extensionHalf=7500;

  PVector[] pvList = {
    new PVector (-extensionHalf, GENERAL_Y_HEIGHT, -extensionHalf), // upper left corner 
    new PVector (-extensionHalf, GENERAL_Y_HEIGHT, extensionHalf), // go down |
    new PVector (extensionHalf, GENERAL_Y_HEIGHT, extensionHalf), // go right ->
    new PVector (extensionHalf, GENERAL_Y_HEIGHT, -extensionHalf) // go up | (to upper right corner) 
  }; 
  fill(255, 0, 0);//RED
  beginShape();
  for (PVector pv : pvList) {
    vertex(pv.x, pv.y, pv.z);
  }
  endShape();
}

// ===========================================================================================================
// class 1

class Car {
  float carX = 0, 
    carY = GENERAL_Y_HEIGHT-88, 
    carZ = 1330;

  void carCamera() {
    camera(carX, carY, carZ, 
      carX, carY, carZ-300, 
      0, 1, 0);
  }

  void keyPressedThroughoutCar() {
    switch (key) {

    case 'w':
      carZ-=12;
      break;

    case 's':
      carZ+=12;
      break;

      //

    case 'a':
      carX-=12;
      break;

    case 'd':
      carX+=12;
      break;
      //
    }//switch
  }//func
}// class

// ===========================================================================================================
// class 1
class Obstacle {

  float x, y, z; // pos - see constr 
  float sizeObst; // size - see constr
  color colObst = color (random(255), random(255), random(255) );

  // constr 
  Obstacle(float s_, float x_) { // mark parameters by _ sign 

    sizeObst=s_;

    x = x_;    
    y=GENERAL_Y_HEIGHT-sizeObst/2;
    z=random(-3300, -55);
  }

  void obstacleDisplay() {

    pushMatrix(); 
    fill(colObst); 
    translate(x, y, z);
    box(sizeObst); //draws the obstacle
    popMatrix();
  }
  //
}// class
//

```
