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.