Inspiration:
I really like trains, and so I thought I could try to make a basic train simulator in Processing. I wanted the user to control a subway train between two stations, have to navigate a red signal, and stop and the next station without overshooting the platform. I also wanted the background to be populated with other NPC trains.
Process:
I started by trying to build the background for the simulator, which would simply be a top-down view of the tracks and tunnel. I made a platform, two rails for the tracks, and made a class for trains. I tried to add a .png image for the tracks, but for some reason, it wouldn’t load in. I never got an error message, I simply couldn’t see the image. As a place-holder, I added some rectangles for the rails. You can’t control the train yet, but the goal is to be able to.
Final Work:
Challenges:
I had a lot of challenges so far. For some reason, the rectangle of the subway train stays on the screen without disappearing. As mentioned above, I can’t load the tracks .png file, and finally I haven’t yet added user control over the train.
Code:
Train[] trains;
int platformDepth;
int platformLength;
int railWidth;
int railSpacing;
int sleeperWidth;
int sleeperLength;
int sleeperSpacing;
PFont stationFont;
PImage img;
void setup(){
size(1280,640);
background(255);
stationFont = createFont("Courier New", 30);
img = loadImage("subwayTracks.png");
platformDepth = 100;
platformLength = 800;
railWidth = 2;
railSpacing = 28;
sleeperWidth = 5;
sleeperLength = 30;
sleeperSpacing = 15;
trains = new Train[3];
for (int i=0; i<trains.length; i++) {
trains[i] = new Train(0, height-platformDepth-10-railSpacing, (10));
}
}
void draw(){
//platform
stroke(0);
fill(255, 200, 100);
rect(width/2-platformLength/2, height-platformDepth, platformLength, platformDepth);
//rails
noStroke();
fill(0);
rect(0, (height-platformDepth) - 10, width, railWidth);
rect(0, (height-platformDepth) - 10 - railSpacing, width, railWidth);
noStroke();
fill(0);
// for (int i=0; i>0; i++){
// rect(i, height-platformDepth - sleeperLength, sleeperWidth, sleeperLength);
// }
for (int i=0; i<trains.length; i++) {
trains[i].runTrain();
textFont(stationFont);
textAlign(CENTER);
text("23rd St. Station", width/2, height-platformDepth+50);
image(img, (height-platformDepth) - 10, width/2);
}
}
class Train{
float posX, posY;
float trainWidth, trainLength;
color trainColor;
float wheelWidth, wheelHeight;
float speed;
Train(float _posX_, float _posY_, float _speed){
posX = _posX_;
posY = _posY_;
trainWidth = 40;
trainLength = trainWidth*1;
trainColor = color(126,127,128);
speed = _speed;
}
void runTrain(){
trainBody();
driveTrain();
}
void constructTrain(float _posX_, float _posY_){
}
void trainBody(){
fill(trainColor);
noStroke();
rect(posX, posY, trainLength, trainWidth, 7);
//trailing carriages
//fill(trainColor);
rect(posX-trainLength-10, posY, trainLength, trainWidth, 7);
rect(posX-(trainLength*2)-10, posY, trainLength, trainWidth, 7);
}
void driveTrain(){
posX += speed;
if (posX > width+trainWidth/2) {
posX = -trainWidth/2;
}
}
}












