mcfly Posted April 7, 2019 Share Posted April 7, 2019 Hi all, I'm new to Pixi.js, so excuse me, if the answer to my question is obvious. I'm building a 2d platformer where I have a PIXI.Container which contains a few sprites (let say player's arm, body, head etc.). Based on the user input I'm moving the whole container (not each sprite individually). I also have container which contains all platforms of the level (they are all of type PIXI.Spirte). I want to detect when the player's container intersects with any of the platforms and stop the container from moving forward (the usual stuff). Currently I'm using the Bump.js library (https://github.com/kittykatattack/bump). But I'm encountering few problems. First of all Bump.js doesn't work for 'container vs array with sprites' type of collision, so I've tried to detect an intersection between each player's sprite against the array with platforms. Basically I'm using the following: player.move(); // move the player's container to any direction BUMP.hit(playersArm, platformsArray, true, false, true); BUMP.hit(playersBody, platformsArray, true, false, true); BUMP.hit(playersHead, platformsArray, true, false, true); This is testing for intersection between each player's sprite and stops it from moving, if there is a collision. All this is working fine and if there is an intersection the intersecting player's sprite position will be set to a value that is not intersecting with the platforms. However all the other sprites will continue moving, as they are not yet intersecting with the platforms. Hope I expressed myself clear. Have you ever had such problem and how did you solve it? I can only think of building a custom collision detection logic which works with 'container vs array with sprites', so I don't have to care for each player's sprite individually, but work with the container. Do you know of any library that already handled such cases? Or maybe I've been wrong from the start by taking such approach (having player's container with several sprites in it)? Thank you in advance. ivan.popelyshev 1 Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted April 7, 2019 Share Posted April 7, 2019 In general: Its not obvious , because you are basically making simple arcade phys engine, and PixiJS has only a few functions that you can rely on for it: "getBounds()", "containsPoint()", "contains()" (that one is about Point but for shapes), and when you look inside element you have to dig out its geometry, its difficult to produce readable code because of that. We are only a renderer lib - we dont know what people want from their physics. We dont have enough expertise to provide physics for newbies, we are all about graphics. Some people integrate existing libs like "p2.js" or "matter.js" with pixi and the result is awesome - when you do that means you know pixi on a good level. Sadly, we still dont have docs about it because people who did that before mostly kept it to themselves. I'm working on a article that explains that but i cant share it yet. All we have are threads in this subforum that are difficult to search but they contain simple physics, and I cant say that code is readable. I've spent many hours helping people to fix solutions that they wanted for their games. Your case: Lets see https://github.com/kittykatattack/bump/blob/master/src/bump.js#L1350 First that I see is it spawns many functions , and you call it several times in a frame - it can be a performance problem in case of 100 and more sprites. I suggest to copy that lib locally and change it the way you need. Quote Link to comment Share on other sites More sharing options...
bubamara Posted April 7, 2019 Share Posted April 7, 2019 simplify the problem - create hidden collision circle for player's container and hit test it against platforms; players will not be able spot difference anyway Quote Link to comment Share on other sites More sharing options...
mcfly Posted April 7, 2019 Author Share Posted April 7, 2019 @ivan.popelyshev, I understand that PIXI is used for rendering only. I don't expect it to have built-in physics methods. I was trying to understand if I'm doing something wrong, as I'm sure a lot of people has encountered the same problem. Thank you for your detailed explanation. I'll definitely wait for the article you've mentioned. @bubamara, thank you too for your suggestion. I'll try to work something out of both your suggestions. ivan.popelyshev 1 Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted April 7, 2019 Share Posted April 7, 2019 15 minutes ago, mcfly said: I was trying to understand if I'm doing something wrong, as I'm sure a lot of people has encountered the same problem. I'll try to work something out of both your suggestions. Yep, you've got it right. I can also recommend to watch out for "width" in containers with children, its a tricky calculated value. "getBounds().width" is fine, "sprite.width" is fine when sprite has no children. And at some point if you have many objects you'll see major garbage collecting when you profile app, and you'll have to remove extra object creations. Also watch out that "getBounds()" and "containsPoint()" are the only things that returns global (screen) coords, everything else is local stuff, you have to be aware in which coord system they work. Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted April 7, 2019 Share Posted April 7, 2019 You also have perfect timing. I'm gonna add physics in the list of my specialisations in pixijs team, so I'm ready to help people more on this subject. ITs like "ok, I solved most of Filter-related problems that people have, whats next" If you do something and it doesnt (or does) work please share, I'll help to find bugs. Quote Link to comment Share on other sites More sharing options...
cjke Posted April 22, 2019 Share Posted April 22, 2019 From someone who is looking at transitioning from Phaser to Pixi and was looking at this exact question, thanks @ivan.popelyshev for answering this (and many other) Pixi questions! Quote Link to comment Share on other sites More sharing options...
macshemp Posted November 5, 2019 Share Posted November 5, 2019 (edited) @ivan.popelyshev Do you have a recommendation for a physics engine to use with Pixi js? I am currently looking at matter.js and planck.js Cheers Edited November 5, 2019 by macshemp Quote Link to comment Share on other sites More sharing options...
d13 Posted November 7, 2019 Share Posted November 7, 2019 I use MatterJS with Pixi, and it's great. PlanckJS is a good choice too. However... physics libraries are a potential rabbit hole. The demos you see on the library sites work flawless, but as soon as you realise you need to do something for which there isn't an example or there's no documentation, you can find yourself in a pitch-battle with the engine. The devil is in the details! So, my advice is, go as far as you can with 2D arcade collision, and only move to physics library if absolutely have to do a detailed physics simulation (like a pinball machine.) Quote Link to comment Share on other sites More sharing options...
macshemp Posted November 7, 2019 Share Posted November 7, 2019 @d13 thanks for taking the time to reply. Decided to go with MatterJS as it seemed more friendly. Quote Link to comment Share on other sites More sharing options...
d13 Posted November 7, 2019 Share Posted November 7, 2019 Just for reference, here's my current MatterJS/Pixi render loop. The most import thing is that every of the matter body needs a reference to its matching Pixi sprite. Something like this: body.sprite =yourPixiSprite; And the Pixi sprites need their anchors set to 0.5 body.sprite.anchor.set(0.5); Then you can run this in your game loop to sync the body and sprite positions: let bodies = MATTER.Composite.allBodies(engine.world); for (let i = 0; i < bodies.length; i++) { let body = bodies; //Non-compound bodies if (body.sprite) { body.sprite.x = body.position.x; body.sprite.y = body.position.y; body.sprite.rotation = body.angle; } else { //Compound bodies (In MatterJS compound bodies can only be one level deep, so no need for recursion) if (body.parts.length > 1) { for (let j = 0; j < body.parts.length; j++) { let childBody = body.parts[j]; if (childBody.sprite) { childBody.sprite.x = childBody.position.x; childBody.sprite.y = childBody.position.y; childBody.sprite.rotation = childBody.parent.angle ; //Or, I'm not sure if this last line might be more correct - I'm still testing: //childBody.sprite.rotation = childBody.parent.angle + childBody.angle; } } } } Quote Link to comment Share on other sites More sharing options...
macshemp Posted November 7, 2019 Share Posted November 7, 2019 Thanks for that, I have something similar, not tidied it up yet so this is really useful Once I got the Matter canvas to sit on top of the pixi stuff it got a lot easier to figure out. I can now draw shapes in PIXI using PIXI.graphics and have them controlled by Matter. In this quick test I have a PIXI sprite with a PIXI graphic drawn on it. All the red shapes in the image are PIXI graphics which become Matter bodies (the white lines are the Matter canvas overlay) Lots of potential Quote Link to comment Share on other sites More sharing options...
mobileben Posted November 9, 2019 Share Posted November 9, 2019 On 11/7/2019 at 2:17 AM, macshemp said: @d13 thanks for taking the time to reply. Decided to go with MatterJS as it seemed more friendly. I would say do your due diligence with MatterJS. I originally was going to use it but then abandoned it due to inconsistent behavior and you cannot (or rather I could not figure out how to) project trajectories with accuracy. I actually figured out how to mostly do it, but there was still a constant value multiplier off. That was unsettling to me. For reference https://github.com/liabru/matter-js/issues/768 https://github.com/liabru/matter-js/issues/767 Quote Link to comment Share on other sites More sharing options...
macshemp Posted November 10, 2019 Share Posted November 10, 2019 @mobileben - I did see your issues on the matter-js when i started looking, which is why I also looked at PlanckJS. Did you find box2d to be more consistent overall? I guess the pixel coordinates in MatterJS were more appealing on first glance than having to convert everything to the box2d world space. What port of box2d do you use as there seemed to be quite a few, was it PlanckJS? Thanks Quote Link to comment Share on other sites More sharing options...
mobileben Posted November 11, 2019 Share Posted November 11, 2019 @macshemp, I'm using this version, as I'm using Typescript. Although it is possible it is now a dead project (see my issues). https://github.com/flyover/box2d.ts My issues are minor and more about some incompleteness in the interface. It is possible once I finish up this prototype that I make my own fork and mod it some. I have, however, found it to be stable and what I would deem as accurate (enough). Those tests I ran in my matterjs were tested against this version of box. I also compared "theoretical" trajectory with actual, and unlike matterjs, the box2d ones were "accurate". While I initially liked matter ... I now really like Box2D. It has some minor quirks, but it works well. I also did what you did ... didn't want to bother with the conversion of pixel to metric and vice versa. However, it is easy to work with. I use game objects with a gfx and physics property, where gfx is the PIXI graphics object (well my wrapped version of it) and physics is a wrapper to Box2D. I have a PhysicsManager which also has some methods for the conversion. Snippet look like this: get ppm(): number { return this._ppm; } set ppm(val: number) { this._ppm = val; this._ppmInv = 1.0 / val; } get ppmInv(): number { return this._ppmInv; } scalarToPhysicsWorld(s: number): number { return s * this._ppmInv; } pointToPhysicsWorld(pos: Point): Point { return { x: pos.x * this._ppmInv, y: pos.y * this._ppmInv }; } scalarFromPhysicsWorld(s: number): number { return s * this._ppm; } pointFromPhysicsWorld(pos: Point): Point { return { x: pos.x * this._ppm, y: pos.y * this._ppm }; } And in my GameObject update code I do the following if (this._physics && this._gfx) { // If we have both physics and gfx, update the gfx based on our physics const pos = this._physics.position; this._gfx.setPosition(pos); // Use rotation because this is in radians this._gfx.setRotation(-this._physics.rotation); } You may need to drop that negative rotation I'm doing. Oh, yeah, on the PhysicsObject, the position code looks like get position(): Point { const pos = this.body.GetPosition(); return { x: PhysicsManager.shared.scalarFromPhysicsWorld(pos.x), y: PhysicsManager.shared.scalarFromPhysicsWorld(pos.y) }; } So essentially I treat everything that doesn't have a special naming to it as "game space". So, box2D lives in "Physics" space. And actually, PIXI lives in Screen space. My game space is cartesian coords with center in the middle of the screen. Forgive any nastiness with the code, I'm a C++ guy that's on the learning curve of Typescript. Quote Link to comment Share on other sites More sharing options...
macshemp Posted November 11, 2019 Share Posted November 11, 2019 @mobileben Thanks for the detailed post, appreciate it. A lot of really useful stuff here for me to digest. I'm still at the "R&D" stage so will definitely take some time to delve deeper into box2d. Cheers Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted November 11, 2019 Share Posted November 11, 2019 (edited) Here's the demo for Pixi & P2 & PhysicsEditor: https://codesandbox.io/s/app-architecture-3-j0di5 Part of update determines whether we need to copy pixi filelds to physics or vice-versa. If pixi position was changed -> copy from pixi. if (this._memLocalId !== display.transform._localID) { this.previousPosition[0] = this.position[0] = -display.position.x * PIXEL_TO_METER; this.previousPosition[1] = this.position[1] = -display.position.y * PIXEL_TO_METER; this.previousAngle = this.angle = display.rotation; this.wakeUp(); } else { display.position.set( -this.interpolatedPosition[0] * METER_TO_PIXEL, -this.interpolatedPosition[1] * METER_TO_PIXEL ); display.rotation = this.interpolatedAngle; } this._memLocalId = display.transform._localID; I used p2 compiled from sources, its different from NPM Demo also has a Mesh&Shaders part. Its not batched i'll make batched version later. From now on i will recommend this as a demo with physics and architecture Edited November 11, 2019 by ivan.popelyshev jonforum 1 Quote Link to comment Share on other sites More sharing options...
tywang2006 Posted November 11, 2019 Share Posted November 11, 2019 PhysicsJS: https://github.com/wellcaffeinated/PhysicsJS/ p2.js: https://github.com/schteppe/p2.js verlet-js: https://github.com/subprotocol/verlet-js JPE: https://github.com/colorhook/JPE Newton: https://github.com/hunterloftis/newton Matter.js: https://github.com/liabru/matter-js that depends what or how you want to do. I used to make my own 3D physics engine for a complicated game before. or you can pick up one and modify to match your demand. ivan.popelyshev 1 Quote Link to comment Share on other sites More sharing options...
macshemp Posted November 11, 2019 Share Posted November 11, 2019 @ivan.popelyshev interested you chose P2, I saw this from http://fatidol.com/phy-benchmark/ finscn who I recognised from the PIXI forums. In this test P2 runs around 20FPS slower than box2d jonforum 1 Quote Link to comment Share on other sites More sharing options...
mobileben Posted November 11, 2019 Share Posted November 11, 2019 There are numerous physics libraries out there. If you're sill undecided, I would recommend making some benchmark test to compare the functionality you need (which is what I did). I'd also look at how active that project is. Some of those listed above haven't been touched in years, so you'd def be on your own. One advantage of box2d is it is well known and used a lot. So while the version I am using may perhaps be dead, it's easy to find out some explanation on how to do what I need to do ... though generally the answer will be C/C++ based, I found it translates over. Just be prepared to wade through the source code for confirmation as well as how that particular implementation of Box2D named stuff :D. The variant I am using is actually pretty close to the C names. Oh, for the version I'm running, I didn't install via npm. I'm actually directly including it with my source files. It makes it easier for me to debug. Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted November 11, 2019 Share Posted November 11, 2019 (edited) 6 hours ago, macshemp said: @ivan.popelyshev interested you chose P2, I saw this from http://fatidol.com/phy-benchmark/ finscn who I recognised from the PIXI forums. In this test P2 runs around 20FPS slower than box2d i honestly didnt care about performance yet, im new to that physics stuff. I needed something, I made it Which box2d lib do you recommend? Edited November 11, 2019 by ivan.popelyshev Quote Link to comment Share on other sites More sharing options...
jonforum Posted November 12, 2019 Share Posted November 12, 2019 (edited) need a live benchmark, the bench is from 2015 ? am sure a lot of thing change in those API. Also versions,codes sources will help. it easy to use a code and algo thats is favorable to a particular engine. Edited November 12, 2019 by jonforum ivan.popelyshev 1 Quote Link to comment Share on other sites More sharing options...
jonforum Posted November 12, 2019 Share Posted November 12, 2019 (edited) 12 hours ago, tywang2006 said: Newton: https://github.com/hunterloftis/newton that depends what or how you want to do. I used to make my own 3D physics engine for a complicated game before. or you can pick up one and modify to match your demand. ho!! if they are the same guys who developed the plugins Newton on AfterEffect or inspired! I'll bet on them, they've created a really good, effective and intuitive physic engine on AE.https://www.motionboutique.com/newton2/ i made a fully tutorial on this physics engine plugins for french interested in dev in physique coding (eascript) inside AE. Released for free on youtube include the 3d physic scripting. https://youtu.be/MoykU_YUZ2Y Edited November 12, 2019 by jonforum ivan.popelyshev 1 Quote Link to comment Share on other sites More sharing options...
jonforum Posted November 12, 2019 Share Posted November 12, 2019 (edited) 17 hours ago, macshemp said: @ivan.popelyshev interested you chose P2, I saw this from http://fatidol.com/phy-benchmark/ finscn who I recognised from the PIXI forums. In this test P2 runs around 20FPS slower than box2d i like your link here because you share data, but the issue here is your link is not a bench! it juste string html data ! I get same result from all my web browsers , firefox,chrome,vivaldi,edge... After look in deep the link compute nothing, and cant be a good reel reference. need a reel bench here, this cant be a bench values to take. Those values cant be take for reference, there only html strings values. i dont know if box2d is >70% more speedUp, but please guys don't take this ref. Edited November 12, 2019 by jonforum Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted November 12, 2019 Share Posted November 12, 2019 I remember back then i used box2d or box2d port with fluids, but of course now im doing it , but it was in 2014. I didnt even measure it back then, but yes, box2d was very performant jonforum 1 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.