skovv |
» 2025-10-27 14:51:49 No i super, dobry patent Ci dałem :D U siebie też za jakoś czas będę dodawał animacje ale myślę napisać także silniczek animacji szkieletowej |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-10-27 14:54:30 |
|
skovv |
» 2025-10-27 15:00:42 Tak, każda część przyczepiona do innej, wraz z rodzicem porusza się dziecko. Będzie trochę zabawy ale to bardzo fajne efekty daje. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-10-27 15:03:42 W takim razie powodzenia :-) Dobra pozostało jeszcze obliczyć rozmiar pojedynczej klatki |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-10-27 15:21:54 i zrobione :-) algorytm napisany. Dziękuję Wszystkim za pomoc :-) sf::Vector2i getFrameSize( std::vector < sf::IntRect > & framesRectsList ) { sf::Vector2i frameSize( 0, 0 ); for( int i = 0; i < framesRectsList.size(); i++ ) { if( framesRectsList[ i ].size.x > frameSize.x ) frameSize.x = framesRectsList[ i ].size.x; if( framesRectsList[ i ].size.y > frameSize.y ) frameSize.y = framesRectsList[ i ].size.y; } return frameSize; }
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-10-27 15:37:22 Jeszcze offset, bo prawie zapomniałem napisać: sf::Vector2i getOffset( std::vector < sf::IntRect > & framesRectsList ) { sf::Vector2i offset( image.getSize().x, image.getSize().y ); for( int i = 0; i < framesRectsList.size(); i++ ) { if( framesRectsList[ i ].position.x < offset.x ) offset.x = framesRectsList[ i ].position.x; if( framesRectsList[ i ].position.y < offset.y ) offset.y = framesRectsList[ i ].position.y; } return offset; } } Czyli mój algorytm działa tak: -wyszukuje wszystkie klatki -z największej pobiera rozmiar -a z pierwszej pobiera offset #include <iostream> #include <string> #include <functional> #define NOMINMAX #include <windows.h> #include <fcntl.h> #include <io.h>
#include "SFML/Window.hpp" #include "SFML/Graphics.hpp"
void loadFrame( sf::Image & image, int x, int y, std::vector < sf::IntRect > & framesRectsList, sf::IntRect & frameRect, sf::Color backgroundColor ) { if( x < 0 || y < 0 || x >= image.getSize().x || y >= image.getSize().y ) return; if( image.getPixel( sf::Vector2u( x, y ) ) != backgroundColor ) { if( x < frameRect.position.x ) frameRect.position.x = x; if( y < frameRect.position.y ) frameRect.position.y = y; if( x >= frameRect.position.x + frameRect.size.x ) frameRect.size.x = x - frameRect.position.x + 1; if( y >= frameRect.position.y + frameRect.size.y ) frameRect.size.y = y - frameRect.position.y + 1; image.setPixel( sf::Vector2u( x, y ), backgroundColor ); loadFrame( image, x + 1, y, framesRectsList, frameRect, backgroundColor ); loadFrame( image, x - 1, y, framesRectsList, frameRect, backgroundColor ); loadFrame( image, x, y + 1, framesRectsList, frameRect, backgroundColor ); loadFrame( image, x, y - 1, framesRectsList, frameRect, backgroundColor ); loadFrame( image, x + 1, y + 1, framesRectsList, frameRect, backgroundColor ); loadFrame( image, x - 1, y - 1, framesRectsList, frameRect, backgroundColor ); loadFrame( image, x + 1, y - 1, framesRectsList, frameRect, backgroundColor ); loadFrame( image, x - 1, y + 1, framesRectsList, frameRect, backgroundColor ); } }
void mergeFrames( std::vector < sf::IntRect > & framesRectsList ) { int i = 0; while( i < framesRectsList.size() ) { for( int j = 0; j < framesRectsList.size(); j++ ) { if( i == j ) continue; sf::IntRect & rectA = framesRectsList[ i ]; sf::IntRect & rectB = framesRectsList[ j ]; if( rectA.findIntersection( rectB ) ) { int left = std::min( rectA.position.x, rectB.position.x ); int top = std::min( rectA.position.y, rectB.position.y ); int right = std::max( rectA.position.x + rectA.size.x, rectB.position.x + rectB.size.x ); int bottom = std::max( rectA.position.y + rectA.size.y, rectB.position.y + rectB.size.y ); rectA.position.x = left; rectA.position.y = top; rectA.size.x = right - left + 1; rectA.size.y = bottom - top + 1; framesRectsList.erase( framesRectsList.begin() + j ); if( j < i ) i--; j--; } } i += 1; } }
void deleteSmallFrames( std::vector < sf::IntRect > & framesRectsList ) { for( int i = 0; i < framesRectsList.size(); i++ ) { sf::IntRect & rect = framesRectsList[ i ]; if( rect.size.x < 16 || rect.size.y < 16 ) { framesRectsList.erase( framesRectsList.begin() + i ); i--; } } }
sf::Vector2i getFrameSize( std::vector < sf::IntRect > & framesRectsList ) { sf::Vector2i frameSize( 0, 0 ); for( int i = 0; i < framesRectsList.size(); i++ ) { if( framesRectsList[ i ].size.x > frameSize.x ) frameSize.x = framesRectsList[ i ].size.x; if( framesRectsList[ i ].size.y > frameSize.y ) frameSize.y = framesRectsList[ i ].size.y; } if( frameSize.x < 16 ) frameSize.x = 16; if( frameSize.y < 16 ) frameSize.y = 16; return frameSize; }
sf::Vector2i getOffset( std::vector < sf::IntRect > & framesRectsList ) { sf::Vector2i offset( 0, 0 ); for( int i = 0; i < framesRectsList.size(); i++ ) { if( framesRectsList[ i ].position.x < offset.x ) offset.x = framesRectsList[ i ].position.x; if( framesRectsList[ i ].position.y < offset.y ) offset.y = framesRectsList[ i ].position.y; } return offset; }
void loadAnimations( sf::Image image ) { sf::Color backgroundColor = image.getPixel( sf::Vector2u( 0, 0 ) ); std::vector < sf::IntRect > framesRectsList; for( int y = 0; y < image.getSize().y; y++ ) { for( int x = 0; x < image.getSize().x; x++ ) { if( image.getPixel( sf::Vector2u( x, y ) ) != backgroundColor ) { sf::IntRect frameRect; frameRect.position.x = x; frameRect.position.y = y; frameRect.size.x = 1; frameRect.size.y = 1; loadFrame( image, x, y, framesRectsList, frameRect, backgroundColor ); framesRectsList.push_back( frameRect ); } } } mergeFrames( framesRectsList ); deleteSmallFrames( framesRectsList ); sf::Vector2i frameSize = getFrameSize( framesRectsList ); std::wcout << L"Detected frame size: " + std::to_wstring( frameSize.x ) + L"x" + std::to_wstring( frameSize.y ) + L"\n"; sf::Vector2i offset = getOffset( framesRectsList ); std::wcout << L"Detected offset: " + std::to_wstring( offset.x ) + L"," + std::to_wstring( offset.y ) + L"\n"; }
int main() { _setmode( _fileno( stdout ), _O_U16TEXT ); sf::RenderWindow * window = new sf::RenderWindow( sf::VideoMode( { 800, 600 } ), "Anim Loader", sf::Style::Titlebar | sf::Style::Resize | sf::Style::Close ); window->setFramerateLimit( 60 ); sf::Clock fpsClock; float fps = 0.0f; int frameCount = 0; sf::Image spriteSheet; spriteSheet.loadFromFile( "sprite sheet — kopia.png" ); std::vector < std::vector < sf::IntRect >> animations; loadAnimations( spriteSheet ); while( window->isOpen() ) { frameCount++; if( fpsClock.getElapsedTime().asSeconds() >= 1.0f ) { fps = frameCount / fpsClock.restart().asSeconds(); frameCount = 0; window->setTitle( L"Anim Paint - FPS: " + std::to_wstring( int( fps ) ) ); } while( const std::optional event = window->pollEvent() ) { if( event->is < sf::Event::Closed >() ) window->close(); } window->clear( sf::Color( 56, 56, 56 ) ); window->display(); } }
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-10-27 16:57:32 Jednak nie jest dobrze. Teraz muszę jakoś z rozmiaru 65x67 zrobić 80x80. Trzeba by jakoś odjąć pozycje klatek w poziomie i w pionie. Tylko nie wiem jak to zrobić. Ma ktoś jakis pomysł? W sensie do poprawy jest funkcja getFrameSize Detected frame size: 65x67 Detected offset: 8,14
 #include <iostream> #include <string> #include <functional> #define NOMINMAX #include <windows.h> #include <fcntl.h> #include <io.h>
#include "SFML/Window.hpp" #include "SFML/Graphics.hpp"
void loadFrame( sf::Image & image, int x, int y, std::vector < sf::IntRect > & framesRectsList, sf::IntRect & frameRect, sf::Color backgroundColor ) { if( x < 0 || y < 0 || x >= image.getSize().x || y >= image.getSize().y ) return; if( image.getPixel( sf::Vector2u( x, y ) ) != backgroundColor ) { if( x < frameRect.position.x ) frameRect.position.x = x; if( y < frameRect.position.y ) frameRect.position.y = y; if( x >= frameRect.position.x + frameRect.size.x ) frameRect.size.x = x - frameRect.position.x + 1; if( y >= frameRect.position.y + frameRect.size.y ) frameRect.size.y = y - frameRect.position.y + 1; image.setPixel( sf::Vector2u( x, y ), backgroundColor ); loadFrame( image, x + 1, y, framesRectsList, frameRect, backgroundColor ); loadFrame( image, x - 1, y, framesRectsList, frameRect, backgroundColor ); loadFrame( image, x, y + 1, framesRectsList, frameRect, backgroundColor ); loadFrame( image, x, y - 1, framesRectsList, frameRect, backgroundColor ); loadFrame( image, x + 1, y + 1, framesRectsList, frameRect, backgroundColor ); loadFrame( image, x - 1, y - 1, framesRectsList, frameRect, backgroundColor ); loadFrame( image, x + 1, y - 1, framesRectsList, frameRect, backgroundColor ); loadFrame( image, x - 1, y + 1, framesRectsList, frameRect, backgroundColor ); } }
void mergeFrames( std::vector < sf::IntRect > & framesRectsList ) { int i = 0; while( i < framesRectsList.size() ) { for( int j = 0; j < framesRectsList.size(); j++ ) { if( i == j ) continue; sf::IntRect & rectA = framesRectsList[ i ]; sf::IntRect & rectB = framesRectsList[ j ]; if( rectA.findIntersection( rectB ) ) { int left = std::min( rectA.position.x, rectB.position.x ); int top = std::min( rectA.position.y, rectB.position.y ); int right = std::max( rectA.position.x + rectA.size.x, rectB.position.x + rectB.size.x ); int bottom = std::max( rectA.position.y + rectA.size.y, rectB.position.y + rectB.size.y ); rectA.position.x = left; rectA.position.y = top; rectA.size.x = right - left + 1; rectA.size.y = bottom - top + 1; framesRectsList.erase( framesRectsList.begin() + j ); if( j < i ) i--; j--; } } i += 1; } }
void deleteSmallFrames( std::vector < sf::IntRect > & framesRectsList ) { for( int i = 0; i < framesRectsList.size(); i++ ) { sf::IntRect & rect = framesRectsList[ i ]; if( rect.size.x < 16 || rect.size.y < 16 ) { framesRectsList.erase( framesRectsList.begin() + i ); i--; } } }
sf::Vector2i getFrameSize( std::vector < sf::IntRect > & framesRectsList ) { sf::Vector2i frameSize( 0, 0 ); for( int i = 0; i < framesRectsList.size(); i++ ) { if( framesRectsList[ i ].size.x > frameSize.x ) frameSize.x = framesRectsList[ i ].size.x; if( framesRectsList[ i ].size.y > frameSize.y ) frameSize.y = framesRectsList[ i ].size.y; } if( frameSize.x < 16 ) frameSize.x = 16; if( frameSize.y < 16 ) frameSize.y = 16; return frameSize; }
sf::Vector2i getOffset( sf::Image & image, std::vector < sf::IntRect > & framesRectsList ) { sf::Vector2i offset( image.getSize().x, image.getSize().y ); for( int i = 0; i < framesRectsList.size(); i++ ) { if( framesRectsList[ i ].position.x < offset.x ) offset.x = framesRectsList[ i ].position.x; if( framesRectsList[ i ].position.y < offset.y ) offset.y = framesRectsList[ i ].position.y; } return offset; }
void loadAnimations( sf::Image image ) { sf::Color backgroundColor = image.getPixel( sf::Vector2u( 0, 0 ) ); std::vector < std::vector < sf::IntRect >> animations; std::vector < sf::IntRect > framesRectsList; for( int y = 0; y < image.getSize().y; y++ ) { for( int x = 0; x < image.getSize().x; x++ ) { if( image.getPixel( sf::Vector2u( x, y ) ) != backgroundColor ) { sf::IntRect frameRect; frameRect.position.x = x; frameRect.position.y = y; frameRect.size.x = 1; frameRect.size.y = 1; loadFrame( image, x, y, framesRectsList, frameRect, backgroundColor ); framesRectsList.push_back( frameRect ); } } } mergeFrames( framesRectsList ); deleteSmallFrames( framesRectsList ); sf::Vector2i frameSize = getFrameSize( framesRectsList ); std::wcout << L"Detected frame size: " + std::to_wstring( frameSize.x ) + L"x" + std::to_wstring( frameSize.y ) + L"\n"; sf::Vector2i offset = getOffset( image, framesRectsList ); std::wcout << L"Detected offset: " + std::to_wstring( offset.x ) + L"," + std::to_wstring( offset.y ) + L"\n"; }
int main() { _setmode( _fileno( stdout ), _O_U16TEXT ); sf::RenderWindow * window = new sf::RenderWindow( sf::VideoMode( { 800, 600 } ), "Anim Loader", sf::Style::Titlebar | sf::Style::Resize | sf::Style::Close ); window->setFramerateLimit( 60 ); sf::Clock fpsClock; float fps = 0.0f; int frameCount = 0; sf::Image spriteSheet; spriteSheet.loadFromFile( "sprite sheet — kopia.png" ); std::vector < std::vector < sf::IntRect >> animations; loadAnimations( spriteSheet ); while( window->isOpen() ) { frameCount++; if( fpsClock.getElapsedTime().asSeconds() >= 1.0f ) { fps = frameCount / fpsClock.restart().asSeconds(); frameCount = 0; window->setTitle( L"Anim Paint - FPS: " + std::to_wstring( int( fps ) ) ); } while( const std::optional event = window->pollEvent() ) { if( event->is < sf::Event::Closed >() ) window->close(); } window->clear( sf::Color( 56, 56, 56 ) ); window->display(); } }
|
|
skovv |
» 2025-10-27 19:21:20 Ale czemu 80x80? |
|
| 1 2 « 3 » 4 |