-
[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.w / tile.w)+1;//amount of tiles on x-axis
tiles_y = Math.ceil(screen.h / tile.h)+1;
//check if those screen tiles are not more as the map dimensions
if (tilesX > map[0].length) tilesX = map[0].length;
if (tilesY > map.length) tilesY = 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 z = 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_cell( z, j, i);//z,x,y
}
}
}
init();
now comes the difficult part , just kidding first something easy:
PHP Code:
_root.onEnterFrame = function(){
var x = (_xmouse-mc_scene._x)*-2.5;
var y = (_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
-
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 x = matrix_x[0];
var y = matrix_y[i];
var z = getZ(x,y,1);//1 as inital setup
trgt["t"+z]._x = ( tiles_x - 1 )*tile.w - (cx+ r )*tile.w;//left to right
var x = -cx+(tiles_x-1)- r;
var y = i -cy;
update_cell(z , x , y );
}
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 x = matrix_x[matrix_x.length-1];
var y = matrix_y[i];
var z = getZ(x,y,1);//1 as inital setup
trgt["t"+z]._x = (0)*tile.w - (cx-r)*tile.w;//
var x = -cx+r;
var y = i -cy;
update_cell(z , x , y );
}
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 y = matrix_y[0];
var x = matrix_x[i];
var z = getZ(x,y,1);//1 as inital setup
trgt["t"+z]._y = ( tiles_y - 1 )*tile.h - (cy+ r )*tile.h;//+ cx
var y = -cy+(tiles_y-1)- r;
var x = i -cx;
update_cell(z , x , y );
}
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 y = matrix_y[matrix_y.length-1];
var x = matrix_x[i];
var z = getZ(x,y,1);//1 as inital setup
trgt["t"+z]._y = (0)*tile.h - (cy-r)*tile.h;//
var y = -cy+r;
var x = i -cx;
update_cell(z , x , y );
}
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 x = matrix_x[0];
var y = matrix_y[i];
var z = getZ(x,y,1);//1 as inital setup
trgt["t"+z]._x = ( tiles_x - 1 )*tile.w - (cx+ r )*tile.w;//+ cx
var x = -cx+(tiles_x-1)- r;
var y = i -cy;
update_cell(z , x , y );
}
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 x = matrix_x[matrix_x.length-1];
var y = matrix_y[i];
var z = getZ(x,y,1);//1 as inital setup
trgt["t"+z]._x = (0)*tile.w - (cx-r)*tile.w;//
var x = -cx+r;
var y = i -cy;
update_cell(z , x , y );
}
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.w / tile.w)+1;//amount of tiles on x-axis
tiles_y = Math.ceil(screen.h / tile.h)+1;
//check if those screen tiles are not more as the map dimensions
if (tilesX > map[0].length) tilesX = map[0].length;
if (tilesY > map.length) tilesY = 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 z = 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_cell( z, j, i);//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 x = matrix_x[0];
var y = matrix_y[i];
var z = getZ(x,y);//
trgt["t"+z]._x = ( tiles_x - 1 )*tile.w - (cx+ r )*tile.w;//+ cx
var x = -cx+(tiles_x-1)- r;
var y = i -cy;
update_cell(z , x , y );
}
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 x = matrix_x[matrix_x.length-1];
var y = matrix_y[i];
var z = getZ(x,y);//
trgt["t"+z]._x = (0)*tile.w - (cx-r)*tile.w;//
var x = -cx+r;
var y = i -cy;
update_cell(z , x , y );
}
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 y = matrix_y[0];
var x = matrix_x[i];
var z = getZ(x,y);//
trgt["t"+z]._y = ( tiles_y - 1 )*tile.h - (cy+ r )*tile.h;//+ cx
var y = -cy+(tiles_y-1)- r;
var x = i -cx;
update_cell(z , x , y );
}
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 y = matrix_y[matrix_y.length-1];
var x = matrix_x[i];
var z = getZ(x,y);//
trgt["t"+z]._y = (0)*tile.h - (cy-r)*tile.h;//
var y = -cy+r;
var x = i -cx;
update_cell(z , x , y );
}
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 x = matrix_x[0];
var y = matrix_y[i];
var z = getZ(x,y);//
trgt["t"+z]._x = ( tiles_x - 1 )*tile.w - (cx+ r )*tile.w;//+ cx
var x = -cx+(tiles_x-1)- r;
var y = i -cy;
update_cell(z , x , y );
}
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 x = matrix_x[matrix_x.length-1];
var y = matrix_y[i];
var z = getZ(x,y);//
trgt["t"+z]._x = (0)*tile.w - (cx-r)*tile.w;//
var x = -cx+r;
var y = i -cy;
update_cell(z , x , y );
}
matrix_x.unshift(matrix_x.pop());
}
}
}
last_cx = cx;
last_cy = cy;
}
//displace map
trgt._x = sx;
trgt._y = sy;
}
_root.onEnterFrame = function(){
var x = (_xmouse-mc_scene._x)*-2.5;
var y = (_ymouse-mc_scene._y)*-2.5;
scroll_screen(x,y);
}
and finally the fla
http://www.renderhjs.net/bbs/flashki...ll/demo_03.fla
-
M.D.
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.
-
Feeling adventurous?
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.
-
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.
-
@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.
-
Who needs pants?
-
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/
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.
-
@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.
-
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?
-
Senior Member
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
-
Senior Member
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|