Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Objekte drehen (https://www.delphipraxis.net/77423-objekte-drehen.html)

Mischn 19. Sep 2006 12:40


Objekte drehen
 
Ich möchte ein Spiel programmieren, in dem man ein Objekt, wie z.B: ein Image durch einen Tastendruck um einen bestimmten Winkel (um die eigene Achse) drehen kann. Wie soll ich das anstellen? :gruebel:

mkinzler 19. Sep 2006 12:48

Re: Objekte drehen
 
In dem du das Bild drehst oder verschiedene Bilder im gedrehten Zustand nimmst.

Mischn 19. Sep 2006 12:52

Re: Objekte drehen
 
Zitat:

Zitat von mkinzler
In dem du das Bild drehst oder verschiedene Bilder im gedrehten Zustand nimmst.

Wie drehen?

Der_Unwissende 19. Sep 2006 12:58

Re: Objekte drehen
 
Zitat:

Zitat von Mischn
Ich möchte ein Spiel programmieren, in dem man ein Objekt, wie z.B: ein Image durch einen Tastendruck um einen bestimmten Winkel (um die eigene Achse) drehen kann. Wie soll ich das anstellen? :gruebel:

Hi,
du gibst ehrlich gesagt etwas wenig Informationen raus. Ist ein Image ein Beispiel oder möchtest du mit einem Image arbeiten? Und wenn du mit einem Image arbeitest, was verstehst du dann unter einem Objekt? Möchtest du wirklich das gesamte Image drehen?

Was Spiele angeht, so werden die ja im Moment gerne für die Schnittstellen DirectX oder OpenGL geschrieben (greifen auf diese zurück). Diese bieten auch was 2D angeht jede Menge Funktionen, vorallem findest du hier schon alles zum Rotieren von Körpern.

Was das rotieren von Bildern (insbesondere Bitmaps) angeht, so musst du nur die Suche bemühen.

Gruß Der Unwissende

mkinzler 19. Sep 2006 13:03

Re: Objekte drehen
 
Hier im Forum suchenBitmap drehen

inherited 19. Sep 2006 13:14

Re: Objekte drehen
 
Schau dir f+ür deinen Zweck lieber mal Bei Google suchenDelphiX an. Damit kann man Bilder sehr viel einfacher und CPU-Freundlicher drehen.
TImageSpriteEx beherbergt die eigenschaft "Angle" welche einfach verändert werden kann.

generic 19. Sep 2006 13:37

Re: Objekte drehen
 
in der gdi+ sind (sogar schnelle) drehroutinen drin.

Mischn 19. Sep 2006 17:42

Re: Objekte drehen
 
OK, werd ich machen! :thumb:

Hawkeye219 19. Sep 2006 18:54

Re: Objekte drehen
 
Hallo Mischn,

falls du am Anfang auf GDI+ und DelphiX verzichten möchtest, kannst du auch mit dem "alten" GDI eine Bitmap drehen:

Delphi-Quellcode:
// uses Math (SinCos)

// zeichnet eine verdrehte Bitmap auf einem Canvas
// aAngle ist der Drehwinkel im Uhrzeigersinn in Grad
// aOffsetX, aOffsetY gibt den Offset für das Zeichnen an

procedure DrawRotatedBitmap (aCanvas: TCanvas; aBitmap: TBitmap;
                             aAngle: Double; aOffsetX, aOffsetY: Integer);
var
  svMode: Integer;
  Mat, svMat: tagXFORM;
  si, co: Extended;
begin
  // aktuellen Zustand retten
  svMode := SetGraphicsMode(aCanvas.Handle, GM_ADVANCED);
  if (svMode = GM_ADVANCED) then
    GetWorldTransform(aCanvas.Handle, svMat);
  // Verschiebung in den Usprung
  FillChar (Mat, SizeOf(Mat), 0);
  Mat.em11 := 1.0;
  Mat.em22 := 1.0;
  Mat.eDx := -(aOffsetX + aBitmap.Width / 2);
  Mat.eDy := -(aOffsetY + aBitmap.Height / 2);
  SetWorldTransform(aCanvas.Handle, Mat);
  // Verdrehung
  SinCos (aAngle * Pi / 180, si, co);
  FillChar (Mat, SizeOf(Mat), 0);
  Mat.em11 := co;
  Mat.em12 := si;
  Mat.em21 := -si;
  Mat.em22 := co;
  ModifyWorldTransform(aCanvas.Handle, Mat, MWT_RIGHTMULTIPLY);
  // Zurückschieben
  FillChar (Mat, SizeOf(Mat), 0);
  Mat.em11 := 1.0;
  Mat.em22 := 1.0;
  Mat.eDx := (aOffsetX + aBitmap.Width / 2);
  Mat.eDy := (aOffsetY + aBitmap.Height / 2);
  ModifyWorldTransform(aCanvas.Handle, Mat, MWT_RIGHTMULTIPLY);
  // Bitmap zeichnen
  aCanvas.Draw(aOffsetX, aOffsetY, aBitmap);
  // alten Zustand wiederherstellen
  if (svMode = GM_ADVANCED) then
    SetWorldTransform(aCanvas.Handle, svMat)
  else
    SetGraphicsMode(aCanvas.Handle, svMode);
end;
Gruß Hawkeye

torud 1. Nov 2006 10:53

Re: Objekte drehen
 
Wie funktioniert das Ganze mit PNG???

Habe schon versucht BMP.Assign := blabla, aber es funzt einfach nicht...

Hawkeye219 1. Nov 2006 11:39

Re: Objekte drehen
 
Hallo Tom,

ich habe den Code so abgeändert, daß er mit beliebigen TGraphic-Nachfolgern arbeiten sollte.

Delphi-Quellcode:
// uses Math (SinCos)

// zeichnet eine verdrehte Grafik auf einem Canvas
// aAngle ist der Drehwinkel im Uhrzeigersinn in Grad
// aOffsetX, aOffsetY gibt den Offset für das Zeichnen an

procedure DrawRotatedGraphic (aCanvas: TCanvas; aGraphic: TGraphic;
                              aAngle: Double; aOffsetX, aOffsetY: Integer);
var
  svMode: Integer;
  Mat, svMat: tagXFORM;
  si, co: Extended;
begin
  // aktuellen Zustand retten
  svMode := SetGraphicsMode(aCanvas.Handle, GM_ADVANCED);
  if (svMode = GM_ADVANCED) then
    GetWorldTransform(aCanvas.Handle, svMat);
  // Verschiebung in den Usprung
  FillChar (Mat, SizeOf(Mat), 0);
  Mat.em11 := 1.0;
  Mat.em22 := 1.0;
  Mat.eDx := -(aOffsetX + aGraphic.Width / 2);
  Mat.eDy := -(aOffsetY + aGraphic.Height / 2);
  SetWorldTransform(aCanvas.Handle, Mat);
  // Verdrehung
  SinCos (aAngle * Pi / 180, si, co);
  FillChar (Mat, SizeOf(Mat), 0);
  Mat.em11 := co;
  Mat.em12 := si;
  Mat.em21 := -si;
  Mat.em22 := co;
  ModifyWorldTransform(aCanvas.Handle, Mat, MWT_RIGHTMULTIPLY);
  // Zurückschieben
  FillChar (Mat, SizeOf(Mat), 0);
  Mat.em11 := 1.0;
  Mat.em22 := 1.0;
  Mat.eDx := (aOffsetX + aGraphic.Width / 2);
  Mat.eDy := (aOffsetY + aGraphic.Height / 2);
  ModifyWorldTransform(aCanvas.Handle, Mat, MWT_RIGHTMULTIPLY);
  // Bitmap zeichnen
  aCanvas.Draw(aOffsetX, aOffsetY, aGraphic);
  // alten Zustand wiederherstellen
  if (svMode = GM_ADVANCED) then
    SetWorldTransform(aCanvas.Handle, svMat)
  else
    SetGraphicsMode(aCanvas.Handle, svMode);
end;
Gruß Hawkeye

torud 1. Nov 2006 12:17

Re: Objekte drehen
 
Funzt schon ganz gut, aber das mit der Transparenz klappt leider nicht. Ich habe in Image2 ein Transparentes PNG, welches ich dann in Image1.Canvas gedreht zeichnen lasse, und danach sogar noch tranparent auf True stelle, aber er ignoriert das Ganze.

Im Anhang, ich hoffe, es klappt, mal das Projekt.

Upload geht bei mir heute schon den ganzen Tag nicht.

Der Download des Projektes

Luckie 20. Feb 2007 13:10

Re: Objekte drehen
 
Ich wende Hawkeyes Methode aus beitrag #9 an, um ein Bitmap zu drehen. Aufrufen tue ich die Prozedur folgendermaßen:
Delphi-Quellcode:
var
  BmpSrc, BmpDest  : TBitmap;
begin
  BmpSrc := TBitmap.Create;
  BmpDest := TBitmap.Create;
  try
    BmpSrc.Width := ImageEnVect1.layers[ImageEnVect1.LayersCurrent].Width;
    BmpSrc.Height := ImageEnVect1.layers[ImageEnVect1.LayersCurrent].Height;
    BmpDest.Width := ImageEnVect1.layers[ImageEnVect1.LayersCurrent].Width;
    BmpDest.Height := ImageEnVect1.layers[ImageEnVect1.LayersCurrent].Height;
    BmpSrc.Assign(ImageEnVect1.Bitmap);
    DrawRotatedBitmap(BmpSrc.Canvas, BmpDest, 10.0, , 0);
    ImageEnVect1.Bitmap.Assign(BmpDest);
    ImageEnVect1.Update;
  finally
    BmpSrc.Free;
    BmpDest.Free;
  end;
end;
Aber das Image innerhalb des Layers verschindet nur. Irgendwas mache ich da wohl noch falsch.

Hawkeye219 20. Feb 2007 13:19

Re: Objekte drehen
 
Hast du nicht Quelle und Ziel vertauscht?

Delphi-Quellcode:
procedure DrawRotatedBitmap (aCanvas: TCanvas; aBitmap: TBitmap;
                             aAngle: Double; aOffsetX, aOffsetY: Integer);
aCanvas ist der Ziel-Canvas, aBitmap das Quell-Bitmap.

Gruß Hawkeye

Luckie 20. Feb 2007 13:39

Re: Objekte drehen
 
So rum hatte ich es auch schon mal, das Resultat ist das gleiche.

Cöster 20. Feb 2007 15:04

Re: Objekte drehen
 
Zitat:

Zitat von Luckie
Delphi-Quellcode:
DrawRotatedBitmap(BmpSrc.Canvas, BmpDest, 10.0, , 0);

Zwischen den beiden letzten Kommata fehlt doch die Zahl für's X-Offset, oder ist das nur'n Copy'n'Paste-Fehler?

x000x 20. Feb 2007 21:43

Re: Objekte drehen
 
Moin Luckie,

Pixelformat vom Ziel auf 24 Bit setzen hat bei mir funktioniert. Ich kann nur nicht erklären warum:
Delphi-Quellcode:
var
  BmpSrc, BmpDest  : TBitmap;
begin
  BmpSrc := TBitmap.Create;
  BmpDest := TBitmap.Create;
  try
    BmpSrc.Assign(ImageEnVect1.Bitmap);

    BmpDest.Width      := ImageEnVect1.layers[ImageEnVect1.LayersCurrent].Width;
    BmpDest.Height     := ImageEnVect1.layers[ImageEnVect1.LayersCurrent].Height;
    BmpDest.PixelFormat := pf24bit;

    DrawRotatedBitmap(BmpDest.Canvas, BmpSrc, 10.0, 0, 0);

    ImageEnVect1.Bitmap.Assign(BmpDest);
    ImageEnVect1.Update;
  finally
    BmpSrc.Free;
    BmpDest.Free;
  end;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:20 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz