Ekraani suuruse vahetus

Kui soovite arendada professionaalset ja kvaliteetset arvutimängu, on äärmiselt oluline kaaluda, kuidas lahendada olukordi, kus mänguaken muutub erineva suurusega ekraanide tõttu. Kui mängija otsustab mänguakent vähendada, et vältida kogu ekraani hõivamist, ja koodi pole kohandatud uutele suurustele vastamiseks, võib mängu töö katkeda või muutuda mängimine ebamugavaks.

Järgnevalt on esitatud kaks meetodit, kuidas seda probleemi lahendada:

1. Avage mäng täisekraanirežiimis.

Seda saab saavutada, lisades klassi DesktopLauncher vastava konfiguratsioonikoodi. See klass on vaikimisi projektiga kaasas ja seal seadistatakse rakenduse konfiguratsioon ja käivitatakse rakendus. Selleks et avada esialgse ekraani täisekraanirežiimis, lisage main meetodi:

Graphics.DisplayMode displayMode = Lwjgl3ApplicationConfiguration.getDisplayMode();
config.setFullscreenMode(displayMode);

Pärast nende ridade lisamist avaneb mäng alati täisekraani.

Kuigi see on lihtsaim viis ekraani suuruse probleemidega tegelemiseks, ei pruugi see alati olla kasutajate jaoks kõige mugavam lähenemine.

2. Kohandage mängu loogikat ja graafikat nii, et see töötaks sujuvalt erineva suurusega ekraanidel.

Selleks on vaja mängu joonistamise ja ekraanisuuruse muutmisega seotud koodiosa ümber mõelda nii, et mängija ja teiste objektide koordinaadid ja suurused arvutatakse dünaamiliselt. Selle lähenemise korral ei kasutata konstante, vaid suurused määratakse ekraani suuruse suhtes.

Oluline komponent selles protsessis on meetod resize, mida käivitatakse iga kord, kui ekraani suurus muutub. Selle meetodi ülesanne on uuendada kaamera ja objektide asukohti ning suurusi vastavalt uuele ekraani mõõtmele. Allpool on toodud üksikasjalik näide, kuidas arvutada mängija uusi koordinaate ja suurusi muudetud ekraani suhtes.

Meetod resize:

Eelmiste maailma mõõtmete salvestamine: Esmalt salvestatakse muutujatesse oldWorldWidth ja oldWorldHeight eelmised kaamera hallatava maailma mõõtmed. See samm on vajalik, et arvutada, kuidas objektide positsioonid ja suurused muutuvad uute mõõtmete suhtes.

float oldWorldWidth = viewport.getWorldWidth()
float oldWorldHeight = viewport.getWorldHeight();

Viewpointi uuendamine: Seejärel uuendatakse viewport vastavalt uutele akna mõõtmetele. Meetodisse update antakse uued laius ja kõrgus, samuti parameeter, mis tähendab kaamera tsentreerimist.

viewport.update(width, height, true);

Uute maailma mõõtmete arvutamine: Pärast vaateakna uuendamist saadakse uued maailma mõõtmed muutujatesse newWorldWidth ja newWorldHeight.

float newWorldWidth = viewport.getWorldWidth();
float newWorldHeight = viewport.getWorldHeight();

Objektide kohandamine uutele mõõtmetele: Kui eelmised maailma mõõtmed on määratud, arvutatakse mängija ja teiste objektide uued koordinaadid ja suurused proportsionaalselt uute mõõtmetega.

if (oldWorldWidth > 0 && oldWorldHeight > 0) {
   playerX = (playerX / oldWorldWidth) * newWorldWidth;
   playerY = (playerY / oldWorldHeight) * newWorldHeight;
}

Kaamera tsentreerimine: Lõpuks tsentreeritakse kaamera uuesti, seades selle positsiooni maailma keskpunkti. See tagab, et kaamera jääb alati keskenduma olulisele osale mängumaailmast.

camera.position.set(newWorldWidth / 2, newWorldHeight / 2, 0);

Kokkuvõttes tagab meetod resize, et mäng kohandub sujuvalt uutele akna suurustele, hoides nii graafikat kui ka loogikat proportsionaalsena ja kasutajale meeldivana.

Allpool on täielik näide mini-mängust, mis demonstreerib, kuidas kasutada meetodi resize.

  import com.badlogic.gdx.ApplicationAdapter;
  import com.badlogic.gdx.graphics.g2d.SpriteBatch;
  import com.badlogic.gdx.Gdx;
  import com.badlogic.gdx.graphics.Color;
  import com.badlogic.gdx.graphics.OrthographicCamera;
  import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
  import com.badlogic.gdx.utils.viewport.Viewport;
  import com.badlogic.gdx.graphics.GL20;
  import com.badlogic.gdx.Input;
  import com.badlogic.gdx.utils.viewport.ScreenViewport;


  public class MyGdxGame extends ApplicationAdapter {
     private SpriteBatch batch; // SpriteBatch vastutab tekstuuride joonistamise eest.
     private OrthographicCamera camera; // Orto-kaamera, mis võimaldab lihtsamat maailmavaate juhtimist.
     private Viewport viewport; // Viewport haldab kaamera ja ekraani suhteid, eriti suuruse muutmisel.
     private ShapeRenderer shapeRenderer; // Kujundite joonistamiseks mõeldud tööriist.

     private float playerX, playerY; // Mängija X ja Y koordinaadid.
     private float playerSpeed = 500f; // Mängija kiirus pikslites sekundis.
     private float playerSize = 50f; // Mängija suurus (ruudu külje pikkus).

     private static final float VIRTUAL_WIDTH = 800f; // Virtuaalne maailma laius.
     private static final float VIRTUAL_HEIGHT = 600f; // Virtuaalne maailma kõrgus.


     @Override
     public void create() {
        batch = new SpriteBatch(); // Initsialiseerib SpriteBatchi.
        shapeRenderer = new ShapeRenderer(); // Initsialiseerib kujundite joonistaja.
        camera = new OrthographicCamera(); // Luuakse kaamera.
        viewport = new ScreenViewport(camera); // Viewport ühendatakse kaameraga.

        playerX = VIRTUAL_WIDTH / 2 - playerSize / 2; // Mängija alguspositsioon (X) - keskpunkt.
        playerY = VIRTUAL_HEIGHT / 2 - playerSize / 2; // Mängija alguspositsioon (Y) - keskpunkt.

        camera.position.set(VIRTUAL_WIDTH / 2, VIRTUAL_HEIGHT / 2, 0); // Kaamera paigutatakse maailma keskele.
        camera.update(); // Kaamera värskendamine.
     }


  @Override
  public void render() {
     float deltaTime = Gdx.graphics.getDeltaTime(); // Aja möödumine kaadrite vahel (sekundites).
     camera.update(); // Kaamera uuendamine.
     batch.setProjectionMatrix(camera.combined); // Sidumine kaamera ja SpriteBatchi vahel.


     // Ekraani puhastamine halli taustaga.
     Gdx.gl.glClearColor(0.1f, 0.1f, 0.1f, 1);
     Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);


     // Kohandab mängija suurust ekraani suuruse järgi.
     playerSize = Math.min(viewport.getWorldWidth(), viewport.getWorldHeight()) * 0.1f;


     // Mängija liikumine.
     if (Gdx.input.isKeyPressed(Input.Keys.LEFT)) {
        playerX -= playerSpeed * deltaTime; // Liikumine vasakule.
     }
     if (Gdx.input.isKeyPressed(Input.Keys.RIGHT)) {
        playerX += playerSpeed * deltaTime; // Liikumine paremale.
     }
     if (Gdx.input.isKeyPressed(Input.Keys.UP)) {
        playerY += playerSpeed * deltaTime; // Liikumine üles.
     }
     if (Gdx.input.isKeyPressed(Input.Keys.DOWN)) {
        playerY -= playerSpeed * deltaTime; // Liikumine alla.
     }


     // Mängija hoidmine ekraani piirides.
     playerX = Math.max(0, Math.min(playerX, viewport.getWorldWidth() - playerSize));
     playerY = Math.max(0, Math.min(playerY, viewport.getWorldHeight() - playerSize));

     // Kujundite joonistamine.
     shapeRenderer.setProjectionMatrix(camera.combined); // Kujundite vastavusse seadmine kaameraga.
     shapeRenderer.begin(ShapeRenderer.ShapeType.Filled); // Alustatakse täidetud kujundite joonistamist.
     shapeRenderer.setColor(Color.RED); // Määratakse mängija värv (punane).
     shapeRenderer.rect(playerX, playerY, playerSize, playerSize); // Joonistatakse mängija.
     shapeRenderer.end(); // Kujundite joonistamine lõpetatakse.
  }


  @Override
   public void resize(int width, int height) {
      // Salvestatakse vanad maailma mõõtmed.
      float oldWorldWidth = viewport.getWorldWidth();
      float oldWorldHeight = viewport.getWorldHeight();


      // Uuendatakse vaadet vastavalt uutele ekraani mõõtmetele.
      viewport.update(width, height, true);


      // Saadakse uued maailma mõõtmed.
      float newWorldWidth = viewport.getWorldWidth();
      float newWorldHeight = viewport.getWorldHeight();


      // Kohandatakse mängija ja objekti koordinaate vastavalt ekraani muutusele.
      if (oldWorldWidth > 0 && oldWorldHeight > 0) {
         playerX = (playerX / oldWorldWidth) * newWorldWidth; // Mängija X-koordinaadi ümberarvutamine.
         playerY = (playerY / oldWorldHeight) * newWorldHeight; // Mängija Y-koordinaadi ümberarvutamine.
      }

      // Kaamera tsentreerimine.
      camera.position.set(newWorldWidth / 2, newWorldHeight / 2, 0);
   }


   @Override
   public void dispose() {
      batch.dispose(); // Ressursside vabastamine.
      shapeRenderer.dispose(); // Kujundite joonistaja vabastamine.
   }
}