Stap 3: De klasse Camera
Nu laten we een andere omweg en de klasse Camera instellen. De klasse Camera houdt spoor van waar de speler bevindt zich in de 2D kaart en zorgt ook voor het bijwerken van de speler positie. Om dit te doen de klasse implementeert KeyListener, dus het moet importeren van KeyEvent en KeyListener.
import java.awt.event.KeyEvent;<br>import java.awt.event.KeyListener;
Veel variabelen zijn nodig om bij te houden van de camera positie en wat het kan zien. Hierdoor is het eerste stuk van de klasse ziet er als volgt:
public class Camera implements KeyListener { public double xPos, yPos, xDir, yDir, xPlane, yPlane; public boolean left, right, forward, back; public final double MOVE_SPEED = .08; public final double ROTATION_SPEED = .045;
xPos en yPos zijn de locatie van de speler op de 2D kaart die ontstond in de Game klasse. xDir en yDir zijn de x en y-componenten van een vector die wijst in de richting van de speler wordt geconfronteerd. xPlane en yPlane zijn ook de x en y-componenten van een vector. De vector gedefinieerd door xPlane en yPlane is altijd loodrecht op de richting vector, en deze verwijst naar de verste rand van het gezichtsveld van de camera's aan de ene kant. De verste rand aan de andere kant is gewoon de negatieve vliegtuig vector. Wat zit er in het gezichtsveld van de camera's, gedefinieerd door de combinatie van de vectoren van de richting en de vliegtuig-vector. De booleans worden gebruikt om bij te houden welke toetsen zijn wordt ingedrukt door de gebruiker, zodat de gebruiker de camera kan bewegen. MOVE_SPEED en ROTATION_SPEED dicteren hoe snel de camera beweegt en draait terwijl de gebruiker is op de overeenkomstige toets te drukken.
Volgende halte is de constructor. De constructor neemt in waarden die de klasse vertellen waar de camera zich bevindt en wat het zien kan en wijst ze toe aan de bijbehorende variabele (xPos, yPos...).
public Camera(double x, double y, double xd, double yd, double xp, double yp) { xPos = x; yPos = y; xDir = xd; yDir = yd; xPlane = xp; yPlane = yp; }
Een camera-object nodig zullen worden in het definitieve programma, dus laten we gaan vooruit en één toevoegen. In het spel klasse met alle van de andere declaraties van variabelen toevoegen in
public Camera camera;
en in de constructor toevoegen in
camera = new Camera(4.5, 4.5, 1, 0, 0, -.66); addKeyListener(camera);
Deze camera werkt met de kaart die ik gebruik, als u een andere kaart gebruikt of als u wilt laten beginnen op een andere locatie waardecorrecties op xPos en yPos (4 en 6 in mijn voorbeeld). Gebruik.66 geeft wat ik voel is een goede gezichtsveld, maar u kunt de waarde om een verschillende FOV aanpassen.
Nu dat de klasse Camera een constructor heeft kunnen we beginnen met het toevoegen van methoden voor het bijhouden van de ingangen van de gebruiker en voor het bijwerken van de positie/oriëntatie van de camera. Omdat de klasse Camera KeyboardListener te geven implementeert moet het alle methoden van het ten uitvoer gelegd. Eclipse moet u deze methoden toevoegen automatisch gevraagd. U kunt de methode keyTyped leeg laten, maar de andere twee methoden zullen worden gebruikt. keyPressed zal het instellen van de booleans op true wanneer de bijbehorende sleutels worden ingedrukt, en keyReleased hen terug naar false veranderen zal wanneer de sleutels worden vrijgegeven. De methoden er als volgt uitzien:
public void keyPressed(KeyEvent key) { if((key.getKeyCode() == KeyEvent.VK_LEFT)) left = true; if((key.getKeyCode() == KeyEvent.VK_RIGHT)) right = true; if((key.getKeyCode() == KeyEvent.VK_UP)) forward = true; if((key.getKeyCode() == KeyEvent.VK_DOWN)) back = true; }
en
public void keyReleased(KeyEvent key) { if((key.getKeyCode() == KeyEvent.VK_LEFT)) left = false; if((key.getKeyCode() == KeyEvent.VK_RIGHT)) right = false; if((key.getKeyCode() == KeyEvent.VK_UP)) forward = false; if((key.getKeyCode() == KeyEvent.VK_DOWN)) back = false; }
Nu dat de klasse Camera is het houden van spoor van die toetsen zijn ingedrukt kunnen we beginnen met het bijwerken van de speler positie. Om dit te doen die zullen we een update-methode die wordt aangeroepen in de run methode van de klasse in het spel gebruiken. Terwijl we in het we ga je gang en botsingdetectie aan de methode update toevoegen door het passeren van de kaart naar het wanneer deze wordt aangeroepen in de Game klasse. De methode update ziet er zo uit:
public void update(int[][] map) { if(forward) { if(map[(int)(xPos + xDir * MOVE_SPEED)][(int)yPos] == 0) { xPos+=xDir*MOVE_SPEED; } if(map[(int)xPos][(int)(yPos + yDir * MOVE_SPEED)] ==0) yPos+=yDir*MOVE_SPEED; } if(back) { if(map[(int)(xPos - xDir * MOVE_SPEED)][(int)yPos] == 0) xPos-=xDir*MOVE_SPEED; if(map[(int)xPos][(int)(yPos - yDir * MOVE_SPEED)]==0) yPos-=yDir*MOVE_SPEED; } if(right) { double oldxDir=xDir; xDir=xDir*Math.cos(-ROTATION_SPEED) - yDir*Math.sin(-ROTATION_SPEED); yDir=oldxDir*Math.sin(-ROTATION_SPEED) + yDir*Math.cos(-ROTATION_SPEED); double oldxPlane = xPlane; xPlane=xPlane*Math.cos(-ROTATION_SPEED) - yPlane*Math.sin(-ROTATION_SPEED); yPlane=oldxPlane*Math.sin(-ROTATION_SPEED) + yPlane*Math.cos(-ROTATION_SPEED); } if(left) { double oldxDir=xDir; xDir=xDir*Math.cos(ROTATION_SPEED) - yDir*Math.sin(ROTATION_SPEED); yDir=oldxDir*Math.sin(ROTATION_SPEED) + yDir*Math.cos(ROTATION_SPEED); double oldxPlane = xPlane; xPlane=xPlane*Math.cos(ROTATION_SPEED) - yPlane*Math.sin(ROTATION_SPEED); yPlane=oldxPlane*Math.sin(ROTATION_SPEED) + yPlane*Math.cos(ROTATION_SPEED); } }
De onderdelen van de methode waarmee u vooruit en achteruit verkeer werken door toevoeging van xDir en yDir aan xPos en yPos, respectievelijk. Voordat deze beweging gebeurt wordt gecontroleerd als het verkeer zal de camera een binnenwand en niet met het verkeer doorlopen als het zal. Voor rotatie zowel de richting vector en het vliegtuig vector worden vermenigvuldigd met de rotatie-matrix, die is:
[ cos(ROTATION_SPEED) -sin(ROTATION_SPEED) ] [ sin(ROTATION_SPEED) cos(ROTATION_SPEED) ]
om hun nieuwe waarden. Met de methode van de update voltooid kunnen we het nu van de Game klasse noemen. In de Game' run klassenmethode toevoegen de volgende coderegel waar het hier wordt weergegeven
Add this: camera.update(map); in here: while(running) { long now = System.nanoTime(); delta = delta + ((now-lastTime) / ns); lastTime = now; while (delta >= 1)//Make sure update is only happening 60 times a second { //handles all of the logic restricted time camera.update(map); delta--; } render();//displays to the screen unrestricted time }
Nu dat dat gebeurt kunnen we eindelijk gaan naar de laatste klas en berekenen van het scherm!