SDL: pixel löschen? <-gelöst!
-
Hallo miteinander,
ich hätte da folgendes Problem in SDL. Ich schreibe gerade einen MapEditor für mein Spiel. Es werden 2 Surfaces erstellt, ein Hintergrund wird auf den Screen kopiert und der Screen wird halb transparent.
SDL_Surface* screen = SDL_SetVideoMode(640, 480, 16, SDL_HWSURFACE|SDL_DOUBLEBUF); SDL_Surface* background = IMG_Load("./maps/hockenheim/Map.png"); SDL_BlitSurface(background, 0, screen, 0); SDL_SetAlpha(screen, SDL_SRCALPHA|SDL_RLEACCEL, 128); SDL_Flip(screen);
So, der User soll nun mit der linken Maustaste auf dem Screen Punkte markieren können und mit einem Rechtsklick wieder löschen können. Ersteres habe ich mit folgendem Code realisiert:
SDL_FillRect(screen, &tmpRect, 0xff0000ff); SDL_UpdateRect(screen, tmpRect.x, tmpRect.y, tmpRect.w, tmpRect.h);
Letzteres mit
SDL_FillRect(screen, &tmpRect, 0xff000000); SDL_UpdateRect(screen, tmpRect.x, tmpRect.y, tmpRect.w, tmpRect.h);
Es wird beim löschen eines markierten Punktes also der entsprechende Punkt wieder voll transparent gemacht.
Es funktioniert auch so, dass auf den Bildschirm nichts gezeichnet wird, wenn ich mit der rechten Maustaste male. Will ich aber einen bereits markierten Punkt damit löschen, wird der Punkt nur dunkler, wird aber nicht voll transparent. Mit den Farbwerten habe ich schon rumgespielt, da hilft irgendwie nichts.Schonmal tausend Dank für jede Hilfe.
-
Hat niemand eine Vermutung, woran das liegen könnte? Oder einen Hinweis, wie ich es anders umsetzen kann, dass auf einem Bild Punkte markiert und gelöscht werden können (markierte Punkte halb transparent darstellen)?
Soll ich vielleicht mal den kompletten Code posten?
Bitte helft mir. Danke.
-
Okay, ich hab
s gelöst, wenn auch vielleicht nicht ganz elegant. Aber warum mein ursprünglicher Ansatz nicht funktioniert, ist mir immer noch ein Rätsel. Wen
s interessiert, bin jetzt folgendermaßen vorgegangen:Die Map, die editiert werden soll, wird auf den Screen kopiert und bildet damit den "background". Eine Kopie davon wird in "theMap" gespeichert. Gezeichnet bzw. Punkte markiert werden dann auf dem background, welcher vorher noch halb transparent gemacht wird, damit das ganze auch was aussieht bzw man sieht, wo man eigentlich genau einen Punkt markiert. Soll ein Punkt wieder gelöscht werden, wird von der Kopie (theMap) der Teil, der wieder gelöscht werden soll, kopiert. Wie gesagt, warum das transparent machen nicht funktioniert, warum sich nur die Farbe ändert, ist mir weiterhin ein Rätsel.
SDL_Surface* screen = SDL_SetVideoMode(640,480,16,SDL_HWSURFACE|SDL_DOUBLEBUF); SDL_Surface* background = IMG_Load("./maps/hockenheim/Map.png"); SDL_BlitSurface(background, 0, screen, 0); SDL_Flip(screen); SDL_SetAlpha(background, SDL_SRCALPHA|SDL_RLEACCEL, 128); SDL_Surface* theMap = IMG_Load("./maps/hockenheim/Map.png");
Punkt markieren:
SDL_FillRect(background, &tmpRect, 0xff00ffff); SDL_BlitSurface(background, &tmpRect, screen, &tmpRect); SDL_UpdateRect(screen, tmpRect.x, tmpRect.y, tmpRect.w, tmpRect.h);
Markierten Punkt wieder löschen:
SDL_BlitSurface(theMap, &tmpRect, screen, &tmpRect); SDL_UpdateRect(screen, tmpRect.x, tmpRect.y, tmpRect.w, tmpRect.h);
-
Täusche ich mich oder hast du keine Trennung zwischen Logik und Grafik gemacht? Bei so einer Arbeit würde ich das definitiv empfehlen.
Mach aus der Map Tiles, die die verschiedenen Bereiche darstellen. Aus dem Dateinamen schließe ich, dass es was mit Autorennspiel zu tun hat? Dann kannst du die Tiles in Strecke, Rand, Gras daneben einteilen.Der Benutzer bearbeitet dann nur noch die Tiles an sich, nicht mehr die Grafik selbst. Mit verschiedenen Tilesets könntest du dann eine Strecke von Europa in die Wüste verlegen, indem du den Tiles einfach andere Grafiken zuordnest.
-
Im Grunde würde ich dir zustimmen, aber es handelt sich hier genau genommen um ein Vektor-Rennspiel. Erklärung: http://de.wikipedia.org/wiki/Racetrack.
Eine Trennung von Grafik und Logik empfand ich hier als nicht notwendig, da der User um eine neue Strecke zu erstellen sich einfach in GIMP oder was auch immer eine Strecke malt, wie`s ihm passt und im MapEditor dann nur noch auf dem darüber gelegten Raster markieren muss, welche Punkte auf der Strecke liegen. Ggf werden später noch Ölflecken oder ähnliches implementiert. Ja, das war so die Idee dahinter.
-
Interessante Spielidee!
Aber ansich ja auch kein Problem, das so umzusetzen. Dann sind deine Tiles halt nur 1x1 Pixel groß
Vorschlag:
Arbeite nicht direkt auf dem Bild. Erstelle dir ein 2D-Array mit bool oder int (je nachdem, wie deine Anforderungen sind). Gehen wir mal aus, dass true befahrbar und false nicht befahrbar sind.
Die Dimensionen des Arrays sind dann einfach gleich den Dimensionen des Bildes, mit 1:1 Umsetzung von Pixel nach bool.Nun zeichnest du zunächst den Hintergrund ganz normal in eine Surface. Dann bastelst du dir eine zweite Surface, in der nun passend zum 2D-Array der Alphawert und die Farbe auf von dir gewünschte Werte gesetzt werden, z.B. Alpha = 0 für befahrbar und Alpha = 128 und Farbe = rot für nicht befahrbar.
Das blittest du einfach drüber. Den Rest sollte SDL ja selbst machen (keine Ahnung, was genau das alles kann, habe es nie genutzt).Wenn der User den linken Button betätigt, suchst du dir die Koordinaten aus dem Bild raus und kannst ohne wildes Umrechnen (dank 1:1 Zuordnung) den Wert im Array auf true setzen (oder false). Mit rechtem Button dann andersherum.
Ich würde Abstand davon nehmen, die Grafik als Logik heranzuziehen. Lass deine Benutzereingaben nie die Grafik direkt manipulieren, sondern nur ein Modell in deinem Programm. Die Grafik ergibt sich dann aus dem Modell.
Ist einfach sauberer und ermöglicht dir, mehr daraus zu machen. Z.B. könntest du das Array auch aus Integerwerten bestehen lassen. Jeder Punkt nimmt einen gewissen Wert an, z.B. 0 für unbefahrbar, 1 für normale Strecke, 2 für Ölfleck, 3 für sandigen Rand mit größerem Drift, 4 für Pfützen mit Aquaplaning,...Dann besteht deine Map im besten Falle aus einem Bild, dass den Hintergrund darstellt, und einem 2D-Array, dass die Befahrbarkeit und weitere Informationen zeigt.
-
Vielen Dank für den gut gemeinten Rat, aber genau so hatte ich es schon umgesetzt Tschuldige, wenn meine zuvorige Nachricht hier für Verwirrung gesorgt hat.
-
Dann ist alles gut.
Das war mir irgendwie nach deinen Ausführungen nicht ganz klar.