Archive for Oktober, 2010


Zentrierte Rotation mit der SDL

[Note that there is also an English Version of this Tutorial aviable]

Viele Menschen (auch ich vor 1 oder 2 Jahren) benutzen bei ihrem ersten grafischen 2D-Spiel die SDL. (Auch wenn ich das nicht mehr empfehlen würden ;) ). Dabei taucht oft das Problem mit der Rotation auf, die bei der SDL nur unzureichend mitgeliefert wird. Der Ausweg aus dieser Kriese lautet SDL_Gfx, das mit der Rotozoom-Bibliothek eine kleine aber feine Funktionssammlung bietet. Der Wermutstropfen bei der Sache: Die Rotation findet nur um den Linken oberen Eckpunkt statt, was für viele Anwendungen sehr ungeschickt ist. Deshalb habe ich diesen kleinen – aber Feinen – Artikel geschrieben, um euch näherzubringen, dass es eigentlich ganz einfach ist, ein SDL_Surface mit SDL_Gfx zentriert rotieren zu lassen.

Die Theorie

Ein Bild sagt mehr als Tausend Worte:

Danke an saru-online.com für die Grafik

In der Praxis
Das ganze wird in der Praxis wie folgt implementiert. Wie immer hier kommt zuerst der Code, und anschliessend die Erklärung dazu. Der Folgende Source befindet sich in dem Teil eures Quellcodes, in dem ihr euer Objekt rendert, und wird in jedem Frame aufgerufen.
(Hinweis: Ich gehe hier davon aus, dass schon Grundkenntnisse im Umgang mit der SDL vorhanden sind.

 // Vorher Deklarierte Variablen:
 // pTestImg (SDL_Surface*)    Das Surface für das Ausgangsbild
 // TestRect (SDL_Rect)        Das Rect, mit der Eigentlichen Position unseres Objekts
 // Temporäres Surface, auf dem das Rotierte ausgangsbild abgebildet ist
 SDL_Surface* tmp = rotozoomSurface (pTestImg, RotationAngle , 1, 0);
 // Die Positionsverschiebung bei der Rotation ausgleichen
 // Erst an dieser Stelle wird bewirkt, dass die Rotation zentriert aussieht
 SDL_Rect tmprect = TestRect;
 tmprect.x -= tmp->w/2 - pTestImg->w/2;
 tmprect.y -= tmp->h/2 - pTestImg->h/2;
 // Das Surface schlussendlich auf den Screen blitten
 SDL_BlitSurface (tmp, NULL, pScreen, &tmprect);
 SDL_FreeSurface (tmp);

Hinweis: Wenn das Surface Colorkeying verwendet, muss der Colorkey auf ‘tmp’ nochmal angwendet werden !

Doch was geschieht hier eigentlich? Der Funktion rotozoomSurface (aus SDL_Gfx) übergeben wir unser Ausgangssurface, und sie gibt uns eine um Rotation Angle gedrehte Version im Rückgabewert zurück.
In den darauffolgenden Zeilen nehmen wir die nötige Verschiebung der Koordinaten des Objektes vor, wie im Abschnitt 'Theorie' Besprochen.
Danach können wir das temporäre Rotierte Surface einfach auf den Bildschirm blitten (dabei natürlich die temporäre Position angeben), und tata, wenn ihr alles richtig in euer Projekt eingegliedert habt, dann seht ihr jetzt ein Zentriert Rotierendes Surface. Wenn nicht, und ihr glaubt, es liegt an dem Hier stehenden Code, oder etwas ist unzureichend erklärt, scheut euch nicht, euch in den Kommentaren auszulassen.
Kleiner Tipp noch: Wenn sich euer Bild nicht in jedem Frame neu rotiert, kann es Performancetechnisch schneller sein, einfach das Bild zwischenzuspeichern ;)

Euer E333

Quellen

SDL_Gfx Dokumentation

SDL Multimedia Library

Dank gehört zusätzlich ICH1994 für einige wichtige Hinweise. (s. Kommentar #1)

Many People (like me, one or two years ago) use the SDL (Simple Direct Media Layer) at their first steps in 2D game programming. (I wouldn’t recommend it now, but that doesn’t count ;) ). Though the problem arises, how to get things rotating, because the SDL won’t deliver any functions to do that. Fortunally there is additionally another library, only doing such things. The downer though is that SDL_Gfx let’s the primitives rotate around the Upper Left Corner, while many programmers wish their objects rotating around their center. I’ve written this (pretty little) article to help you to easily get around this limitation and point out, how simple it is to get things into rotation ;)

Theory

A Picture tells you more than one thousand words. ;)

Thanks to saru-online.com for the Image

Implementation
First of all you need to link and include SDL_gfx onto your project, but that could you do at your own well :) .
Now i’ll give you my implementation for that, and after the Code i will explain it. The following source will be in the part of your code, in wich you’ll render your Object, being called every frame.
[Hint: I act on the assumption that you're alredy got a little bit of experience with dealing the SDL library.]

 // Variables declared out of this Scope:
 // pTestImg (SDL_Surface*)    The Surface for our Startup Image
 // TestRect (SDL_Rect)        The Rect saving the Position of our Object
 ///////////////////////////////////////
 // Rotate the Image (with RotationAngle as angle) and store the resulting pointer in 'tmp'
 SDL_Surface* tmp = rotozoomSurface (pTestImg, RotationAngle , 1, 0);
 // Equalize the Positionchange from the Rotation
 // The next 3 Lines of code are making our Object  (seem) rotating around the Center and not around the Top Left Corner
 SDL_Rect tmprect = TestRect;
 tmprect.x -= tmp->w/2 - pTestImg->w/2;
 tmprect.y -= tmp->h/2 - pTestImg->h/2;
 // Blit the Temporal Surface onto the Screen (don't forget to place tmprect instead of TestRect in your Blit function Call  )
 SDL_BlitSurface (tmp, NULL, pScreen, &tmprect);
 SDL_FreeSurface (tmp);

Note: If you’re using colorkeyed transparency, you have to set the Colorkey again for ‘tmp’.

So let’s me explain me what happens in this code. The rotozoomSurface Function (from SDL_Gfx) gets our Startup-Surface (the one with the original image of our Object on) and returns us a version which is rotated as much Degrees as in ‘RotationAngle’ Stored around the Top-Left-Corner. Now we have to get them looking like a rotation around the Center of our Object. The next three lines implement the Principle we’ve discussed above in the ‘Theory’ Part.
Finally we blit the temporary and rotated image on the Screen-Surface.
It will be easy to integrate the Above code into your project ;) (hope so^^)
And if you and me did our jobs well, you’ll get an image rotating around his own Center-Point. If not, maybe someone of us made a mistake. (could be mine too), so don’t worry and let me a comment here in which there is the part of your code and a description what happens, and i’ll give my best to help you getting that running. If you find some Translation mistakes or will place grammatical correction or simply will give me your opinion about this article don’t be shy, let me a comment :)

Your E333 (with his first English Article)

References (German):

SDL_Gfx Dokumentation

SDL Multimedia Library

Special Thanks to ICH1994.

Layout umgestellt

Nach langer inaktivität gibt es jetzt endlich mal wieder ein Lebenszeichen von eurem Lieblingsblogger :D

Im Ernst, diese Umstellung des Layouts wird vorraussichtlich dann auch die Endgültige sein, das alte hatte einige Nachteile. Spätestens Morgen werden auch 2 Hilfreiche Tutorials folgen.

Euer E333

Follow

Bekomme jeden neuen Artikel in deinen Posteingang.