A Flash Developer Resource Site

Results 1 to 12 of 12

Thread: [Tutorial] independent scrolling

  1. #1
    Student
    Join Date
    Apr 2001
    Location
    -
    Posts
    4,756

    [Tutorial] independent scrolling

    independent scrolling tutorial

    a regular member here asked me help him with some scrolling issues since he noticed that I somehow fixed something most scrolling mechanics have in common:
    they can´t update independently meaning if either booth axis need to be updated and or booth with different offset values the engine wont update propper since it´s often programmed in a linear manner wich only exepts linear speeds/ offsets. This idea is part of my "Tank Move" project wich requires something like this as the map can be navigated in realtime without movement delays.

    My method wich I will explain in the following and wich is posted with source code and authoring files has some special features:
    - scrolling wich updates only the tiles that really need to be updated. Not the whole screen. Though map movement requires only displacing 1 container movie
    - gap control, if the offset is greater then 1 row (most engines) it updates thus more rows (if needed on booth axis)
    - using only that many tiles as visible on the screen. No target swapping or _visible=true/false hack. Makes it even faster and less memory intense as other methods.

    I assume that the readers are already familar with basic scrolling mechanics. For those that arent:
    Basicly the aim is to save CPU resources by updating a grid- layout of graphics (called tiles) only at those spots where the camera is moved to. Movement is usually done with just 1 container instead of using a loop for all graphics aka tiles.

    so first a demo:
    http://www.renderhjs.net/bbs/flashki...ll/demo_03.swf
    and here a performance demo:
    http://www.renderhjs.net/bbs/flashki...ormance_03.swf
    (this bigger screen demo manages 368 screen tiles (the ones that are visible!), the ones a map can contain are almost unlimited)

    the red fading cells (in the first demo) are the ones that got updated recently, move the mouse to scroll the map and see wich cells are updated. If you move the mouse instantly you´d see that the whole screen or a big area of the screen is updated. The less tiles need to be updated the faster it runs, though if you move instantly to a new area you wont notice that much the delay since visually speaking there is anyway a flash.

    I´ll let first these pictures explain some basics and the concept my method:

    as mentioned in the last part here is smal video how we progress if booth axis change

    here is a demo where the last fix isn´t applied:
    http://www.renderhjs.net/bbs/flashki...rong_shift.swf
    as you can see some lines are off wich we dont want and thus need that final fix


    so how did I translate this into AS?
    first some variables, array and object declarations- the ones that will be used on this level/ class, some additional explainations:
    - matrix_x[]/matrix_x[] = are the rulers as I described them earlier. They contain the sequential numbers of the first lopps that we use init function later on.

    PHP Code:
    var screen = {w:320,h:200};//screen dimensions
    var tile = {w:32,h:32};//tile dimensions

    var matrix_x = new Array();//described before as ruler-x
    var matrix_y= new Array();

    var 
    map = new Array();
    map = [[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
            [
    1,0,0,0,1,0,1,1,1,1,0,1,1,1,0,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,1],
            [
    1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,0,1,1,0,1,1,1],
            [
    1,0,0,1,1,0,1,1,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,1,1,0,1,1,0,1,1,1],
            [
    1,0,1,1,1,0,1,1,1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,1,1,1],
            [
    1,0,1,1,1,0,0,0,1,0,1,0,1,0,0,1,1,0,1,0,1,0,1,0,1,0,1,1,0,1,0,1],
            [
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
            
            [
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
            [
    1,0,0,0,1,0,1,1,1,1,0,1,1,1,0,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,1],
            [
    1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,0,1,1,0,1,1,1],
            [
    1,0,0,1,1,0,1,1,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,1,1,0,1,1,0,1,1,1],
            [
    1,0,1,1,1,0,1,1,1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,1,1,1],
            [
    1,0,1,1,1,0,0,0,1,0,1,0,1,0,0,1,1,0,1,0,1,0,1,0,1,0,1,1,0,1,0,1],
            [
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]];

    var 
    last_cx 0;//last corner X
    var last_cy 0;

    var 
    tiles_x 0;//x-tiles amount that are used for the screen width
    var tiles_y 0
    now some simple functions:

    - getZ: function to manage the unique ID´s - this can be later used as well for the z-Ordering including sub-layer depth manegement. In this sample code a map can only be max. 100 cells width otherwise the values it returns are no unique ones anymore
    - update_cell(): core function that updates a single tile. Add layers or whater complex structure here to give your tiles complexity
    - init(): does what it stands for inite all basic elements like creating the tiles that are pushed later on the screen. tiles_x stand for the amount of tiles that are needed on the x-axis. The rulers-> now known as matrix_y and matrix_x are filled as well here with the i and j loop numbers so in each case 0,1,2,3,...
    the init(); functions is called at the end and so does it all start. If you compile the current code it should already display the map - but scrolling doesn´t work yet.
    PHP Code:
    function getZ(x,y){//get unique depth ID
        
    var val = (y*100)+x+1;
        return 
    val;
    }
    function 
    update_cell(z,x,y){//update single cell...
        
    var trgt mc_scene.stage;
        
    trgt["t"+z].tex.removeMovieClip();//remove previous item
        
    if ( map[y][x] == 0){
            
    trgt["t"+z].attachMovie("B","tex",1);
        }else{
            
    trgt["t"+z].attachMovie("A","tex",1);
        }
    }

    function 
    init(){//init screen, resets all
        
    var trgt mc_scene.stage;//target to dump tiles inside
        
        
    tiles_x Math.ceil(screen.tile.w)+1;//amount of tiles on x-axis
        
    tiles_y Math.ceil(screen.tile.h)+1;
        
    //check if those screen tiles are not more as the map dimensions
        
    if (tilesX map[0].lengthtilesX map[0].length;
        if (
    tilesY map.lengthtilesY map.length;
        
        
    matrix_x = new Array();
        
    matrix_y = new Array();
        
        for (var 
    i=0;i<tiles_y;i++){
            
    matrix_y.push(i);
            for (
    j=0;j<tiles_x;j++){
                if (
    i==0){
                    
    matrix_x.push(j);
                }
                var 
    getZ(j,i);//unique ID
                
    trgt.createEmptyMovieClip("t"+z,z);//create tile
                
                
    trgt["t"+z]._x j*tile.w;
                
    trgt["t"+z]._y i*tile.h;
                
                
    update_cellzji);//z,x,y
            
    }
        }
    }
    init(); 
    now comes the difficult part , just kidding first something easy:
    PHP Code:
    _root.onEnterFrame = function(){
        var 
    = (_xmouse-mc_scene._x)*-2.5;
        var 
    = (_ymouse-Stage.height/2)*-2.5;
        
    scroll_screen(x,y);

    a enterFrame event will call a function named scroll_screen with negative values (remember opposite directions of camera/screen). This function will displace the map to the x and y coordinates and based on how much was moved move within that map movieClip the tiles that switch places

  2. #2
    Student
    Join Date
    Apr 2001
    Location
    -
    Posts
    4,756
    ok now the heavy function,- but I´ll split it for you
    A.) basic structure:
    - check if shift x and shift y (sx,sy) values are above 0 if so set them to 0
    - set variable cornder x/y wich is basicly the upper left corner in tiles in wich the map is currently placed. This value is needed for calculating later the offset values but also to check if the screen even needs to be updated or if the camera is idle.
    - check if movement changed from last update (note smal mouse movement dont need to affect the update process)
    - check within that if it´s moved on the x- axis, on the y-axis and in the end if it perhaps move(s/d) on booth axis?
    - update values of last_cx so that it can be compared next time again
    - at the very end move the map movieClip
    PHP Code:
    function scroll_screen(sx,sy){//shift x, shift y
        
    var trgt mc_scene.stage;//the movieClip wich contains the tiles
        
        
    if (sx>0)sx=0;
        if (
    sy>0)sy=0;
        
        
        var 
    cx Math.ceil(sx/tile.w);//corner x
        
    var cy Math.ceil(sy/tile.h);//corner y

        
    if ( ((cx !=last_cx) || (cy !=last_cy)) ){
            if (
    cx !=last_cx){//moved on the x-axis
                /*
                swap cells on the x-axis
                
                B.)
                
                */
            
    }
            if (
    cy !=last_cy){//moved on the y-axis
                /*
                swap cells on the y-axis
                
                C.)
                
                */
            
    }
            if (
    cx !=last_cx && cy !=last_cy  ){//moved on the x and y-axis, fix first x-row(s)
                /*
                fix x-cells as explained before
                
                D.)
                
                */
            
    }
            
            
    last_cx cx;//update last corner_x, so it can be compared next time again
            
    last_cy cy;
        }
        
    trgt._x sx;//displace the movieClip
        
    trgt._y sy

    B.) swap cells on the x-axis
    - determine the gap between the current and the last cell x offset, e.g it could been shifted by -1 cells
    - skip = absolute value of the gap value in order to loop through it later
    - loop through the amount of skips - thus the amount of cell rows wich need to be pushed {
    ....- check if cells need to be pushed to the left or the right side of the screen {
    ......- loop through screen y-tiles {
    .........- r = remaining value of the skip,- it basicly counts down insead of wha the i var does. So the r variable goes for example like: 2,1,0
    .........- x= first item of the x-ruler
    .........- y= squential i item of the y-ruler
    .........- z= get the id based on the collected x and y coordinates,- this z id will guide us to the tile of those x/y coordinates
    .........- trgt["t"+z]._x = move the current tile from the left side to the right side-with the gap value in mind
    .........- x= new map x position (note: not what was in the x-ruler before, but rather a absolute map coordinate
    .........- y= same as x but now for y: absolute y- map coordinate
    .........- update_cell(z , x , y ); = udpate the cell with still the z- id (note "z" id hasn´t been changed in the last 3 lines). This will render or update the new tile
    .....- matrix_x.push(matrix_x.shift()); = updates the x-ruler array and does the same as we did with the tiles before but only with the 1 dimensional array

    the other part does the same for the other direction wich basicly moves the cells from the lefst side of the screen to the right side of the screen if the tiles need to be moved to that direction
    PHP Code:
    var gap cx last_cx;
    var 
    skip =Math.abs(gap);
        
    for (var 
    j=0;j<skip;j++){
        if (
    gap 0){//<<   new line left
            
    for (var i=0;i<tiles_y;i++){//for each row, //first to last pos, all others move up
            //take first
                
    var r  skip- (j+1);//remain 3-(0+1) = 2
                
    var matrix_x[0];
                var 
    matrix_y[i];
                var 
    getZ(x,y,1);//1 as inital setup
                
                
    trgt["t"+z]._x = ( tiles_x )*tile.w  - (cxr  )*tile.w;//left to right
                
                
    var = -cx+(tiles_x-1)- r;
                var 
    -cy;
                
    update_cell();
            }
            
    matrix_x.push(matrix_x.shift());//move first item to the end of the array
        
    }else{//>> new line right, 
            
    for (var i=0;i<tiles_y;i++){//for each row, //first to last pos, all others move up
                
                
    var r  skip- (j+1);//remain 3-(0+1) = 2
                
    var matrix_x[matrix_x.length-1];
                var 
    matrix_y[i];
                var 
    getZ(x,y,1);//1 as inital setup
                
                
    trgt["t"+z]._x = (0)*tile.w  - (cx-r)*tile.w;//
                
                
    var = -cx+r;
                var 
    -cy;
                
    update_cell();
            }
            
    matrix_x.unshift(matrix_x.pop());
        }


    C.) swap cells on the y-axis
    now for this part you dont need to use your brain that much,- its the same procedure as for the x-axis just swap all the x characters with y and w with h

    PHP Code:
    var gap cy last_cy;
    var 
    skip =Math.abs(gap);

    for (var 
    j=0;j<skip;j++){
        if (
    gap 0){//^^   new line down
            
    for (var i=0;i<tiles_x;i++){//for each row, //first to last pos, all others move up
            //take first
                
    var r  skip- (j+1);//remain 3-(0+1) = 2
                
    var matrix_y[0];
                var 
    matrix_x[i];
                var 
    getZ(x,y,1);//1 as inital setup
                
                
    trgt["t"+z]._y = ( tiles_y )*tile.h  - (cyr  )*tile.h;//+ cx
                
                
    var = -cy+(tiles_y-1)- r;
                var 
    -cx;
                
    update_cell();
            }
            
    matrix_y.push(matrix_y.shift());
        }else{
    //>> new line right, 
            
    for (var i=0;i<tiles_x;i++){//for each row, //first to last pos, all others move up
                
                
    var r  skip- (j+1);//remain 3-(0+1) = 2
                
    var matrix_y[matrix_y.length-1];
                var 
    matrix_x[i];
                var 
    getZ(x,y,1);//1 as inital setup
                
                
    trgt["t"+z]._y = (0)*tile.h  - (cy-r)*tile.h;//
                
                
    var = -cy+r;
                var 
    -cx;
                
    update_cell();
            }
            
    matrix_y.unshift(matrix_y.pop());
        }

    D.) swap cells on the y-axis
    remember we need to fix something if it scrolled on the x and y axis that part comes now.
    - so first check if it scrolled on the x and y axis
    from the issue I illustrated in the beginning (the gif animation) you should now know that we just need to fix 1 row on the x-ruler so it follows a little bit the first part [that was B.) ]
    - so again we calculate the gap value, the absolute skip value based on it
    - next is to undo the ruler x aka matrix_x array,- I guess I did this so that I could just reuse the code from part B.) because now we have the ruler-x state we had from the beginning. Within this loop/ procedure of course we need to determine wether to undo the operation by shifting the array in it´s supposed direction. Note that the y-ruler array aka matrix_y wont be changed since we dont need to fix that axis
    - from here on we apply the same code from part B.) it will fix the row like illustrated in the beginning
    PHP Code:
    if (cx !=last_cx && cy !=last_cy  ){//moved on the y-axis
        
    var gap cx last_cx;
        var 
    skip =Math.abs(gap);
        
        for (var 
    j=0;j<skip;j++){//reset
            
    if (gap 0){
                
    matrix_x.unshift(matrix_x.pop());
            }else{
                
    matrix_x.push(matrix_x.shift());
            }
        }
        for (var 
    j=0;j<skip;j++){
            if (
    gap 0){//<<   new line left
                
                
    for (var i=0;i<tiles_y;i++){//for each row, //first to last pos, all others move up
                //take first
                    
    var r  skip- (j+1);//remain 3-(0+1) = 2
                    
    var matrix_x[0];
                    var 
    matrix_y[i];
                    var 
    getZ(x,y,1);//1 as inital setup
                    
                    
    trgt["t"+z]._x = ( tiles_x )*tile.w  - (cxr  )*tile.w;//+ cx
                    
                    
    var = -cx+(tiles_x-1)- r;
                    var 
    -cy;
                    
    update_cell();
                }
                
    matrix_x.push(matrix_x.shift());
            }else{
    //>> new line right, 
                
    for (var i=0;i<tiles_y;i++){//for each row, //first to last pos, all others move up
                    
                    
    var r  skip- (j+1);//remain 3-(0+1) = 2
                    
    var matrix_x[matrix_x.length-1];
                    var 
    matrix_y[i];
                    var 
    getZ(x,y,1);//1 as inital setup
                    
                    
    trgt["t"+z]._x = (0)*tile.w  - (cx-r)*tile.w;//
                    
                    
    var = -cx+r;
                    var 
    -cy;
                    
    update_cell();
                }
                
    matrix_x.unshift(matrix_x.pop());
            }
        }

    puh so that was it basicly,- dont worry if you didn´t get it all or hardly anything as I provided the complete sample code at the end and a very simplified fla that should be very easy to modify. Play with it if you think it might be usefull for you
    as mentioned here the complete code:
    PHP Code:
    var screen = {w:320,h:200};//screen dimensions
    var tile = {w:32,h:32};//tile dimensions

    var matrix_x = new Array();
    var 
    matrix_y= new Array();

    var 
    map = new Array();
    map = [[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
            [
    1,0,0,0,1,0,1,1,1,1,0,1,1,1,0,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,1],
            [
    1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,0,1,1,0,1,1,1],
            [
    1,0,0,1,1,0,1,1,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,1,1,0,1,1,0,1,1,1],
            [
    1,0,1,1,1,0,1,1,1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,1,1,1],
            [
    1,0,1,1,1,0,0,0,1,0,1,0,1,0,0,1,1,0,1,0,1,0,1,0,1,0,1,1,0,1,0,1],
            [
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
            [
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
            [
    1,0,0,0,1,0,1,1,1,1,0,1,1,1,0,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,1],
            [
    1,0,1,1,1,0,1,1,1,0,1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,0,1,1,0,1,1,1],
            [
    1,0,0,1,1,0,1,1,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,1,1,0,1,1,0,1,1,1],
            [
    1,0,1,1,1,0,1,1,1,0,1,0,1,1,1,0,1,0,1,0,1,0,1,0,1,0,1,1,0,1,1,1],
            [
    1,0,1,1,1,0,0,0,1,0,1,0,1,0,0,1,1,0,1,0,1,0,1,0,1,0,1,1,0,1,0,1],
            [
    1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]];

    var 
    last_cx 0;
    var 
    last_cy 0;
    var 
    tiles_x 0;
    var 
    tiles_y 0;



    function 
    getZ(x,y){//get unique depth ID
        
    var val = (y*100)+x+1;
        return 
    val;
    }
    function 
    update_cell(z,x,y){//update single cell...
        
    var trgt mc_scene.stage;
        
    trgt["t"+z].tex.removeMovieClip();//remove previous item
        
    if ( map[y][x] == 0){
            
    trgt["t"+z].attachMovie("B","tex",1);
        }else{
            
    trgt["t"+z].attachMovie("A","tex",1);
        }
    }


    function 
    init(){//init screen, resets all
        
    var trgt mc_scene.stage;//target to dump tiles inside
        
        
    tiles_x Math.ceil(screen.tile.w)+1;//amount of tiles on x-axis
        
    tiles_y Math.ceil(screen.tile.h)+1;
        
    //check if those screen tiles are not more as the map dimensions
        
    if (tilesX map[0].lengthtilesX map[0].length;
        if (
    tilesY map.lengthtilesY map.length;
        
        
    matrix_x = new Array();
        
    matrix_y = new Array();
        
        for (var 
    i=0;i<tiles_y;i++){
            
    matrix_y.push(i);
            for (
    j=0;j<tiles_x;j++){
                if (
    i==0){
                    
    matrix_x.push(j);
                }
                var 
    getZ(j,i);//unique ID
                
    trgt.createEmptyMovieClip("t"+z,z);//create tile
                
                
    trgt["t"+z]._x j*tile.w;
                
    trgt["t"+z]._y i*tile.h;
                
                
    update_cellzji);//z,x,y
            
    }
        }
    }
    init();




    function 
    scroll_screen(sx,sy){//shift x, shift y
        
    var trgt mc_scene.stage;
        
        if (
    sx>0)sx=0;
        if (
    sy>0)sy=0;
        
        var 
    cx Math.ceil(sx/tile.w);//corner x
        
    var cy Math.ceil(sy/tile.h);//corner y

        
    if ( ((cx !=last_cx) || (cy !=last_cy)) ){
            if (
    cx !=last_cx){//moved on the x-axis
                
                
    var gap cx last_cx;
                var 
    skip =Math.abs(gap);
                        
                for (var 
    j=0;j<skip;j++){
                    if (
    gap 0){//<<   new line left
                        
    for (var i=0;i<tiles_y;i++){//for each row, //first to last pos, all others move up
                        //take first
                            
    var r  skip- (j+1);//remain 3-(0+1) = 2
                            
    var matrix_x[0];
                            var 
    matrix_y[i];
                            var 
    getZ(x,y);//
                            
                            
    trgt["t"+z]._x = ( tiles_x )*tile.w  - (cxr  )*tile.w;//+ cx
                            
                            
    var = -cx+(tiles_x-1)- r;
                            var 
    -cy;
                            
    update_cell();
                        }
                        
    matrix_x.push(matrix_x.shift());
                    }else{
    //>> new line right, 
                        
    for (var i=0;i<tiles_y;i++){//for each row, //first to last pos, all others move up
                            
                            
    var r  skip- (j+1);//remain 3-(0+1) = 2
                            
    var matrix_x[matrix_x.length-1];
                            var 
    matrix_y[i];
                            var 
    getZ(x,y);//
                            
                            
    trgt["t"+z]._x = (0)*tile.w  - (cx-r)*tile.w;//
                            
                            
    var = -cx+r;
                            var 
    -cy;
                            
    update_cell();
                        }
                        
    matrix_x.unshift(matrix_x.pop());
                    }
                }
            }
            
            if (
    cy !=last_cy){//moved on the y-axis
                
    var gap cy last_cy;
                var 
    skip =Math.abs(gap);
                
                for (var 
    j=0;j<skip;j++){
                    if (
    gap 0){//^^   new line down
                        
    for (var i=0;i<tiles_x;i++){//for each row, //first to last pos, all others move up
                        //take first
                            
    var r  skip- (j+1);//remain 3-(0+1) = 2
                            
    var matrix_y[0];
                            var 
    matrix_x[i];
                            var 
    getZ(x,y);//
                            
                            
    trgt["t"+z]._y = ( tiles_y )*tile.h  - (cyr  )*tile.h;//+ cx
                            
                            
    var = -cy+(tiles_y-1)- r;
                            var 
    -cx;
                            
    update_cell();
                        }
                        
    matrix_y.push(matrix_y.shift());
                    }else{
    //>> new line up
                        
    for (var i=0;i<tiles_x;i++){//for each row, //first to last pos, all others move up
                            
                            
    var r  skip- (j+1);//remain 3-(0+1) = 2
                            
    var matrix_y[matrix_y.length-1];
                            var 
    matrix_x[i];
                            var 
    getZ(x,y);//
                            
                            
    trgt["t"+z]._y = (0)*tile.h  - (cy-r)*tile.h;//
                            
                            
    var = -cy+r;
                            var 
    -cx;
                            
    update_cell();
                        }
                        
    matrix_y.unshift(matrix_y.pop());
                    }
                }
            }
            
            if (
    cx !=last_cx && cy !=last_cy  ){//moved on the y-axis
                
    var gap cx last_cx;
                var 
    skip =Math.abs(gap);
                
                for (var 
    j=0;j<skip;j++){//reset
                    
    if (gap 0){
                        
    matrix_x.unshift(matrix_x.pop());
                    }else{
                        
    matrix_x.push(matrix_x.shift());
                    }
                }
                for (var 
    j=0;j<skip;j++){
                    if (
    gap 0){//<<   new line left
                        
                        
    for (var i=0;i<tiles_y;i++){//for each row, //first to last pos, all others move up
                        //take first
                            
    var r  skip- (j+1);//remain 3-(0+1) = 2
                            
    var matrix_x[0];
                            var 
    matrix_y[i];
                            var 
    getZ(x,y);//
                            
                            
    trgt["t"+z]._x = ( tiles_x )*tile.w  - (cxr  )*tile.w;//+ cx
                            
                            
    var = -cx+(tiles_x-1)- r;
                            var 
    -cy;
                            
    update_cell();
                        }
                        
    matrix_x.push(matrix_x.shift());
                    }else{
    //>> new line right, 
                        
    for (var i=0;i<tiles_y;i++){//for each row, //first to last pos, all others move up
                            
                            
    var r  skip- (j+1);//remain 3-(0+1) = 2
                            
    var matrix_x[matrix_x.length-1];
                            var 
    matrix_y[i];
                            var 
    getZ(x,y);//
                            
                            
    trgt["t"+z]._x = (0)*tile.w  - (cx-r)*tile.w;//
                            
                            
    var = -cx+r;
                            var 
    -cy;
                            
    update_cell();
                        }
                        
    matrix_x.unshift(matrix_x.pop());
                    }
                }
            }
            
    last_cx cx;
            
    last_cy cy;
        }
        
    //displace map
        
    trgt._x sx;
        
    trgt._y sy;
    }

    _root.onEnterFrame = function(){
        var 
    = (_xmouse-mc_scene._x)*-2.5;
        var 
    = (_ymouse-mc_scene._y)*-2.5;
        
    scroll_screen(x,y);

    and finally the fla
    http://www.renderhjs.net/bbs/flashki...ll/demo_03.fla

  3. #3
    M.D. mr_malee's Avatar
    Join Date
    Dec 2002
    Location
    Shelter
    Posts
    4,140
    nice

    Looking at the code briefly, it looks almost the same as what I had. Apart from the different style of code of course. But for some reason when mine moved faster than the screen size tiles were left over.

    When I get back to work I'll do a comparison and see what I was doing wrong

    thanks.
    lather yourself up with soap - soap arcade

  4. #4
    Feeling adventurous? T1ger's Avatar
    Join Date
    Mar 2004
    Posts
    850
    Nice tutorial Render If only there was a AS3 version too.. *hint, hint*

    What I really would like to know, is how you do it in Tank Move.. you use bitmap-thingy there right?
    I don't have a photograph, but you can have my footprints. They're upstairs in my socks.

  5. #5
    Senior Member
    Join Date
    Aug 2007
    Location
    Spencerville, Ontario, Canada
    Posts
    146
    Wow, renderhjs this is a good tutorial. I'm also very excited for Tank Moves completion. This specific subject at the moment is very important to me, because my game needs to have the ability to load many platforms quickly, because I want stages that constantly change up, and are dynamic. This method is a good one, the thing is wich method is faster, your method or Strille's? http://www.strille.net/tutorials/part1_scrolling.php
    http://www.strille.net/works/misc/platform_demo/

    I need the fastest method possible, because I want my stages to scroll horizontally for minutes. Also my game would not show a grid so I would have to take the grid off, if I where to use a similar method as yours.
    So what do you suggest for my particular game renderhjs? A platform method similar to yours, Strille's or something different all together? Thanks for the helpful tutorial, and keep on making your awesome Tank move game.

  6. #6
    Student
    Join Date
    Apr 2001
    Location
    -
    Posts
    4,756
    @mr_malee:
    the code isn´t that big (although my 2 posts are),- just download the FLA files and have a look. What I assume is that you didn´t used the gap mechanis that update the cells that went out of the screen and that are missing in the new screen position.

    @T1ger:
    for me right now AS3 is a hype not a practice , but soemone that has expierence in AS3 it should be a problem porting it to the benefits of AS3. For example instead of using multiple movieClips one could use display childs and sprites instead of attached Bitmaps or MovieClips- that´s all up to you.
    Right now most things I code are still in AS1/2 simply because AS3 doesn´t give the benefits I really need- for some reason everything I code not in AS3 runs fast enough and is easy enough for me to update/ maintain.
    Perhaps this winter I´ll have a look at AS3 again as I already wrote some complex things with it. But I hope I already provided a basic explaination with all the media I included.

    @ Sauceofallevils:
    to some extend different from what I did- on the other hand based already on a gird. He used as well a grid but stored within each cell multiple objects with rectangular bounding boxes. You can mix his method with mine by rendering the objects that are catched witin a cell and removing the container it it leaves the screen. This would require a 3 dimensional array the first dimension for the lines, next for thecolumns and the last for the objects within the cell or their id´s.

    but that´s up to you,- my method is pretty efficient for massive tiles of all the same size. Wich is even more effective if the tile or grid size is below your screensize and there are massive of them to display. What strille wrote is has the advantage of diplaying objects in different size that aren´t placed in the grid (but wich are sorted later into the grid cells).

    anyway I encapsulated the update cell function so If you´d have multiple objects within a cell it could look like this:
    PHP Code:
    function update_cell(z,x,y){//update single cell... 
        
    var trgt mc_scene.stage
        
    trgt["t"+z].tex.removeMovieClip();//remove previous item 
        
    trgt["t"+z].createEmptyMovieClip("tex",1);
         
        for (var 
    i=0;i<= map[y][x].length;i++){
             
    trgt["t"+z].tex.attachMovie(  map[y][x][i].id,"obj"+i,i);
         
    trgt["t"+z].tex["obj"+i]._x map[y][x][i].x;
         
    trgt["t"+z].tex["obj"+i]._y map[y][x][i].y;
        }

    but with every engine I strongly suggest investigating the subject yourself because there is no ready to go solution for every game- and a strille method or the one I posted wont make out the engine alone.

  7. #7
    Who needs pants? hooligan2001's Avatar
    Join Date
    Apr 2001
    Location
    Somewhere
    Posts
    1,976
    Great read render.

  8. #8
    Member
    Join Date
    Aug 2007
    Posts
    61
    Quote Originally Posted by T1ger
    Nice tutorial Render If only there was a AS3 version too.. *hint, hint*
    Actually there is already and AS3 version of this method. I wrote a package that does exactly this but is a completely generic way:

    http://yaa-blog.blogspot.com/2007/08...data-grid.html

    and I use it in my engine, latest demo here http://yaa-blog.blogspot.com/

    Quote Originally Posted by renderhjs
    Right now most things I code are still in AS1/2 simply because AS3 doesn´t give the benefits I really need
    Errmm what benefits are those? Consuming all the CPU to move a few bitmaps around?

    Its a nicely written tutorial though.

    If anybody does do this in AS3, merge your tiles into several large bitmaps. It seems the AVM2 is more efficient at moving around a couple of large bitmaps instead of a couple of hundred small ones - this does however make animated tiles harder...
    Last edited by rje; 09-09-2007 at 09:59 AM.

  9. #9
    Student
    Join Date
    Apr 2001
    Location
    -
    Posts
    4,756
    @rje
    thx for pimping but I dont see a benefit of it for those who are unfamilar with it? All I see is pimping with unexplained code.
    I dont write in AS3 that much because it´s time consuming and it doesnt give >>"ME"<< the benefits right now.

  10. #10
    Member
    Join Date
    Aug 2007
    Posts
    61
    Ahh sorry if I offended you.

    I just wanted to provided the source and example of the technique being discussed in this thread in direct response to a request.

    Its a great tutorial - must of taken you ages to write, keep up the good work!

    Its an interesting subject - and not too much written on it. Its also worthwhile looking at the advantages of this approach. If you can recycle the objects in the grid, the VM doent have to garbage collect and re-allocate the memory for the bitmaps. This is certainly true for AS3, dont know so much about AS1/2. Can you use animated tiles?

  11. #11
    Senior Member random10122's Avatar
    Join Date
    Mar 2002
    Location
    Sheffield, UK
    Posts
    1,747
    good stuff render,

    i could have really done with this when i first joined FK all those years ago. Hopefully some of the more inexperienced flashers will find this of great use.

    fracture2 - the sequel
    fracture - retro shooter
    blog - games, design and the rest

    "2D is a format, not a limitation" -Luis Barriga

  12. #12
    Senior Member Alluvian's Avatar
    Join Date
    Jun 2006
    Posts
    967
    Good stuff. My engine is doing all the stuff this one avoids, lol.

    Lets see:
    Updating full screen each update? Check!
    Using _visible = false? Check!
    Much Much Much lower framerate? Check! Check! Check!

    I'll wait till final art and see what things like quality = low do for my performance and then possibly redo the tile display after. The tile display and tracking is pretty abstracted thankfully.

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