[2D] Hintergrund basierend der Spielerposition bewegen und verhindern dass das Ende des Hintergrundes sichtbar ist

  • C#
  • .NET (FX) 4.5–4.8

Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von ClonkAndre.

    [2D] Hintergrund basierend der Spielerposition bewegen und verhindern dass das Ende des Hintergrundes sichtbar ist

    Hallo liebe Community,

    ich arbeite im Moment an einem kleinem 2D Spiel (es ist eher noch ein Test anstelle eines wirklichen Spieles) und ich habe ein Grid basierten Hintergrund der 32x32 groß ist, und jede Zelle in diesem 32x32 großen Grid ist 64x64 groß.

    Nun habe ich einen Charakter der sich in der Mitte des Bildschirmes befindet, ich kann ihn mit den NumPad Tasten bewegen. Wenn ich diesen Charakter nach rechts bewege, so wird der Hintergrund nach links verschoben. Wenn ich ihn nach oben bewege, so wird der Hintergund nach unten verschoben. Und das selbe für die beiden anderen Richtungen.

    Soweit so gut! Nun bin ich aber etwas überfragt wie ich es bezwecken kann das der Hintergrund aufhört sich zu verschieben wenn das Ende des Hintergrundes Sichtbar ist.
    Hier ein visuelles Beispiel

    Die Rote stelle in diesem Bild darf nicht Sichtbar sein. Der Spieler soll das Ende natürlich nicht sehen.
    Der Hintergrund muss aufhören sich zu verschieben wenn dessen X und Y Position kleiner oder gleich 0 ist für die linke und obere Position. Das selbe für die rechte und untere Position.

    Jede Zelle bekommt die "Initial Position" beim erstellen zugewiesen. Das geschiet beim laden des Grids.
    Hier ist der Code der die Initial Position setzt
    Spoiler anzeigen

    C#-Quellcode

    1. for (int x = 0; x < grid.Width; x++) {
    2. for (int y = 0; y < grid.Height; y++) {
    3. CellProperties cellProperties = grid.GetCellObject(x, y);
    4. TextureProperties textureProperties = cellProperties.TextureProperties;
    5. int cellSize = grid.CellSize;
    6. if (textureProperties != null) {
    7. textureProperties.InitialPosition = new Vector2((x * cellSize) - cellSize, (y * cellSize) + cellSize - (Game.Resolution.Height / 2));
    8. }
    9. }
    10. }



    Dies ist der Code um jede Zelle zu zeichnen
    Spoiler anzeigen

    C#-Quellcode

    1. int cellSize = e.Grid.CellSize;
    2. float posX = cellProperties.TextureProperties.InitialPosition.X - pedPosX;
    3. float posY = cellProperties.TextureProperties.InitialPosition.Y - pedPosY;
    4. // Cell properties of top left, bottom left, top right and bottom right cell.
    5. CellProperties topLeftCell = e.Grid.GetCellObject(0, 0);
    6. CellProperties bottomLeftCell = e.Grid.GetCellObject(0, e.Grid.Height - 1);
    7. CellProperties topRightCell = e.Grid.GetCellObject(e.Grid.Width - 1, 0);
    8. CellProperties bottomRightCell = e.Grid.GetCellObject(e.Grid.Width - 1, e.Grid.Height - 1);
    9. // Top Left Tile
    10. double topLeftCellX = Math.Round(topLeftCell.TextureProperties.InitialPosition.X - pedPosX - (cellSize / 2), 0) * -1;
    11. double topLeftCellY = Math.Round(topLeftCell.TextureProperties.InitialPosition.Y - pedPosY - (cellSize / 2), 0) * -1;
    12. // Bottom Left Tile
    13. double bottomLeftCellX = Math.Round(bottomLeftCell.TextureProperties.InitialPosition.X - pedPosX - (cellSize / 2), 0) * -1;
    14. double bottomLeftCellY = Math.Round(bottomLeftCell.TextureProperties.InitialPosition.Y - pedPosY + (cellSize / 2), 0) * -1;
    15. // Top Right Tile
    16. double topRightCellX = Math.Round(topRightCell.TextureProperties.InitialPosition.X - pedPosX + (cellSize / 2), 0);
    17. double topRightCellY = Math.Round(topRightCell.TextureProperties.InitialPosition.Y - pedPosY - (cellSize / 2), 0) * -1;
    18. // Bottom Right Tile
    19. double bottomRightCellX = Math.Round(bottomRightCell.TextureProperties.InitialPosition.X - pedPosX + (cellSize / 2), 0);
    20. double bottomRightCellY = Math.Round(bottomRightCell.TextureProperties.InitialPosition.Y - pedPosY + (cellSize / 2), 0);
    21. // Boundaries
    22. // Funktioniert! Hintergrund scrolling wird gestoppt wenn X und Y Position der oberen linke Zelle kleiner oder gleich 0 ist.
    23. if (topLeftCellX <= 0) {
    24. //Game.DisplayText("Left is less or equal then 0"); // Debug
    25. posX = e.DrawingLocations.ScreenPos.X + (cellSize / 2);
    26. }
    27. if (topLeftCellY <= 0) {
    28. //Game.DisplayText("Top is less or equal then 0"); // Debug
    29. posY = e.DrawingLocations.ScreenPos.Y + (cellSize / 2);
    30. }
    31. // Nur noch die Begrenzung für die rechte und untere Bildschirmseite fehlt...
    32. if (topRightCellX <= Game.Resolution.Width) {
    33. //Game.DisplayText("Right is bigger or equal then 1920"); // Debug
    34. //posX = // ?
    35. }
    36. if (bottomRightCellY <= Game.Resolution.Height) {
    37. //Game.DisplayText("Bottom is bigger or equal then 1080"); // Debug
    38. //posY = // ?
    39. }
    40. // Get matrix and draw tile on screen
    41. Matrix matrix = GetMatrix(posX, posY, cellSize, cellSize);
    42. e.Graphics.DrawSprite(aTexture.Texture, matrix);
    43. // GetMatrix Funktion
    44. public Matrix GetMatrix(float CenterX, float CenterY, float Width, float Height)
    45. {
    46. Matrix matrix1 = Matrix.Translation(CenterX, CenterY, 0.0f);
    47. Matrix matrix2 = Matrix.Scaling(Width, Height, 1f);
    48. return Matrix.Identity * Matrix.Translation(-0.5f, -0.5f, 0.0f) * matrix2 * matrix1;
    49. }



    e.DrawingLocations.ScreenPos.X und Y wird so ausgerechnet:
    Spoiler anzeigen

    C#-Quellcode

    1. private Vector2 GetScreenPosition(int x, int y)
    2. {
    3. return new Vector2(x, y) * CellSize + gOriginPosition; // gOriginPosition ist ein Vector2 der aber Zero ist.
    4. }



    Meine endgültige Frage lautet: Wie würde der Code aussehen der das Hintergrund scrolling stoppt wenn der Hintergrund auf der rechten Seite kleiner oder gleich die momentane Breite des Bildschirms hat. Das selbe für die untere Position vom Hintergrund.

    C#-Quellcode

    1. if (topRightCellX <= Game.Resolution.Width) {
    2. //Game.DisplayText("Right is bigger or equal then 1920"); // Debug
    3. //posX = // ?
    4. }
    5. if (bottomRightCellY <= Game.Resolution.Height) {
    6. //Game.DisplayText("Bottom is bigger or equal then 1080"); // Debug
    7. //posY = // ?
    8. }



    Danke für eure Hilfe!
    Wenn ich dir auf irgendeiner Art und Weise helfen konnte, drück doch bitte den "Hilfreich" Button :thumbup:

    Für VB.NET Entwickler: Option Strict On nicht vergessen!
    Ohne mich jetzt in Deinen Code reinwühlen zu wollen: Wie soll es denn aussehen, wenn der Spieler dem Rand näher kommt? Soll sich dann die Spielerposition doch vom Zentrum wegbewegen? Dann musst Du eben genau das tun, würd ich mal behaupten. Also: Wenn Spielfeldrand außerhalb des Bildschirms, dann bewege Speilfeld; sonst bewege Spieler
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    VaporiZed schrieb:

    Wenn Spielfeldrand außerhalb des Bildschirms, dann bewege Speilfeld; sonst bewege Spieler


    Genau richtig!
    Ich hab hier auch ein kleines Video hochgeladen wie es im Moment aussieht.
    Wenn ich dir auf irgendeiner Art und Weise helfen konnte, drück doch bitte den "Hilfreich" Button :thumbup:

    Für VB.NET Entwickler: Option Strict On nicht vergessen!
    Wie man im Video sieht scrollt der Hintergrund nicht weiter nach links da dieser dort endet. Der Hintergrund scrollt aber weiter nach rechts und nach unten da ich mir da noch nicht sicher bin wie ich das angehen soll.

    Dies ist der Code der checkt ob der Hintergrund im Moment über den Bildschirmrand hinweg geht.
    Ganzer Code im ersten Post.

    C#-Quellcode

    1. double topRightCellX = Math.Round(topRightCell.TextureProperties.InitialPosition.X - pedPosX + (cellSize / 2), 0);
    2. double bottomRightCellY = Math.Round(bottomRightCell.TextureProperties.InitialPosition.Y - pedPosY + (cellSize / 2), 0);
    3. if (topRightCellX <= Game.Resolution.Width) {
    4. //Game.DisplayText("Right is bigger or equal then 1920"); // Debug
    5. //posX = // ?
    6. }
    7. if (bottomRightCellY <= Game.Resolution.Height) {
    8. //Game.DisplayText("Bottom is bigger or equal then 1080"); // Debug
    9. //posY = // ?
    10. }

    Wenn ich dir auf irgendeiner Art und Weise helfen konnte, drück doch bitte den "Hilfreich" Button :thumbup:

    Für VB.NET Entwickler: Option Strict On nicht vergessen!
    Was mich verwundert ist die Tatsache, dass sich Spieler UND Hintergrund bewegen. Ich hätte erwartet: entweder, oder. Ich kenn aber auch viele Spiele, da bewegt sich der Spieler einen Teil und danach der Hintergrund, z.B. SoM.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Ja ich muss sagen das ich mir es auch eher vorstelle das der Spieler in der Mitte des Bildschirmes bleibt, also das sich nur der Hintergrund bewegen kann. Ich möchte gerne die Steuerung von GTA 2 nachbauen, und da bleibt der Spieler auch nur in der Mitte. Aber das war erstmal das was ich hinbekommen habe Steuerungsmäßig, und deswegen habe ich sie erstmal drinne gelassen weil sie erstmal ganz akzeptabel ist.
    Wenn ich dir auf irgendeiner Art und Weise helfen konnte, drück doch bitte den "Hilfreich" Button :thumbup:

    Für VB.NET Entwickler: Option Strict On nicht vergessen!