Jump to content

Drawing the UI with the DOM


pixelburp
 Share

Recommended Posts

So in leaning towards drawing the UI using the DOM, CSS and a JS framework of choice, but am a little unsure what's the best tool for the job here. Seems counter intuitive to create a user interface in phaser when this is the web's strongpoint.

I wrote a proof of concept with React-Redux but having to dispatch an action for every event is a little bloated; I want my UI to display live unit stats (as well as buffs, effects, queued actions etc), but even though the redux reducer contains objcect references to the game actors, the html components never update (obviously, as this isn't how react works as such)

Anyone got any better frameworks in mind, better suited to live, per-frame updates? Angular 1 I've used a lot, but it's got poor performance IMO for fast updates against groups of complx objects - never used angular 2 so unsure if this is a better option and they made things faster.

Ditto vueJS; seems to have growing popularity but not sure if it's geared towards fast, live updates or more static, 'react' esque.

Thoughts?

Link to comment
Share on other sites

I'd go with Phaser. You will avoid the struggle of events (like you said) and you'll be able to do much more complex UI, with animations or things like that. Sure, it might add some work, but in the end you'll have it perfectly integrated within your game. And you won't struggle with cross-browser issues (I mean, you shouldn't).

 

Link to comment
Share on other sites

5 hours ago, Skeptron said:

I'd go with Phaser. You will avoid the struggle of events (like you said) and you'll be able to do much more complex UI, with animations or things like that. Sure, it might add some work, but in the end you'll have it perfectly integrated within your game. And you won't struggle with cross-browser issues (I mean, you shouldn't).

 

What's appealing to me about going the html/css route is that it's naturally capable of dealing with varying screen sizes and browsers through trivial css selectors, and these days crossbrowser issues are fairly minor (compared with the bad old days of ie6 etc - yes, I'm that old!). Animation is still possible with css, and feels like less work phaser is asked to do. 

The events thing is a pain, but angular1 would in theory be able to watch any game object data I want, without the need for extra events or methods - the only problem is angular 1s well documented performance issues. I suspect once I threw a lot of data at it at 60fps, angular 1 would chug & die.

So something LIKE angular 1, that can just watch any object you point it at, but with better performance would be ideal. 

TBH I'd also prefer this way, because my background is frontend development, so building html,css,is UIs is familiar.

Link to comment
Share on other sites

9 hours ago, pixelburp said:

The events thing is a pain, but angular1 would in theory be able to watch any game object data I want, without the need for extra events or methods - the only problem is angular 1s well documented performance issues.

Ha ha, I think you do realise that these two things are very tightly related!

The reason other frameworks have deviated away from two-way binding is because perf gets tricky.

What I think you really want is just an abstraction so you don't have to think about it when your unit stats update themselves.

I like to use HTML for UI layer/s, for reasons you've stated, but, if you data is changing as frequently as your 60 fps main screen maybe throwing it all though canvas would be better and you just take the hit the actual coding of responsive stuff inside canvas (I recently did a quick summary of modules for rendering loads of data into tables, a canvas based module was pretty conclusively the fastest across almost all tests).

10 hours ago, pixelburp said:

So something LIKE angular 1, that can just watch any object you point it at, but with better performance would be ideal. 

Put it this way: Why observe changes to every object when you can react to those changes before (or whilst) they happen?

If that doesn't make sense consider the following:

* Trigger a function that updates an object

* Observing function triggers on the update

* Some stuff happens due to the observer triggering -> probably calculate what changed in the UI and redraw

The system that causes mutations to your object (point 1) and the system that watch it (point 2) look decoupled, but, in practise you'd probably punt those together i.e. when you create an update to an object you also fire an event to say 'I've changed' from the same place. All things like Redux (and other stuff like Flux, designed to work with React) do is take away the mutation part, so you have a trigger, which causes a mutation, which causes a redraw.

You don't actually want 2-way binding like Angular 1, you just want a way to implement stuff that React/Vue/Ng2 do without really thinking about it (I think).

I think what complicates it is that you have 2 competing data stores, you game data, and your reducers (for redux) and you don't want to mix the two, which is fair enough. You don't have to use the usual React mechanism of triggering redraws only when something in its state changes, you can take that responsibility away from redux.

The redux issue I think you are facing is that you are creating references to objects, when they change redux doesn't know about it and even if it did (i.e. you fired a message for redux to evaluate, which is impossible, but, imagine) it typically performs '==' or '===' evaluation which wouldn't understand that an object has changed, only that the reference is the same, so, the change becomes invisible and it doesn't rerender.

However, YOU know the update took place so just force React to re-render, that impossible message above becomes trivial, if effect its the observer function from point 2 above, just have React re-render itself (you may additionally have to do some work with the `shouldComponentUpdate` method to make sure it re-renders).

To be honest, Vue or Ng2 might make this easier by doing some of this heavy lifting for you, I don't know, and I don't know if there would be any perf hits from doing this.

Link to comment
Share on other sites

31 minutes ago, QLNEO said:

From what I understand you want a DOM UI that updates when something changes ingame, correct?

Maybe you don't need a framework, but something like RxJS?

Yeah, that's the jist of what I'm getting at; interesting, will have a look at RxJS. Something I keep meaning to review anyway. Thanks!

 

On 06/11/2017 at 9:49 AM, mattstyles said:

Ha ha, I think you do realise that these two things are very tightly related!

The reason other frameworks have deviated away from two-way binding is because perf gets tricky.

What I think you really want is just an abstraction so you don't have to think about it when your unit stats update themselves.

I like to use HTML for UI layer/s, for reasons you've stated, but, if you data is changing as frequently as your 60 fps main screen maybe throwing it all though canvas would be better and you just take the hit the actual coding of responsive stuff inside canvas (I recently did a quick summary of modules for rendering loads of data into tables, a canvas based module was pretty conclusively the fastest across almost all tests).

Yeah, I get what you mean, and does feel like a tricky needle to thread; in real terms I won't be tracking anything that'll be updating as fast as (for example) a sprite's x,y position, but the option to catch things like health, or unit buffs - that sort of things.

It's just a pity there isn't a way to quickly prototype UIs in Phaser / Canvas as neatly & universally as HTML/CSS allows - or at least I don't think there is. I see there is the Button class, which seems like an input enabled Sprite, but having to define spritesheets etc. seems like a fussy trade-off for the more extensible avenue of HTML & CSS.

 

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...