Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Automatyczne wyznaczanie klatek z Sprite Sheetu

Ostatnio zmodyfikowano 2025-10-28 17:58
Autor Wiadomość
tBane
Temat założony przez niniejszego użytkownika
» 2025-10-27 19:24:54
Bo taki jest rozmiar pojedynczej klatki w tym spritesheet'cie
P-183293
skovv
» 2025-10-27 19:30:47
No to wychodzi na to że nie działa, racja? :D źle ustalasz klatki. Obczaj odkąd zaczyna się grafika, jak na całą wysokość obrazka znów będzie tło to można zgadywać że jest to koniec klatki. Potem z góry do dołu po wykryciu obrazka jak znów jest tło to to jest podstawowa wysokość. Jak masz to to sprawdzasz zwiększając wartość o 1:
-Czy szerokosc całego sheetu podzielona przez tą wartość daje resztę? Jeśli daje to chyba lipa, domyślnie zakładamy że nie powinno.
-Jesli nie zostawia reszty to sprawdź czy klatki się domykają, w sensie sprawdzaj linie na krańcach klatki, sprawdzaj wszystkie. Jeśli jest tam coś poza tłem to lipa, nie zgadza się
P-183294
tBane
Temat założony przez niniejszego użytkownika
» 2025-10-27 20:13:32
chyba zrezygnuję z tej opcji w moim programie, bo nie mam pojęcia jak to napisać :-/
P-183295
skovv
» 2025-10-27 21:04:15
Jeśli będę pisał u siebie coś takiego to podzielę się kodem
P-183296
tBane
Temat założony przez niniejszego użytkownika
» 2025-10-27 21:13:02
Ok, dziękuję
P-183297
skovv
» 2025-10-28 17:35:01
W Twoim spritesheecie jest bład: ta klatka spadania nie mieści się w zakresie 80x80, dotyka lini i dlatego jej mi wykrywało 80x240 zamiast 80x80. Przesunąłem tą klatke w gore i jest ok :) Załączam kod
C/C++
class winEditTileset
    : public GuiWindow
{
   
public:
   
GeTileset * sprr;
   
int kx = 0, ky = 0;
   
Color backgroundColor = { 0, 0, 0, 0 };
   
   
bool ColorsEqual( Color a, Color b ) {
       
return a.r == b.r && a.g == b.g && a.b == b.b && a.a == b.a;
   
}
   
void ObliczKlatki() {
       
if( !sprr || !sprr->Icon || !sprr->Icon->id ) return;
       
       
Image image = LoadImageFromTexture( * sprr->Icon );
       
Color * pixels =( Color * ) image.data;
       
backgroundColor = pixels[ 0 ];
       
       
int width = image.width;
       
int height = image.height;
       
       
// Znajdź podstawową szerokość klatki
       
int baseWidth = FindBaseWidth( width, height, pixels );
       
       
// Znajdź podstawową wysokość klatki
       
int baseHeight = FindBaseHeight( width, height, pixels );
       
       
// Znajdź rzeczywistą szerokość klatki sprawdzając podzielniki
       
kx = FindTileWidth( width, height, pixels, baseWidth );
       
       
// Znajdź rzeczywistą wysokość klatki sprawdzając podzielniki
       
ky = FindTileHeight( width, height, pixels, baseHeight );
       
       
UnloadImage( image );
   
}
   
   
int FindBaseWidth( int width, int height, Color * pixels ) {
       
for( int x = 0; x < width; x++ ) {
           
bool foundContent = false;
           
for( int y = 0; y < height; y++ ) {
               
if( !ColorsEqual( pixels[ y * width + x ], backgroundColor ) ) {
                   
foundContent = true;
                   
break;
               
}
            }
           
if( foundContent ) {
               
for( int endX = x + 1; endX < width; endX++ ) {
                   
bool allBackground = true;
                   
for( int y = 0; y < height; y++ ) {
                       
if( !ColorsEqual( pixels[ y * width + endX ], backgroundColor ) ) {
                           
allBackground = false;
                           
break;
                       
}
                    }
                   
if( allBackground ) {
                       
return endX - x;
                   
}
                }
               
return width - x;
           
}
        }
       
return width;
   
}
   
   
int FindBaseHeight( int width, int height, Color * pixels ) {
       
for( int y = 0; y < height; y++ ) {
           
bool foundContent = false;
           
for( int x = 0; x < width; x++ ) {
               
if( !ColorsEqual( pixels[ y * width + x ], backgroundColor ) ) {
                   
foundContent = true;
                   
break;
               
}
            }
           
if( foundContent ) {
               
for( int endY = y + 1; endY < height; endY++ ) {
                   
bool allBackground = true;
                   
for( int x = 0; x < width; x++ ) {
                       
if( !ColorsEqual( pixels[ endY * width + x ], backgroundColor ) ) {
                           
allBackground = false;
                           
break;
                       
}
                    }
                   
if( allBackground ) {
                       
return endY - y;
                   
}
                }
               
return height - y;
           
}
        }
       
return height;
   
}
   
   
int FindTileWidth( int width, int height, Color * pixels, int baseWidth ) {
       
// Sprawdź wszystkie możliwe szerokości klatki zaczynając od baseWidth
       
for( int candidate = baseWidth; candidate <= width; candidate++ ) {
           
if( width % candidate != 0 ) continue;
           
           
bool allLinesClean = true;
           
int tileCount = width / candidate;
           
           
// Sprawdź wszystkie pionowe linie podziału
           
for( int i = 1; i < tileCount; i++ ) {
               
int lineX = i * candidate;
               
bool lineClean = true;
               
               
for( int y = 0; y < height; y++ ) {
                   
if( !ColorsEqual( pixels[ y * width + lineX ], backgroundColor ) ) {
                       
lineClean = false;
                       
break;
                   
}
                }
               
               
if( !lineClean ) {
                   
allLinesClean = false;
                   
break;
               
}
            }
           
           
if( allLinesClean ) {
               
return candidate;
           
}
        }
       
       
return width;
   
}
   
   
int FindTileHeight( int width, int height, Color * pixels, int baseHeight ) {
       
// Sprawdź wszystkie możliwe wysokości klatki zaczynając od baseHeight
       
for( int candidate = baseHeight; candidate <= height; candidate++ ) {
           
if( height % candidate != 0 ) continue;
           
           
bool allLinesClean = true;
           
int tileCount = height / candidate;
           
           
// Sprawdź wszystkie poziome linie podziału
           
for( int i = 1; i < tileCount; i++ ) {
               
int lineY = i * candidate;
               
bool lineClean = true;
               
               
for( int x = 0; x < width; x++ ) {
                   
if( !ColorsEqual( pixels[ lineY * width + x ], backgroundColor ) ) {
                       
lineClean = false;
                       
break;
                   
}
                }
               
               
if( !lineClean ) {
                   
allLinesClean = false;
                   
break;
               
}
            }
           
           
if( allLinesClean ) {
               
return candidate;
           
}
        }
       
       
return height;
   
}
   
   
winEditTileset( GameElement * sprhandle )
        :
GuiWindow( & e, "Tileset: " + sprhandle->Name,
   
{ 5, 5, 300, 300 } ) {
       
gehandle = sprhandle;
       
sprr = static_cast < GeTileset * >( gehandle );
       
       
ObliczKlatki();
   
}
   
void OnMainUpdate() {
       
title = "Tileset: " + gehandle->Name;
   
}
   
void OnRender() {
       
DrawTexture( * gehandle->Icon, WX + 5, WY + 5, WHITE );
       
DrawRectLines( WX + 5, WY + 5, gehandle->Icon->width, gehandle->Icon->height, { 120, 140, 140, 255 } );
       
       
for( int ww = 0; ww < gehandle->Icon->width; ww += kx ) {
           
DrawLine( WX + 5 + ww, WY + 5, WX + 5 + ww, WY + 5 + gehandle->Icon->height, RED );
       
}
       
for( int hh = 0; hh < gehandle->Icon->height; hh += ky ) {
           
DrawLine( WX + 5, WY + 5 + hh, WX + 5 + gehandle->Icon->width, WY + 5 + hh, RED );
       
}
       
       
DrawTextEx( e.sa->guifont20,( "KW: " + std::to_string( kx ) + "\nKH: " + std::to_string( ky ) ).c_str(), { WX, WY }, 20, 0, RED );
   
}
}
;

P-183318
tBane
Temat założony przez niniejszego użytkownika
» 2025-10-28 17:58:03
Ok, Dziękuję :-)
P-183319
1 2 3 « 4 »
Poprzednia strona Strona 4 z 4