A Flash Developer Resource Site

Page 1 of 3 123 LastLast
Results 1 to 20 of 53

Thread: if then statements confusion

  1. #1
    Senior Member
    Join Date
    Oct 2009
    Posts
    112

    if then statements confusion

    I am reading information from binary sockets.

    I have an array of movie clips, each with a different instance name:
    ex: MCarray:Array=new Array (mc1,mc2,mc3,mc4,mc5);
    I have already done all the coding for the arrays so theres no confusion there.

    I need a statement that says:
    Code:
    "if the incoming variable refers to mc1+2, then make mc1 go to frame 2"
    "if the incoming variable refers to mc2+2, then make mc2 go to frame 2"
    if the incoming variable referrs to mc3+2, then make mc3 go to frame 2"
    and so on....

    does that make sense? anyway the problem with that is that i just want ONE statement because I will eventually have over a hundered movie clips, and so I don't want to make a hundred if-then statements for each function.

    there must be a way to say
    Code:
    my.addEventListener(ProgressEvent.SOCKET_DATA, myfunction);
    function myfunction(e:ProgressEvent):void{
           if("incoming variable=one of the movie clips from the array"+"2"){
               MCarray.(make that movie clip which was named go to frame 2);
           }
    }
    any ideas? thanks
    Last edited by mattwatts15; 11-13-2009 at 04:45 PM.

  2. #2
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    What sort of data is it that's incoming? If it's a string like "mc1+2", you could parse out the relevant parts. But why are you using a binary socket to send text like that? An xml socket seems better suited to sending text.

    Assuming you do have a string.
    Code:
    var embeddedNums:Array = incomingVar.match(/\d+/g);
    var clipIndex:int = embeddedNums[0] -1; //because arrays start at 0.
    var frameIndex:int = embeddedNums[1];
    MCarray[clipIndex].goToAndStop(frameIndex);
    I assume you meant "go to frame 2" because go to a function makes no sense.

    If your format was simplified to "1|2", you could simplify the parsing part to this:
    Code:
    var embeddedNums:Array = incomingVar.split("|");
    Of course, since you're using a binary socket, you could simply send each int independently and use readInt to get each one. Or you could send an Object with properties and use readObject.

  3. #3
    Senior Member
    Join Date
    Oct 2009
    Posts
    112
    right...i meant go to FRAME 2 not function

    the reason i can't use numbers is because you cant give instance names to movie clips that is just a number, it has to start out with a letter.

    all parts of your code are new to me so ill try it but i might have more questions, thanks for the help

  4. #4
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    You can't name a clip with just a number, but you don't need to pass a name from your socket in the first place. The only thing you're doing with the "mc" part of the string you get from the socket is throw it away so you can get to the number after it.

  5. #5
    Senior Member
    Join Date
    Oct 2009
    Posts
    112
    oh ok, so eventually when i have the 100 or more movie clips on the stage, it would be ideal for them all to have just a number for their name (1-100), so i could give them all an instnace name of: S1, S2, S3.....S100, and use the .split function to drop the S?

    and I just tried your code, heres how i put it in mine:
    Code:
    var ONarray:Array=new Array("on1","on2","on3","on4","on5",
    				"on6","on7","on8","on9","on9",
    				"on10","on11","on12","on13",
    				"on14","on15","on16","on17",
    				"on18","on19","on20","on21","on22",
    				"on23","on24","on25","on26","on27",
    				"on28","on29","on30","on31","on32");
    
    var onLastDown:MovieClip=null;
    s.addEventListener(ProgressEvent.SOCKET_DATA, onDATA);
    	function onDATA(e:ProgressEvent):void{
    	var d:String=s.readUTFBytes(2);
    	var embeddedNums:Array = d.match(/\d+/g);
    	var clipIndex:int = embeddedNums[0] -1; //because arrays start at 0.
    	var frameIndex:int = embeddedNums[1];
    	ONarray[clipIndex].goToAndStop(frameIndex);
    }
    and i get this error:
    Code:
    TypeError: Error #1006: value is not a function.
    	at NEW_fla::MainTimeline/onDATA()
    i replaced "incomingVars" with d, because I already had that in my function as "d:String=readUTFBytes;"
    what does the (/\d+/g); mean?

  6. #6
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    You have strings in your ONarray in that code, but in your original post you had put the actual clips in. If you can put the actual clips in, it will make it much easier.

    You should trace d after reading it. It looks like you're only reading 2 bytes, which won't result in "mc1+2". If anything, it'll just get you "mc".

    /\d+/g is a regular expression. Broken down, here's how it works:
    \d means a digit. 0 through 9. + after that means "1 or more". The g at the end means "global" so it will find all matches of this pattern in the string. So, when we feed it "mc1+2" it finds 2 things that match that pattern: "1" and "2". If we fed it "mc100+23", it would find "100" and "23".

    I forgot to then convert those to numbers. Oops! Here are some corrected lines:
    Code:
    	var clipIndex:int = Number(embeddedNums[0]) -1; //because arrays start at 0.
    	var frameIndex:int =Number(embeddedNums[1]);
    Since your ONarray entries are strings, you cannot call goToAndStop on them. Strings don't have that method. If you want to keep strings in ONarray, you'll have to change the last line to:
    Code:
    this[ONarray[clipIndex]].goToAndStop(frameIndex);
    or
    Code:
    MovieClip(getChildByName(ONarray[clipIndex])).goToAndStop(frameIndex);
    Can you tell exactly which line is throwing the error?

  7. #7
    Senior Member
    Join Date
    Oct 2009
    Posts
    112
    ok i fixed those changes

    you know where it says readUTFBytes(2); ?
    well i think its actually only reading 1, because in the output before that error came up, it was always only giving out one of the bytes that i inputed.
    ex: if i tried to input "on1+2" it would only output the "o"
    and then i changed it to readUTFBytes(5); and its still only giving out the o....
    here's my code again:
    Code:
    var s:Socket = new Socket(MYsocketINFO);
    
    import flash.events.TimerEvent;
    var onTimer:Timer=new Timer(500);
    var ONarray:Array=new Array("on1","on2","on3","on4","on5",
    							"on6","on7","on8","on9","on9",
    							"on10","on11","on12","on13",
    							"on14","on15","on16","on17",
    							"on18","on19","on20","on21","on22",
    							"on23","on24","on25","on26","on27",
    							"on28","on29","on30","on31","on32");
    var onLastDown:MovieClip=null;
    s.addEventListener(ProgressEvent.SOCKET_DATA, onDATA);
    	function onDATA(e:ProgressEvent):void{
    	var d:String=s.readUTFBytes(5);
    	trace(d);
    	var embeddedNums:Array = d.match(/\d+/g);
    	var clipIndex:int = Number(embeddedNums[0]) -1; //because arrays start at 0.
    	var frameIndex:int = Number(embeddedNums[1]);
    	this[ONarray[clipIndex]].goToAndStop(frameIndex);
    }
    
    for (var i:uint; i < ONarray.length; i++) {
        var ON:MovieClip=getChildByName(ONarray[i]) as MovieClip;
    	ON.buttonMode = true;
    	ON.addEventListener(MouseEvent.MOUSE_DOWN, onPRESS);
    	ON.addEventListener(MouseEvent.MOUSE_UP, onRELEASE);
    	ON.doubleClickEnabled=true;
    	ON.addEventListener(MouseEvent.DOUBLE_CLICK, onDC);	
    	ON.stop();
    	var clipName:String=ON.name;
    	
    }
    idk if u would need to see the rest of the code to see the problem, i doubt it but if u do let me knwo and ill add the rest, with all the EventListener functions

  8. #8
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    What's on the other end of the socket? How are you doing the input to the socket? Why are you using a binary socket to send Strings? At the very least, use readUTF() rather than specifying a number of bytes.

  9. #9
    Senior Member
    Join Date
    Oct 2009
    Posts
    112
    on the other end of a socket i've used another software program (just to test for now), it has two text boxes, a send and a receive. when i put numbers into the SEND text box, i have sliders that move up and down, but i'll later need to change that to do the same thing i'm trying to do with these "on1","on2","on3","on4" buttons, because right now all the sliders move at the same time.

    i'm not sure why I use binary sockets, i was working with someone and we werent having succes with the xml sockets and then somehow we decided binary sockets were best.

    i tried using readUTF(), and I got the same error as before:
    Code:
    Error: Error #2030: End of file was encountered.
    	at flash.net::Socket/readUTF()
    	at D3264NEW_fla::MainTimeline/onDATA()
    other than the readUTF() change I just made, my code is exactly the same as what i last posted.
    do you think this problem has to do with where my event listeners are placed?

    and also i don't think its reading all the bytes, the only thing that came up in the traced output is the "o" when i tried to input "on1+2"

  10. #10
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    I've never dealt with sending strings like that through a binary socket. If the other end is not encoding them with the length prefix, that might result in that error.

    You may also need to check the socket's bytesAvailable property to make sure that there are enough bytes to read to get your entire string. Since that value will vary based on the length of the string, that will be difficult. If there's just the one byte available, that would explain why you kept getting just "o".

    I'd probably try to switch to sending ints instead of strings, or switch to an xml socket. Parsing is always a headache.

  11. #11
    Senior Member
    Join Date
    Oct 2009
    Posts
    112
    its working now that im usin BytesAvailable, another problem was that it said
    goToAndStop instead of
    gotoAndStop

    just one question, how come when i trace stuff in the OUTPUT, it comes out with the o on a seperate line?
    ex: i input "on1+2"
    and it comes out like this:

    o
    n1+2
    its still working so its not a problem, im just curious as to why it does that

  12. #12
    Senior Member
    Join Date
    Oct 2009
    Posts
    112
    actually for some reason a new problem just started happen randomly...
    i renamed all the movie clips ("s1","s2","s3","s4","s5","s6"etc....)
    and now when i input "s1", s1 automaticall jumps to frame 2, without waiting for the "+2"

    HOWEVER when i input "s1" and then "s1+1" it DOES jump back to frame 1. this would be fine to work wiht, but some buttons will eventually have more than 2 frames so I need to have full control over which frame its jumping to

    ex: sending s1 by its self should not do anything for right now.
    s1+1 means the movie clip s1 goes to frame 1
    s1+2 means the movie clip s1 goes to frame 2
    s30+4 means the movie clip s30 goes to frame 4
    etc....

    heres my code again:
    Code:
    var ONarray:Array=new Array("s1","s2","s3","s4","s5","s6","s7","s8","s9","s10","s11","s12","s13","s14",
    							"s15","s16","s17","s18","s19","s20","s21","s22","s23","s24","s25","s26","s27",
    							"s28","s29","s30","s31","s32","s33","s34","s35","s36","s37","s38","s39","s40",
    							"s41","s42","s43","s44","s45","s46","s47","s48","s49","s50","s51","s52","s53",
    							"s54","s55","s56","s57","s58","s59","s60","s61","s62","s63","s64");
    var onLastDown:MovieClip=null;
    s.addEventListener(ProgressEvent.SOCKET_DATA, onDATA);
    	function onDATA(e:ProgressEvent):void{
    	var d:String=s.readUTFBytes(s.bytesAvailable);
    	trace(d);
    	var embeddedNums:Array = d.match(/\d+/g);
    	var clipIndex:int = Number(embeddedNums[0]) -1; //because arrays start at 0.
    	var frameIndex:int = Number(embeddedNums);
    	this[ONarray[clipIndex]].gotoAndStop(frameIndex);
    }
    
    for (var i:uint; i < ONarray.length; i++) {
        var ON:MovieClip=getChildByName(ONarray[i]) as MovieClip;
    	ON.buttonMode = true;
    	ON.addEventListener(MouseEvent.MOUSE_DOWN, onPRESS);
    	ON.addEventListener(MouseEvent.MOUSE_UP, onRELEASE);
    	ON.doubleClickEnabled=true;
    	ON.addEventListener(MouseEvent.DOUBLE_CLICK, onDC);	
    	ON.stop();
    	var clipName:String=ON.name;
    	
    }

  13. #13
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    You need to use s.bytesAvailable to determine whether there's enough to read your complete string, not just as a limit on readUTFBytes. As it is, it looks like you get one data event when there's one byte ("o"), and one after that with the rest. That explains why you're getting two different traces. You also need to use embeddedNums[1] rather than the embeddedNums array when setting frameIndex. That doesn't explain why it works sometimes and not others though. You either mistyped it when posting it just now, or something weirder is going on.

    Once again, I strongly suggest changing the data you send over the socket to pairs of ints rather than variable length strings with parts that are ignored.

  14. #14
    Senior Member
    Join Date
    Oct 2009
    Posts
    112
    im sure i didnt misstype it...i copied it exactly after the last time i tested it, and just double checked it. it was working sometimes, and after i changed all the numbers to s1,s2,s3 it just started to do that:
    when i input s1, it sends s1 to frame 2.....but when i do s1+1 it does send s1 back to frame 1
    i am now using the bytesAvailable function, could there be an error in your function?

  15. #15
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    Of course there could be an error in my code since I'm completely unable to run tests on it.

    My point above was that there are logical errors in the code you posted. You are attempting to convert an Array to a Number, instead of converting the String containing that number into a Number. This should never work. At best, you get 0 out as the number. I have no idea why it would differ depending on what you send, since it isn't even looking at the second number you send.

    You are using bytesAvailable, but you are not using it to check whether there are enough bytes available to actually get the data you want. You'd have to have something like:
    Code:
    if (s.bytesAvailable >= 4){
      //read just enough bytes.
      //do code to process.
    }
    As it is now, you are simply reading however many bytes are ready. That could be "s", or it could be "s1+" or it could be "s1+1s2+4", or any other combination of stuff you've sent along.

    Your communication protocol is really not suited for a binary socket, since you are not taking advantage of the binary nature, and you have variable length packets ("s1+1" is 4, but "s10+2" is 5). All you really need to send is two ints. The first represents which movie, the second represents which frame. Doing it that way would let you check whether there are enough bytes available (2*4bytes per int = 8 bytes), and only process when there are enough to read both. And you'd then never read too much which would screw up the processing of the next signal.

  16. #16
    Senior Member
    Join Date
    Oct 2009
    Posts
    112
    oh ok i see what your saying. is there a way to separate messages by a period? so that if i send s1+2.s30+4. etc it will know that there are two different messages (even though each message is a different lenght-so potentially it wouldnt screw up the processing of the next signal)?

    where exactly would you put in that bit of code? here's what i tried:
    Code:
    var ONarray:Array=new Array("s1","s2","s3","s4","s5","s6","s7","s8","s9","s10","s11","s12","s13","s14","s15");
    var onLastDown:MovieClip=null;
    s.addEventListener(ProgressEvent.SOCKET_DATA, onDATA);
    	function onDATA(e:ProgressEvent):void{
    	var d:String=s.readUTFBytes(s.bytesAvailable);
    	trace(d);
    	if (s.bytesAvailable >= 4){
    		var embeddedNums:Array = d.match(/\d+/g);
    		var clipIndex:int = Number(embeddedNums[0]) -1; //because arrays start at 0.
    		var frameIndex:int = Number(embeddedNums);
    		this[ONarray[clipIndex]].gotoAndStop(frameIndex);
    	}
    }
    but now its ignoring anything i input so in the meantime ill keep researching and tryin different ways of the code i have

  17. #17
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    You've already got a character which effectively separates your messages. You can use 's' rather than adding a period.

    But, to do it this way, you'll have to have a buffer String in your class. When new data comes in, you need to read all of it. Append that data to the buffer, then split the buffer by your delimiter ('s', or '.'). Handle all of the complete messages, and leave whatever's left over in the buffer to be appended to by the next incoming data. Your incoming data function should be separate from the function which handles a message, since they are not one-to-one.

  18. #18
    Senior Member
    Join Date
    Oct 2009
    Posts
    112
    Code:
    var d:String=s.readUTFBytes(s.bytesAvailable.split(".");
    does delimiter mean the symbol/letter that is being used to separate each line of code. and do you know how i would put this into the code? earlier u said
    Code:
    var embeddedNums:Array = incomingVar.split("|");
    but that will give me a duplicate function error because i already have
    Code:
    var embeddedNums:Array = incomingVar.match(/\d+/g);

  19. #19
    Will moderate for beer
    Join Date
    Apr 2007
    Location
    Austin, TX
    Posts
    6,801
    Yes, the delimiter is the token (symbol/letter) used to separate the stuff you care about.

    The split and match methods are two different ways of parsing useful stuff out of your string. Do one or the other, but not both to do the same task. I do use both below, because we are parsing at two different levels. The split separates messages, the match parses an individual message.

    Also, you can't call bytesAvailable.split because bytesAvailable is an int. You'd need to split the result of reading the bytes. It looks like that was just a typo above.

    Code:
    var socketBuffer:String = "";
    s.addEventListener(ProgressEvent.SOCKET_DATA, onDATA);
    function onDATA(e:ProgressEvent):void{
      var d:String=s.readUTFBytes(s.bytesAvailable);
      socketBuffer = socketBuffer.concat(d);
      var tokens:Array = socketBuffer.split(".");
      var done:Boolean = false;
      while (tokens.length > 1 && !done){
        var token:String = tokens.shift();
        if (!processToken(token)){
           socketBuffer = token;
           done = true;
        }
      }
    }
    
    function processToken(token:String):Boolean{
      var embeddedNums:Array = token.match(/\d+/g);
      if (embeddedNums.length < 2){
        return false;
      }
      var clipIndex:int = Number(embeddedNums[0]) -1; //because arrays start at 0.
      var frameIndex:int = Number(embeddedNums[1]);
      this[ONarray[clipIndex]].gotoAndStop(frameIndex);
      return true;
    }
    You must send a final "." after the last message in this scheme. Again, because this is complex stuff and I can't test it, there are probably lurking bugs.
    Last edited by 5TonsOfFlax; 11-16-2009 at 01:41 PM.

  20. #20
    Senior Member
    Join Date
    Oct 2009
    Posts
    112
    wow...nearly no errors at all.

    idk if u remember but i said i have two text boxes built in another program with the purpose to interact with flash. thers an INPUT and OUTPUT, so when i click the movie clips i recieve messages in the OUTPUT, and when i need to tell the movie clip to go to the next frame, i type s30+2 (for example) into the INPUT.

    when i pretype s30+2. and copy and paste it into the INPUT, this works perfectly with no errors. when i just type it regularly (like character by character) into the box it says "a term is undefined and has no properties : processToken."

    im thinkin this might be ok, because the other program i'm using will eventually be submitting the full message (s30+2.), not typing it character by character. but i thought id just double check with you, do you see any potential problems wiht this? does that make sense?
    Last edited by mattwatts15; 11-16-2009 at 05:00 PM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center