Flüssige wie gezeichnet wirkende Linien/Pfade

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Flüssige wie gezeichnet wirkende Linien/Pfade

    Ich möchte gerne Boxen zeichnen, die aussehen als wären sie von Hand gezeichnet.
    Dazu bräuchte ich einen Pfad der diese Linien beschreibt(wird dann nicht nur zum zeichnen verwendet).

    Das einzige was ich dazu gefunden habe ist dieser Screenshot aus den Jackboxgames:


    Aber ich habe Probleme ähnliche Ergebnisse zu erzielen.
    Ich brauche keine komplett fertige Lösung sondern nur einen funktionierenden Ansatz.

    Danke im Vorraus
  • Also, du möchtest praktisch, dass man die Boxen klicken kann, aber nur wenn man eben mit der Maus auf der Box ist, und nicht etwa in einem quadratischen Umfeld um die Box?

    Ich habe selber keine Erfahrung damit, aber könntest du nicht theoretisch die Collision-Mask der gezeichneten Boxen auf genau Stellen und irgendwie abfragen, ob mousex/y damit kollidiert?
    Ansonsten würde ich einen Umweg gehen und ein unsichtbares Objekt erschaffen, dass sich im step_event zur Mausposition bewegt und dann eben über dieses Objekt abgefragt wird, ob mouse x/y mit der Collisionmask der Boxen kollidiert.

    Hoffe das war ne Hilfe

    MfG
    Falcfire
    Im Internet weiß niemand, dass du ein Truthahn bist.
  • Schwierig. Normalweise bestehen diese Grafiken aus vorgezeichneten Grafiken die mithilfe von Vektoren gezeichnet werden.
    D.h. man zeichnet die Linie und der PC berechnet dann eine weichere Version davon. (Z.b. in Adobe Flash oder Manga Studio)

    Sowas ähnliches in Echtzeit und im GM umzusetzen halte ich für ziemlich schwierig, wenn es überhaupt möglich ist.

    Ein Möglichkeit wäre es die Linien vorzuzeichnen und dann nur als Grafik zu verwenden. Aber du willst sie ja per Code generieren....

    Aufjedenfall wirst du die Pfade zwischenspeichern müssen da die Linien nicht in Echtzeit entstehen können. D.h. wie genau die Linie aussieht entscheidet sich erst wenn sie komplett zuende gezeichnet ist.
    Ansonsten kriegst du niemals so schöne Ergebnisse.
    Aufjedenfall spielt da eine große Zahl an Effekten, Shadern und Berechnungen drin.

    Du musst vermutlich den Pfad der Linie speichern (weiß nich ob das auch mit Paths realisierbar wäre) und dann musst du diesen Pfad interpolieren und mit ein bisschen zufall hier und da den pfad nachziehen.

    Also ich weiß nicht wie das geht, aber du hast ja auch nur um einen Ansatz gebeten.

    Und eine Sache sag ich dir: Einfach ist das nicht, jedenfalls nich wenn du gute Ergebnisse erzielen willst.

    Versuch mal irgendwie den Pfad mit einzelnen Punkten zu beschreiben und dann auf einer Surface diese Punkte interopliert nachzuzeichnen. Schwierig wäre dann noch die Kantenglättung, aber dafür gibts ja Algorithmen.
    Nur das ganze mitm Game maker umzusetzen dürfte nochmal etwas trickey sein.
    Sorm ist Schuld

    Edit: Doch ist er
  • Könnte man nicht praktisch ein Objekt erstellen, dass den Pfad praktisch zeichnet?

    Also, halb-zufällig natürlich: Ein Objekt wird erstellt, welches sich in eine Richtung mit einer Geschwindigkeit bewegt und dabei einen Pfad zeichnet (wobei startposition als lokale variable im create event gespeichert werden), alle paar Steps entscheidet ein choose(x1,x2,x3,...) ob eine weitere Variable "nächsterpunkt" 1, 0 oder -1 ist, wobei mit zwei Weiteren variablen der X/Y Standort vor dem choose() event zwischengespeichert wird. Durch den "nächsterpunkt"-Wert wird die Richtung verändert, wodurch in der gezeichneten Linie eine Kurve ensteht. Nach einer gewissen Distanz (relativ zum vorherigen X/Y Standort) wird die Richtungsänderung wieder behoben und das Objekt kehrt auf seine Bahn zurück.
    Dadurch entsteht eine Linie mit Wölbungen. Nach einer Distanz relativ zur Startposition (länge/höhe der box) müsste man dann eben noch die Richtung so manipulieren, dass eine glatte Kurve gefahren wird.

    Allerdings klingt das ganze auch wieder unheimlich kompliziert. Wofür musst du den die Linien zeichnen? Vielleicht kann man den Zweck der Linien auch durch was anderes erreichen?
    Im Internet weiß niemand, dass du ein Truthahn bist.
  • Zufälligerweise arbeite ich an Bézierkurven Shader. Mithilfe dessen kann man runde Kurven in Echtzeit rendern. Es ist zwar nicht exakt auf dieses Problem zugeschnitten, aber mit den Tipps von den vorherigen Posts kann man sicherlich damit arbeiten.

    init_bezier

    GML-Quellcode

    1. ///init_bezier(detail)
    2. globalvar shd_bezier_anker_1, shd_bezier_anker_2, shd_bezier_anker_3, shd_bezier_anker_4, shd_bezier_size, mdl_bezier;
    3. shd_bezier_anker_1 = shader_get_uniform(shd_bezier, "u_vAnker_1");
    4. shd_bezier_anker_2 = shader_get_uniform(shd_bezier, "u_vAnker_2");
    5. shd_bezier_anker_3 = shader_get_uniform(shd_bezier, "u_vAnker_3");
    6. shd_bezier_anker_4 = shader_get_uniform(shd_bezier, "u_vAnker_4");
    7. shd_bezier_size = shader_get_uniform(shd_bezier, "u_fSize");
    8. mdl_bezier = d3d_model_create();
    9. d3d_model_primitive_begin(mdl_bezier, pr_trianglestrip);
    10. for(i=0;i<=1;i+=1/argument0)
    11. {
    12. d3d_model_vertex(mdl_bezier, i, 1, 0);
    13. d3d_model_vertex(mdl_bezier, i, -1, 0);
    14. }
    15. d3d_model_primitive_end(mdl_bezier);
    Alles anzeigen

    draw_bezier

    GML-Quellcode

    1. ///draw_bezier(x1, y1, x2, y2, x3, y3, x4, y4, size)
    2. shader_set(shd_bezier);
    3. shader_set_uniform_f(shd_bezier_anker_1, argument0, argument1);
    4. shader_set_uniform_f(shd_bezier_anker_2, argument2, argument3);
    5. shader_set_uniform_f(shd_bezier_anker_3, argument4, argument5);
    6. shader_set_uniform_f(shd_bezier_anker_4, argument6, argument7);
    7. shader_set_uniform_f(shd_bezier_size, argument8);
    8. d3d_model_draw(mdl_bezier, 0, 0, 0, -1);
    9. shader_reset();

    shd_bezier (Vertexshader)

    Quellcode

    1. attribute vec3 in_Position;
    2. attribute vec4 in_Colour;
    3. varying vec4 v_vColour;
    4. uniform vec2 u_vAnker_1;
    5. uniform vec2 u_vAnker_2;
    6. uniform vec2 u_vAnker_3;
    7. uniform vec2 u_vAnker_4;
    8. uniform float u_fSize;
    9. void main()
    10. {
    11. vec4 object_space_pos = vec4(in_Position, 1.0);
    12. float i = in_Position.x;
    13. float iP2 = i*i;
    14. float inv_i = 1.-i;
    15. float inv_iP2 = inv_i*inv_i;
    16. object_space_pos.xy = inv_iP2*inv_i*u_vAnker_1+3.*i*inv_iP2*u_vAnker_2+3.*iP2*inv_i*u_vAnker_3+i*iP2*u_vAnker_4;
    17. vec2 i_tan = normalize(-3.*u_vAnker_1*inv_iP2+3.*u_vAnker_2*(inv_iP2-2.*i*inv_i)+3.*u_vAnker_3*(-iP2+inv_i*2.*i)+3.*u_vAnker_4*iP2);
    18. object_space_pos.xy += vec2(-i_tan.y*in_Position.y, i_tan.x*in_Position.y)*u_fSize;
    19. gl_Position = gm_Matrices[MATRIX_WORLD_VIEW_PROJECTION] * object_space_pos;
    20. v_vColour = in_Colour;
    21. }
    Alles anzeigen

    shd_bezier (Fragmentshader)

    Quellcode

    1. varying vec4 v_vColour;
    2. void main()
    3. {
    4. gl_FragColor = v_vColour;
    5. }


    Alle Funktionen und Shader müssen exakt so genannt werden. init_bezier sollte nur ein einziges mal am Anfang des Spiels aufgerufen werden. Ich hoffe die Funktionen sind selbsterklärend und hilfreich.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von Chris987 ()

  • Also ich würde per random Punkte , die in der Nähe von der Linie sind generieren und dann in kurvenlienen die verbinden.
    Ich hatte noch kein sinus und cosinus aber damit kann man ja glaub ich ekreieine art Kreisverbindung machen.
    Ein Bug ist mehr als nur ein Bug, es ist ein... Käfer!
    Egal, wie gut du eine Mauer baust, sie fällt um.... der klügere gibt nach :D

    Willst du mit mir auf Discord Chatten/Quatschen?
    Meine Husi's Tutorial Reihe