jloa Posted July 25, 2014 Share Posted July 25, 2014 So, i'm trying to make a top-view car game prototype using the P2 physics engine and i've faced some weird bug? with the RevoluteConstraints.The idea is simple: create a car body sprite, create two tires and attach them to the car body, then apply car physics simulation on those tires and let the body follow. And the problem is that when tires are joint to the car, they are positioned wrong (which is weird) + the car starts rotating and the reason for that i just can't understand as: tires are positioned symmetrically + both RevoluteConstraints have the same forces that should be applied to constrain the bodies. May be i'm getting something wrong?I wouldn't make this topic if there were more advanced examples covering the P2 physics or at least examples in the docs/source code (yep, i've already googled for a solution). Here's a picture And here's the code (also available here http://pastebin.com/qjqeF5bc):var ns = ns || {}; (function(ns){ // ref to the engine's keyboard cursors var cursors; // world info var worldInfo = { 'w': 10000, 'h': 5980, 'friction': 0.3, 'restitution': 0.5, 'stiffness': 1e7, 'relaxation': 5, 'frictionStiffness': 1e7, 'frictionRelaxation': 5, 'surfaceVelocity': 0.0, 'material': null }; // car reference var raceCar; /** * RaceCar class * @param x:int init x position of the car * @param y:int init y position of the car * @param worldInfo:object world info object */ var RaceCar = function(x, y, worldInfo) { // debug sprites this.debug = false; this.damping = 0.5; this.angularDamping = 0.5; // car material ref this.material = null; // contact material ref this.contactMaterial = null; // world info ref this.worldInfo = worldInfo; // car sprite ref this.car = null; // tire sprites ref this.tires = { 'left': null, 'right': null }; // sprite ids for car parts this.spriteIds = { 'car': 'car', 'tire': 'tire' }; // tire offets (relative to the car's center of mass offsets used for positioning the tires and for constrait points) // mind that the 'x' get sum/subs with the car.width/2, so that the x be dynamic // so the real x offset will be offsetRealX = car.width/2 + x this.tireOffsets = { 'left': { x:2, y:-16 }, 'right': { x:-2, y:-16 } }; // create sprites this.createSprites(x, y); // enable physics this.enablePhysics(); // create materials this.createMaterials(); }; /** * Creates car part sprites (should be call before other methods) * @param x:int init x position of the car * @param y:int init y position of the car */ RaceCar.prototype.createSprites = function(x, y) { // create sprites this.car = game.add.sprite(x, y, this.spriteIds['car'], 0); this.tires.left = game.add.sprite(x - this.car.width/2 + this.tireOffsets.left.x, y + this.tireOffsets.left.y, this.spriteIds['tire']); this.tires.right = game.add.sprite(x + this.car.width/2 + this.tireOffsets.right.x, y + this.tireOffsets.right.y, this.spriteIds['tire']); this.car.bringToTop(); }; /** * Enables physics for the car (should be called after @see this.createSprites()) */ RaceCar.prototype.enablePhysics = function() { // enable physics game.physics.p2.enable(this.car, this.debug); game.physics.p2.enable(this.tires.left, this.debug); game.physics.p2.enable(this.tires.right, this.debug); // revolutes // // @TODO now this is the bug place // when we create revolutes there are 2 problems need to be solved: // - tires are wrong positioned (even thought the force is 200 000) // - car starts rotating despite that the tires are positioned symmetrically relative to the car's center of mass which is 50% 50% by default // game.physics.p2.createRevoluteConstraint(this.tires.left, [0,0], this.car, [-this.car.width/2 + this.tireOffsets.left.x, this.tireOffsets.left.y], 20000); game.physics.p2.createRevoluteConstraint(this.tires.right, [0,0], this.car, [this.car.width/2 + this.tireOffsets.right.x, this.tireOffsets.right.y], 20000); // set damping this.tires.left.body.damping = this.damping; this.tires.right.body.damping = this.damping; this.car.body.damping = this.damping; // set angularDamping; this.tires.left.body.angularDamping = this.angularDamping; this.tires.right.body.angularDamping = this.angularDamping; this.car.body.angularDamping = this.angularDamping; // allow sleep this.tires.left.body.allowSleep = true; this.tires.right.body.allowSleep = true; this.car.body.allowSleep = true; // collide with world this.tires.left.body.collideWorldBounds = true; this.tires.right.body.collideWorldBounds = true; this.car.body.collideWorldBounds = true; // revolutes seem work only if the tires' mass is significantly less than the car's this.tires.left.body.mass = 1; // .01 seems to work, kind of, still buggy coz tires get rotated like +1 degree why?! this.tires.right.body.mass = 1; // .01 seems to work, kind of, still buggy coz tires get rotated like +1 degree why?! this.car.body.mass = 1; }; /** * Creates the car material + the contact material with the world (should be called after @see this.enablePhysics()) */ RaceCar.prototype.createMaterials = function() { this.material = game.physics.p2.createMaterial('carMaterial'); // assign material this.car.body.setMaterial(this.material); this.tires.left.body.setMaterial(this.material); this.tires.right.body.setMaterial(this.material); // create contactMaterial this.contactMaterial = game.physics.p2.createContactMaterial(this.material, this.worldInfo['material']); this.contactMaterial.friction = this.worldInfo['friction']; // Friction to use in the contact of these two materials. this.contactMaterial.restitution = this.worldInfo['restitution']; // Restitution (i.e. how bouncy it is!) to use in the contact of these two materials. this.contactMaterial.stiffness = this.worldInfo['stiffness']; // упругость - Stiffness of the resulting ContactEquation that this ContactMaterial generate. this.contactMaterial.relaxation = this.worldInfo['relaxation']; // Relaxation of the resulting ContactEquation that this ContactMaterial generate. this.contactMaterial.frictionStiffness = this.worldInfo['frictionStiffness']; // Stiffness of the resulting FrictionEquation that this ContactMaterial generate. this.contactMaterial.frictionRelaxation = this.worldInfo['frictionRelaxation']; // Relaxation of the resulting FrictionEquation that this ContactMaterial generate. this.contactMaterial.surfaceVelocity = this.worldInfo['surfaceVelocity']; // Will add surface velocity to this material. If bodyA rests on top if bodyB, and the surface velocity is positive, bodyA will slide to the right. }; var preload = function() { game.load.image('car', 'assets/i/car.png'); game.load.image('tire', 'assets/i/tire.png'); game.load.image('map', 'assets/i/map.jpg'); }; var create = function() { // resize our game world to be game.world.setBounds(0, 0, worldInfo.w, worldInfo.h); game.stage.backgroundColor = '#ffffff'; game.stage.disableVisibilityChange = true; // physics game.physics.startSystem(Phaser.Physics.P2JS); game.physics.p2.setBounds(0, 0, worldInfo.w, worldInfo.h, true, true, true, true, false); game.physics.p2.friction = worldInfo['friction']; game.physics.p2.restitution = worldInfo['restitution']; game.physics.p2.applyDamping = true; // world material worldInfo['material'] = game.physics.p2.createMaterial('worldMaterial'); game.physics.p2.setWorldMaterial(worldInfo['material'], true, true, true, true); // create a race car raceCar = new RaceCar(200, 200, worldInfo); // camera follow car game.camera.follow(raceCar.car, Phaser.Camera.FOLLOW_LOCKON); // input controls cursors = game.input.keyboard.createCursorKeys(); }; var update = function() { // do nothing for now }; var render = function() { // do nothing for now }; // start the game var game = new Phaser.Game(800, 600, Phaser.AUTO, 'game', { preload: preload, create: create, update: update, render: render });})(ns); Link to comment Share on other sites More sharing options...
jloa Posted July 25, 2014 Author Share Posted July 25, 2014 Fixed!Ok, i've figured it out now.In case anyone else stumbles upon this problem: "what to do when revolute constaraint overlap and apply force to each other and what them to ignore each other".The answer took me a while, because there's nothing said in the docs http://docs.phaser.io/Phaser.Physics.P2.RevoluteConstraint.htmlThe things is that the docs are totally incomplete. The p2 RevoluteContraint class has lots of other methods/props http://schteppe.github.io/p2.js/docs/classes/RevoluteConstraint.htmlAnd the property that solves the issue iscollideConnected:Boolean// Set to true if you want the connected bodies to collide.Default: trueSo when you create an instance of revolute costraint (in phaser game.physics.p2.createRevoluteConstraint() method will return the instance reference), don't forget to set the property to false.And finally, if you are working with p2 physics better use the p2 docs @ http://schteppe.github.io/p2.js/docs/ ps: how do i close the thread? Link to comment Share on other sites More sharing options...
lewster32 Posted July 25, 2014 Share Posted July 25, 2014 No need to close the thread, just mark your own answer as solved Link to comment Share on other sites More sharing options...
jloa Posted July 25, 2014 Author Share Posted July 25, 2014 No need to close the thread, just mark your own answer as solved Ye, thanks. I'm first time here, didn't notice the button lewster32 1 Link to comment Share on other sites More sharing options...
valueerror Posted September 12, 2014 Share Posted September 12, 2014 sorry if this is a dump question but.. aren't you pulling the tires 4px inside the car with you constraints? that would mean they constantly would try to get closer but they collide so they start acting weird.. -this.car.width/2 + this.tireOffsets.left.x -15 + 2 = -13 shouldn't this be: -(15+2) = -17 ?? then you wouldn't need to deactivate the collision between those two.. and here comes another question: this is a very interesting find.. does this disable the collision only between those two objects connected to each other but still allows collisions with other objects??and how would the code look like if i want to use those extra options in phaser.. i would also like to use lowerlimit and upperlimit to keep the constraint in place.. thx Link to comment Share on other sites More sharing options...
Ousaf Posted December 15, 2015 Share Posted December 15, 2015 You save my night Link to comment Share on other sites More sharing options...
Recommended Posts