Stephan Posted September 18, 2014 Share Posted September 18, 2014 Hi there, Todat I was doing some testings in panda.js and I encountered something strange. It appears that collision between two bodies is not detected upon shifting a body with a tween. In contrast: When I move one of the bodies, the collisiondetection works fine). Here is my code example:game.module( 'game.main').body(function() { game.addAsset('box.png'); Box = game.Class.extend({ init: function(x, y, speed) { //container for graphics this.container = new game.Container(); this.container.addTo(game.scene.stage); //link to scene to get the update() function of this object running. game.scene.addObject(this); //sprite this.sprite = new game.Sprite('box.png',0,0,{anchor: { x: 0.5, y: 0.5 }}); this.sprite.addTo(this.container); //body this.body = new game.Body({ position: { x: x, y: y }, collisionGroup: 0, collideAgainst: 0, mass: 0, }); this.body.collide = this.collide.bind(this); this.body.addShape(new game.Rectangle(136, 176)); game.scene.world.addBody(this.body); }, collide: function() { console.log("Collision. This line is not called."); return true; }, update: function(){ this.sprite.position.x = this.body.position.x; this.sprite.position.y = this.body.position.y; }, remove: function() { game.scene.removeObject(this); game.scene.world.removeBody(this.body); this.container.remove(); }, }); game.createScene('Main', { backgroundColor: 0x44cce2, init: function() { this.world = new game.World(0, this.gravity); this.box=new Box(100,500,0); this.box2=new Box(500,500, 0); game.scene.addTween(this.box2.body.position, {x: -100}, 300, {repeat: Infinity, yoyo: true}).start(); }, });});Has anyone experienced this too? Is this a bug or should I just use movement in stead? Suggestions are welcome. cheers,Stephan Quote Link to comment Share on other sites More sharing options...
enpu Posted September 19, 2014 Share Posted September 19, 2014 Physics bodies should be moved using gravity and velocity. Quote Link to comment Share on other sites More sharing options...
Stephan Posted September 19, 2014 Author Share Posted September 19, 2014 Thanx enpu, I guess you're right.I am currently working on some small adaptions in the basic physics engine (the physics.js file). For my project I need slightly improved collision handling and I will post the resulting code when I am done. (It won't be anything too complicated but I want the collision to work like colliding balls and it must be able to deal with different masses).Stephan Quote Link to comment Share on other sites More sharing options...
Stephan Posted September 19, 2014 Author Share Posted September 19, 2014 Hi Enpu, Here is the code that I wrote to replace hitResponse (from the src/engine/physics.js file). It isn't a perfect physics simulation but it is in my opinion a bit more realistic than the original code.Would you be interested to incorporate this in the main engine or shall I write a plugin for it? Here is the code: /** Hit response a versus b. @method hitResponse @param {game.Body} a @param {game.Body} b @return {Boolean} **/ hitResponse: function(a, { //Execute the collide function of body a to let the object know that a collision occured. //The response of the function tells us wether we should perform a hit response. if (a.collide() { //determine center if shape A var a_center=new game.Vector().copy(a.position); if(a.shape instanceof game.Rectangle){ a_center.x+=a.shape.width/2; a_center.y+=a.shape.height/2; } else if(a.shape instanceof game.Circle){ a_center.add(a.shape.radius); } //determine center if shape B var b_center=new game.Vector().copy(b.position); if(b.shape instanceof game.Rectangle){ b_center.x+=b.shape.width/2; b_center.y+=b.shape.height/2; } else if(b.shape instanceof game.Circle){ b_center.add(b.shape.radius); } //prepare masses var a_mass=a.mass+0.001; var b_mass=b.mass+0.001; //calculate an impulse vector based on velocity and mass of each body var distanceAB=new game.Vector().copy(b_center).subtract(a_center); var velocityAB=new game.Vector().copy(b.velocity).subtract(a.velocity); //is distance decreasing? Then invert both speeds var dDistance=new game.Vector().copy(distanceAB).multiply(velocityAB); if(dDistance.x<0){ //execute impuls var avx=a.velocity.x; var bvx=b.velocity.x; a.velocity.x=(avx*(a_mass-b_mass)+2*b_mass*bvx)/(a_mass+b_mass); b.velocity.x=(bvx*(b_mass-a_mass)+2*a_mass*avx)/(a_mass+b_mass); } if(dDistance.y<0){ //execute impuls //execute impuls var avy=a.velocity.y; var bvy=b.velocity.y; a.velocity.y=(avy*(a_mass-b_mass)+2*b_mass*bvy)/(a_mass+b_mass); b.velocity.y=(bvy*(b_mass-a_mass)+2*a_mass*avy)/(a_mass+b_mass); } return true; } return false; },Hope this is usefull,Stephan Quote Link to comment Share on other sites More sharing options...
enpu Posted September 21, 2014 Share Posted September 21, 2014 Hi Stephan!Would you like to show example on using your code? Quote Link to comment Share on other sites More sharing options...
Stephan Posted September 22, 2014 Author Share Posted September 22, 2014 Sure, here is an example of 4 bouncing boxes. game.module( 'game.main').body(function() {game.addAsset('box.png');Box = game.Class.extend({ init: function(x, y, speedx, speedy, mass) { //container for graphics this.container = new game.Container(); this.container.addTo(game.scene.stage); //link to scene to get the update() function of this object running. game.scene.addObject(this); //sprite this.sprite = new game.Sprite('box.png',0,0,{anchor: { x: 0.5, y: 0.5 }});this.sprite.addTo(this.container);//body this.body = new game.Body({ position: { x: x, y: y }, collisionGroup: 0, collideAgainst: 0, mass: mass, velocity: {x:speedx,y:speedy}, }); this.body.collide = this.collide.bind(this); this.body.addShape(new game.Rectangle(136, 176)); game.scene.world.addBody(this.body); }, collide: function() { console.log("Collision function called."); return true; }, update: function(){this.sprite.position.x = this.body.position.x; this.sprite.position.y = this.body.position.y; }, remove: function() { game.scene.removeObject(this); game.scene.world.removeBody(this.body); this.container.remove(); },});game.createScene('Main', { backgroundColor: 0x44cce2, init: function() { this.world = new game.World(0, 0); this.boxa=new Box(500,750, 0, -20, 50); this.boxb=new Box(350,200,70, 190, 10); this.boxc=new Box(500,1200,70, -250, 20); this.boxd=new Box(900,750,-100, 0, 100); },});the new function hitResponse() is included in the engine file physics.js. To use the new collision handling you don't have to do anything special. Just let some bodies collide and see what happens... I included the complete test project (with graphic) in the zip-file.collisiontest.zip Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.