Ich spiele mich gerade ein wenig mit JEDI-SDL und bin da nun auf ein Problem gestoßen, welches ich bisher nicht lösen konnte.
Daher hoffe ich nun auf eure Unterstützung.
Laut Dokumentation ist es so, dass man für ein "Surface" (in diesem Fall ist das Surface ein Bild) eine Farbe definieren kann, welche auf dem "Haupt-Surface" (also der "Screen") nicht erscheint. Es wird also Transparent dargestellt.
Das Definieren dieses Bereiches soll mit SDL_SetColorKey() funktionieren, wobei folgende Parameter notwendig sind:
- Surface/Bild welches dargestellt werden soll.
- ein Flag (dessen Sinn sich mir noch nicht erschließt). Laut Dokumentation kann der Wert 0 sein. Damit werden bestehende "Colorkeys" gelöscht - was auch immer damit gemeint ist.
- Die Farbe, welche transparent sein soll im Format key : UInt32
Dazu muss man das Format (also die Auflösung) einer Quelle heranziehen und dann die Farbe in RGB (ähnlich wie oben beschrieben) definieren. Als Format empfiehlt sich der Screen selbst (so ist es zumindest in anderen Wrappern für SDL die ich kenne).
Was ich also habe:
Code: Alles auswählen
var
// SCREEN
screen : PSDL_Surface;
// HINTERGRUNDBILD:
backIMG : PSDL_Surface;
i, j : Integer; // Counter für HintergrundTile
// FIGUR
gbImage : PSDL_Surface;
gbRect : PSDL_Rect;
begin
begin
{
SDL Initialisieren (sofern möglich),
Fenster erzeugen und konfigurieren.
}
if (SDL_Init(SDL_INIT_VIDEO) < 0) then
begin
SDL_Quit;
exit;
end;
SDL_WM_SetCaption('GearBoy Walks on Tiles 01', 'Icon Name');
screen := SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE or SDL_HWACCEL);
if screen = NIL then
begin
halt;
SDL_Quit;
end;
{
Laden des Hintergrundbildes (Tile) und verteilen über den Screen.
Dazu wird ein "RECT" benötigt, welches über eine For-Schleife
auf den genügend oft (in Zusammenhang mit der Screen-Größe)
auf den Bildschirm gemalt wird.
}
backIMG := SDL_LoadBMP('GRASS32x32.bmp');
new(screen_RECT);
screen_RECT^.x:= 0;
screen_RECT^.y:= 0;
for i := 0 to 20 do
begin
for j := 0 to 15 do
begin
screen_RECT^.x := (i * 32);
screen_RECT^.y := (j * 32);
SDL_BlitSurface(backIMG, nil, screen, screen_RECT);
end;
end;
{
GEARBOY LADEN:
}
gbImage:= SDL_LoadBMP('GB_WALK.bmp');
SDL_SetColorKey(gbImage, 0, SDL_MapRGB(screen^.format, 255,0,255));
new(gbRECT);
gbRECT^.x := 0;
gbRect^.y := 0;
gbRect^.w := 32;
gbRect^.h := 48;
{
MAINLOOP
Der Mainloop startet hier:
Erst wird ein Event erzeugt und dieser dann in einer Schleife immer wieder
abgefragt.
Eventverarbeitung:
}
New(mEvent);
While loopstop = False do
begin
if SDL_PollEvent(mEvent) = 1 then // wenn etwas in der Queue ist...
begin
case mEvent^.type_ of
{ Unterscheiden der diversen Events:}
// QUIT (Schließen des Fensters durch klicken auf 'x'
SDL_QUITEV:
begin
loopstop := True;
end;
// Eine Taste wurde gedrückt...
SDL_KEYDOWN:
begin
// welche Taste:
case mEvent^.key.keysym.sym of
SDLK_ESCAPE: loopstop:= True;
SDLK_UP: ;
SDLK_DOWN: ;
SDLK_LEFT: ;
SDLK_RIGHT: ;
end;
end;
end;
end;
{
Zeichnoperationen:
}
SDL_BlitSurface(gbImage, gbRECT, screen, nil);
SDL_Flip(screen);
end;
{
Mainloop endet hier.
}
{
AUFRÄUMEN:
Freigeben der Ressourcen:
}
Dispose(mEvent);
Dispose(screen_RECT);
Dispose(gbRECT);
SDL_FreeSurface(gbImage);
SDL_FreeSurface(backIMG);
SDL_FreeSurface(screen);
SDL_Quit;
end.
So, das ist nun ein wenig viel, aber wenn es jemand testen will, hat er schon was lauffähiges (sofern SDL installiert ist).
Das "Problem", bzw. den Grund, warum es nicht funktioniert vermute ich in diesem Codeabschnitt:
Code: Alles auswählen
gbImage:= SDL_LoadBMP('GB_WALK.bmp');
SDL_SetColorKey(gbImage, 0, SDL_MapRGB(screen^.format, 255,0,255));
Die Transparente Farbe RGB(255,0,255) ist ein hässliches Pink, welches in Sprites für 2D-Spiele üblich ist. Wenn ich das Bild in anderen Sprachen und Game-Libs benutze, funktioniert es einwandfrei.
Ein Fehler des Bildes kann also ausgeschlossen werden.
Ich hatte ein paar mal WriteLn() eingebaut, um zu sehen, was die Funktionen so zurückgeben, und konnte auch dort nirgends einen Fehler meinerseits ausmachen.
Kann mir von euch jemand auf die Sprünge helfen, oder kennt jemand eine Lösung?
Was mache ich falsch?
Hier noch die verwendeten Bilder:
Wie ihr am letzten Bild sehen könnt, habe ich das Problem nur mit Lazarus, was bestätigt, dass es an meinem Code liegen muss und die Bilder fehlerfrei sind.