I am working on creating a 2d sidescoller car game (Think hill climb racing). The land is a line and generated at once. I have been setting up the physics for car tires and them hitting the lines and have the problem of tunneling. Currently when the tires are touching the ground I add 1 to the height of the car. This is a basic fix and does not solve my tunneling. Any idea on getting the tunneling to stop? If you need my code here it is. Also the code for the collisions is in Car.collide
var keys = [];
var keyPressed = function() {
keys[keyCode] = true;
};
var keyReleased = function() {
keys[keyCode] = false;
};
var transX = 0;
var transY = 0;
var level = [
];
var collide = [];
{
var createTerrain = function(size, dist, store, scale, scm) {
this.dist = dist;
this.size = size;
this.storage = store;
this.scale = scale;
this.scm = scm;
};
createTerrain.prototype.pushNoise = function() {
for (var i = 0; i < this.size; i++) {
noiseDetail(7, 0.69);
this.storage.push([abs((noise(i * random(0, 100) * 0.02, i * random(0, 100) * 0.02) - 1) + 1) * 165]);
//this.storage.push([1,1]);
}
};
createTerrain.prototype.drawMap = function() {
for (var i = 0; i < this.storage.length - 1; i++) {
stroke(82, 35, 35);
//nnslate(10,10);
// scale(this.scale);
line((30 * i + 110) * this.scale - this.scale * this.scm + transX, (this.storage[i] / 1.5 + 100) * this.scale - this.scale * this.scm+transY, (30 * i + 140) * this.scale - this.scale * this.scm + transX, (this.storage[i + 1] / 1.5 + 100) * this.scale - this.scale * this.scm+transY);
}
};
} //Terrain
{
var isBetween = function(c, a, b) {
return (a - c) * (b - c) <= 0;
};
var isInCircle = function(x, y, cx, cy, diam) {
var dx = x - cx;
var dy = y - cy;
return dx * dx + dy * dy <= diam * diam / 4;
};
var lineCircleCollide = function(x1, y1, x2, y2, cx, cy, diam) {
var m = (y2 - y1) / (x2 - x1);
if (abs(m) > 1024) {
return lineCircleCollide(y1, x1, y2, x2, cy, cx, diam);
}
if (isInCircle(x2, y2, cx, cy, diam)) {
return true;
}
x1 -= cx;
x2 -= cx;
y1 -= cy;
y2 -= cy;
var r = diam * diam / 4;
var k = y1 - m * x1;
var a = (1 + m * m) / r;
var b = 2 * m * k / r;
var c = k * k / r - 1;
var discrim = b * b - 4 * a * c;
if (discrim < 0) {
return false;
}
discrim = sqrt(discrim);
a *= 2;
return isBetween((-b - discrim) / a, x1, x2) || isBetween((-b + discrim) / a, x1, x2);
};
} //Bob lyon
var distance = function (P1, P2, C) {
return abs( (P2.y - P1.y)*C.x - (P2.x - P1.x)*C.y + P2.x*P1.y - P2.y*P1.x ) / sqrt( pow(P2.y - P1.y, 2) + pow(P2.x - P1.x, 2) ) < C.radius; //If the distance from the center of C to the closest point on line P1P2 is less than the radius of C, returns true. Otherwise, returns false.
};
{
var car = function(locatio, accel, image, dragcoof) {
this.loc = locatio;
this.accel = accel;
//this.power = power;
this.image = image;
this.volocity = new PVector(0, 0);
this.acceleration = new PVector(0, 0);
this.drag = new PVector(0, 0);
this.dragcoof = new PVector(dragcoof.x, dragcoof.y);
//this.trans = new PVector(0,0);
this.rot = 0;
this.wheelX = 0;
this.wheelY = 0;
this.canFall = true;
};
car.prototype.draw = function() {
if (this.image === null) {
//println("please put a nice image but I will supply a simple box for testing");
pushMatrix();
translate(this.loc.x, this.loc.y);
rotate(this.rot);
fill(255, 0, 0);
rect(0, 0, 50, 10);
ellipse(7, 10, 10, 10);
ellipse(45, 10, 10, 10);
//this.wheelX= this.loc.x+7;
//this.wheelY = this.loc.y+10;
popMatrix();
this.wheelX = mouseX;
this.wheelY = mouseY;
} else {
this.image(this.loc.x, this.loc.y);
}
};
car.prototype.update = function() {
//this.momentum = this.volocity.mult(this.mass);
if (this.volocity.x >= 10) {
this.volocity.x = 9.99;
}
if (this.volocity.x <= 0.1) {
// this.volocity.x = 0;
}
if(this.canFall){
this.acceleration.add(0,0.072);
}
if(!this.canFall){
this.acceleration.y = 0;
this.volocity.y = 0;
}
this.volocity.add(this.acceleration);
transX -= (this.volocity.x);
this.drag = PVector.mult(this.volocity, this.dragcoof);
this.volocity.sub(this.drag);
transY -= (this.volocity.y);
//translate(-this.trans.x,0);
};
car.prototype.move = function(keycodeLeft, keycodeRight) {
if (keys[RIGHT] && this.volocity.x < 10) {
this.acceleration.add(this.accel.x, 0);
}
if (!keys[RIGHT] && !keys[LEFT]) {
this.acceleration.set(0, 0);
}
if (keys[LEFT] && this.volocity.x >= -0.5) {
this.acceleration.set(-0.1, 0);
}
if(keys[DOWN]){
this.rot--;
}
if(keys[UP]){
this.rot++;
}
}; // x1, y1, x2, y2, cx, cy, diam
car.prototype.collide = function(lanvar) {
for (var i = 0; i < level.length - 1; i++) {
// fill(255, 255, 255, 2);
// ellipse(this.loc.x+6,this.loc.y+10,10,10);
if (lineCircleCollide((30 * i + 110) * lanvar.scale - lanvar.scale * lanvar.scm + transX, (lanvar.storage[i] / 1.5 +100) * lanvar.scale - lanvar.scale * lanvar.scm+transY, (30 * i + 140) * lanvar.scale - lanvar.scale * lanvar.scm + transX, (lanvar.storage[i + 1] / 1.5 + 100) * lanvar.scale - lanvar.scale * lanvar.scm+transY, this.loc.x+6,this.loc.y+10, 10)) {
this.canFall=false;
// collide.push([i, i + 1]);
// println(this.loc.x+45-transX);
// println(this.loc.x+55-transX+" "+this.loc.y);
transY++;
fill(3, 3, 3);
text("Back Wheel hit",100,100);
break;
}
if (lineCircleCollide((30 * i + 110) * lanvar.scale - lanvar.scale * lanvar.scm + transX, (lanvar.storage[i] / 1.5 + 100) * lanvar.scale - lanvar.scale * lanvar.scm+transY, (30 * i + 140) * lanvar.scale - lanvar.scale * lanvar.scm + transX, (lanvar.storage[i + 1] / 1.5 + 100) * lanvar.scale - lanvar.scale * lanvar.scm+transY, this.loc.x+45,this.loc.y+10, 10)) {
this.canFall=false;
// collide.push([i, i + 1]);
fill(3, 3, 3);
text("Front Wheel hit",100,100);
{
var n = new PVector(-this.loc.x+45+(30 * i + 110) * lanvar.scale - lanvar.scale * lanvar.scm + transX,-(this.loc.y+10)+(lanvar.storage[i] / 1.5 + 100) * lanvar.scale - lanvar.scale * lanvar.scm);
///println(n);
var u = new PVector((this.volocity.x*n.x)/(n.x*n.x),(this.volocity.y*n.y)/(n.y*n.y));
//var w = new PVector(PVector.subt(this.volocity,u));
var w = new PVector(this.volocity.x-u.x,this.volocity.y-u.y);
}//Just some math that is not used (now but also never is possible)
//
//transX-=this.volocity.x;
/**
var slopeX = ((30 * i + 140) * lanvar.scale - lanvar.scale * lanvar.scm + transX)-((30 * i + 110) * lanvar.scale - lanvar.scale * lanvar.scm + transX);
var lastX=this.loc.x-this.volocity.x;
if((this.loc.x-lastX)%slopeX){
println(this.loc.x+" ");
println(lastX+" lastX");
println(slopeX+" slopeX");
var slopeY = ((lanvar.storage[i + 1] / 1.5 + 100) * lanvar.scale - lanvar.scale * lanvar.scm+transY)-((lanvar.storage[i] / 1.5 + 100) * lanvar.scale - lanvar.scale * lanvar.scm+transY);
println(slopeY);
if(slopeY<0){
this.transY+=slopeY;
}
*///junk
transY++;
break;
}
this.canFall=true;
}
};
} //Car
{
var a = new car(new PVector(300, 200), new PVector(0.01, 0), null, new PVector(0.022, 0));
var b = new createTerrain(200, 2000, level, 4, 130);
b.pushNoise();
var draw = function() {
background(255, 255, 255);
a.draw();
a.update();
a.move();
text(a.acceleration + "\n" + a.volocity + "\n" + a.drag + "\n" + mouseX + " " + mouseY + "\n" + a.loc, 400, 100.5);
b.drawMap();
a.collide(b);
//println(collide[0]);
// println(collide[1]);
};
} //Draw and other things that don't deserve another bracket
https://www.khanacademy.org/computer-programming/car-physics-thingy/5378059343