2016-09-27 3 views
0

Meine 2D-Engine Auflösung ist unabhängig und hat eine Kamera auf den Artikel basiert hier: http://www.david-gouveia.com/portfolio/2d-camera-with-parallax-scrolling-in-xna/korrekte Position des Bildes Erste basierend auf 2D-Parallax-Kamera

ich Parallax-Scrolling in meine Kamera-Klasse der Artikel über die gleiche Art und Weise implementiert haben Erwähnungen. Es funktioniert gut, aber es hat meinen Culling-Code vermasselt und ich kämpfe darum, die Mathematik herauszufinden.

Jedes meiner Hintergrundbilder hat ein Rechteck, mit dem ich überprüfe, ob es gerade auf dem Bildschirm ist. Wenn es nicht mit meinem Kamera-Rechteck kollidiert, zeichne ich es nicht. Das Problem besteht darin, dass das Rechteck, wenn es als Parallax-Ebene gezeichnet wird, nicht dort berechnet wird, wo es wirklich auf dem Bildschirm angezeigt wird.

Die Matrix in meine Kamera-Klasse verwandeln sieht wie folgt aus:

public static Matrix GetTransformMatrix(Vector2 parallax) 
     { 
      return Matrix.CreateTranslation(new Vector3(-position * parallax, 0)) * Matrix.CreateRotationZ(rotation) * 
         Matrix.CreateScale(new Vector3(zoom, zoom, 1)) * Matrix.CreateTranslation(new Vector3(Resolution.VirtualWidth 
          * 0.5f, Resolution.VirtualHeight * 0.5f, 0)); 
     } 

Für jede Parallaxe Schicht, ich nenne SpriteBatch.Begin() und es oben passieren die in Abhängigkeit von geben Offset-Matrix mit der richtigen Parallaxe-Transformation Welche Ebene zeichnen wir (Vordergrund, Hintergrund usw.)?

Ich habe erfolgreich eine ScreenToWorld-Funktion erstellt, die dazu dient, die Position zu erhalten, an der die Maus geklickt wurde. Beachten Sie, dass ich sowohl meine Auflösungsmatrix als auch die Kameramatrix berechnen muss, damit sie funktioniert.

public static Vector2 ScreenToWorld(Vector2 input, Vector2 parallax) 
     { 
      input.X -= Resolution.VirtualViewportX; 
      input.Y -= Resolution.VirtualViewportY; 

      Vector2 resPosition = Vector2.Transform(input, Matrix.Invert(Resolution.getTransformationMatrix())); 
      Vector2 finalPosition = Vector2.Transform(resPosition, Matrix.Invert(Camera.GetTransformMatrix(parallax))); 

      return finalPosition;  
     } 

Also habe ich die richtigen Positionen Rectangle meiner Parallaxe Schichten berechnen ich eine WorldToScreen Funktion brauchen würde ... Ich habe versucht, diese, aber es funktioniert nicht:

public static Vector2 WorldToScreen(Vector2 input, Vector2 parallax) //I pass the same parallax value that is used in the Camera matrix function. 
     { 
      input.X -= Resolution.VirtualViewportX; 
      input.Y -= Resolution.VirtualViewportY; 

      Vector2 resPosition = Vector2.Transform(input, Resolution.getTransformationMatrix()); 
      Vector2 finalPosition = Vector2.Transform(resPosition, Camera.GetTransformMatrix(parallax)); 

      return finalPosition;  
     } 

Ich bin Ich denke, ich bin auf dem richtigen Weg, aber meine Mathematik ist falsch? Ich übergebe die obige Funktion die nicht-parallaxierte Rectangle-Position mit der Hoffnung, dass sie aktualisiert wird, wo das Parallax-Bild wirklich gezeichnet wird. Vielen Dank im Voraus, wenn jemand helfen kann!

Antwort

0

Meine Mathematik war richtig, aber ich musste meinen Kamera-Bildschirm rect basierend auf der Matrix der Kamera berechnen. Wenn Sie dies tun, müssen Sie die Hintergrundrechtecke überhaupt nicht berühren. Geben Sie einfach den Parallaxenwert des Hintergrunds in diese Funktion ein und überprüfen Sie dann das Rechteck, das zurückgegeben wird:

/// <summary> 
/// Calculates the Camera's screenRect based on the parallax value passed in. 
/// </summary> 
public static Rectangle VisibleArea(Vector2 parallax) 
{ 
    Matrix inverseViewMatrix = Matrix.Invert(GetTransformMatrix(parallax)); 
    Vector2 tl = Vector2.Transform(Vector2.Zero, inverseViewMatrix); 
    Vector2 tr = Vector2.Transform(new Vector2(Resolution.VirtualWidth, 0), inverseViewMatrix); 
    Vector2 bl = Vector2.Transform(new Vector2(0, Resolution.VirtualHeight), inverseViewMatrix); 
    Vector2 br = Vector2.Transform(new Vector2(Resolution.VirtualWidth, Resolution.VirtualHeight), inverseViewMatrix); 
    Vector2 min = new Vector2(
     MathHelper.Min(tl.X, MathHelper.Min(tr.X, MathHelper.Min(bl.X, br.X))), 
     MathHelper.Min(tl.Y, MathHelper.Min(tr.Y, MathHelper.Min(bl.Y, br.Y)))); 
    Vector2 max = new Vector2(
     MathHelper.Max(tl.X, MathHelper.Max(tr.X, MathHelper.Max(bl.X, br.X))), 
     MathHelper.Max(tl.Y, MathHelper.Max(tr.Y, MathHelper.Max(bl.Y, br.Y)))); 
    return new Rectangle((int)min.X, (int)min.Y, (int)(max.X - min.X), (int)(max.Y - min.Y)); 
} 
Verwandte Themen