Mam to 800x600square Chcę narysować na ekranie. Chcę "wyciąć" kółka (gdzie alfa będzie wynosić 0). Zasadniczo rysuję cały prostokąt na mapie, więc w tych "okręgach", które narysowałem, możesz zobaczyć mapę, w przeciwnym razie zobaczysz szary kwadratSDL - rysowanie kół "negatywnych" (Mgła wojny)
Odpowiedz
Zakładam więc, że próbujesz dodać mgłę wojny do jedna z was gra?
Miałem małe demo, które zrobiłem dla lokalnego Uniwersytetu kilka tygodni temu, aby pokazać ścieżkę A *, więc pomyślałem, że mógłbym dodać do ciebie mgłę wojny. Oto wyniki:
Początkowa mapa
pierwsze, należy uruchomić z pełną mapą, całkowicie widocznym
mgła
Następnie dodałem powierzchnię zakryj cały ekran (zauważ, że moja mapa jest mniejsza niż ekran, więc w tym przypadku dodałem tylko mgłę wojny na sc reen, ale jeśli przewijanie, upewnij się, że obejmuje każdy piksel map 1: 1)
mFogOfWar = SDL_CreateRGBSurface(SDL_HWSURFACE, in_Width, in_Height, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
SDL_Rect screenRect = {0, 0, in_Width, in_Height};
SDL_FillRect(mFogOfWar, &screenRect, 0xFF202020);
Następnie trzeba go wyciągnąć ... dodałem tego połączenia po pobraniu gry i obiektów przed wyciągnięciem UI
DrawSurface(mFogOfWar, 0, 0);
Gdzie
void RenderingManager::DrawSurface(SDL_Surface* in_Surface, int in_X, int in_Y)
{
SDL_Rect Dest = { in_X, in_Y, 0, 0 };
SDL_BlitSurface(in_Surface, NULL, mScreen, &Dest);
}
które powinno dać następujący wynik:
"Poncz Surface"
Potem stworzył 32 bitów .png
że wygląda następująco (szachownica pokazuje alfa)
Podczas renderowania moją bohaterkę, dodałem do tej rozmowy :
gRenderingManager.RemoveFogOfWar(int(mX) + SPRITE_X_OFFSET, int(mY) + SPRITE_Y_OFFSET);
Przesunięcie jest tylko tam, aby wycentrować cios duszkiem, w zasadzie to, co przechodzę do RemoveFogOfWar
jest centrum mojego duszka.
Usuń Fog of War
Teraz mięso mgle wojny. Zrobiłem dwie wersje, z których mgła wojny została usunięta na stałe, a druga, w której mgła wojny jest resetowana. Reset mojej mgły wojennej opiera się na mojej powierzchni punch
, aby uzyskać kontur, w którym alfa jest resetowany do 0
, a fakt, że mój znak porusza się o mniej pikseli niż kontur zawiera na ramkę, w przeciwnym razie zachowałbym Rect
, w którym zastosowano uderzenie i Uzupełniam go, zanim znów zacznę nowy cios.
Ponieważ nie mogłem znaleźć "mnogiej" mieszanki z SDL, postanowiłem napisać prostą funkcję, która iteruje na powierzchni stempla i aktualizuje alfa na mgle powierzchni wojny. Najważniejszą częścią jest, aby upewnić się pozostać w granicach swoich powierzchniach, dzięki czemu zajmuje większość kodu ... nie mogą być pewne funkcje crop ale nie przeszkadzało sprawdzanie:
void RenderingManager::RemoveFogOfWar(int in_X, int in_Y)
{
const int halfWidth = mFogOfWarPunch->w/2;
const int halfHeight = mFogOfWarPunch->h/2;
SDL_Rect sourceRect = { 0, 0, mFogOfWarPunch->w, mFogOfWarPunch->h };
SDL_Rect destRect = { in_X - halfWidth, in_Y - halfHeight, mFogOfWarPunch->w, mFogOfWarPunch->h };
// Make sure our rects stays within bounds
if(destRect.x < 0)
{
sourceRect.x -= destRect.x; // remove the pixels outside of the surface
sourceRect.w -= sourceRect.x; // shrink to the surface, not to offset fog
destRect.x = 0;
destRect.w -= sourceRect.x; // shrink the width to stay within bounds
}
if(destRect.y < 0)
{
sourceRect.y -= destRect.y; // remove the pixels outside
sourceRect.h -= sourceRect.y; // shrink to the surface, not to offset fog
destRect.y = 0;
destRect.h -= sourceRect.y; // shrink the height to stay within bounds
}
int xDistanceFromEdge = (destRect.x + destRect.w) - mFogOfWar->w;
if(xDistanceFromEdge > 0) // we're busting
{
sourceRect.w -= xDistanceFromEdge;
destRect.w -= xDistanceFromEdge;
}
int yDistanceFromEdge = (destRect.y + destRect.h) - mFogOfWar->h;
if(yDistanceFromEdge > 0) // we're busting
{
sourceRect.h -= yDistanceFromEdge;
destRect.h -= yDistanceFromEdge;
}
SDL_LockSurface(mFogOfWar);
Uint32* destPixels = (Uint32*)mFogOfWar->pixels;
Uint32* srcPixels = (Uint32*)mFogOfWarPunch->pixels;
static bool keepFogRemoved = false;
for(int x = 0; x < destRect.w; ++x)
{
for(int y = 0; y < destRect.h; ++y)
{
Uint32* destPixel = destPixels + (y + destRect.y) * mFogOfWar->w + destRect.x + x;
Uint32* srcPixel = srcPixels + (y + sourceRect.y) * mFogOfWarPunch->w + sourceRect.x + x;
unsigned char* destAlpha = (unsigned char*)destPixel + 3; // fetch alpha channel
unsigned char* srcAlpha = (unsigned char*)srcPixel + 3; // fetch alpha channel
if(keepFogRemoved == true && *srcAlpha > 0)
{
continue; // skip this pixel
}
*destAlpha = *srcAlpha;
}
}
SDL_UnlockSurface(mFogOfWar);
}
Która następnie dał mi to z keepFogRemoved = false
nawet po postać przeniosła się wokół
a to z keepFogRemoved = true
Validation
Ważną częścią jest naprawdę, aby upewnić się, że nie napisać poza swoim buforze pikseli, więc uważaj z negatywnymi przesunięcia lub offsetu, która wyprowadzi was z tej szerokości lub wysokości. Aby potwierdzić mój kod, dodałem prostego połączenia do RemoveFogOfWar
gdy mysz jest kliknął i próbował narożniki i krawędzie, aby upewnić się, że nie mają „off przez jeden” problem
case SDL_MOUSEBUTTONDOWN:
{
if(Event.button.button == SDL_BUTTON_LEFT)
{
gRenderingManager.RemoveFogOfWar(Event.button.x, Event.button.y);
}
break;
}
Uwagi
Oczywiście do "uderzenia" nie potrzeba tekstury 32-bitowej, ale był to najczystszy sposób, w jaki mogłem wymyślić, jak to zrobić. Można to zrobić, używając tylko 1 bit na piksel (wł./Wył.). Można też dodać trochę gradientu i zmień
if(keepFogRemoved == true && *srcAlpha > 0)
{
continue; // skip this pixel
}
do czegoś
if(*srcAlpha > *destAlpha)
{
continue;
}
Aby utrzymać sprawne połączenie takiego:
3 State Fog of War
I pomyślałem, że powinienem dodać ... Dodałem sposób na stworzenie 3 państwowej mgły wojny: visible
, seen
i fogged
.
Aby to zrobić, po prostu trzymam SDL_Rect
miejsca, w którym ostatnio "uderzyłem" mgłę wojny, i jeśli wartość alfa jest niższa od pewnej wartości, zacisnę ją przy tej wartości.
Więc, po prostu dodając
for(int x = 0; x < mLastFogOfWarPunchPosition.w; ++x)
{
for(int y = 0; y < mLastFogOfWarPunchPosition.h; ++y)
{
Uint32* destPixel = destPixels + (y + mLastFogOfWarPunchPosition.y) * mFogOfWar->w + mLastFogOfWarPunchPosition.x + x;
unsigned char* destAlpha = (unsigned char*)destPixel + 3;
if(*destAlpha < 0x60)
{
*destAlpha = 0x60;
}
}
}
mLastFogOfWarPunchPosition = destRect;
tuż przed pętlą, gdzie mgła wojny jest „dziurkowana”, pojawia się mgła wojny podobny do tego, co można mieć w grach takich jak StarCraft:
Teraz, ponieważ "widziana" mgła wojny jest półprzezroczysta, musisz poprawić swoją metodę renderowania, aby odpowiednio przyciąć "wrogów", które będą we mgle, więc nie widzisz ich, ale ty nadal widzę teren.
Mam nadzieję, że to pomoże!
Naprawdę doceniam pracę, którą włożyłeś w swoją odpowiedź. To bardziej przypomina samouczek! +1 –
@BartekBanachewicz dzięki! Mam nadzieję, że odpowiedź jest wystarczająco jasna! :) – emartel
woah. Człowieku, jesteś niesamowity! Nie jestem tak doświadczony w stackoverflow, czy jest coś, co mogę zrobić, niż dać odpowiedź Tobie i uprowadzeniu? : P – will
- 1. Mgła OpenGL a mgła OpenGL ES
- 2. Algorytm negatywnych zdań
- 3. Instalacja pliku kół
- 4. Algorytm 2D/dym/ogień/mgła
- 5. Modulo negatywnych dywidend w Pythonie
- 6. Guma 2 (mgła) i błąd keypair
- 7. Program OpenGL SDL/C++, jak zatrzymać przechwytywanie SDL SIGINT
- 8. HoughCircles Nie wykrywa kół prawidłowo w OpenCV
- 9. sdl ttf_rendertext_blended losowo nieudane
- 10. Skalowanie ikonki w SDL
- 11. Nauka SDL w C
- 12. Jak połączyć wojny w jedno?
- 13. Jak uruchomić aplikację z wojny?
- 14. Rysowanie trójkąta
- 15. SDL Tridion EventSubscription UnSubscribe Issue
- 16. Haskell SDL na OS X
- 17. Rozmieszczanie wojny w Jboss 7.0.1 do Commandline
- 18. Jak ręcznie rozmieścić pliki wojny w tomcat?
- 19. Jak używać repozytorium Git jako wojny eksplodowanej?
- 20. Jak wdrożyć/zaimportować pakiet wojny do Netbeans
- 21. Pakowanie plików JavaScript w czasie wojny?
- 22. Wtyczka Maven wojny: archiveClasses bez archiwizacji zasobów
- 23. Komenda linux do wypakowywania pliku wojny
- 24. Generowanie pliku wojny z katalogu webapp tomcat
- 25. Wiele Wojny próbuje załadować klasy siebie
- 26. Pakowanie gry! Aplikacja prosto do wojny
- 27. Algorytm losowych lądów w grze "Wojny czołgowe"
- 28. Konwersja waluty float (a nawiasach oznaczają ilość negatywnych)
- 29. Format TimeSpan do mm: ss pozytywnych i negatywnych TimeSpans
- 30. Google Maps Rysowanie/Edycja polilinii V3/Kontynuuj rysowanie
Chcesz nadrukować obrazek koła bezpośrednio w kanale alfa mapy? – Tommy
Chcę mieć szare pudełko, z kółkiem "wymazanym" z niego, dzięki czemu mogę dokładnie przejrzeć warstwę, na której przeciągane jest szare pole. – will