XNA - Gedrehtes Rechteck

  • Allgemein

Es gibt 19 Antworten in diesem Thema. Der letzte Beitrag () ist von SystemUnknow.

    XNA - Gedrehtes Rechteck

    Hallo zusammen;
    für ein aktuelles XNA Spiel von mir brauche ich die Möglichkeit, ein Rechteck für die Kollisionsüberprüfung gedreht abzuspeichern. Wie mache ich das? Mit einem Polygon? Wenn ja, wie überprüfe ich eine Kollision von diesen?
    Vielen Dank,
    TheoTechnic
    Ich hab hier Code für Rect Erkennung mit anschließender per Pixel..
    Nur ganz verstanden hab ich den noch nicht bezüglich

    Vector3
    Matrix
    Matrix.transform

    Werde mich morgen mal einlesen (brauche auch per Pixel) und hoffe ich kapier es ^^
    Falls nicht wäre ich an einem Eintrag in deinem Blog über dieses Thema interessiert ^^


    Hier der Code:

    VB.NET-Quellcode

    1. // Person
    2. Rectangle personRectangle =
    3. new Rectangle((int)personPosition.X, (int)personPosition.Y,
    4. personTexture.Width, personTexture.Height);
    5. // Build the block's transform
    6. Matrix blockTransform =
    7. Matrix.CreateTranslation(new Vector3(-blockOrigin, 0.0f)) *
    8. // Matrix.CreateScale(block.Scale) * would go here
    9. Matrix.CreateRotationZ(blocks[i].Rotation) *
    10. Matrix.CreateTranslation(new Vector3(blocks[i].Position, 0.0f));
    11. // Calculate the bounding rectangle of this block in world space
    12. Rectangle blockRectangle = CalculateBoundingRectangle(
    13. new Rectangle(0, 0, blockTexture.Width, blockTexture.Height),
    14. blockTransform);
    15. // The per-pixel check is expensive, so check the bounding rectangles
    16. // first to prevent testing pixels when collisions are impossible.
    17. if (personRectangle.Intersects(blockRectangle))
    18. {
    19. // Check collision with person
    20. if (IntersectPixels(personTransform, personTexture.Width,
    21. personTexture.Height, personTextureData,
    22. blockTransform, blockTexture.Width,
    23. blockTexture.Height, blockTextureData))
    24. {
    25. personHit = true;
    26. }
    27. }
    28. public static bool IntersectPixels(Rectangle rectangleA, Color[] dataA,
    29. Rectangle rectangleB, Color[] dataB)
    30. {
    31. // Find the bounds of the rectangle intersection
    32. int top = Math.Max(rectangleA.Top, rectangleB.Top);
    33. int bottom = Math.Min(rectangleA.Bottom, rectangleB.Bottom);
    34. int left = Math.Max(rectangleA.Left, rectangleB.Left);
    35. int right = Math.Min(rectangleA.Right, rectangleB.Right);
    36. // Check every point within the intersection bounds
    37. for (int y = top; y < bottom; y++)
    38. {
    39. for (int x = left; x < right; x++)
    40. {
    41. // Get the color of both pixels at this point
    42. Color colorA = dataA[(x - rectangleA.Left) +
    43. (y - rectangleA.Top) * rectangleA.Width];
    44. Color colorB = dataB[(x - rectangleB.Left) +
    45. (y - rectangleB.Top) * rectangleB.Width];
    46. // If both pixels are not completely transparent,
    47. if (colorA.A != 0 && colorB.A != 0)
    48. {
    49. // then an intersection has been found
    50. return true;
    51. }
    52. }
    53. }
    54. // No intersection found
    55. return false;
    56. }

    Quelle: Leider k.A. hab den Code schon lange, müsste aber Microsoft(c) sein.

    Eistee schrieb:


    VB.NET-Quellcode

    1. //Person
    2. Rectangle personRectangle =
    3. new Rectangle((int)personPosition.X, (int)personPosition.Y,
    4. personTexture.Width, personTexture.Height);
    5. // Build the block's transform
    6. Matrix blockTransform =
    7. Matrix.CreateTranslation(new Vector3(-blockOrigin, 0.0f)) *
    8. // Matrix.CreateScale(block.Scale) * would go here
    9. Matrix.CreateRotationZ(blocks[i].Rotation) *
    10. Matrix.CreateTranslation(new Vector3(blocks.Position, 0.0f));
    11. // Calculate the bounding rectangle of this block in world space
    12. Rectangle blockRectangle = CalculateBoundingRectangle(
    13. new Rectangle(0, 0, blockTexture.Width, blockTexture.Height),
    14. blockTransform);


    Hier blick ich nicht ganz durch (das andere kenn ich schon ;)). Man kann doch in einem Rectangle kein transformiertes (sprich rotiertes) Rectangle abspeichern?!
    Soweit ich das verstanden habe wird da einfahc ein Rechteck um das Transformierte Objekt gelegt und damit geprüft.

    Nach jeder Transformation wird das Rechteck neu um das Objekt gelegt, darauf folgt immer die Rechteck-Rechteck Prüfung und wenn diese Interagieren, wird innerhalb dieser Fläche auf die Transparenz getestet.
    Achso ;) Dann bleibt nur noch das Problem, wie ich die Texture2D drehe, da sie ja nur gedreht gezeichnet wird (bei PerPixel würde sie ja dann in der Ausgangsposition, also nicht rotiert, genommen werden)

    Vielen Dank bisher :)
    TheoTechnic
    alle pixel auslesen in array schreiben und dann einfach rotieren, Polarkoordinaten dürften helfen(Wobei das eigt. dasselbe ist wie aus der Schule Trigonometrie - 9te Klasse?!)...
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---

    TheoTechnic schrieb:

    Achso ;) Dann bleibt nur noch das Problem, wie ich die Texture2D drehe


    Hab damit noch nciht gearbeitet und auch nur überflogen und bin mir nicht sicher ^^
    aber wird hier unter "Build the block's transform" (Edit habs mal übersetzt ^^) das 2D Sprite nicht gedreht?
    Position ist Vector3 und damit kannste die z-achse manipulieren um so das Sprite zu drehen.

    Also wenn ich mich nicht ganz irre. Code:

    Esit:

    Ich such heute abend mal das ganze Projekt raus.
    Denn es scheit so als ob da noch etwas fehlt.


    VB.NET-Quellcode

    1. // Das Sprite2D drehen
    2. Matrix blockTransform =
    3. Matrix.CreateTranslation(new Vector3(-blockOrigin, 0.0f)) *
    4. // Matrix.CreateScale(block.Scale) * would go here
    5. Matrix.CreateRotationZ(blocks[i].Rotation) *
    6. Matrix.CreateTranslation(new Vector3(blocks[i].Position, 0.0f));
    7. // Berechnen des Rechtecks für das gedrehte Sprite2D
    8. Rectangle blockRectangle = CalculateBoundingRectangle(
    9. new Rectangle(0, 0, blockTexture.Width, blockTexture.Height),
    10. blockTransform);

    jvbsl schrieb:

    alle pixel auslesen in array schreiben und dann einfach rotieren, Polarkoordinaten dürften helfen(Wobei das eigt. dasselbe ist wie aus der Schule Trigonometrie - 9te Klasse?!)...

    Dafür müsste man halt in der 9. Klasse sein :D

    @ Eistee: Wie kann ich jetzt aber meine Texture2D mit dem Matrix verändern? Steh grad ein bisschen auf dem Schlauch ^^
    HAHAH :D

    Ich liebe XNA, ist einfach das beste!
    Um 2D Sprites zu drehen einfach 3 Parameter mehr angeben! Der Hammer!

    spriteBatch.Draw(Sprite, TargetRect, SourceRect, Color.White, Winkel, Origin, SpriteEffects.None), Layer)

    Winkel = Muss in Radiant angegeben werden!
    Origin = Punkt um den gedreht werden soll! Wird als Vector2 angegeben!
    SpriteEffects = Hier kann man den Sprite Horizointal oder Vertikal kippen!
    Layer = Standart ist 0.0f

    Tipp: Zum umrechnen von Winkel in Radiant: Winkel = MathHelper.ToRadians(90) '90° Winkel wird in Radiant umgerechnet.

    Ein Hoch auf das XNA Framework :thumbsup:
    Also ich habe noch nie mehr wie die Color Parameter gebraucht :D
    Und ich finde die Klamotten erst wenn ich dannach suche!

    wie man die Texture2D für die pixelgenaue Kollision drehen kann
    nicht, wie man sie gedreht darstellt -.-

    Das eine baut doch auf dem anderen auf!

    1. Sprite wird rotiert dargestellt
    2. Rechteck drum
    3. Wenn Rechteck vom Spieler sich mit Rechteck vom AutoXY berührt

    Wird das Feld für die Per Pixel ermittelt

    VB.NET-Quellcode

    1. int top = Math.Max(rectangleA.Top, rectangleB.Top);
    2. int bottom = Math.Min(rectangleA.Bottom, rectangleB.Bottom);
    3. int left = Math.Max(rectangleA.Left, rectangleB.Left);
    4. int right = Math.Min(rectangleA.Right, rectangleB.Right);


    Dan mit 2 For Next wird jeder Pixel der mit sich interagierenden Objekte auf die Transparenz überprüft.
    Wenn eins der beiden Pixel nicht zu 100% Transparent ist, hat es gekracht.

    Da sind zwar noch ein paar Schritte dazwischen wie z.B. das Color Array mit den Daten der 2 Objekte füllen und so weiter, aber das kannste am Projekt selber besser erkennen. Vorallem weil ich mir nicht zu 100% sicher bin ob ich alles 'richtig' verstanden habe. :rolleyes:

    Im anhand das Projekt (C#).
    Dateien

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Eistee“ ()