Posted By: Alan
Niedriger "time"-Wert trotz konstanter Framerate? - 02/25/09 18:22
Hi @all,
ja ich habe mich mit einem Tutorial bewaffnet mal wieder an mein 3DGS 7 Extra gesetzt - diesmal geht es um Partikel.
Konkret handelt es sich um das "Advanced Particles Tutorial" von Thomas Gisiger, zu finden auf der Acknex Unlimited-Page.
Das Problem hat sich bereits beim ersten Beispiel ergeben (einer Partikel-Fontäne). Während die Grund-Version noch sehr gut funktioniert hat, wird sie dahingehend erweitert, dass die Anzahl der generierten Partikel pro Sekunde von der Framerate unabhängig gemacht werden soll. Bevor ich hier lange erzähle, hier ist der Code:
Eine sehr einfache Main-Funktion, die Aktion "a_minimal_source" wird der einzigen Modell-Entity in einem kleinen Level zugewiesen, der sonst nichts beinhaltet außer dem hohlen Block, in dem sie sich befindet.
Interessant wird es jetzt. Starte ich nämlich das mitgelieferte, fertige Beispiel, funktioniert alles. Starte ich aber MEINEN Code (der nach dem Tutorial erstellt wurde und fast identisch ist mit dem fertigen mitgelieferten Beispiel), sinkt die "time"-Variable auf einen Wert um 0.02. Und da time_0 von vornherein den Wert 0.02 besitzt, liefert diese Zeile hier:
n = round(n_0*time/time_0);
... den Wert 0 für n zurück (n ist die Anzahl der pro Frame zu generierenden Partikel) und es werden keine Partikel generiert. Keine? Nun das stimmt nicht ganz. Alle paar Sekunden werden einzelne Partikel abgegeben - anders als man durch die niedrige Time-Variable vermuten könnte, bewegen sich diese aber vollkommen FLÜSSIG. Vom Einbruch der Framerate kann man hier also keinesfalls sprechen.
Hier zum Abschluss noch der Original-Code aus dem mitgelieferten Beispiel (achtung, lang), der relevante Teil kommt ganz zum Schluss, die Aktion heißt "an_improved_source".
Und meine Frage ist: was mache ich falsch? Warum beträgt die Time-Variable im mitgelieferten Beispiel konstant den Wert 2, während sie sich in meinem Code immer so um 0.02 bewegt, wobei die Framerate in beiden Fällen konstant ist???
Hoffe ihr könnt mir helfen ^^'
Alan
ja ich habe mich mit einem Tutorial bewaffnet mal wieder an mein 3DGS 7 Extra gesetzt - diesmal geht es um Partikel.
Konkret handelt es sich um das "Advanced Particles Tutorial" von Thomas Gisiger, zu finden auf der Acknex Unlimited-Page.
Das Problem hat sich bereits beim ersten Beispiel ergeben (einer Partikel-Fontäne). Während die Grund-Version noch sehr gut funktioniert hat, wird sie dahingehend erweitert, dass die Anzahl der generierten Partikel pro Sekunde von der Framerate unabhängig gemacht werden soll. Bevor ich hier lange erzähle, hier ist der Code:
Code:
// Advanced Particles Tutorial - Part 1 // ==================================== var velocity; var part_life = 20; var part_size = 100; var n_0 = 2; var time_0 = 0.2; var n; bmap part_image = <novaB1.pcx>; function main() { level_load("testlevel1.wmb"); wait(2); } function round(x) { return(int(x) + (frc(x)>0.5)); } function minimal_part() { if (my.lifespan == 80) { my.bmap = part_image; my.size = random(part_size); my.bright = ON; my.flare = ON; my.alpha = 255; my.move = ON; my.red = random(255); my.green = random(255); my.blue = random(10); my.gravity = 2; my.lifespan = part_life; } } action a_minimal_source { while(1) { // emit particles when user pushes "1" key if (key_1) { my.skill1 = 1; n = round(n_0*time/time_0); while (my.skill1 <= n) { // generate initial velocity - push "shift" for a velocity boost velocity.x = (0.5-random(1))*(10+40*key_shift); velocity.y = (0.5-random(1))*(10+40*key_shift); velocity.z = 10 + 40*key_shift; // generate those particles effect(minimal_part, 1, my.x, velocity.x); my.skill1 += 1; } } wait(1); } }
Eine sehr einfache Main-Funktion, die Aktion "a_minimal_source" wird der einzigen Modell-Entity in einem kleinen Level zugewiesen, der sonst nichts beinhaltet außer dem hohlen Block, in dem sie sich befindet.
Interessant wird es jetzt. Starte ich nämlich das mitgelieferte, fertige Beispiel, funktioniert alles. Starte ich aber MEINEN Code (der nach dem Tutorial erstellt wurde und fast identisch ist mit dem fertigen mitgelieferten Beispiel), sinkt die "time"-Variable auf einen Wert um 0.02. Und da time_0 von vornherein den Wert 0.02 besitzt, liefert diese Zeile hier:
n = round(n_0*time/time_0);
... den Wert 0 für n zurück (n ist die Anzahl der pro Frame zu generierenden Partikel) und es werden keine Partikel generiert. Keine? Nun das stimmt nicht ganz. Alle paar Sekunden werden einzelne Partikel abgegeben - anders als man durch die niedrige Time-Variable vermuten könnte, bewegen sich diese aber vollkommen FLÜSSIG. Vom Einbruch der Framerate kann man hier also keinesfalls sprechen.
Hier zum Abschluss noch der Original-Code aus dem mitgelieferten Beispiel (achtung, lang), der relevante Teil kommt ganz zum Schluss, die Aktion heißt "an_improved_source".
Code:
//////////////////////////////////////////////////////////////////////// // A6 main wdl: // Created by WED. //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// // The PATH keyword gives directories where template files can be found. path "C:\\PROGRAM FILES\\GSTUDIO7\\template_6"; // Path to A6 templates directory path "C:\\PROGRAM FILES\\GSTUDIO7\\template_6\\code"; // Path to A6 template code subdirectory path "C:\\PROGRAM FILES\\GSTUDIO7\\template_6\\images"; // Path to A6 template image subdirectory path "C:\\PROGRAM FILES\\GSTUDIO7\\template_6\\sounds"; // Path to A6 template sound subdirectory path "C:\\PROGRAM FILES\\GSTUDIO7\\template_6\\models"; // Path to A6 template model subdirectory ///////////////////////////////////////////////////////////////// // Filename of the starting level. string level_str = <LESSON2.WMB>; // give file names in angular brackets //////////////////////////////////////////////////////////////////////////// // Included files include <gid01.wdl>; // global ids include <display00.wdl>; // basic display settings ///////////////////////////////////////////////////////////////// // Desc: The main() function is started at game start function main() { // set some common flags and variables // freeze all entity functions freeze_mode = 1; // no level has been loaded yet... gid01_level_state = gid01_level_not_loaded; // entry: Warning Level (0,1, or 2) // entry_help: Sets sensitivity to warnings (0 = none, 1 = some, 2 = all). warn_level = 2; // announce bad texture sizes and bad wdl code // entry: Starting Mouse Mode (0, 1, or 2) mouse_mode = 0; // wait 3 frames (for triple buffering) until it is flipped to the foreground wait(3); max_particles = 10000; // now load the level level_load(level_str); wait(2); // let level load // level should be loaded at this point... gid01_level_state = gid01_level_loaded; //+++ load starting values // main game loop while(1) { if(gid01_level_state != gid01_level_loaded) { // pause the game freeze_mode = 1; } else { // un-freeze the game freeze_mode = 0; } wait(1); } } // Desc: this is the function used to restart the game. function main_restart_game() { // wait 3 frames (for triple buffering) until it is flipped to the foreground wait(3); max_particles = 10000; // now load the level level_load(level_str); // freeze the game freeze_mode = 1; wait(2); // 1-level loads, 2-entities load //+++ load starting values // un-freeze the game freeze_mode = 0; } // Desc: this is the function used to quit the game. function main_quit() { //+++ // save global skills & strings exit; } ///////////////////////////////////////////////////////////////// // The following definitions are for the pro edition window composer // to define the start and exit window of the application. WINDOW WINSTART { TITLE "3D GameStudio"; SIZE 480,320; MODE IMAGE; //STANDARD; BG_COLOR RGB(240,240,240); FRAME FTYP1,0,0,480,320; // BUTTON BUTTON_START,SYS_DEFAULT,"Start",400,288,72,24; BUTTON BUTTON_QUIT,SYS_DEFAULT,"Abort",400,288,72,24; TEXT_STDOUT "Arial",RGB(0,0,0),10,10,460,280; } /* no exit window at all.. WINDOW WINEND { TITLE "Finished"; SIZE 540,320; MODE STANDARD; BG_COLOR RGB(0,0,0); TEXT_STDOUT "",RGB(255,40,40),10,20,520,270; SET FONT "",RGB(0,255,255); TEXT "Any key to exit",10,270; }*/ ///////////////////////////////////////////////////////////////// //INCLUDE <debug.wdl>; string instructions = "Press: 1(+SHIFT) = basic fountain, 2(+SHIFT) = improved fountain"; text instructions_txt { font = _a4font; pos_x = 10; pos_y = 10; } function on_screen(str) { instructions_txt.string = str; instructions_txt.visible = on; } ////////////////////////////////////////// // Minimal code // ///////////////////////////////////////// function minimal_part(); bmap part_image = <novaB1.pcx>; var part_life = 20; var part_size = 100; var velocity; action a_minimal_source { randomize(); on_screen(instructions); while(1) { // emit particles when user pushes "1" key if (key_1) { // generate initial velocity - push "shift" for a velocity boost velocity.x = (0.5-random(1))*(10+40*key_shift); velocity.y = (0.5-random(1))*(10+40*key_shift); velocity.z = 10 + 40*key_shift; // generate the particles effect(minimal_part,1,my.x,velocity); } wait(1); } } function minimal_part() { if (my.lifespan==80) { my.bmap = part_image; my.size = part_size; my.bright = on; my.flare = on; my.alpha = 255; my.move = on; my.red = 100; my.green = 100; my.blue = 255; my.gravity = 2; my.lifespan = part_life; } } ////////////////////////////////////////////////////////////////////// // More elaborate script // ///////////////////////////////////////////////////////////////////// function improved_part(); function round(x) { return(int(x) + (frc(x)>0.5)); } var n_0 = 2; var time_0 = 0.2; var start_glow; var position; var n; action a_improved_source { var theta; var phi; var speed; while(1) { // press "2" for particles if (key_2) { // adapt the glowing time and initial speed of particles start_glow = 5 + 10*key_shift; speed = 10 + 40*key_shift; // creates the particles my.skill1 = 1; n = round(n_0*time/time_0); while(my.skill1<=n) { // compute velocity theta = random(45); phi = random(360); velocity.x = speed*sin(theta)*cos(phi); velocity.y = speed*sin(theta)*sin(phi); velocity.z = speed*cos(theta); // move the particles a "step" behind position.x = my.x - time*velocity.x; position.y = my.y - time*velocity.y; position.z = my.z - time*velocity.z; // create particles effect(improved_part,1,position.x,velocity.x); my.skill1 += 1; } } wait(1); } } function improved_part() { if (my.lifespan==80) { my.bmap = part_image; my.size = 0; my.bright = on; my.flare = on; my.alpha = 100; my.move = on; my.red = 100; my.green = 100; my.blue = 255; my.gravity = 2; my.lifespan = 5 + random(part_life-5); } if (my.lifespan<start_glow) { my.size = part_size*sin(180*my.lifespan/start_glow); } }
Und meine Frage ist: was mache ich falsch? Warum beträgt die Time-Variable im mitgelieferten Beispiel konstant den Wert 2, während sie sich in meinem Code immer so um 0.02 bewegt, wobei die Framerate in beiden Fällen konstant ist???
Hoffe ihr könnt mir helfen ^^'
Alan