3

I have an app that's currently working with a single stage but i need to add a side display/section as a HUD, with scores/lives etc on it, so that the HUD is on the left, and the main hand screen on the right. The main game screen will be fixed and will not move around.

From researching I've found a couple of solutions.

1 - two stages 2 - a group with two groups to it, possibly using a horizontalgroup 3 - two cameras one stage 4 - one stage, one camera, but changing the position of the camera for each set of actors.

I think, option 1 is my preference, but i have some questions.

  • Do stages always fill the whole screen, or can i start then where i want? This would make it easier for the right hand screen to calculate positions based on 0,0 of that screen rather than always having to add the width of the HUD on to any calculations.
  • Do i need to work about viewports? Currently I'm not using one (which i think means my stage is set to scaling by default) but nothing looks stretched as a result of this. I don't know much about viewports, but there always seems to be a compromise to be made with them, i.e. black bars top or sides.
  • If I have two stages, do they each have their own camera? Do I need to with about this? Can I possibly aim the right hand camera at an offset so i can still draw things from 0,0 with that being the bottom left corner of the right stage, not the whole screen?

Finally, off topic, I am a little confused about spritebatch. I'm not currently using one, because I use a stage. Is that OK, or should i still be using one in conjunction with a stage somehow? And add all my actors to that?

Russ Wheeler
  • 2,590
  • 5
  • 30
  • 57

1 Answers1

8

It I understand correctly, you're using scene2d for your game world and also for your HUD. And the HUD doesn't overlay the game world, but rather uses its own portion of the screen exclusively.

Stages do not always fill the whole screen. They have no concept of filling or not filling anything, because they can have objects that are being drawn off screen. However, they are clipped to a rectangle defined by their Viewport.

In your case, it seems you need two Viewports, and therefore, two stages. You say you aren't using a Viewport, but you are...Stage automatically creates its own ScalingViewport that's set up like a StretchViewport. (ScalingViewport is not mentioned in the documentation, which is out of date.) StretchViewport is usually bad because your game will be distorted to fit whatever the aspect ratio of the device is.

ExtendViewports do not cause black bars as long as you don't set a max width/height on them and I think are usually the best choice for any game world view.

You can set your two Viewports to cover specific parts of the screen that you calculate yourself. Since this is a specialized case, I think you will have to directly subclass the Viewport class (not one of its subclasses) and manipulate each of them using viewport.setScreenBounds(...).

Regarding your last question: yes, each of the two stages has its own Viewport, and each Viewport has its own camera. Once you set up your two Viewports to each have their own portion of the screen, you can also set them to treat their respective bottom left corners as 0,0.

Tenfour04
  • 83,111
  • 11
  • 94
  • 154
  • (using the viewport that is setup by default for my stage) when I try and run setScreenBounds, nothing changes. I log all the values and they have changed, but my viewport still feels the whole of my phones screen. At this rate, I think I will just use one stage with two groups. This multiple stage thing makes no sense to me! – Russ Wheeler Feb 11 '15 at 01:22
  • Yeah, that's why I said you'd have to subclass Viewport yourself. The provided subclasses automatically call setScreenBounds on themselves in order to do what they respectively claim, thereby making your calls useless. The downside to using two groups in one Stage is that if you have a game world where the camera pans around an area that's larger than your screen, you'll be using up valuable fill rate drawing stuff behind your HUD. – Tenfour04 Feb 11 '15 at 02:06
  • OK, so maybe i should've added more about my type of game. It's a single screen card game so there won't be any need for scrolling. So, a method exists in a class, that i can call with variables but it does nothing!? How does that work? I'm not saying your wrong or don't believe you, far from it, I'm just wondering how that would work. So, if i override setbounds, what do i actually code inside that method? SetPosition and separate setX and setY? – Russ Wheeler Feb 11 '15 at 09:55
  • Oh wait. Having read that, you're not trying me to override the setScreenBounds method but to just call it itself. Sorry, half asleep – Russ Wheeler Feb 11 '15 at 09:58
  • There are three direct subclasses of Viewport, ScreenViewport, ExtendViewport and ScaleViewport. All of them indirectly call setBounds from their update methods, but Viewports only work correctly if you are calling update on them from the game's resize method. So that's why direct calls to setBounds don't really work without finagling. I think it's maybe a design error or the documentation just needs to be clearer. – Tenfour04 Feb 11 '15 at 13:18
  • So should I add my own extended Viewport class to my stage in resize? I got something very basic working after reading through the docs and realising that I had to pass through both the world sizes and also create a new camera inside my extended Viewport. I think I'm close-ish to getting this working, once I do, I'll accept your answer. I'm pretty certain it's going to be the right way to do it, but I won't accept till I've got it working :P – Russ Wheeler Feb 11 '15 at 15:44
  • I would follow the pattern of ExtendViewport, but change all the math to get it to set bounds that make sense for what you're doing. You can pass this viewport to your stage when you first instantiate it, and you need to update the viewport in resize. – Tenfour04 Feb 11 '15 at 15:54
  • Thanks for all your help. I got my extended Viewport working after a few tweaks, and it now does exactly what I wanted. Thankyou so much for bearing with me – Russ Wheeler Feb 12 '15 at 01:09