mobileben

Members
  • Content Count

    64
  • Joined

  • Last visited

  • Days Won

    3

mobileben last won the day on September 11 2019

mobileben had the most liked content!

1 Follower

About mobileben

  • Rank
    Advanced Member

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. I started the process of adding audio to my game. I'm building using Typescript and Webpack. I'm using version 5.2.0. I installed pixi-sound via npm using npm install --save pixi-sound I've tried to follow the examples from here: https://github.com/bigtimebuddy/pixi-sound-webpack-example/blob/master/src/index.js I've noticed a couple of things. The resource loaded for the sound does not have the `sound` property. And if I try and play like in the demo code doing `sound.play('test')`, `sound` is undefined. The version of pixi-sound is 3.0.4.
  2. One thing you should do if you are using WebFont is ensure before you proceed, the load is already done. You can use the active callback for this. I use some fonts which are web based or are local to my game. I do something like the following. WebFont.load({ google: { families: ['Pacifico'] }, active: function() { app.webFontsLoaded = true; if (app.coreAssetsLoaded) { app.nextState = GameState.Game; } } }); There are two flags in use here since I have 2 async things loading: font and and "core assets". So both loading mechanisms check to see if the other one is done. If you don't have this need, you can remove it.
  3. 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.
  4. @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.
  5. Okay. I guess I'll just live with what I have now and cross fingers. There is some witchcraft going on, because I found that certain combos required me to clear the cache in BaseTexture versus Texture. These were all spritesheet cases. But right now I really don't want to crawl through that code to figure out why. Actually I think this could be cleaned up with some small tweaks. Essentially making Texture and BaseTexture (and perhaps Spritesheet) supporting getting or even destroying a texture by name versus destroying by object. To make this work right, you would probably want to have the texture hold a reference to the loader that loaded it so it could clean it up. The draw back here being it should actually be a weak reference object, and I do not know if Javascript supports that. There are ways around this, for example, requiring creating new loaders through a factory and then having a unique name assigned to them. You could then something later like: const texture = Texture.getTexture(key); Then later do either texture.destroy(); Or even Texture.destroyTexture(key); This could probably be made so that it would not break any existing implementation. Really the part the makes it harder is the dependency of Loader and resource, which really should probably not exist once a resource is loaded.
  6. 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
  7. @jonforum Cool, thanks that looks very helpful and always good to learn new tricks. I was using WebFonts at first, but from what I could tell, it didn't quite work with "local" assets. As I am also using Cordova for mobile, it seemed silly to do a fetch over the network for fonts I can bundle in.
  8. Thanks for the reply. This seems to work, however I have found that there is far more razing that needs to be done :(. Here is the snippet I am using. I tried removing items, but it seems all those items are required, which is a lot. // Purge old spritesheet const oldSheet = this._game.loader.resources[oldName].spritesheet; if (oldSheet) { oldSheet.destroy(); } // PIXI does not clean up the loader or caches const oldAtlasName = 'assets/' + oldName + Layout.LayoutManager.shared.decoratedSuffix + '.png'; const oldAtlasKey = oldName + '_image'; delete this._game.loader.resources[oldName]; delete this._game.loader.resources[oldAtlasKey]; PIXI.BaseTexture.removeFromCache(oldAtlasKey); PIXI.BaseTexture.removeFromCache(oldAtlasName); PIXI.Texture.removeFromCache(oldAtlasKey); PIXI.Texture.removeFromCache(oldAtlasName); I would say there is a bit of code smell here. This also makes me wonder whether or not the OpenGL textures are actually truly released, or if I have simply just removed cache entries and references. The reason I cite this is in the destroy code for Texture and BaseTexture, it should in theory clear the cache. I am assuming that PIXI.utils.TextureCache points to one of these caches. Does the above look about correct, and is it fair to assume the texture memory has actually been released? Or did I just simply cover the tracks of a texture that still exists? It would seem better served to decouple loaders with the actual resulting resources. Those resources could have their own managers (or whatever you want to call them). This way if there are multiple loaders, there is still consistency. A user does something like app.loader.resources[key].texture or app.loader.resources[key].spritesheet to get a Texture or Spritesheet, respectively. Thus they are already in effect showing intent. If they did something like TextureManager.getTexture(key) Or SpritesheetManager.getSpritesheet(key) The intent is still covered. Any explicit destroy is then easier to handle. Since Spritesheets know they are dependent on textures, it can use TextureManager to do proper cleanup, for example. Also one last question. How does one access the specific SpritesheetLoader for an Application? I assume there is one created by default. This is one weakness I think pixi has. Too much "cleverness" being applied in trying to insulate end users from certain things. But the reality with game dev is at some point of time, when you have a lot of assets, control over loaders and assets is actually quite important. Or perhaps that's just the nature of JS coding :D.
  9. Just wanted to add something else. I tried to explicitly purge the Loader resources via something like delete this._game.loader.resources[name]; I have found that after this is done, on the next load, the spritesheet property is undefined. I load this asset using this code if (!this._game.loader.resources[bname]) { const tname = Layout.LayoutManager.shared.decoratedAssetName('assets/' + bname + '.json'); this._game.loader.add(bname, tname); this._game.loader.load((loader: PIXI.Loader, resources: Partial<Record<string, PIXI.LoaderResource>>) => { postLoadHandler(); }); } postLoadHandler tries to access the spritesheet via this code (note that resource is split out as a const right now to make it easier to inspect in the debugger). const resource = this._game.loader.resources[bname]; let spritesheet = resource.spritesheet; spritesheet is undefined when I try to reload a spritesheet which was forcibly removed using delete as described above.
  10. I have an in-game asset that can be swapped out. I want to do the right thing by loading the new asset on-demand and then be a good citizen and release the older textures. Code looks something like the following: // Purge old spritesheet spritesheet = this._game.loader.resources[oldName].spritesheet; if (spritesheet) { spritesheet.destroy(); } I notice the side effect is the loader does not realize the sprite sheet has been destroyed. So once I try and re-use the original asset, it causes problems since I check for existence in the loader resources to see if I should reload the asset. Most APIs I've worked with or built have texture systems which are independent of the loader and also clean up properly. So any query for the texture, once destroyed is consistent. Has there been any thought of, instead of grabbing stuff from Loader's resources, having a TextureManager or SpritesheetManager (you actually could get away with just one which is what typically do)? Anyways, what is my best way to handle this? Just set the entry to null? Also, another question I had was related to PIXI.utils.TextureCache. I've found there are times I actually need to use PIXI.utils.TextureCache to find textures. I know it's not ideal and I think I read one shouldn't use it, but there are times I need to get a sub-texture but do not have the atlas name. Oh, I tested and it does appear the TextureCache is actually cleaned up.
  11. Okay, a quick update on this. I solved it, though it really doesn't answer why the strange behavior existed. It seems the trick is adding "sans-serif". As an example, the data I store to define the font looks like this. fontStyle: { family: [ "Roboto", "sans-serif" ], size: 20, weight: "bold", alignment: "center", color: 0xFFFFFF } @d13, I load the font this way <style type="text/css"> @font-face { font-family: "Roboto", sans-serif; src: url("assets/Roboto-Regular.ttf") format('truetype'); } </style>
  12. So the one quirky thing about this problem is that it the font fails at times after it's already been used. So, for example, if I am creating a PIXI.Text for the following strings: ONE, TWO, 3, FOUR. The PIXI.Text are instantiated in that order. ONE, TWO, and FOUR will be Roboto 3 will be the browser default, Times Roman From what I can tell the PIXI.TextStyle is the same. Since ONE and TWO are created before 3, I can assume that Roboto is loaded.
  13. I have a bit of a head scratcher. I am using web fonts, which I load prior to starting. I've defined these as @font-face in the style tags. I include these in my assets folder with all my assets. I can verify via the Developer tools the font is indeed loaded. I've noticed a strange behavior where the font is not always used. I am currently using Roboto as my standard font during prototyping. This is a sans-serif font. It seems that when I try and use a font that doesn't "exist", it defaults to a serif font which is probably Times Roman, as I'm testing on Chrome. So visibly, it is obvious when the text is Roboto versus Times Roman. I've noticed that for certain text, it seems to use the default font versus Roboto. I've dumped out the text style and it's the same for the text. The TextStyle settings I set are fontFamily (Roboto), fontSize, fontStyle (always normal), fill, and align. I do sometimes set fontWeight (either normal or bold). What is bizarre is that the exact same TextStyle will fail for some text. I've noticed in particular, numbers will fail. By fail I mean it ends up using the default font, Times Roman. Another odd thing I noticed is the fontFamily should be "Roboto". In Chrome, if I use "Robots-Regular" everything will work. However, when I try and use this on iOS (Cordova), then it uses the default Times Roman. Note usage of PIXI.Text doesn't matter. It's interleaved, but always the same items use the default. So I'm investigating it more for user error. But it seems very strange behavior that using Roboto-Regular versus Roboto will make it always work on Chrome (but then fail in iOS). I'm trying to find in the pixi code where it makes the decision point on the font to see if I can at least try and better deduce why this is happening.
  14. @RomainMazB got it, I perused the code. Some unsolicited suggestions (feel free to ignore) which may make your life easier, especially given the actual behavior is to make `onClick` part of the CardSprite class and avoid using `event` to derive the target to use. I would also recommend you wrap setting the card to be interactive and listening to events into another `CardSprite` method. You can control enabling and disabling a card from being interactive as well as listening to the mouse over. This will be helpful if you have several cards where some are interactable but others are not ... and the state can change depending on user actions.
  15. @ivan.popelyshev I created a issue here: https://github.com/pixijs/pixi.js/issues/6149