Traffic Light simulation

Hi guys, so I tried my best to try and do this without any help from the forums but I've cracked.

I'm trying to simulate 4 way traffic. My intention was to get the traffic going one way, then simply change/add variables and rotate the objects I've already got to make it go all 4 ways. However I'm having difficulties going about it.

So I have the lights working(this is all just for one way, but the way) and I have an Arraylist of cars, random colours, coming up to the light, stopping, then going when it's green. Right now I'm trying to add a sort of Car queue for when they stop at the lights, so they don't bunch up. Ultimately, I want the cars all coming randomly in all 4 entrances so I'd want this car queuing to work no matter what way I set the cars. This being said, the way I've attempted so far is to have a box behind each car. The intention was if a car goes over that block, it should stop.

I've attempted 2 ways of doing this, dis() and with if statements.

Right now Ive attempted the dist() and it just doesn't work. At one point I ran though my y values and they're just crazy, y goes through so many numbers I don't think it would even be plausible to do this with array lists. Notice, the function checking the distance is never even returning true, even when cars are overlapping.

So my question is, how could I get a car queue going?

How do I exactly rotate objects?(I've attempted and it went under the bus, so I left it for a later time), plan to rotate the cars and traffic lights.

Is there anything else in my code that could be improved to make other aspects of it run smoother?

Here is the code. I'm very sorry but there's quite a bit of code. I've removed the useless code and the road class for readability, I've left the traffic light class there simply so it can be seen what the lights are doing. If you want the full code though I'll paste it. I will gladly answer questions about it though. I appreciate any help, honestly.

`

    car c1, c2;
    road r1;
    ArrayList carList=new ArrayList();
    Lights SouthLight;
    Lights NorthLight;
    Lights WestLight;
    Lights EastLight;
    int i=0;
    boolean isRed= false;
    boolean isOrange= false;
    boolean isGreen= false;
    int back =80;

    int count;

    void setup() {
      size(1000, 700);
      r1 = new road() ;
      c1 = new car (width/2-30, height, int(random(255)));
      c2= new car(width/2-30, height-130, int(random(255)));
      SouthLight = new Lights(width/2-100, height/2+105);
      NorthLight = new Lights(width/2+100, height/2-105);
      smooth();
      for (int i=0; i<10; i++) {
        carList.add(new car(width/2-30, height+back, (color(random(int(256)), random(int(256)), random(int(256))))));   

        back+=80;

      }

    } 

    void draw() {
      count = frameCount/60; 
      background (0, 200, 0);
      r1.display();
      for (int i = 0; i<=carList.size()-1; i++) {
        car CarSouth = (car)carList.get(i);
        CarSouth.display();
        CarSouth.move();

        if(CarSouth.insideBox(CarSouth.x,CarSouth.y,CarSouth.x_box,CarSouth.y_box)){
          CarSouth.speedy=0;
        }
        if ( CarSouth.finished(CarSouth.y)) {
          carList.remove(i);
          carList.add(new car(width/2-30, height+back, (color(random(int(256)), random(int(256)), random(int(256))))));   
        back+=80;
        }
      }

      SouthLight.display();
      SouthLight.TurnRed();
      SouthLight.TurnGreen();
      SouthLight.TurnOrange();

      switch(count) {
      case 0:

        isRed=true;
        break;

      case 1:

        isOrange=true;
        break;

      case 2:
        isRed=false;
        isOrange=false;
        isGreen=true;
        break;

      case 3:
        isGreen=false;
        isOrange=true;
        break;

      case 4:
        isOrange=false;
        isRed=true;

      case 5:
        count=0;
        frameCount=0;
      default :
      }
    }

    class car {

      int x;
      color col;
      int speed=-2;
      int speedy=constrain(speed, -2, 0);
      int y;
      int w=35;
      int h=30;
      int r=8;
      int x_box=x;
      int y_box=y;
      int w_box=30;
      int h_box=15;

      boolean waited =false;

      int space = height/2+100;

      int LerpSpace = height/2+120;


      car(int xpos, int ypos, color  c) {

        x = xpos;
        y = ypos;
        col=c;
      }

      void display() {
        x_box=x+13;
        y_box=y+65;
        rectMode(CENTER);
        fill(255);
        rect(x_box, y_box, w_box, h_box);

        rectMode(CORNER);
        fill(col);
        rect(x, y, w-10, h+30, r-2);//car body 

        rect(x+2, y+20, w-15, h-10, r, r, r, r);//Oblong roof

        fill(255, 255, 0);//yellow
        ellipse(x+5, y+2, 5, 5);// front light on the left
        ellipse(x+20, y+2, 5, 5);// front light on the right

        fill(255, 0, 0);
        ellipse (x+5, y+59, 5, 5);
        ellipse (x+20, y+59, 5, 5);

        fill(0); // black 
        quad(x+4, y+17, x+1, y+9, x+24, y+9, x+21, y+17);//front windscreen 
        quad(x+4, y+43, x+1, y+51, x+24, y+51, x+21, y+43); // back windscreen
        rect(x-1, y+14, 1, 7);
        rect(x-1, y+45, 1, 7);
        rect(x+25, y+14, 1, 7);
        rect(x+25, y+45, 1, 7);
      }

      void move() {


        if (isBehindLight(y)) {
          slowDown(y);
          waited=true;
        }

        if (!SouthLight.TurnRed()) {
          speedy=-2;
          y=y+speedy;
        } else {
          if (isBehindLight(y)==false) {
            speedy=-2;
            y=y+speed;
          }
        }
      }

      void Stop() {
        speedy=0;
      }

      void slowDown(int y) {

        if (speedy<0) {
          y=(int)lerp(y, space, 1);
        }
      }

      boolean isBehindLight(int y) {
        if (y>space&&y<460) {
          return true;
        } else {
          return false;
        }
      }

      boolean finished(int y) {
        if (y<-50) {
          return true;
        } else {

          return false;
        }
      }


      boolean insideBox(int x, int y, int xb, int yb) {
        if (dist(x, y, xb, yb)<15) {
      println (true);
          return true;
        } else {
          println(false);
          return false;
        }
      }
    }

    public class Lights {

      int xpos;
      int ypos;


      Lights(int x, int y) {
        xpos = x;
        ypos=y;
      }

      void display() {
        fill(0);//Black Rectangle 
        rect(xpos, ypos, 40, 80);//Takes x and y position 

        fill(255, 0, 0);//red circle for red light
        ellipse( xpos+20, ypos+15, 20, 20);//fade to represent it's off
        fill(50, 200);//faded grey
        ellipse( xpos+20, ypos+15, 20, 20);

        fill(255, 255, 0);//Orange circle for orange light
        ellipse( xpos+20, ypos+40, 20, 20);
        fill(50, 200);//Faded grey to represent it's off
        ellipse( xpos+20, ypos+40, 20, 20);

        fill(0, 255, 0);
        ellipse( xpos+20, ypos+65, 20, 20);
        fill(50, 200);
        ellipse( xpos+20, ypos+65, 20, 20);
      }

      Boolean TurnRed() {
        if (isRed==true) {
          fill(255, 0, 0);//red circle for red light
          ellipse( xpos+20, ypos+15, 20, 20);
        }

        if (isRed==true){
        return (true);
        } else {
          return (false);
        }
      }

      Boolean TurnOrange() {
        if (isOrange==true) {
          fill(255, 255, 0);//Orange circle for orange light
          ellipse( xpos+20, ypos+40, 20, 20);
        }
        return isOrange;
      }

      Boolean TurnGreen() {
        if (isGreen==true) {
          fill(0, 255, 0 );//Orange circle for orange light
          ellipse( xpos+20, ypos+65, 20, 20);
        }
        return isGreen;
      }
    }

`

Answers

  • You could have separate lists for each lane. So that when you add a car to one of the lanes, you know how many cars are in that lane, thus can say "stop at carDistance*amountOfCarsInLane".

    And when a car goes past the traffic light. You should probably also have an int counting how many cars have passed the traffic lights, so that the cars don't keep stopping far away from the light...

    Or you could have ints counting how many cars are in each lane like this:

    newCar = random(0,3);
    if(newCar>1){
    lane0 +=1;
    //the code for adding a car
    }
    

    And then when a car form lane 0 passes the traffic lights, you subtract 1 from lane0.

    Rotating is actually not that hard when you're dealing with an object. Do this:

    pusMatrix();
    translate(/*to wherever you want the car to be*/);
    rotate(/*as much as you like*/);
    //draw the car with the center at 0,0!
    popMatrix();
    
  • I would just put red traffic lights on the back of cars.

  • Thanks for the suggestions Eeyorelife. That was definitely something I was considering when it came to implementing multiple cars, numbering the lanes and having them correspond to the lanes.

    I've never rotated anything other than shapes, ya see. But thanks.

    TfGuy, that seems crazy enough to work, only, the way I've coded everything, it would mean the space variable in which they stop around would need to vary much more.

    I'll give it a go, actually, considering I do have the traffic lights working fine.

    I do also want to know why dist isn't working as well. I believe when I ran it through the console, it was returning 60 regardless of the position of the cars.

  • edited March 2016

    Sorry for the double post but I want to bump this a little with an extra query.

    So I started by trying to use a similar method to how I got the cars to stop to the traffic lights, and I've made progress in what the programs are returning, it's registering that the cars are crossing over each other, (got it to return true when they do, which it wasn't doing before) and even got it going down to another function which I use to slow the cars down (which they don't even do anymore, but at this point I stopped caring about that)

    The issue is that it's reaching the lerp function slowDownBehind() taking the car position y, and setting the stop position at the y position of the box behind the cars, at a rate of 1. It doesn't seem to do anything, however this code is being accessed, because it's printing.

    here's the code

    `

      int y_box=y;
      int w_box=30;
      int h_box=15;
      int carSpace=y_box+h_box;
      int counter=0;
      boolean waited =false;
      int space = height/2+100;
      int endSpace = 460;
    
       void move() {
    
        if (isBehindLight(y)) {
           if (isBehindCar(y)) {
            slowDownBehind(y);
          } else {
    
            slowDown(y);
            waited=true;
          }
    
        }
    
        if (!SouthLight.TurnRed()) {
          speedy=-2;
          y=y+speedy;
        } else {
          if (isBehindLight(y)==false) {
            speedy=-2;
            y=y+speedy;
          }
        }
    
      }
    
    void slowDown(int y) {
        if (speedy<0) {
          y=(int)lerp(y, space, 0.5);
        }
      }
    
      boolean isBehindLight(int y) {
        if (y>space&&y<endSpace) {
          return true;
        } else {
          return false;
        }
      }
    
      boolean isBehindCar(int y) {
        if (y+speedy>y-carSpace) {
    
          y=y-carSpace;
          println(true);
          return true;
        } else {
          speedy=-2;
          return false;
        }
      }  
    
      void slowDownBehind(int y) {
    
        if (speedy<0) {
          println("lerp true");
          y=(int)lerp(y, carSpace+y, 0.01);
          y=y+carSpace;
          speedy=0;
        }
      }
    

    `

Sign In or Register to comment.