I am having an issue with my implementation of gravity and collision on many objects on a canvas...I understand where I have gone wrong I just cannot for the life of me think of a solution to fix it.
I am checking if dropped objects reach a y position on the canvas and then reverse the velocity * friction to bounce the object...This works fine with one object or many objects. However, because of my conditional when the objects stack on top of each other the velocity never decreases as it is always being increased by the gravity, meaning the objects slowly pass through each other after they have finished bouncing around.
I have tried checking if "this" object is colliding however this will not work as the objects should be able to bounce until friction causes the velocity to decrease or increase to zero(or very close in this case).
Here is the function for gravity.
gravity() {
//If the objects y + the height and delta are greater than the canvases height reverse the velocity * friction also apply
//same friction to x to stop the objects from sliding
if (this.y + this.height + this.delta_y >= this.canvas.height) {
this.delta_y = -this.delta_y * this.FRICTION;
this.delta_x = this.delta_x * this.FRICTION;
//If the delta_y does not push the objects y over the canvas height increase the delta by the gravitational pull
} else {
this.delta_y += this.GRAVITY;
}
//Apply reversed velocity over x - works because no constant gravity being added
if (this.x + this.width >= this.canvas.width || this.x - this.width <= 0) {
this.delta_x = -this.delta_x * this.FRICTION;
}
//update the x and y coordinates with the new delta value
this.x += this.delta_x;
this.y += this.delta_y;
//set the new centre for collision.
this.center = {
"x": this.x + this.width / 2,
"y": this.y + this.height / 2
};
}
I also thought I maybe able to run a timer on the y variable for a few milliseconds and if it has not changed outside of a bound then I could stop movement. However, this is not ideal and im not sure if a timeout would be good as javascript is single threaded? I would be at home in python but I am struggling here.
I have enclosed the calling function here
gameLoop(timeStamp) {
// Calculate how much time has passed // was thinking I could use this to check y after some time
//but stopped and decided to post to stack
let secondsPassed = (timeStamp - this.oldTimeStamp) / 1000;
this.oldTimeStamp = timeStamp;
if (this.gameObjects.length > 0) {
//update all objects and pass all objects to update to check for collision
for (let i = 0; i < this.gameObjects.length; i++) {
this.gameObjects[i].update(this.gameObjects);
}
//clear the canvas ready for next draw
this.clearCanvas();
//draw the next iteration of the gameobjects
for (let i = 0; i < this.gameObjects.length; i++) {
this.gameObjects[i].draw();
}
}
window.requestAnimationFrame((timeStamp) => this.gameLoop(timeStamp));
}
Finally here is the update function for completeness
update(gameObjects) {
//impose gravity on this object
this.gravity();
//loop through objects and check for collision
for (let i = 0; i < gameObjects.length; i++) {
// if this object is the same as the iterated object skip it
if (this === gameObjects[i]){continue;}
//test variable to check collision on this object
this.colliding = this.collisionDetection(gameObjects[i]);
//if colliding resolve the collision
if (this.colliding) {
this.resolveCollision(this, gameObjects[i]);
}
}
}
Thank you, vanilla JS only please.
question from:
https://stackoverflow.com/questions/65540672/gravity-implementation-causing-obj-to-continue-through-object 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…