Hey you’re right, actually it’s a new topic, but you could change the title to “Questions about a racing game”
First of all, I now know why the game is lagging.
You have to say in size () that the P2D renderer should be used.
so: size(1200, 675, P2D);
Now we come to a small problem because the start line is rotated.
We could ignore that and instead simply say that we are “testing” the start line imprecisely.
So roughly like this:
You can think about it later. How to do it more precisely.
Here is an interesting link: Collision Detection - point hitting a rotating rectangle - Game Development Stack Exchange
Click to see the code in Processing language
PVector pos;
PVector size;
float angle = 0;
boolean isInside = false;
void setup() {
rectMode(CENTER);
size(600, 600);
pos = new PVector(width/2, height/2);
size = new PVector(400, 150);
}
void draw() {
angle += radians(1);
background(0);
if (isInside) {
fill(255);
} else {
fill(0);
}
stroke(255);
strokeWeight(2);
translate(pos.x, pos.y);
rotate(angle);
rect(0, 0, size.x, size.y);
PVector rotatedMousePos = Rotate(new PVector(mouseX, mouseY), angle, pos);
isInside = isInsideRect(rotatedMousePos, pos, size);
}
boolean isInsideRect(PVector p, PVector rp, PVector rs) {
if (p.x > rp.x - rs.x/2 && p.x < rp.x + rs.x/2 &&
p.y > rp.y - rs.y/2 && p.y < rp.y + rs.y/2) {
return true;
}
return false;
}
PVector Rotate(PVector point, float angle, PVector center_of_rotation) {
angle = -angle;
float sinus = sin(angle);
float cosinus = cos(angle);
PVector temp = new PVector();
point = PVector.sub(point, center_of_rotation);
temp.x = point.x * cosinus - point.y * sinus;
temp.y = point.x * sinus + point.y * cosinus;
point = PVector.add(temp, center_of_rotation);
return point;
}
The problem is, as you said, the background is moving, so we just have to move the starting line position at the same time as the background. And we can just do that in the “moveBackground()” function
So that we know that the player has driven around once, we need a checkpoint. Here it is the same as with the starting line
Click to see the Code
PImage carImage;
PImage background;
PVector backgroundPos;
Car car;
boolean move = false;
float speed;
float angle;
/* STEERING */
float mapval;
int val;
//Start is start and end
PVector startPos, startSize;
//You could of course make more checkpoints mabye with an array or with an own class :)
PVector checkpointPos, checkpointSize;
boolean checkpointCleared = false;
boolean raceStarted = false;
float raceTime = 0;
void setup() {
rectMode(CENTER);
imageMode(CENTER);
//hey I dont know why but when you use the P2D rederer
//then the programm doesnt legg anymore
size(1200, 675, P2D);
carImage = loadImage("car.png");
background = loadImage("https://www.clipartkey.com/mpngs/m/33-331548_clip-art-oval-oval-race-track-clipart.png");
int size = 3;
background.resize(background.width*size, background.height*size);
car = new Car(width/2, height/2);
startPos = new PVector(width/2+20, height/2-40);
startSize = new PVector(150, 300);
checkpointPos = new PVector(2420, 800);
checkpointSize = new PVector(300, 150);
backgroundPos = new PVector(background.width/2, background.height/2);
}
void draw() {
if (raceStarted) {
raceTime += 1 / frameRate;
}
println("Time: " + raceTime + " seconds");
println("Race on going: " + raceStarted);
background(0);
//Instead of that:
//pushMatrix();
//translate(backgroundPos.x, backgroundPos.y);
//image(background, 0, 0);
//popMatrix();
//You could also say:
image(background, backgroundPos.x, backgroundPos.y);
updateStart();
if (raceStarted) {
fill(0, 255, 0);
} else {
fill(255, 0, 0);
}
stroke(255, 0, 0);
strokeWeight(10);
rect(startPos.x, startPos.y, startSize.x, startSize.y);
updateCheckpoint();
if (checkpointCleared) {
fill(0, 255, 0);
} else {
noFill();
}
stroke(255, 0, 0);
strokeWeight(10);
rect(checkpointPos.x, checkpointPos.y, checkpointSize.x, checkpointSize.y);
car.show();
car.update();
}
void updateCheckpoint() {
//We dont have to do more than that i think
if (isInsideRect(car.pos, checkpointPos, checkpointSize)) {
checkpointCleared = true;
}
}
void updateStart() {
if (isInsideRect(car.pos, startPos, startSize)) {
if (raceStarted == false && checkpointCleared == false) {
raceStarted = true;
println("Race Started");
} else if (checkpointCleared == true) {
//If raceStarted then test if the checkpoint is clear
raceStarted = false;
println("Race finished");
}
}
}
boolean isInsideRect(PVector p, PVector rp, PVector rs) {
if (p.x > rp.x - rs.x/2 && p.x < rp.x + rs.x/2 &&
p.y > rp.y - rs.y/2 && p.y < rp.y + rs.y/2) {
return true;
}
return false;
}
void keyPressed() {
if (key == 'w' || key == 'W' || key == ' ') {
move = true;
}
}
void keyReleased() {
move = false;
}
void moveBackground(PVector vel) {
vel.x = -vel.x;
vel.y = -vel.y;
//move also the start and endpoint
startPos.add(vel);
//of course we need to move the checkpoint aswell
checkpointPos.add(vel);
backgroundPos.add(vel);
}
class Car {
//PImage carImage;
PVector pos;
//float angle;
//float speed;
Car(float x, float y) {
//carImage = loadImage("car.png");
//link to the Picture: https://toppng.com/uploads/preview/aston-martin-one77-01-top-down-car-sprite-1156302814774vtgthfmb.png
carImage.resize(0, 100);
pos = new PVector(x, y);
angle = 0;
speed = 20;
}
void show() {
pushMatrix();
translate(pos.x, pos.y);
rotate(angle);
image(carImage, 0, 0);
popMatrix();
}
void update() {
updateAngle();
//Just try both and decide which one you like more
//updateMovementFirstExample();
updateMovementSecondExample();
}
void updateAngle() {
PVector vel = PVector.sub(new PVector(mouseX, mouseY), pos);
angle = atan2(vel.y, vel.x);
}
void updateMovementSecondExample() {
if (move == false) return;
PVector vel = PVector.sub(new PVector(mouseX, mouseY), pos);
if (vel.mag() < speed) return;
vel.normalize();
vel.mult(speed);
moveBackground(vel);
}
}
I hope I could help you
Edit:
I removed the Serialport because I dont have an Arduino sorry