Stage and the boolean stretch

Anything libgdx related goes here!

Stage and the boolean stretch

Postby spoiltProgrammer » Wed Feb 22, 2012 5:05 pm

I recently came to know that libgdx has some of its own functionality to maintain aspect ratios which I would like to discuss here. While searching the aspect ratio issue across the internet, I came across several forums/developers who had this problem of "How to maintain the aspect ratio on different screen sizes?" One of the solutions that really worked for me was posted in the following thread:
viewtopic.php?f=11&t=3291&p=16295#p16295

However I couldn't get any replies about the pros and cons of this solution. Later on when I proceeded with implementing the touchDown() methods for the screen, I found that due to scaling on resize, the co-ordinates on which I had implemented touchDown() would change by a great amount. After working with some code to translate the co-ordinates in accordance with the screen resize, I reduced this amount to a great extent but I wasn't successful to maintain them with pin point accuracy. For example, if I had implemented touchDown() on a texture, resizing the screen would shift the touchListener on the texture region some pixels to the right or left, depending on the resize and this was obviously undesired.

Later on I came to know that the stage class has its own native functionality to maintain the aspect ratio (boolean stretch = false). Now that I have implemented my screen by using the stage class, the aspect ratio is maintained well by it. However on resize or different screen sizes, the black area that is generated always appears on the right side of the screen; that is the screen is not centered which makes it quite ugly if the black area is substantially large.

Can any community member help me out to resolve this problem??
spoiltProgrammer
 
Posts: 34
Joined: Wed Feb 08, 2012 8:46 pm

Re: Stage and the boolean stretch

Postby Magnesus » Wed Feb 22, 2012 7:10 pm

I do it that way:

stage = new Stage(width, height, false);
stage.getCamera().translate(px, py, 0);

Where px and py are calculated sth like that (sorry for the ugly code, I haven't got time to clean it):

Code: Select all
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
        int wx = width;
        int wy = height;
        realwi = width;
        realhe = height;
        int px;
        int py;
       
        boolean landscape = true;
       
        if(landscape)
        {
           if(height>width)
            {
              int ow = width;
               width = height;
               height = ow;
            }
           
           wx = width;
            wy = height;
            realwi = width;
            realhe = height;

              float prop1 = 1280/800.0f;
              float prop2 = ((float)width)/height;
              if(prop2>=prop1) // ekran jest szerszy
              {
                 wx = (int)(1280*prop2/prop1);
                 wy = 800;
                 px = (1280-wx)/2;
                 py = 0;
              }
              else // ekran jest węższy
              {
                 wx = 1280;
                 wy = (int)(800*prop1/prop2);
                 px = 0;
                 py = (800-wy)/2;
              }

           isPhone = realhe<=600;
            config.resolutionStrategy = new FixedResolutionStrategy(realwi,realhe);
        }
        else
        {
           if(width>height)
            {
              int ow = width;
               width = height;
               height = ow;
            }
           
           wx = width;
            wy = height;
            realwi = width;
            realhe = height;
                   
           if(height>1200&&height<=1280&&width==800) // klasyczne 1280x800
           {
              wx = 800;
              wy = 1280;
              px = 0;
              py = (1280-height)/2;
           }
           else // inna rozdziałka, rozszerz do szerokości albo wysokości?
           {
              float prop1 = 800/1280.0f;
              float prop2 = ((float)width)/height;
               Log.v("test", String.format("%d %d %f %f", width, height, prop1, prop2));
              if(prop2>=prop1) // ekran jest szerszy
              {
                 wx = 800;
                 wy = (int)(1280*prop1/prop2);
                 px = 0;
                 py = (1280-wy)/2;
              }
              else // ekran jest węższy
              {
                 wx = (int)(800*prop2/prop1);
                 wy = 1280;
                 px = (800-wx)/2;
                 py = 0;
              }
           }
           isPhone = realwi<=600;
           //Log.v("test", String.format("%d %d %d %d", wx, wy, px, py));
            config.resolutionStrategy = new FixedResolutionStrategy(realwi,realhe);
        }
Magnesus
 
Posts: 1083
Joined: Sun Sep 25, 2011 3:50 pm

Re: Stage and the boolean stretch

Postby travis.wyatt » Thu Feb 23, 2012 9:04 am

Simply set the stage's camera to the center of the stage:
Code: Select all
stage.getCamera().position.set(STAGE_WIDTH / 2, STAGE_HEIGHT / 2, 0);


Here's an example used within a screen (hope it helps):
Code: Select all
public class DefaultScreen implements Screen {

   public static final float STAGE_WIDTH  = 854f;
   public static final float STAGE_HEIGHT = 480f;
   
   public Color backgroundColor = Color.BLACK;
   public Stage stage;
   
   public DefaultScreen() {
      boolean stretch = false;
      stage = new Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), stretch);
      
      Box box = new Box();
      box.width = STAGE_WIDTH;
      box.height = STAGE_HEIGHT;
      box.color.set(Color.RED);
      stage.addActor(box);
   }
   
   @Override
   public void render(float delta) {
      GLCommon gl = Gdx.graphics.getGLCommon();
      clearScreen(gl);
      stage.draw();
   }

   protected void clearScreen(GLCommon gl) {
      gl.glClearColor(backgroundColor.r, backgroundColor.g, backgroundColor.b, backgroundColor.a);
      gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
   }
   
   @Override
   public void resize(int width, int height) {
      boolean stretch = false;
      stage.setViewport(STAGE_WIDTH, STAGE_HEIGHT, stretch);
      stage.getCamera().position.set(STAGE_WIDTH / 2, STAGE_HEIGHT / 2, 0);
   }
   
   @Override
   public void dispose() {
      stage.dispose();
      stage = null;
   }
   
   public class Box extends Actor {
      private ImmediateModeRenderer10 renderer = new ImmediateModeRenderer10();

      @Override
      public void draw(SpriteBatch batch, float parentAlpha) {
         renderer.begin(GL10.GL_TRIANGLES);
         
         // bottom left corner
         renderer.color(color.r, color.g, color.b, color.a);
         renderer.vertex(0, 0, 0);
         
         // bottom right corner
         renderer.color(color.r, color.g, color.b, color.a);
         renderer.vertex(width, 0, 0);
         
         // upper right corner
         renderer.color(color.r, color.g, color.b, color.a);
         renderer.vertex(width, height, 0);
         
         
         // upper right corner
         renderer.color(color.r, color.g, color.b, color.a);
         renderer.vertex(width, height, 0);
         
         // upper left corner
         renderer.color(color.r, color.g, color.b, color.a);
         renderer.vertex(0, height, 0);
         
         // bottom left corner
         renderer.color(color.r, color.g, color.b, color.a);
         renderer.vertex(0, 0, 0);
         
         renderer.end();
      }

      @Override
      public Actor hit(float x, float y) {
         return null;
      }
      
   }

}
travis.wyatt
 
Posts: 3
Joined: Mon Jun 06, 2011 3:59 am

Re: Stage and the boolean stretch

Postby spoiltProgrammer » Fri Feb 24, 2012 10:52 am

Thanks a lot travis.wyatt. That actually did the trick for me. Thanks again.
spoiltProgrammer
 
Posts: 34
Joined: Wed Feb 08, 2012 8:46 pm

NonStretching Maxpect (fit inside, no clipping)

Postby wolfieee » Sat Jun 02, 2012 12:38 am

The previous codes I tried out, but got either stretching or clipping.... finally came up with this one:

Code: Select all
//screenWidth == GAME width
//screenHeight == GAME height

@Override
   public void resize(int width, int height) {
      float scale=1;
      float newWidth;
      float newHeight;
      
      scale=(float)screenWidth/(float)width;
      if ((float)screenHeight/(float)height>scale){
         scale=(float)screenHeight/(float)height;
      }
      newWidth=(float) Math.ceil(scale*width);
      newHeight=(float) Math.ceil(scale*height);
      
      System.out.println("=============================");
      System.out.println("scale: "+scale);
      System.out.println("Width: "+newWidth+", Height: "+newHeight);
      System.out.println("=============================");

      stage.getCamera().viewportHeight=newHeight;
      stage.getCamera().viewportWidth=newWidth;
      stage.getCamera().position.set(screenWidth/2, screenHeight/2, 0);
   }
wolfieee
 
Posts: 156
Joined: Sun May 20, 2012 1:59 am

Stage, Resize, and the Mouse

Postby wolfieee » Sun Sep 08, 2013 11:23 pm

Starting having mouse tracking issues today.....

seems that the viewport on the STAGE needs to be reset along with camera on resize ...

Code: Select all

//fullscan contains the targeted screen dimensions, and should match your target stage size

@Override
   public void resize(int width, int height) {
      System.out.println("resize: "+width+"x"+height);
      float scale_h;
      float scale;
      float newWidth;
      float newHeight;

      /*
       * http://www.badlogicgames.com/forum/viewtopic.php?f=11&t=3422
       */
      scale = (float) fullscan.width / (float) width;
      scale_h = (float) fullscan.height / (float) height;

      if (scale_h > scale) {
         scale = scale_h;
      }

      newWidth = (float) Math.ceil(scale * width);
      newHeight = (float) Math.ceil(scale * height);

      gameStage.setViewport(newWidth, newHeight, true);
      gameStage.getCamera().viewportHeight = newHeight;
      gameStage.getCamera().viewportWidth = newWidth;
      gameStage.getCamera().position.set(fullscan.width / 2, fullscan.height / 2, 0);
      gameStage.getCamera().update();
   }
wolfieee
 
Posts: 156
Joined: Sun May 20, 2012 1:59 am


Return to Libgdx

Who is online

Users browsing this forum: Bing [Bot], javadocmd and 14 guests