Jump to content

Persistent elements - best practice?


danhett
 Share

Recommended Posts

Hey all.

I'm using Phaser to create a sort of playable book with lots of pages and interactivity. It's a full-screen scaling affair, with a centrally-aligned book and some UI elements around it (back/next arrows and some other stuff). I'd like the background and UI to be created once, and then stay there for the duration of the experience. The book itself uses scenes, which will change as the user hits next/back.

Currently I've whipped up some floating DOM objects as the UI elements, but I'm not entirely sure how to pass events back into the Phaser game object with faffing about. Or option two I guess is to do it all in Phaser and avoid the DOM, in which case I need to presumably create renderable objects that aren't inside scenes? Is that a thing in Phaser?

What's the best approach here? I'm sure I could smash this together and get it working, but what I'm more interested in is if there's an existing agreed-upon best way of going about this. 

I channeled my inner four year-old and drew a picture to illustrate. 

Thanks!

example.jpg

Link to comment
Share on other sites

The DOM and Phaser can indeed work well together (lovely diagram btw). I think you're getting a little entrenched in what bits of your code live where. In essence, all the DOM is is a front-end for your code, if you think about it as a separation between business logic (app code) and presentational logic then things become a little easier. One of the easiest ways to tie-in the presentation and the app logic is using the pub/sub pattern (i.e. event emitters and listeners e.g. element.addEventListener, Phaser uses the same thing for comms too).

Have your UI emit events and have your app code listen for those events and respond accordingly.

The following is a super basic structure for this:

// Global event emitter
var events = new EventEmitter()

// UI Stuff (DOM)
var el = document.querySelector('.js-swipeRight')
el.addEventListener('click', event => {
  events.emit('SWIPE_RIGHT')
})

// Somewhere in your app logic, this could
// all be within some Phaser structures
events.addEventListener('SWIPE_RIGHT', event => {
  PhaserThing.swipeRight()
})

You can get as complex and clever with this as you like or keep it super simple and have your behaviours arise from the interaction of those simple procedures (simple is good). Up to you.

Link to comment
Share on other sites

Dunno, I don't use Phaser much.

At a push I'd guess that your main Phaser state would contain elements that then make up your scene, in your case that will be your UI controls and your book element. Given your screenshot I'd guess you'd need 2 page containers, plus, whenever you hit the swipe left/right controls you'd create another 1 or 2, do your transition, and destroy the now invisible container/s.

The difficult bit is your glorified carousel housing your book. Phaser states won't really help you here as you need to transition in and out of those states and Phaser states are global anyway, you need to recreate this on a local level i.e. within your 'book' object/element/structure.

Whether you use the DOM or not, I don't think Phaser states are going to help much as they are global states. Phaser probably isn't a natural fit for this project although it is flexible enough that some of it will be of use to you.

Link to comment
Share on other sites

On 8/1/2016 at 1:33 PM, danhett said:

Ah, good - my first instinct was correct then. That's more or less where I'm at. 

Purely out of interest (I probably won't do this), what's the best way to do the none-DOM route? Can scenes be persisted without hackery somehow? 

You can achieve this using game states. 

http://perplexingtech.weebly.com/game-dev-blog/using-states-in-phaserjs-javascript-game-developement

The above link deals on how to implement states in an easy to use manner. 

Phaser is a natural fit for this project.

You can make do with 2 states, one used for loading your assets and the other to run your app.

Game states are objects, can be reached from within any state and you can add onto them:

game.state.states['statename'].new_var = value;

These can in turn be read anywhere inside the app by calling the game.state assets.

 

Your app with the carousel would need to initiate the variables in the load state then call/modify them in the main state.

Link to comment
Share on other sites

I got this working pretty well in the end, using DOM objects for UI, across desktop and mobile. My pages are actually a single entity, not two - obviously the book metaphor suggests pages, but actually I guess they're just spreads/screens really.

Interestingly the only thing I've not figured out yet is graceful scaling - when I go full screen Phaser does the usual scalemode stuff, but actually what I really want to do is go fullscreen, recalculate the screen real estate, and scale everything again. Haven't quite worked it out fully yet but I assume there's a way to do this...

Link to comment
Share on other sites

And with regard to the comment above, I'd say Phaser is absolutely a good fit for this project - sometimes the fact that a library is handling a lot of the legwork around scaling and devices is enough as-is! 

These aren't static pages, they're very rich and interactive. There's parallax layers, animation, particles and all sorts of crazy whizz-bang going on, which Phaser is helping me do very efficiently. It's a slightly different use case to gamey games, but absolutely perfect for this. 

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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