Mängija pööramine hiire suunas 2D mängus

LibGDX-is töötades on põhimõte sama, mis teistes mootorites: meil on vaja leida nurk mängija ja hiire asukoha vahel. Kuna LibGDX kasutab vaikimisi 2D-s OpenGL-i koordinaatsüsteemi, kus Y=0 on ekraani allservas, aga hiire koordinaadid tulevad operatsioonisüsteemilt, kus Y=0 on ekraani ülaservas, on esimeseks sammuks koordinaatide sünkroniseerimine.

1. Teooria: Koordinaatide teisendamine (Unprojecting)

Enne arvutuste juurde asumist peame hiire positsiooni ekraanil teisendama mängumaailma koordinaatideks ja need salvestama muutujasse. LibGDX-is aitab selle töö ära teha kaamera funktsioon unproject().

Miks see vajalik on? Kui sinu mänguaken on suurusega 800x600, aga mängija asub maailmas koordinaadil (50, 20), siis hiire positsioon ekraani nurgas näiteks koordinaadil (790, 10) ei ühti otseselt maailma koordinaatidega. unproject() viib need samale skaalale.

2. Koodinäide

Vajalikud impordid koodi alguses:

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector3;

Vajalikud muutujad klassi alguses:

private OrthographicCamera camera;
private Vector3 mousePos; // libGDX unproject vajab Vector3 objekti
private float playerX, playerY; // Mängija asukoht maailmas
private float playerRotation; // Mängija pööre kraadides

Realiseerimine render() või update() meetodis:

public void update(float delta) {
    // 1. Võtame hiire hetkepositsiooni (pikslites)
    mousePos.set(Gdx.input.getX(), Gdx.input.getY(), 0);

    // 2. Teisendame hiire koordinaadid mängumaailma süsteemi
    camera.unproject(mousePos);

    // 3. Arvutame vahemaa (delta) mängija ja hiire vahel
    float deltaX = mousePos.x - playerX;
    float deltaY = mousePos.y - playerY;

    // 4. Arvutame nurga radiaanides kasutades Math.atan2
    float radians = (float) Math.atan2(deltaY, deltaX);

    // 5. Konverteerime radiaanid kraadideks
    playerRotation = radians * MathUtils.radDeg;

    // Kui sinu tegelane vaatab mängus vales suunas,
    // pead tulemusest 90 kraadi maha lahutama või liitma
    // Kuna mäng renderab mängijat pildi järgi, siis on võimalik,
    //et pead sisestama muud kraadid
    // playerRotation -= 90;
}

Mängija joonistamine render() Kui kasutad SpriteBatch-i ja TextureRegion-it, tuleb pööramisel määrata ka pööramise keskpunkt. Tavaliselt on selleks mängija keskkoht.

public void render(float delta) {
    // Uuenda loogikat
    update(delta);

    // Joonistamine
    batch.setProjectionMatrix(camera.combined);
    batch.begin();

    float width = 64; // Mängija tekstuuri laius
    float height = 64; // Mängija tekstuuri kõrgus

    batch.draw(
    playerTexture,
    playerX - width/2, playerY - height/2, // Positsioon joonistame keskkohast
    width/2, height/2, // Pööramise keskpunkt
    width, height, // Laius ja kõrgus
    1f, 1f, // skaala
    playerRotation // Pöördenurk
    );

    batch.end();
}

3. LibGDX-i eripärad

1. Sprite'i algsuund: Matemaatiliselt on 0 kraadi suunatud alati paremale. Kui sinu mängija pilt on joonistatud nii, et ta vaatab otse üles, siis koodi käivitamisel hakkab ta hiirt vaatama küljega. Lahendus: Kas pildirakendusega keerad pilti nii, et nägu vaataks paremale või lisa koodis nurgale playerRotation korrektsioon:

2. Mäluhaldus: Vältige new Vector3() loomist iga kaadri (frame) ajal render() meetodis. See koormab Java-t ja mäng hakkab hakkima. Loo mousePos valmis klassi konstruktoris ja kasuta .set() meetodit selle taas täitmiseks.