Zurück   Flashforum > Flash > Flash Einsteiger

Antwort
 
LinkBack Themen-Optionen Ansicht
Alt 25-11-2011, 08:27   #1 (permalink)
Neuer User
 
Registriert seit: Nov 2011
Beiträge: 5
Ladebalken wird zu spät aktualisiert

Hallo,

ich habe mich in den letzten Tagen mehr oder weniger erfolgreich mit Actionscript 3 beschäftigt und bin mit meinen Ergebnissen bislang sehr zufrieden.

Jetzt stehe ich vor dem Problem, dass ich 2 Ladebalken haben möchte: Einen fürs Laden einer Textdatei und einen der anzeigt wie weit die while Schleife, die nach dem Laden aufgerufen wird schon durchgelaufen ist.

Das funktioniert soweit auch alles bis auf das kleine Problem, dass beide Balken erst das erste mal aktualisiert werden, wenn die while Schleife fertig ist. Und dann natürlich schon auf 100%.

Ich habe bei meiner suche im internet ansätze gefunden ähnliche Probleme mit Multithreading zu lösen . Allerdings handelte es sich bei dem Problem um Java und das Problem bestand darin, dass die Grafikausgabe den Fortschritt
der Schleife behinderte (soweit ich das verstanden habe).

Mein Script gibt aber für eine kurze Zeit keine Rückmeldung, auch wenn ich die Breite des Ladebalkens nicht verändere (das war auch der Grund warum ich dafür überhaupt einen Ladebalken haben wollte). Mit Veränderung der Breite dauert die keine Rückmeldung Phase natürlich deutlich länger.

Ich hoffe ihr könnt mir helfen.
Topsi ist offline   Mit Zitat antworten
Alt 25-11-2011, 09:50   #2 (permalink)
Flash-Designer
 
Benutzerbild von Martin Kraft
 
Registriert seit: May 2006
Ort: Wiesbaden
Beiträge: 6.164
Hallo und willkommen im Forum!

Code-Schleifen (for, while) sind keine Zeitschleifen! Ein while-Schleife ist nichts, womit man auf irgendetwas warten könnte, sondern würde in diesem Fall nur dafür sorgen, dass der gesamte FlashPlayer einfriert oder gar abstürzt.

Multithreading gibt es in AS (noch) nicht.

Wenn man also irgendwelche Prozesse ausführenen will (z.B. einen Preloader) während andere noch laufen, muss man sie asynchron zu einander asuführen. Sowas kann man erreichen, indem man Letzere in mehren Durchgängen (z.B. durch einen Event.ENTER_FRAME oder einen Timer) aufruft und in Ersteren auf ein sprechende Events reagiert (z.B. Event.PROGRESS oder Event.COMPLETE).

Deutlicher wird das wahrscheinlich an einem konkreten Beispiel:
  • Was steht denn in Deiner while-Schleife drin?
  • Worauf willst Du warten?
__________________
Viele Grüße // Martin

Martin Kraft // Interaktionsdesign

Hilfreiche Websites:
// Hilfe zur Adobe Flash Plattform
// ActionScript 2 Referenz
// ActionScript 3 Referenz
// ActionScript 3 Arbeitshandbuch
// weitere Flash Ressourcen

Bitte keine Flashfragen per PM oder Profilnachricht! Dafür ist das Forum da!

Geändert von Martin Kraft (25-11-2011 um 09:51 Uhr)
Martin Kraft ist offline   Mit Zitat antworten
Alt 25-11-2011, 13:23   #3 (permalink)
Neuer User
 
Registriert seit: Nov 2011
Beiträge: 5
Das mit dem Multithreading hatte ich auch schon ausprobiert (mit Timern), aber es hat trotzdem keine Rückmeldung gegeben.

Wie man am Code sieht warte ich für den ersten Ladebalken auf das Progress Event des Loaders.
Beim Zweiten warte ich darauf, dass die while Schleife einmal durchgelaufen ist, denn es scheint ja einige Zeit zu dauern bis diese einmal durchläuft.

Der Code ist bestimmt schrecklich anzusehen, da ich auch vieles von Tutorials kopiert habe.^^

Code:
var myRequest:URLRequest = new URLRequest("data.txt"); 
myRequest.method = URLRequestMethod.POST;
var myVariables:URLLoader = new URLLoader(); 
myVariables.dataFormat = URLLoaderDataFormat.VARIABLES; 
myVariables.addEventListener(Event.COMPLETE, processData);

configureListeners(myVariables);

function configureListeners(dispatcher:IEventDispatcher):void {
	
	dispatcher.addEventListener(ProgressEvent.PROGRESS, progressHandler);
}

function progressHandler(event:ProgressEvent):void {
	
	
	var total:Number = event.bytesTotal;
	var loaded:Number = event.bytesLoaded;
	
	bar_mc.width = (loaded/total) * 400;
	loader_txt.text = Math.floor((loaded/total)*100)+ "%";
bar_mc.width, (loaded/total)*400, 0.00001, true);
	
	//trace("progressHandler: bytesLoaded=" + event.bytesLoaded + " bytesTotal=" + event.bytesTotal);
}

function loadData() {
	
	try { 
		myVariables.load(myRequest);
		
	}  
	catch (error:Error) { 
		trace("Die Datei konnte nicht geladen werden: " + error); 
	}
}

function processData(event:Event):void {
	
	var loader:URLLoader = URLLoader(event.target);	
	
	var variables:URLVariables = new URLVariables(loader.data); 
	
	
	var x:int = 0
	
	var hstep:int = 0;
	
	while (variables["s" + x]) {
		//trace (x)
		x++;
		
		if (hstep < x) {
			hstep = x;
		}		
	}
	
	
	var h:int = 0
	
	while (variables["s" + h]) {
		
		this["s" + h] = variables["s" + h].split(",");
		
		for (var i:int = 0; i < 16; i++) {
			
			if (variables["s" + h + "j" + i]) {
				this["s" + h + "j" + i] = variables["s" + h + "j" + i];
			}
			
			if (variables["s" + h + "l" + i]) {
				this["s" + h + "l" + i] = variables["s" + h + "l" + i];
			}
			
			if (variables["s" + h + "k" + i]) {
				this["s" + h + "k" + i] = variables["s" + h + "k" + i];
			}
			
			if (variables["s" + h + "v" + i]) {
				this["s" + h + "v" + i] = variables["s" + h + "v" + i];
			}
		}
		
		h++;
		if (highestStepValue < h) {
			highestStepValue = h;
			stepsSlider.maximum = highestStepValue - 1;
		}
		bar_mc2.width = (h/hstep) * 400;
		oader_txt2.text = Math.floor((h/hstep)*100)+ "%";
	}
	
	xMemoryStuff = this["s0"][0];
	yMemoryStuff = this["s0"][1];
	dataLoaded = true;
}

Geändert von Topsi (25-11-2011 um 13:42 Uhr)
Topsi ist offline   Mit Zitat antworten
Alt 25-11-2011, 15:09   #4 (permalink)
Flash-Designer
 
Benutzerbild von Martin Kraft
 
Registriert seit: May 2006
Ort: Wiesbaden
Beiträge: 6.164
Eigentlich sollte das doch garnicht so lange dauern?
Wie hoch kann den h maximal werden?
Was ist variables["s" + h + "j" + i]?
Wie sieht denn das aus, was Du da lädst?

Wiederholte dynamische Zugriffe sind übrigens ziemliche Performancefresser. Arbeit stattdessen besser mit Arrays!
__________________
Viele Grüße // Martin

Martin Kraft // Interaktionsdesign

Hilfreiche Websites:
// Hilfe zur Adobe Flash Plattform
// ActionScript 2 Referenz
// ActionScript 3 Referenz
// ActionScript 3 Arbeitshandbuch
// weitere Flash Ressourcen

Bitte keine Flashfragen per PM oder Profilnachricht! Dafür ist das Forum da!
Martin Kraft ist offline   Mit Zitat antworten
Alt 25-11-2011, 18:14   #5 (permalink)
Neuer User
 
Registriert seit: Nov 2011
Beiträge: 5
ratrace2d.html
(rauszoomen, wenn die menüleiste unten nicht zu sehen ist)

Zum ersten Mal seit ich die Ladebalken drin habe hochgeladen und der Downloadfortschritt wird angezeigt, obwohl es mit der download simulation nicht geklappt hat o.0. Naja ich bin froh drum.

Die Schleife macht natürlich immer noch Probleme:

data.txt

s steht für step. Die Abstände zwischen den einzelnen Schritten betragen 10 Millisekunden - daher dauert die for schleife auch so lange (wird halt einmal anfang durchgangen und danach nochmal in "Echtzeit").
Ein Spiel dauert durchschnittlich 10 Minuten ich möchte wenn möglich aber auch auf Spiele vorbereitet sein die eine Stunde dauern (möglich ist unendlich also wer weiß...^^). -> h = 360000

Zusätzlich prüft er ob irgendwelche Ereignisse eingetreten sind.
+ "j" + i] bedeutet Spieler Nummer i ist dem Spiel beigetreten (join)
Zu erwähnen ist noch, dass ich noch vorhabe deutlich mehr Informationen zu verwalten (Die Lebensanzeige und Waffen der Spieler und ähnliches) solange es die Performance zulässt.
Aber Performance hängt sowieso vom Client ab, sowie ich das verstanden habe.

Leider wusste ich mir nicht anders zu helfen als diese dynamischen Zugriffe zu verwenden.
Besserungsvorschläge nehme ich natürlich gerne an.^^

Geändert von Topsi (25-11-2011 um 18:29 Uhr)
Topsi ist offline   Mit Zitat antworten
Alt 25-11-2011, 18:43   #6 (permalink)
Flash-Designer
 
Benutzerbild von Martin Kraft
 
Registriert seit: May 2006
Ort: Wiesbaden
Beiträge: 6.164
Ach Du ******e
Das ist ein 14MB Text-Datei!
Das willst Du doch hoffentlich nicht in dieser Form produktiv einsetzen, oder? Selbst mit meiner VDSL-Anbindung dauert das Laden so viel zu lange und irgendwann wirst Du bei diesen Mengen auch Probleme mit dem Arbeitspeicher bekommen!


Ich würde Dir daher dringend empfehlen, die Datenmenge drastisch zu reduzieren:
  • Es ist z.B. unsinnig alle 10ms Daten (also 100 mal pro Sekunde) Daten zu erheben, wenn Framerates über 30fps eh nicht wahrgenommen werden können (-66%).

  • Dann sind eh 90% der Daten identisch, weil sich eben nichts verändert hat. Die könntest Du Dir schenken, wenn Du einfach nur die Veränderungen speicherst.

  • Brauchst Du wirklich 13(!) Nachkommastellen? Wenn Du auf "nur" 3 rundest, sparst Du Dir 75% der Dateigröße!

  • Außerdem würde ich sowas nicht über URLVariables verarbeiten. Da dauert ja allein das parsen der Variablen ewig. Lade die Daten stattdessen in einem CSV-Format, das Du mit zweimal Array.split zerlegen kannst.

    Wenn es sich nur um Zahlenwerte handelt(?) würde es sich u.U. auch anbieten, diese binär zu kodieren und dann als ByteArray zu laden.

Und wenn die Daten dann mal geladen sind, solltest Du sie (wie gesagt) nicht in irgendwelchen durchnummerierten Variablen verwalten, sondern in einem (ggf. mehrdimensionalen) Array.
__________________
Viele Grüße // Martin

Martin Kraft // Interaktionsdesign

Hilfreiche Websites:
// Hilfe zur Adobe Flash Plattform
// ActionScript 2 Referenz
// ActionScript 3 Referenz
// ActionScript 3 Arbeitshandbuch
// weitere Flash Ressourcen

Bitte keine Flashfragen per PM oder Profilnachricht! Dafür ist das Forum da!

Geändert von Martin Kraft (25-11-2011 um 18:46 Uhr)
Martin Kraft ist offline   Mit Zitat antworten
Alt 25-11-2011, 18:52   #7 (permalink)
Neuer User
 
Registriert seit: Nov 2011
Beiträge: 5
Zitat:
Ich würde Dir daher dringend empfehlen, die Datenmenge drastisch zu reduzieren:
Jop, hatte ich auch vor. Aber das Laden dauert bei mir zur Zeit nur eine Sekunde eh...

Danke für die Tipps. Also kann ich mein Problem lösen, indem ich ein dreidimensionales Array benutze (step, spieler, event)?
Topsi ist offline   Mit Zitat antworten
Alt 25-11-2011, 20:13   #8 (permalink)
Flash-Designer
 
Benutzerbild von Martin Kraft
 
Registriert seit: May 2006
Ort: Wiesbaden
Beiträge: 6.164
Zitat:
Zitat von Topsi Beitrag anzeigen
Jop, hatte ich auch vor. Aber das Laden dauert bei mir zur Zeit nur eine Sekunde eh...
Lokal nehme ich an?! Du wirst diese Anwendung aber sicher nicht nur für Dich basteln und auch online ausfüren wollen?! Und für's Web sind 14 MB für sowas eben viel zu viel!

Zitat:
Zitat von Topsi Beitrag anzeigen
Danke für die Tipps. Also kann ich mein Problem lösen, indem ich ein dreidimensionales Array benutze (step, spieler, event)?
Ein zweidimensionales reicht (eine Dimension für die verschieden Zeiten und eine für die verschiedenen Werte). Du könntest aber Du auch ein Array mit Objekten verwenden:
ActionScript:
  1. deinArray.push({
  2.   step: "einWert",
  3.   spieler: "einWert",
  4.   event: "einWert"
  5. });
Das allein wird aber Dein Problem nicht lösen, wenn Du die Werte nicht deutlich reduzierst und anders parst. Ich hab' Dir ja oben beschrieben wie...
__________________
Viele Grüße // Martin

Martin Kraft // Interaktionsdesign

Hilfreiche Websites:
// Hilfe zur Adobe Flash Plattform
// ActionScript 2 Referenz
// ActionScript 3 Referenz
// ActionScript 3 Arbeitshandbuch
// weitere Flash Ressourcen

Bitte keine Flashfragen per PM oder Profilnachricht! Dafür ist das Forum da!

Geändert von Martin Kraft (25-11-2011 um 20:16 Uhr)
Martin Kraft ist offline   Mit Zitat antworten
Alt 02-01-2012, 09:59   #9 (permalink)
Neuer User
 
Registriert seit: Nov 2011
Beiträge: 5
Ich habe jetzt alle Vorschläge befolgt, aber das Problem tritt immer noch auf:

MDR®

Logfile:
http://halo103.com/test/rr/data2/data2.txt

Code:
function processData(event:Event):void 
	var loader:URLLoader = URLLoader(event.target);	
	
	var fileContent:String=loader.data;
	var rows:Array=fileContent.split("\n");
	
	var i:int = 0;
	var hstep:int = rows.length;
	var x:int = 0;
	while (rows[i]) {
		
		savedSteps[highestStepValue] = rows[i].split(",");
		
		//if typecast failed or savedSteps[i] = 0
		if(int(savedSteps[highestStepValue][0]) == 0) {
			
			if (savedSteps[highestStepValue][0] == "k") {
				
				savedKillEvents.push({
					step: highestStepValue,
					killer: savedSteps[highestStepValue][1],
					victim: savedSteps[highestStepValue][2]
				});
				
			} else if (savedSteps[highestStepValue][0] == "j") {
				savedJoinEvents.push({
					step: highestStepValue,
					player: savedSteps[highestStepValue][1],
					name: savedSteps[highestStepValue][2]
				});
				
				
			} else if (savedSteps[highestStepValue][0] == "l") {
				
				savedLeaveEvents.push({
					step: highestStepValue,
					player: savedSteps[highestStepValue][1]
				});
				
			}
			
		} else {
			highestStepValue++;
		}
		i++;
		
		bar_mc2.width = (i/hstep) * 400;
		loader_txt2.text = Math.floor((i/hstep)*100)+ "%";
	}
	stepsSlider.maximum = highestStepValue - 1
	
	dataLoaded = true;
}

Geändert von Topsi (02-01-2012 um 10:01 Uhr)
Topsi ist offline   Mit Zitat antworten
Alt 02-01-2012, 12:25   #10 (permalink)
Flash-Designer
 
Benutzerbild von Martin Kraft
 
Registriert seit: May 2006
Ort: Wiesbaden
Beiträge: 6.164
Irgendwie machen die if-Abfragen so keinen Sinn:
Wenn int(savedSteps[highestStepValue][0]) == 0 ist kann ja nicht gleichzeitig savedSteps[highestStepValue][0] == "k" sein

Wie ich oben schon erwähnt habe...
Zitat:
Zitat von Martin Kraft Beitrag anzeigen
Code-Schleifen (for, while) sind keine Zeitschleifen! Ein while-Schleife ist nichts, womit man auf irgendetwas warten könnte, sondern würde in diesem Fall nur dafür sorgen, dass der gesamte FlashPlayer einfriert oder gar abstürzt.
Es bringt also nichts die länge eines Balkens in einer while-Schleife zu verändern, weil man eh nur den Endzustand sehen wird!

Du musst also ...
  • entweder Dein Script so verschlanken (s.o.), dass es in einem Rutsch abgearbeitet werden kann, ...
    Als Grundgerüst würde ich dafür sowas verwenden:
    ActionScript:
    1. import flash.events.Event;
    2. import flash.net.URLLoader;
    3.  
    4. var savedSteps:Array = [];
    5.  
    6. function processData(event:Event):void
    7.     var loader:URLLoader = URLLoader(event.target);
    8.  
    9.     var rows:Array = String(loader.data).split("\n");
    10.     var rowsNo:uint = rows.length
    11.     var rowArray:Array;
    12.  
    13.     for each (var rowStr:String in rows) {
    14.         if(rowStr){
    15.             rowArray = rowStr.split(",");
    16.             savedSteps.push(rowArray);
    17.        
    18.             // Deine if-Abfragen
    19.         }
    20.     }
    21. }

  • oder es so umschreiben, dass asynchron (z.B. in einem Intervall oder bei Event.ENTER_FRAME) nach und nach immer nur eine bestimmte Anzahl an Zeilen verarbeitet wird.
    Ein Grundgerüst hierfür sähe so aus:
    ActionScript:
    1. import flash.events.Event;
    2. import flash.net.URLLoader;
    3. import flash.utils.setTimeout;
    4.  
    5. var savedSteps:Array = [];
    6. var rows:Array;
    7. var rowsNo:uint;
    8.  
    9. function processData(event:Event):void
    10.     var loader:URLLoader = URLLoader(event.target)
    11.    
    12.     rows = String(loader.data).split("\n");
    13.     rowsNo = rows.length;
    14.    
    15.     processRows();
    16. }
    17.  
    18. function processRows():void {
    19.     // Reihen, die pro Durchgang verarbeitet werden sollen
    20.     var steps:int = 100;
    21.     var rowArray:Array
    22.     var rowStr:String;
    23.    
    24.     while ( rows.length > 0 && steps-- ) {
    25.         if( rowStr = rows.shift() as String ){
    26.             rowArray = rowStr.split(",");
    27.             savedSteps.push(rowArray);
    28.            
    29.             // Deine if-Abfragen
    30.         }
    31.     }
    32.    
    33.     var fractionProcessed:Number = rows.length / rowNo;
    34.     bar_mc2.width = fractionProcessed * 400;
    35.     loader_txt2.text = Math.floor(fractionProcessed*100)+ "%";
    36.    
    37.     if (rows.length > 0) setTimeout(processRows, 20);
    38. }
__________________
Viele Grüße // Martin

Martin Kraft // Interaktionsdesign

Hilfreiche Websites:
// Hilfe zur Adobe Flash Plattform
// ActionScript 2 Referenz
// ActionScript 3 Referenz
// ActionScript 3 Arbeitshandbuch
// weitere Flash Ressourcen

Bitte keine Flashfragen per PM oder Profilnachricht! Dafür ist das Forum da!

Geändert von Martin Kraft (02-01-2012 um 12:27 Uhr)
Martin Kraft ist offline   Mit Zitat antworten
Antwort

Lesezeichen

Stichworte
ladebalken, loader, verzögert

Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind an
Pingbacks sind an
Refbacks sind an


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
textfeld wird nicht aktualisiert sebasta Flash Einsteiger 2 07-08-2008 09:56
Preloader wird zu spät angezeigt 6-Speed Flash MX 3 25-04-2007 09:41
Preloader wird zu spät eingeblendet????!!!! tomtom69 ActionScript 2 5 30-10-2006 18:03
Klasse wird nicht aktualisiert flash bier Softwarearchitektur und Entwurfsmuster 9 22-07-2005 16:48


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:49 Uhr.

Domains, Webhosting & Vserver von Host Europe
Unterstützt das Flashforum!
Adobe User Group


Copyright ©1999 – 2012 Marc Thiele