Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
123 views
in Technique[技术] by (71.8m points)

javascript - Gravity implementation causing Obj to continue through object

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I think the problem is that, when the object is out of bounds, you reduce its speed, so it doesn't have enough speed to come back in 100%.

Maybe you can apply your "friction" in the next update, not the one with the collision.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...