[AS3] Preloader + Loader: Μου σπάσε τα νεύρα

ActionScript και Flex Προγραμματισμός

Συντονιστές: WebDev Moderators, Super-Moderators

Απάντηση
Άβαταρ μέλους
kalmisurf
Δημοσιεύσεις: 14
Εγγραφή: 29 Μάιος 2009 12:35
Τοποθεσία: Athens
Επικοινωνία:

[AS3] Preloader + Loader: Μου σπάσε τα νεύρα

Δημοσίευση από kalmisurf » 08 Μαρ 2010 18:12

Καλησπέρα
θα θελα τη βοήθεια της κοινότητας στο πρόβλημα που αντιμετωπίζω.
Είμαι καινούργιος στην ΑS3 και προσπαθώ να τη μάθω. Δουλεύω σε flash CS4 άν έχει σημασία.

A. Loaded SWF:
Έχω δημιουργήσει ένα "open.swf" και λόγω βάρους το καλώ σε ένα loader το οποίο περιέχει και τον preloader.
To open.swf εκτός των άλλων, περιέχει (music control):
1. volume_mc (movie clip για έλεγχο της έντασης ήχου) που αποτελείται απο slide_btn (button),
2. play_btn &
3. stop_btn.
Στο frame 1 έχω action script AS3 για το χειρισμό της μουσικής (σταμάτα, παίξε & έλεγχο έντασης) και στο τελευταίο frame ένα stop (); για να σταματά το fotoshow
O κωδικός του:

Κώδικας: Επιλογή όλων

var music:Sound = new Sound(new URLRequest("SND/x.mp3"));
var sc:SoundChannel = music.play(0, 999);
var isPlaying:Boolean = true;

stop_btn.addEventListener(MouseEvent.CLICK, stopMusic);

function stopMusic(e:Event):void
{
	sc.stop();
	isPlaying = false;
}

play_btn.addEventListener(MouseEvent.CLICK, playMusic);

function playMusic(e:Event):void
{
	if (!isPlaying)
	{
		sc = music.play(0, 999);
		isPlaying = true;
	}
}

//---VOLUME SLIDER--- To σημειώνω γιατί ίσως έχει σημασία στο πρόβλημά μου που θα δείτε παρακάτω στη Β' ΣΗΜΕΙΩΣΗ//

var dragging:Boolean = false;
var rectangle:Rectangle = new Rectangle(0,0,50,0);
volume_mc.slider_mc.addEventListener(MouseEvent.MOUSE_DOWN, dragIt);
stage.addEventListener(MouseEvent.MOUSE_UP, dropIt);

function dragIt(e:Event):void
{
	volume_mc.slider_mc.startDrag(false,rectangle);
	dragging = true;
	volume_mc.slider_mc.addEventListener(Event.ENTER_FRAME, adjustVolume);
}

function dropIt(e:Event):void
{
	if (dragging)
	{
		volume_mc.slider_mc.stopDrag();
		dragging = false;
	}
}

function adjustVolume(e:Event):void
{
	var vol:Number = volume_mc.slider_mc.x / 50;
	var st:SoundTransform = new SoundTransform(vol);
	if (sc != null)
	{
		sc.soundTransform = st;
	}
}
ΣΗΜ: Και παίζει μια χαρά χωρίς πρόβλημα. Δεν χρησιμοποιώ class και δεν έχω τίποτα export in frame or for Action.

B. Loader:
Στο frame 1 είναι το preload_txt (dynamic txt & embedding)
Στο frame 1 είναι και η Action Script AS3 που καλεί το external swf και ο preloader
Κώδικας:

Κώδικας: Επιλογή όλων

var req:URLRequest = new URLRequest("open.swf");
var loader:Loader = new Loader();
loader.load(req);
/* Εδώ add on the stage. --- A' ΣΗΜΕΙΩΣΗ: Αν το χρησιμοποιήσω τότε όλα ΟΚ με έλεγχο μουσικής, αλλά ξεκινά το external swf πριν τελείωσει ο preloader, περίπου στο 23%*/
// addChild(loader);

Συνέχεια κώδικα:

Κώδικας: Επιλογή όλων

loader.contentLoaderInfo.addEventListener(Event.COMPLETE,fileLoaded);

function fileLoaded(e:Event):void
{
	var main:MovieClip = MovieClip(loader.content);
/* Εδώ add on the stage. ----- Β' ΣΗΜΕΙΩΣΗ: Εφόσον δεν χρησιμοπιώ το A' ΣΗΜΕΙΩΣΗ το καλώ εδώ και αρχίζουν τα παρατράγουδα.
1. Να ξεκινά η μουσική στο 23% ενώ δεν έχει έρθει όλο το external swf και
2. στο 100% που έρχεται χάνω τον έλεγχο της έντασης του ήχου, και όταν κάνω κλικ στο slide_btn τότε ακολουθεί τον κέρσορα*/

Συνέχεια και τέλος κώδικα:

Κώδικας: Επιλογή όλων

	addChild(loader);
}

loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, preload);

function preload(e:ProgressEvent):void
{
	var percent:Number = Math.round(e.bytesLoaded / e.bytesTotal * 100);
	preload_txt.text = String(percent) + "%";
}

Το πρόβλημά μου είναι
1. Αν καλέσω στο STAGE (A' ΣΗΜΕΙΩΣΗ) και όχι στο COMPLETE το external swf ξεκινά να παίζει στο 23% του preloading. Λάθος υπολογισμός του preloading ίσως στο ProgressEvent. Δεν ξέρω αν υπάρχει κάτι άλλο στον υπολογισμό ή κάτι γενικά σε σχέση με το external swf που δεν έχω κάνει.

2. Αλλά αν το καλέσω στο COMPLETE (Β' ΣΗΜΕΙΩΣΗ) παίζει η μουσική πριν έρθει όλο το swf και έχω πρόβλημα μόνο με το slider και λαμβάνω το εξής error:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at open_fla::MainTimeline/frame1()


Ίσως χρειάζομαι μια σύνδεση με import με το external swf ή export???

Έχω ψάξει όλα τα forum στα αγγλικά και εδώ αλλά κάτι που να ταιριάζει στην περίπτωσή μου δεν βρήκα ή απο τη κούραση δεν το είδα.

Όποιος έχει κάτι να προτείνει θα το εκτιμούσα ιδιαιτέρως και ειδικά τα νεύρα μου και το pc. :hammer:

ΥΓ: Σε AS2 τα έχω όλα μαζί σε ένα swf (και τον preloader) αλλά είπα να περάσω σε AS3 και με ποιό ελαφρύ swf.
"Τα πάντα γύρω μας εκπέμπουν μηνύματα. Το δικό σας μήνυμα επιλέξτε να το πείτε μεσαφήνεια, δημιουργία και αποτελεσματικότητα."
--------------------------------------------------------
http://users.otenet.gr/~mikals/

nkast
Δημοσιεύσεις: 137
Εγγραφή: 15 Νοέμ 2009 20:31
Επικοινωνία:

[AS3] Preloader + Loader: Μου σπάσε τα νεύρα

Δημοσίευση από nkast » 08 Μαρ 2010 21:53

Δοκίμασε στο βασικο SWF να μην εκτελέσεις τίποτα αρχικά.
Βάλε ένα ΑDDTOSTAGE event, και όταν το λάβεις τότε μόνο εκτέλεσε τον κώδικα σου.

Στον loader καλο θα είναι να κάνεις το Addchild στο COMPLETE. (αυτο θα στείλει το ADDTOSTAGE event).

Αυτο που συμβαίνει είναι πως ο κώδικας αρχιζει να εκτελείται πριν τοποθετηθεί στο stage.
Έτσι όταν κάνεις stage.addEventListener , το stage είναι null.



Συγχαρητήρια πάντος. Αν και νέος όπως λες, διάλεξες τον σωστό δρόμο.
Είναι αστείο να βλέπεις ακόμα να κάνουν preloaders μεσα στα πρώτα 2 frames. :lol:

Άβαταρ μέλους
kalmisurf
Δημοσιεύσεις: 14
Εγγραφή: 29 Μάιος 2009 12:35
Τοποθεσία: Athens
Επικοινωνία:

[AS3] Preloader + Loader: Μου σπάσε τα νεύρα

Δημοσίευση από kalmisurf » 08 Μαρ 2010 22:32

nkast έγραψε:Δοκίμασε στο βασικο SWF να μην εκτελέσεις τίποτα αρχικά.
Βάλε ένα ΑDDTOSTAGE event, και όταν το λάβεις τότε μόνο εκτέλεσε τον κώδικα σου.

........................ :lol:
Ευχαριστώ για την ανταπόκριση και τα καλά σου λόγια. Μου πήρε 2 βδομάδες να το φτιάξω παρακολουθώντας dvd lessons

Θέλω να ρωτήσω όταν λες αρχικό εννοείς υποθέτω στο external swf??

Αν μπορούσες να σουν λίγο πιό σαφής θα με βοηθούσε αρκετά

κάτι σαν
stage.addEventListener( Event.ADDED_TO_STAGE, addedToStage );
function addedToStage(e.Event)
{

}
και που αν είναι αυτό??
"Τα πάντα γύρω μας εκπέμπουν μηνύματα. Το δικό σας μήνυμα επιλέξτε να το πείτε μεσαφήνεια, δημιουργία και αποτελεσματικότητα."
--------------------------------------------------------
http://users.otenet.gr/~mikals/

Άβαταρ μέλους
kalmisurf
Δημοσιεύσεις: 14
Εγγραφή: 29 Μάιος 2009 12:35
Τοποθεσία: Athens
Επικοινωνία:

[AS3] Preloader + Loader: Μου σπάσε τα νεύρα

Δημοσίευση από kalmisurf » 09 Μαρ 2010 04:22

kalmisurf έγραψε:2. Αλλά αν το καλέσω στο COMPLETE (Β' ΣΗΜΕΙΩΣΗ) παίζει η μουσική πριν έρθει όλο το swf και έχω πρόβλημα μόνο με το slider και λαμβάνω το εξής error:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at open_fla::MainTimeline/frame1()


Με την αναφορά σου για ΑDDTOSTAGE event είδα ένα λάθος μου στο αρχικό swf και διόρθωσα τον κώδικά του και έτσι έφυγε το Error #1009 και απέκτησα έλεγχο στην ένταση του ήχου (slider).

Αλλά παρόλαταυτα παίζει η μουσική στο 23% πριν έρθει όλο το swf και ψάχνω για κάποια άλλη διόρθωση ώστε να αρχίζει η μουσική στο 100% μαζί με το υπόλοιπο του external swf.
kalmisurf έγραψε:var music:Sound = new Sound(new URLRequest("SND/x.mp3"));
Μήπως δημιουργείται το πρόβλημα λόγω ότι καλώ external sound file??? Τά χω πάιξει :hammer:

Οποιαδήποτε βοήθεια-διόρθωση-ιδέα καλοδεχούμενη

No pain No gain!! :roll:
Ευχαριστώ

Παρατήρηση: Βάζοντας Addchild στο COMPLETE (που είναι και πιό σωστό) έρχεται το swf πιό αργά εν σχέση με το να μπεί όπως αναφέρω στη A' ΣΗΜΕΙΩΣΗ
"Τα πάντα γύρω μας εκπέμπουν μηνύματα. Το δικό σας μήνυμα επιλέξτε να το πείτε μεσαφήνεια, δημιουργία και αποτελεσματικότητα."
--------------------------------------------------------
http://users.otenet.gr/~mikals/

Άβαταρ μέλους
HeRu
Flash Moderator
Δημοσιεύσεις: 800
Εγγραφή: 16 Αύγ 2004 10:49
Επικοινωνία:

[AS3] Preloader + Loader: Μου σπάσε τα νεύρα

Δημοσίευση από HeRu » 09 Μαρ 2010 07:16

Το θέμα, όπως είπε και ο nkast, είναι ότι επειδή το flash είναι streaming content, καλείτε ο κώδικας του loaded.swf με το που φορτωθεί το πρώτο frame.

Οπότε στην ουσία αυτό που θέλεις να κάνεις, είναι να καλέσεις τον κώδικα που ξεκινάει τον ήχο μόνο αφού έχει φορτωθεί ολόκληρο το loaded.swf.

Γιαυτό χρησιμοποιείς το Added to stage event, που είσαι σίγουρος ότι θα γίνει αφού έχει ολοκληρωθεί ολόκληρο το preload.

π.χ. στο loaded.swf

Κώδικας: Επιλογή όλων

var music:Sound;
var sc:SoundChannel;
var isPlaying:Boolean; 

this.addEventListener(Event.ADDED_TO_STAGE, startMusic);	

function startMusic(event:Event):void
{
music = new Sound(new URLRequest("SND/x.mp3"));
sc = music.play(0, 999);
isPlaying= true;
}

Άβαταρ μέλους
kalmisurf
Δημοσιεύσεις: 14
Εγγραφή: 29 Μάιος 2009 12:35
Τοποθεσία: Athens
Επικοινωνία:

[AS3] Preloader + Loader: Μου σπάσε τα νεύρα

Δημοσίευση από kalmisurf » 09 Μαρ 2010 12:53

Φοβερόοοοοοοοοοοο!!!! :kaloe:

Πήγα ένα βήμα παρακάτω με την βοήθεια σας και σας ευχαριστώ πάρα πολύ και τους 2 σας.
HeRu όπως πάντα πολύ κατατοπιστικός χωρίς να μειώνω τη συμβολή και ανταπόκριση του nkast.

Ερώτηση τώρα για να κατανοήσω περισσότερο και όχι απλώς μια copy paste, ψεκάστε - σκουπίστε - τελειώσατε.

1. όταν έχω να καλέσω swf streaming content πρέπει πρώτα να το τοποθετώ στο stage του αρχικού. (κάπου τόχα διαβάσει αλλά αν είσαι newbis κάπου το προσπερνάς)

2. Στο αρχικό loaded.swf άλλαξα όλο το τρόπο του load sound με το δικό σου που το τοποθετεί στο stage δηλαδή πέταξα όλο το

Κώδικας: Επιλογή όλων

var music:Sound = new Sound(new URLRequest("SND/x.mp3"));
var sc:SoundChannel = music.play(0, 999);
var isPlaying:Boolean = true;
και τώρα στο αρχικό λαμβάνω το εξής error:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at open_fla::MainTimeline/stopMusic()
at open_fla::MainTimeline/playMusic()

Είναι σωστό να έχω αυτό το λάθος (αν και στο loader παίζει μιά χαρά)???
Υποθέτω ότι τοχω λόγω ότι το αρχείο το προετοιμάσαμε να καλεσθεί απο κάπου. Αν κάνω λάθος διόρθωσέ με.

ΥΓ: Στο VOLUME SLIDER άλλαξα το κάλεσμα στο stage

Κώδικας: Επιλογή όλων

stage.addEventListener(MouseEvent.MOUSE_UP, dropIt);
κώδικας που σε AS2 θα γράφαμε "onReleaseOutside" event handler
με το

Κώδικας: Επιλογή όλων

volume_mc.slider_mc.addEventListener(MouseEvent.MOUSE_UP, dropIt);
και έτσι απέκτησα τον έλεγχο της έντασης ήχου στον loader
"Τα πάντα γύρω μας εκπέμπουν μηνύματα. Το δικό σας μήνυμα επιλέξτε να το πείτε μεσαφήνεια, δημιουργία και αποτελεσματικότητα."
--------------------------------------------------------
http://users.otenet.gr/~mikals/

Άβαταρ μέλους
HeRu
Flash Moderator
Δημοσιεύσεις: 800
Εγγραφή: 16 Αύγ 2004 10:49
Επικοινωνία:

[AS3] Preloader + Loader: Μου σπάσε τα νεύρα

Δημοσίευση από HeRu » 09 Μαρ 2010 13:56

Το πρόβλημα μάλλον είναι ότι το sc είναι null, οπότε μπορείς να βάλεις ένα έλεγχο αν υπάρχει πριν:

Κώδικας: Επιλογή όλων

function stopMusic(e:Event):void
{
   if(sc)
      sc.stop();
   isPlaying = false;
}

Άβαταρ μέλους
kalmisurf
Δημοσιεύσεις: 14
Εγγραφή: 29 Μάιος 2009 12:35
Τοποθεσία: Athens
Επικοινωνία:

[AS3] Preloader + Loader: Μου σπάσε τα νεύρα

Δημοσίευση από kalmisurf » 09 Μαρ 2010 14:53

σωστή παρατήρηση και το βάλα και στο function playMusic αλλά στο αρχικό παραυτά δεν παίζει την μουσική και όπως είπα πριν υποθέτω λόγω της αλλαγής του load sound.

Aπλώς για μεγαλύτερη κατανόηση το αναφέρω γιατί το ζητούμενο πέτυχε.
"Τα πάντα γύρω μας εκπέμπουν μηνύματα. Το δικό σας μήνυμα επιλέξτε να το πείτε μεσαφήνεια, δημιουργία και αποτελεσματικότητα."
--------------------------------------------------------
http://users.otenet.gr/~mikals/

Άβαταρ μέλους
HeRu
Flash Moderator
Δημοσιεύσεις: 800
Εγγραφή: 16 Αύγ 2004 10:49
Επικοινωνία:

[AS3] Preloader + Loader: Μου σπάσε τα νεύρα

Δημοσίευση από HeRu » 09 Μαρ 2010 15:08

Βασικά ο σωστός τρόπος να φορτώσεις τον ήχο, είναι να βάλεις και εκεί έναν αντίστοιχο listener.

Κώδικας: Επιλογή όλων

_music = new Sound();
_music.addEventListener( Event.COMPLETE, loadmusic );

function loadMusic(event:Event):void
{
	sc = music.play(0, 999); 
}

nkast
Δημοσιεύσεις: 137
Εγγραφή: 15 Νοέμ 2009 20:31
Επικοινωνία:

[AS3] Preloader + Loader: Μου σπάσε τα νεύρα

Δημοσίευση από nkast » 10 Μαρ 2010 00:49

Αυτο που *υποθέτω* συμβαίνει είναι πως όταν τρέχεις το loaded.swf μονο του, δεν γίνεται ποτε fire το event ADDED_TO_STAGE επειδή ήδη όλα βρίσκονται στο stage. Ετσι το sc παραμένει null;

Πιστεύω ότι για το event MOUSE_UP θα πρέπει να παρακολουθείς το stage όπως έκανες αρχικά. Αν ο χρήστης μετακινήσει πλαγίως το mouse και αφήσει το κουμπί εκτός του slider, δεν θα λάβεις το MOUSE_UP και το αποτέλεσμα θα είναι το slider να εξακολουθεί να αλλάζει τιμές με το mouse.

Κώδικας: Επιλογή όλων

this.addEventListener(Event.ADDED_TO_STAGE, startMusic);    

if(stage!=null) startMusic(null); // Πρόσθεσε αυτη τη γραμμή

function startMusic(event:Event):void 
{ 
music = new Sound(new URLRequest("SND/x.mp3")); 
sc = music.play(0, 999); 
isPlaying= true; 
stage.addEventListener(MouseEvent.MOUSE_UP, dropIt);  //μετεφερε αυτή τη γραμμή 
// εντός της startMusic.
}
Μια καλύτερη ιδέα , θα ήταν να βάλεις το addlistener gia to mouseup μέσα στην dragIt και να το κάνεις release στην dropit. Ετσι δεν θα μπορείς να το ακους στo stage χωρίς να μπερδεύεται με αλλά clicks.

Το στήσιμο γενικά μπορει να γίνει

Κώδικας: Επιλογή όλων

if(stage==null) 
   this.addEventListener(Event.ADDED_TO_STAGE, init);
else init(null);

function init(event:Event):void 
{
    // this is where your program starts.
    // put any event listeners and initilization code here...

    startMusic();
    // ...
}


var music:Sound; 
var sc:SoundChannel; 
var isPlaying:Boolean;
var rectangle:Rectangle = new Rectangle(0,0,50,0);

function startMusic(event:Event):void 
{ 
  music = new Sound(new URLRequest("SND/x.mp3")); 
  sc = music.play(0, 999); 
  isPlaying= true; 
  stop_btn.addEventListener(MouseEvent.CLICK, stopMusic);
  play_btn.addEventListener(MouseEvent.CLICK, playMusic);
  volume_mc.slider_mc.addEventListener(MouseEvent.MOUSE_DOWN, dragIt);
}

function dragIt(e:Event):void 
{ 
   volume_mc.slider_mc.startDrag(false,rectangle);   
   volume_mc.slider_mc.addEventListener(Event.ENTER_FRAME, adjustVolume); 
   stage.addEventListener(MouseEvent.MOUSE_UP, dropIt);
} 

function dropIt(e:Event):void 
{ 
      volume_mc.slider_mc.stopDrag(); 
      volume_mc.slider_mc.releaseEventListener(Event.ENTER_FRAME, adjustVolume); 
      stage.releaseEventListener(MouseEvent.MOUSE_UP, dropIt);   
}

Άβαταρ μέλους
kalmisurf
Δημοσιεύσεις: 14
Εγγραφή: 29 Μάιος 2009 12:35
Τοποθεσία: Athens
Επικοινωνία:

[AS3] Preloader + Loader: Μου σπάσε τα νεύρα

Δημοσίευση από kalmisurf » 10 Μαρ 2010 02:14

σωστά το γράφεις
event MOUSE_UP θα πρέπει να παρακολουθείς το stage
και με αυτο το σκεπτικό τοχα κάνει αλλά το βγαλα λόγω προβλημάτων όπως ανέφερα προηγουμένως.

Επειδή θέλω να τόχω σωστό για να κατανοώ περισσότερο την AS3 θα πειραματιστώ με τις παρατηρήσεις σου για να δω τι γίνεται ώστε να το λύσω μια και καλή το θέμα

thnx πάντως και απο το αρχικό σου ποστάρισμα μου δώσες αρκετή βοήθεια για να ψαχτώ περισσότερο και έπεται συνέχεια
"Τα πάντα γύρω μας εκπέμπουν μηνύματα. Το δικό σας μήνυμα επιλέξτε να το πείτε μεσαφήνεια, δημιουργία και αποτελεσματικότητα."
--------------------------------------------------------
http://users.otenet.gr/~mikals/

Απάντηση

Επιστροφή στο “ActionScript και Flex Προγραμματισμός”

Μέλη σε σύνδεση

Μέλη σε αυτήν τη Δ. Συζήτηση: Δεν υπάρχουν εγγεγραμμένα μέλη και 0 επισκέπτες