Generowanie Animowanej Rzeki w SFML

Generowanie Animowanej Rzeki w SFML
tBane
  • Rejestracja:prawie 2 lata
  • Ostatnio:4 minuty
  • Lokalizacja:Poznań
  • Postów:319
0

Witam Wszystkich. Zastanawiam się jak zaprogramować animowaną rzekę. Chciałbym animować przepływ wody z jednego punktu do drugiego.
Jak na razie wymyśliłem coś takiego, że Rzeka składałaby się z fragmentów i wszystko bym przetwarzał w sf::VertexArray (pozycja, kolor jako kierunek), ale przy dużej ilości tych fragmentów gra może zacinać - przynajmniej tak mi się wydaje.
Programował z Was ktoś kiedyś coś podobnego i doradziłby mi?

Kopiuj
class RiverFragment {
public:
    sf::Vector2f direction; // kierunek przepływu wody
};

screenshot-20250314232643.png


W wolnych chwilach od codzienności programuję hobbystycznie Edytor gier RPG 2D.
Technologie, z których korzystam to C++ oraz SFML 2.6.
edytowany 4x, ostatnio: tBane
MS
  • Rejestracja:około 2 miesiące
  • Ostatnio:4 dni
  • Postów:9
0

Może napisz do tego shader?

Spine
  • Rejestracja:około 22 lata
  • Ostatnio:minuta
  • Postów:6687
0
Michał Skovv napisał(a):

Może napisz do tego shader?

Shader tak, tylko jego implementacja jest tutaj kluczową kwestią :]

@tBane:Takie coś znalazłem:

Mógłbyś każdemu fragmentowi wody przypisać flow mapę właściwą dla kierunku przepływu wody.

W użyciu ten sposób przypominałby przypisywanie odpowiednich animacji sprite'ów kafelkom wody.

Tak właściwie to sprite'owa animacja dla wody jest bardziej wskazana w Twoim projekcie. Skoro postacie mają niski FPS animacji, to woda też powinna.

A to co zacząłeś robić to by mogła być nadbudówka na ten system. Wzdłóż punktów ścieżki umieszczane by były na mapie odpowiednio animowane kafle rzeki.


🕹️⌨️🖥️🖱️🎮
edytowany 7x, ostatnio: Spine
tBane
  • Rejestracja:prawie 2 lata
  • Ostatnio:4 minuty
  • Lokalizacja:Poznań
  • Postów:319
0

Mam jeszcze jedną prośbę do Was. Zerknąlby ktoś na mój shader i wytłumaczył dlaczego nie działa "przepływ wody" w kierunku direction vec2(1.0f, 1.0f) - w górę w prawo?

Kopiuj
// river.frag
uniform sampler2D texture;
uniform vec2 resolution;
uniform float time;
varying vec2 worldPos;
uniform vec2 direction;	// kierunek przepływu wody rzeki

float random(float x) {
 
    return fract(sin(x) * 10000.);
          
}

float noise(vec2 p) {

    return random(p.x + p.y * 10000.);
            
}

vec2 sw(vec2 p) { return vec2(floor(p.x), floor(p.y)); }
vec2 se(vec2 p) { return vec2(ceil(p.x), floor(p.y)); }
vec2 nw(vec2 p) { return vec2(floor(p.x), ceil(p.y)); }
vec2 ne(vec2 p) { return vec2(ceil(p.x), ceil(p.y)); }

float smoothNoise(vec2 p) {

    vec2 interp = smoothstep(0., 1., fract(p));
    float s = mix(noise(sw(p)), noise(se(p)), interp.x);
    float n = mix(noise(nw(p)), noise(ne(p)), interp.x);
    return mix(s, n, interp.y);
        
}

float fractalNoise(vec2 p) {

    float x = 0.;
    x += smoothNoise(p      );
    x += smoothNoise(p * 2. ) / 2.;
    x += smoothNoise(p * 4. ) / 4.;
    x += smoothNoise(p * 8. ) / 8.;
    x += smoothNoise(p * 16.) / 16.;

    x /= 1. + 1./2. + 1./4. + 1./8. + 1./16.;
    return x;
            
}

float movingNoise(vec2 p) {
    vec2 moveOfWater = direction * time;
    float x = fractalNoise(p + time);
    float y = fractalNoise(p - time);
    return fractalNoise(p + vec2(x, y) - moveOfWater);   
    
}

float nestedNoise(vec2 p) {
    vec2 moveOfWater = direction * time;
    float x = movingNoise(p);
    float y = movingNoise(p + 100.);
    return movingNoise(p + vec2(x, y) - moveOfWater );	// nie działa kierunek wody
    
}

void main()
{
    vec4 texcolor = texture2D(texture, gl_TexCoord[0].xy);
    if(texcolor.x == 127./255. && texcolor.y == 127./255. && texcolor.z == 127./255. && texcolor.w == 1.0) {
        vec2 coords = worldPos.xy/resolution;
        float pixelationFactor = 0.00390625;
        vec2 pixelCoord = floor(coords / pixelationFactor) * pixelationFactor;
        float n = nestedNoise(pixelCoord * 25.60);
        vec3 color = mix(vec3(.4, .6, 1.), vec3(.05, .1, 1.), n);
        vec3 darkcolor = color * 0.7;
        gl_FragColor = vec4(darkcolor, 1.);
    }else{
        gl_FragColor = texcolor;
    }
}

W wolnych chwilach od codzienności programuję hobbystycznie Edytor gier RPG 2D.
Technologie, z których korzystam to C++ oraz SFML 2.6.
edytowany 4x, ostatnio: tBane
tBane
  • Rejestracja:prawie 2 lata
  • Ostatnio:4 minuty
  • Lokalizacja:Poznań
  • Postów:319
1

Dobra już mam ... :D

Kopiuj
// river.frag
uniform sampler2D texture;
uniform vec2 resolution;
uniform float time;
varying vec2 worldPos;
uniform vec2 direction;

float random(float x) {
 
    return fract(sin(x) * 10000.);
          
}

float noise(vec2 p) {

    return random(p.x + p.y * 10000.);
            
}

vec2 sw(vec2 p) { return vec2(floor(p.x), floor(p.y)); }
vec2 se(vec2 p) { return vec2(ceil(p.x), floor(p.y)); }
vec2 nw(vec2 p) { return vec2(floor(p.x), ceil(p.y)); }
vec2 ne(vec2 p) { return vec2(ceil(p.x), ceil(p.y)); }

float smoothNoise(vec2 p) {

    vec2 interp = smoothstep(0., 1., fract(p));
    float s = mix(noise(sw(p)), noise(se(p)), interp.x);
    float n = mix(noise(nw(p)), noise(ne(p)), interp.x);
    return mix(s, n, interp.y);
        
}

float fractalNoise(vec2 p) {

    float x = 0.;
    x += smoothNoise(p      );
    x += smoothNoise(p * 2. ) / 2.;
    x += smoothNoise(p * 4. ) / 4.;
    x += smoothNoise(p * 8. ) / 8.;
    x += smoothNoise(p * 16.) / 16.;

    x /= 1. + 1./2. + 1./4. + 1./8. + 1./16.;
    return x;
            
}

float movingNoise(vec2 p) {
 
    float x = fractalNoise(p + time);
    float y = fractalNoise(p - time);
    return fractalNoise(p + vec2(x, y));   
    
}

float nestedNoise(vec2 p) {
    vec2 moveOfWater = -direction * time;
    moveOfWater.y = -moveOfWater.y;
    float x = movingNoise(p);
    float y = movingNoise(p + 100.);
    return movingNoise(p + vec2(x, y) + moveOfWater);
    
}

void main()
{
    vec4 texcolor = texture2D(texture, gl_TexCoord[0].xy);
    if(texcolor.x == 127./255. && texcolor.y == 127./255. && texcolor.z == 127./255. && texcolor.w == 1.0) {
        vec2 coords = worldPos.xy/resolution;
        float pixelationFactor = 0.00390625;
        vec2 pixelCoord = floor(coords / pixelationFactor) * pixelationFactor;
        float n = nestedNoise(pixelCoord * 25.60);
        vec3 color = mix(vec3(.4, .6, 1.), vec3(.05, .1, 1.), n);
        vec3 darkcolor = color * 0.7;
        gl_FragColor = vec4(darkcolor, 1.);
    }else{
        gl_FragColor = texcolor;
    }
}

W wolnych chwilach od codzienności programuję hobbystycznie Edytor gier RPG 2D.
Technologie, z których korzystam to C++ oraz SFML 2.6.
edytowany 1x, ostatnio: tBane
tBane
  • Rejestracja:prawie 2 lata
  • Ostatnio:4 minuty
  • Lokalizacja:Poznań
  • Postów:319
0

Teraz jeszcze mam pytanie, bo się nie mogę zdecydować. Mam dwie opcje na wstawianie wody.
Pierwsze polega na tym, że z palety wybierana jest woda płynąca w określonym kierunku tzn. wybieram kafelek z wodą płynącą na północny zachód i taka też woda jest wstawiania.
A druga opcja jest taka, że przy wstawianiu wody jej kierunek jest obliczany z ruchu myszy tzn gdy wstawiamy wodę i przesuwamy kursorem z góry na doł to kierunek wody wstawianej będzie ku południowi. Która opcję byście wybrali ?


W wolnych chwilach od codzienności programuję hobbystycznie Edytor gier RPG 2D.
Technologie, z których korzystam to C++ oraz SFML 2.6.
Spine
  • Rejestracja:około 22 lata
  • Ostatnio:minuta
  • Postów:6687
1

Raczej pierwsza opcja lepsza. Wybierasz wodę płynącą w jednym kierunku i wstawiasz kafle bez dodatkowych akcji.

Jeśli musiałbyś po dodaniu każdego kafla ustawiać kierunek, to komplikuje proces tworzenia mapy.


🕹️⌨️🖥️🖱️🎮
edytowany 2x, ostatnio: Spine
tBane
  • Rejestracja:prawie 2 lata
  • Ostatnio:4 minuty
  • Lokalizacja:Poznań
  • Postów:319
1

@Spine ok dzięki. Nie mogłem się zdecydować. Jutro to zaprogramuję


W wolnych chwilach od codzienności programuję hobbystycznie Edytor gier RPG 2D.
Technologie, z których korzystam to C++ oraz SFML 2.6.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.