A Flash Developer Resource Site

Results 1 to 18 of 18

Thread: [AS3] looping and manipulating arrays

  1. #1
    Member
    Join Date
    May 2008
    Posts
    49

    [AS3] looping and manipulating arrays

    Hey I am working on a project and I need to loop through a couple arrays.

    oX:Array = new Array(); //location of the movieclip top left registration point
    oY:Array = new Array(); //same but for the y location
    oMc:Array = new Array(); //houses the movieclip for this object (x,y)
    oW:Array = new Array(); //width of the MC
    oH:Array = new Array(); //height of the MC

    Now the viewing area is 800x400 pixles. I want to be able to place movieclips on a much larger sprite if they are in the viewing area based on the arrays above. Then removed if they ouside.

    As of now I know how to determine the screens display area. I know a couple ways to do this, but im not sure about memory leaks, and effeciency.

    Right now i figure i can use a for loop and go through the length of oX:array. For everything greater than the area in view, and less than the area in view, put them into a new array. Then i can use another for loop on the new array, checking to see if any of those are in oY.

    Any constuctive ideas or elaborations?

  2. #2
    Senior Member tonypa's Avatar
    Join Date
    Jul 2001
    Location
    Estonia
    Posts
    8,223
    Not sure why you need so many arrays. You could simply use 1 array where movie clips are and loop through that one, comparing coordinates with screen size.

  3. #3
    Developer
    Join Date
    Apr 2007
    Location
    UK
    Posts
    324
    He's using code from striile (where is he nowadays?):
    http://www.strille.net/tutorials/part1_scrolling.php

    code for how to loop through it is already on that page...
    now known as dVyper

  4. #4
    Member
    Join Date
    May 2008
    Posts
    49
    tonypa - because I will need to add and removeChild as they are no longer on the stage. I will also need to remove any listeners. As far as having an array for X and one for Y, should I use one array and take advantage of points. ie) coords:array = new Array(new Point(100,250));

    Cortana, your correct, im trying to adapt that for AS3, but I dont know as1 or 2. And am still learning three. I know he has a loop, I sort of understand that, but im asking if this is the most efficent way. Or does as3 offer any way to automate, or offer any built in array functions or what have you, that would make this process easier, or less strainful on the engine.

  5. #5
    Truimagz.com everfornever's Avatar
    Join Date
    Sep 2006
    Location
    St. Louis
    Posts
    1,306
    You can use 1 array and then use an Object to store extra data.

    for example

    var obj : Object = new Object ();

    obj.pos = [xpos, ypos]

    myArray[0] = obj

  6. #6
    Member
    Join Date
    May 2008
    Posts
    49
    Do you think objects combined with arrays will use less memory? Also im doikng this project in OOP style, so rather than objects, I would probably use a class. And as far as your example, i would probably use a POINT to store that particular data.

    I guess my main question is the best way to arrange the data, so that pulling specific points will use the least ammount of resources possible.


    IE I have 5 points (0,32) (16,16) (100,132) (416,32) (432,64)
    my screen is 400x400 pixles

    that means if I am viewing the top left, i can see (0,32) (16,16) (100,132).
    The reason I dont want to default to looping through an array looking for > < something, is that this list will eventually have THOUSANDS of locations. This loop will be called every time the player moves his screen more than the viewing area, so very often.

    Is there a more efficent way than looping through greater than less than, then removingChild and addingChild?



    EDIT: One thing i was contimplating is combinding the X location and Y location array into a position array, and adding a Point(x,y) for one location. Advantage: This would allow me to sort the array by decending or accending X values. Further Advantage: It would allow me to break the loop after I got past a certain X position, rather than looping through all objects to find them.
    Last edited by cyberoptics; 09-02-2008 at 09:58 AM.

  7. #7
    Student
    Join Date
    Apr 2001
    Location
    -
    Posts
    4,756
    better handle the arrays like this for example
    PHP Code:
    var array:Array = new Array();
    function 
    addMc(mc){
        array.
    push( {x:mc.x,y:mc.y,w:mc.width,h:mc.height});

    and then loop through it like this
    PHP Code:
    for (var i:int=0;i<array.length;i++){
        
    trace(i+".: "+array[i].x+" / "+array[i].y);


  8. #8
    Truimagz.com everfornever's Avatar
    Join Date
    Sep 2006
    Location
    St. Louis
    Posts
    1,306
    There ya go.

    That's what I was thinking, Render accomplished it without using an object.

  9. #9
    Member
    Join Date
    May 2008
    Posts
    49
    Now in http://www.strille.net/tutorials/part1_scrolling.php he says to try to avoid multi dimensional arrays as much as possible for the purpose of speed. Having such a large multi array, how would performance be affected if the function to search it was called very often?

  10. #10
    Member
    Join Date
    May 2008
    Posts
    49
    and rather than looping, what about built in array functions?

    For example: using myArray.filter(viewableInScreen);

    private function viewableInScreen(element:*,index:int, arr:Array)
    {
    if(element.x > leftscreen < rightscreen)
    {
    return true;
    }{else
    return false;
    }

    This is just an example of trying to use built in methods, although ive never used this one, and there might be flaws or errors in this.

  11. #11
    Member
    Join Date
    May 2008
    Posts
    49
    Actually this might all not be necessary. This is why.

    My game is going to use PHP. As such, the game area is broken into much larger super tiles. Everytime the player moves to a different super tile, a load request is sent to the server requesting all buildings from the database that are viewable.

    The server then returns xml with the building number (used to know which mc and functions to give it), x locaton, y location, and owner of the building.

    The game willt he parse the XML depending on how many buildings are returned for the area.

    NOTE: I will make a building class

    The game will then buildings.push( new Building(xloc,yloc,buildID,"owner");
    creating a new instance of the building in the array for that area. Based on how the data is pulled, it will upon creating be addChild so that the graphic in building.as is made viewable.

    When the player moves into a new supertile, the process will continue, however, it will removeChild all buildings in the array, also remove any added listeners. Clear the array buildings = [];

    In theory this should work, but my only question is this. This method will create hundreds, if not thousands of instances, that are no longer used once the player goes to another section of the map. This seems wasteful if the player goes back to locations hes already been. Thus polling the server when not needed wasting bandwith, and creating instances of objects that were already made, and not changed.

    Note: This is a turn based game, so not much will change between the hours when everything is refreshed. Any suggestions?

  12. #12
    Senior Member
    Join Date
    Mar 2008
    Posts
    301
    Flash has a built in Rectangle class, I'm sure you know. I can't give you much information on the real speed of some of this stuff, but if we assume that using built in flash functions is faster than otherwise, then you could do something like this:

    (I am assuming that you don't just want to know if the (x,y) point is on screen, but actually whether the image intersects the screen at all)

    Code:
    var imgArray = (an array of whatever images you're working with);
    
    var stageRec = new Rectangle(0,0,stage.stageWidth,stage.stageHeight);
    
    var recArray = imgArray.map(function(...e):Rectangle{return new Rectangle(e[0].x,e[0].y,e[0].width,e[0].height);});
    and then loop through it like this

    Code:
    var insideArray = recArray.filter(function(...e):Boolean{return stageRec.intersects(e[0]);});

    That's if your things aren't moving around. (Although if they aren't moving, I assume that just sorting them at the start somehow would be far more efficient than looping through all of them every time) If they're moving, you should use this to loop instead:


    Code:
    var insideArray = recArray.filter(function(...e):Boolean{e[0].x=imgArray[e[1]].x;e[0].y=imgArray[e[1]].y;return stageRec.intersects(e[0]);});


    But generally I agree about just using Objects (or a specific class, whatever) being the best way, so that one array stores everything. Would just look like this:

    Code:
    
    var tempImgArray = (an array of whatever images you're working with);
    
    var stageRec = new Rectangle(0,0,stage.stageWidth,stage.stageHeight);
    
    var imgArray = tempImgArray.map(function(...e):Object{return {img:e[0],rec:new Rectangle(0,0,e[0].width,e[0].height),vis:false};});
    
    
    function loopfunc():void {
          imgArray.forEach(
                function(...e):void {
                      stageRec.offset(-e[0].img.x,-e[0].img.y);
                      if (stageRec.intersects(e[0].rec)) {
                            if (!e[0].vis) {
                                  e[0].vis = true;
                                  someAddImgFunction(e[0].img);
                            }
                      } else {
                            if (e[0].vis) {
                                  e[0].vis = false;
                                  someRemovedImgFunction(e[0].img);
                            }
                      }
                     stageRec.offset(e[0].img.x,e[0].img.y);
                }
          );
    }
    somefin like that maybe
    Last edited by WesIsGood; 09-02-2008 at 11:27 AM.

  13. #13
    Pumpkin Carving 2008 ImprisonedPride's Avatar
    Join Date
    Apr 2006
    Location
    Grand Rapids MI
    Posts
    2,378
    Squize wrote a good article here: http://blog.gamingyourway.com/PermaL...e75aaaafa.aspx. Worth a read.
    The 'Boose':
    ASUS Sabertooth P67 TUF
    Intel Core i7-2600K Quad-Core Sandy Bridge 3.4GHz Overclocked to 4.2GHz
    8GB G.Skill Ripjaws 1600 DDR3
    ASUS ENGTX550 TI DC/DI/1GD5 GeForce GTX 550 Ti (Fermi) 1GB 1GDDR5 (Overclocked to 1.1GHz)
    New addition: OCZ Vertex 240GB SATA III SSD
    WEI Score: 7.6

  14. #14
    Hype over content... Squize's Avatar
    Join Date
    Apr 2001
    Location
    Lost forever in a happy crowd...
    Posts
    5,926
    Thanks for the pimp. I'd never considered using that with a superTile engine, I guess it could work, although with too many objects you may start to lose performance.

    Rectangle.intersection is evil slow, it's best to check the values by hand.

    Having a large multi-dim array in as3 isn't a bad thing, nothing really is in as3, that baby can fly.

    Just thinking off the top of my head, could the arrays be stored in sectors ? Say you've got a 4000x4000 sized play area, with a visible screen window of 400x400, you could split that play area up and then just test the arrays that are near to the player. Perhaps then with a combination of distance based broadphase it could run nice and quick 'cause there will never be enough objects ( In theory ) to choke it.

    Squize.

  15. #15
    Senior Member
    Join Date
    Mar 2008
    Posts
    301
    Rectangle.intersection is evil slow, it's best to check the values by hand.
    Really? I figured built in functions would be efficient.

    You mean "Rectangle.intersects" as well as "Rectangle.intersection", correct? I'm sure Rectangle.intersection would be slower because it calculates the intersection rectangle, whereas intersects just checks whether the rectangles have any intersection, but doesn't care what that intersection is.

  16. #16
    Senior Member
    Join Date
    Mar 2008
    Posts
    301
    I just did a speedcheck and you're right, Rectangle.intersects is significantly slower than manual checking. Like 2.5 times slower. Surprising.

  17. #17
    Hype over content... Squize's Avatar
    Join Date
    Apr 2001
    Location
    Lost forever in a happy crowd...
    Posts
    5,926
    "you're right"

    Thanks

    Squize.

  18. #18
    Member
    Join Date
    May 2008
    Posts
    49
    Quote Originally Posted by Squize

    Just thinking off the top of my head, could the arrays be stored in sectors ? Say you've got a 4000x4000 sized play area, with a visible screen window of 400x400, you could split that play area up and then just test the arrays that are near to the player. Perhaps then with a combination of distance based broadphase it could run nice and quick 'cause there will never be enough objects ( In theory ) to choke it.

    Squize.
    Thats one thing i was considering is having an area for every section. As it stands, every time i scroll to the next screen, it can trace the section im in. I was thinking of having an array for every section. But this is what I will do for now to make my life easier since it is a turn/tick based multiplayer game drawing data from php/mysql.

    Every time a arrive in a new section I will load the sections point(x,y) into an array of super tiles I've visted. I will then use a load event to pull the buildings that are in this area from the DB using a return XML. It will then parse the XML and add each building in the section to an Buildings:Array (which will be an instance of a building class, containing but not limited to the buildingID, x location, y location, and movieclip). If this is the first visit to this section, it will addChild now to make the object visible.

    If you are revisiting a section, or just polling the section for new data, it will submit a load. It will then check the buildings returned, [i am now speculating] using a for ... in loop to see if the MC has been added to screen. If so, it will do nothing, if not, it will push it to Buildings:Array and addChild.

    I just need to find a way to remove data that is no longer valid. Like a destroyed building.

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