Jump to content

dmko

Members
  • Content Count

    101
  • Joined

  • Last visited

Posts posted by dmko

  1. 20 minutes ago, caymanbruce said:

    I am familiar with a single canvas on a single page. But I never know how the combination of framework work.

    In this sense nothing changes. You're not adding/removing elements from the page, you're wrapping all the imperative canvas calls up in a declarative framework.

    The same way React-DOM deals with all the element.innerHTML stuff, your react renderer (or components) deal with all the canvas.draw (or rather, PIXI.*) type calls - but on the app level you don't touch any of that, you just write the changes declaratively.
     

  2. @caymanbruce Thanks for bringing this thread up - I should note that my experiments here were superseded at this other thread:

     

    I don't know anything about Angular. With React, essentially, there's two approaches :)

    1. Using React as-is with the built-in React-Dom renderer. With this approach, there's nothing really special going on, you just handle all your imperative PIXI updates in render() or one of the other lifecycle methods. To make it worthwhile, you'd probably want to create some boilerplate components that do this for you and expect certain props to exist. E.g. a Sprite component that expects `texture`, `x`, `y`, etc.

    2. Replacing the React-Dom renderer with a custom renderer. This is what's posted at the other thread - you can get it at https://github.com/dakom/react-pixi-renderer

    However, I'm not sure how far I'll pursue that... as I'm playing with it more, it turns out writing a React-renderer is super easy. It may make more sense to have a custom per-project renderer (using that repo as a starting point) than abstracting everything into generic stuff.

    For example, it may be more useful to have like a Character instance/element/component built-in to the renderer rather than abstracting over a Sprite instance/element/component. That difference won't make much sense unless you plan to go that route, but it's a reason why I'm probably not going to pursue the react-pixi-renderer too much beyond making sure it works as a boilerplate/starter package.

  3. Also just to add if you call app.render() directly, you should setup the PIXI.Application with `autoStart: false`

    I'm not sure if it makes a difference practically (e.g. double-render somehow), but it can only help ;)

  4. I created a very early, very alpha React renderer for PIXI. There's some other projects out there but I wanted to start from scratch.

    You can get it at https://github.com/dakom/react-pixi-renderer

    However, be warned, performance kindof sucks if you use it for lots of nodes. See this test/demo I wrote that tries to figure out where the bottleneck is: https://dakom.github.io/react-renderer-test/

    Turns out that the bottleneck is basically React itself and the size of the tree. The React-pixi-renderer could be really useful for declaratively describing a few of a small number of items - I get a solid framerate for like <4000 bunnies on desktop.

    If performance is an issue for lots of items, you can squeeze more juice out of it by constructing the architecture so that the edge nodes render null rather than proper elements, though that means ditching the inherent pipeline and managing your own objects. That technique can work with any renderer and using ReactDOM vs. this custom renderer, so there's no real point in using this renderer if you go that route.

    Have fun!

  5. 8 minutes ago, mattstyles said:

    This isn't really what you're after though as it takes React totally out of the loop for pixi

    Yeah, for this context I'm focused really on using it with react (or as I'm now looking into, maybe Inferno)

    Cool stuff though :) and reminds me that I'm missing a baseline comparison hehe... will write that now :D

    9 minutes ago, mattstyles said:

    What might be really clever would be to create a transform that converts your scene-describing JSX into regular ole pixi calls

    Right on, that's what I meant by like "built-in ability to "removeChild" when the JSX changes" but you nailed the overall idea in that sentence.

    It would be super awesome if that were possible imho, I don't think it would be rubbish unless it introduced a bunch of restrictions like specific props you have to pass in etc (kindof like in my implementation, where you have to pass a "parent" prop)

  6. Yeah - everything you're saying is spot-on @mattstyles  

    The performance killer here is definitely React as far as I can tell.

    This attempt to use React as-is and simply render `null` does rely on lifecycle methods so stopping propagation via shouldComponentUpdate isn't going to work completely. I did change everything except `withPixi` to be PureComponents just now though - negligible gains. 

    I'm not aware of how to bypass all that evaluation stuff... I looked at react-pixi and couldn't make heads or tails of what's going on there and I'm not immediately convinced without seeing a bunnymark. Maybe I'll look more into it from a more fundamental place of like how it's done for react-native.

    Though, on one foot, I haven't really come across relevant benchmarks yet. The "high load" things seem to be cases of like dealing with a few hundred elements and being blown away... ;) I want at least 10,000 bunnies at 60fps without a hiccup - not sure if react is simply the wrong tool for the job (i.e. can react-native do that? and I mean where each bunny is a distinct class - no cheating by batching draws)

    From another angle - the simplicity (after all the boilerplate hackery) of being able to describe the scene in simple declarative JSX is pretty compelling.

    I'm not sure how to really approach this subject since I don't know the internals of PIXI - but do you think that's something that could be done as like native sugar for the PIXI scene graph itself?

    In other words something like this with built-in ability to "removeChild" when the JSX changes? I get that it's a big sweeping topic and a one liner like "yeah sure we can do that" may not be simple... feel free to discuss in larger depth :)

    <Container>
       <Sprite x={10} y={10} texture={someTexture} />
    </Container>

     

  7. Just pushed an update - might take a little bit for Travis/github, but testing locally - it didn't seem to fix it, I think it's probably something with React itself :\

    Btw I suck with profiling, when you have a minute can you take a couple screenshots to show me where you see that 19% GC stat?

    Shutting down for the night, thanks for taking a look

  8. Ah - so I'm looking at more for describing the PIXI scene itself, not for additional UI. I'll try to mock up the bunny-mark test and put it on github for all to fork and tinker with. I actually may need to use this approach for an upcoming project so I'm very interested in any gotchas

  9. I haven't done a ton of React stuff but I am tinkering a lot more lately :)

    Here's a little JSFiddle to benchmark - it doesn't include PIXI stuff but just to see how long it takes to get from a render on a parent to an update on a child, and I think this is roughly the way I'd structure a React+PIXI app (the pixi updates happen in the child's componentWillReceiveProps() - and the render() from child would just always return null)

    https://jsfiddle.net/dakom/e65tbxsy/

    I'm getting less than .1ms between the parent's render() and the child's componentWillReceiveProps(). Assuming I benchmarked it right - that's the performance hit you get from using React vs. just straight JS., and it's way more than acceptable imho. However, even if I did benchmark it right, there's a few questions:

    1. performance.now() is super fine-grained... a normal js pipeline isn't going to be 0 either, so it's a bigger win than .1ms

    2. really important question - is this per component or across a render cycle? Need to test out like nesting 10 or 100 components deep. If it stays like this, then React is 100% fine imho. If it adds .1ms per layer, I dunno, gotta really think about that.

    3. Realistically, a complex app is...well, complex. Performance bottlenecks and developer headache can happen in lots of ways. If using React is performant enough, even if it's not the absolute best way to squeeze every ms out, it may be a worthwhile save in other areas.

    For me it really depends on #2 which hopefully I'll test in the near future just to be sure. If that turns out to be fine then I think using React with PIXI could be a really nice architecture.

  10. It's a debatable topic, that's for sure.

    On the one hand - you're of course right, GC sucks for games and creating a bunch of objects is a no-no.

    On the other hand - code that's easy to reason about is a huge win for lots of reasons.

    I'm working on something which I'll hopefully share in the next week or two, it's really just pong but using some functional programming and object-copying stuff. The neat thing is I'm pushing all of the game logic off to a web-worker. Theoretically, browsers are allowed to compartmentalize GC per thread, and those that do (if they do) would get the best of both worlds from that (imho).

  11. I guess you can get the pixel data via something like http://pixijs.download/dev/docs/PIXI.extract.WebGLExtract.html#pixels

    Though once you have that, for a space shooter you're in real trouble because you really need to test against the in-between frames too

    For example let's say frame 1 your scene is like this

    ----- BULLET ------- TARGET ------

    And then in frame 2 it's like:

    ----- TARGET ------ BULLET -----

    So we know the bullet passed _through_ the target between renders - and when you're just calculating against simple shapes like via `distance` it's no big deal to just keep the last position in memory and compare (e.g. by drawing a "line" between previous and current position and seeing if it intersects with the target)

    But for comparing against the pixels in both frames you need to keep all that pixel data in memory, along with continually grabbing it. At least if you want it to truly be pixel-perfect for _both_ objects.

    No doubt there are more advanced solutions to deal with this, but I don't know of any offhand...

  12. Yeah that's basically the idea, trying to get more into functional stuff and keep things pure... in this case we're mutating the "this.children" anyway so there's no point really, but still - trying to force myself into new habits :D

    Not sure why the action isn't working for me yet, maybe I'll add a fiddle here tomm...

  13. I'm still having some weird stuff happening where the same code run over two different objects is having the opposite effect.

    In other words, for the more recent object (starting at top layer) things work correctly. For the first object (starting at bottom layer) the action is refersed ("send to back == send to front and vice-versa")

    It's almost like the ordering is affected by setting children(), but it's somehow affected by the original placement too? Not sure... will revisit on Monday probably. Have a good weekend!

  14. I'm trying to implement a simple "move to back" / "move to front" without relying on the heavy lifting of something like https://github.com/pixijs/pixi-display

    Here's my ordering code, but it doesn't seem to always work... though it does work some of the time... I think it looks like for some of the items it works but in reverse? What am I missing? :)

    //moves an item in an array to either the front or back
    export const PopTo = (isFront:boolean) => items => item => {
        const copy = items.concat();
        const ret = copy.splice(copy.indexOf(item), 1);
    
        return (isFront) ? ret.concat(copy) : copy.concat(ret);
    }
    export const PopToFront = PopTo(true);
    export const PopToBack = PopTo(false);
    
    
    //move item to back
    this.children = PopToBack (this.children) (target)
    //move item to front
    this.children = PopToFront (this.children) (target)

     

×
×
  • Create New...