Lex_Hedley
08-03-11, 08:23 AM
Hi Delta,
I was thinking of finally doing a game and was wanting to do the scrolling like in Dizzy Legends and Rock Dash Dizzy.
I found a thread from Dizzy Legends
http://www.yolkfolk.com/bb/showthread.php?p=9688#post9688
is this the code used in Rock Dash Dizzy too?
I would like to move blocks around the screen too, would this be possible?
Meph, i'm guessing you have Vista.
People with vista seem to have more trouble with it flickering, even when their computer is high spec like yours.
ah well, 'tis all solved now with Alex integrating scrolling as an option in v2.3 of DizzyAGE!
so as he's done that, i'll explain how i did the scrolling in my scroll demo (if anyone is interested!!).
basically i realised when coding BTD that i could change a lot of brushes en-mass, by doing a For loop from 0 up to BrushCount(). this allowed me in BTD to change the colour of every brush in the game. (BrushCount() counts the number of brushes in the map)
now it occurred to me a while back that there was a similar code for objects, ObjCount().and that if i could change the colour of all the brushes in BTD, there should be no reason at all why i couldn't change the X or Y values of all the objects in a map.
Two problems then arise. firstly you can't move static brushes (the block material). this means that in TLoD you'd be able to walk through walls, and in classic Dizzy games, that you'd fall through the map. The second problem is getting Dizzy to stay still while the entire map is moved.
the second problem was the easiest to solve. i simply wrote a new function:
func Scroll_Screen(dirx,diry)
{
//set all objects to new location
for(i=0;i < ObjCount();i++)
{
if(dirx==-1) { ObjSet(i,O_X,ObjGet(i,O_X)+CM_SMLMOVE); }
if(dirx==1) { ObjSet(i,O_X,ObjGet(i,O_X)-CM_SMLMOVE); }
if(diry==-1) { ObjSet(i,O_Y,ObjGet(i,O_Y)+CM_SMLMOVE); }
if(diry==1) { ObjSet(i,O_Y,ObjGet(i,O_Y)-CM_SMLMOVE); }
}
ObjPresentGather();
}
then called this function, instead of the code that moves dizzy. As you may be able to see, this function loops through *every single object in the map* and moves it up, down, left or right, depending on what the input is. This is what causes the slow-down and flickering on slow (and vista) computers.
The function is called by replacing this (TLoD-specific up-movement coding):
PlayerSet(P_Y, PlayerGet(P_Y)-CM_SMLMOVE);
with this:
Scroll_Screen(0,-1);
That's the easy bit. The problem then is that there are no static brushes at all in the map. this means that walls can be walked through. To counter this, i defined Object Property 45 thus:
#def O_BLOCK 45 // 2 = block but can drop items 1 = block and can't drop items, 0 = not block
then in the movement checks, where the game checks the space ahead to see if there is any block material, i changed this:
func CM_CheckWalkY()
{
x1=0;y1=0;x2=0;y2=0;
PlayerMakeBB(&x1,&y1,&x2,&y2);
//find player position
px = PlayerGet(P_X);
py = PlayerGet(P_Y);
//set box corner coords
boxx = px-8;
boxy = py-20;
boxw = px+8;
boxh = py-8;
roomw = GameGet(G_ROOMW);
roomh = GameGet(G_ROOMH);
//check if player is inside 'box'
return MaterialCheckFree(boxx%roomw,boxy%roomh,boxw%roomw ,boxh%roomh);
}
to this:
func CM_CheckWalkY()
{
//find player position
px = PlayerGet(P_X);
py = PlayerGet(P_Y);
//set box corner coords
boxx = px-12;
boxy = py-38;
boxw = px+12;
boxh = py-14;
//check if player is inside 'box'
return Check_Blocker(boxx,boxy,boxw,boxh);
}
The above code defines a 'box' 24x24 big, ahead of the player (depending on which way he is facing - the above code is for facing up). then i added a couple more functions to deal with the checking of the area ahead.
func Check_Blocker(x,y,w,h)
{
pcount = ObjPresentCount();
for(idxlayer=7;idxlayer > =0;idxlayer--)
{
for(pidx=0;pidx < =pcount-1;pidx++) // iterate present objects
{
idx = ObjPresentIdx(pidx); // object index
if( ObjGet(idx,O_DISABLE) ) continue;
if( ObjGet(idx,O_LAYER==idxlayer) )
{
if( Find_Obj_Touch(idx,x,y,w,h)==1 ) // touched objects only
{
blocktype = ObjGet(idx,O_BLOCK);
if (blocktype==1)
{
return 1;
}
if (blocktype==2)
{
return 2;
}
}
}
}
}
return 0;
}
the above code cycles through all the objects in the room (sorting through them by layer), uses function Find_Obj_Touch (shown below) to determine which ones are within the 24x24 box that was defined earlier, then checks O_BLOCK (object property 45) to see if any of those ones are 1 or 2 (blocking). if they are, it stops the function and doesn't allow him to move into that space.
func Find_Obj_Touch( idx,x,y,w,h )
{
//player positions
px1 = x;
py1 = y;
px2 = w;
py2 = h;
//object positions
ox1 = ObjGet(idx,O_X);
oy1 = ObjGet(idx,O_Y);
ox2 = ox1+ObjGet(idx,O_W);
oy2 = oy1+ObjGet(idx,O_H);
if( px1 > =ox2 || px2 < =ox1 ) return 0;
if( py1 > =oy2 || py2 < =oy1 ) return 0;
return 1;
}
(the above code was bastardised from the 'examine' code in TLoD, hence some slightly unneccessary code)
Also, the code in action.gs that checks for dropping items is changed too, to reference Check_Blocker(x,y,w,h) as well. if the property is anything other than 1, then it alows dropping of items. This is useful for dealing with tables etc that you can't walk over, but may want to drop something onto. They are simply set to have an O_BLOCK property of 2.
personally i think it's a rather elegant little solution myself, if a touch CPU-heavy. in fact the method of determining whether there's a block in the space ahead is so much better and more elegant than the method TLoD uses, that i'll probably use it in CoTM.
I hope that was of some interest to someone! Any questions regarding it, just ask.
Regards
Alex
I was thinking of finally doing a game and was wanting to do the scrolling like in Dizzy Legends and Rock Dash Dizzy.
I found a thread from Dizzy Legends
http://www.yolkfolk.com/bb/showthread.php?p=9688#post9688
is this the code used in Rock Dash Dizzy too?
I would like to move blocks around the screen too, would this be possible?
Meph, i'm guessing you have Vista.
People with vista seem to have more trouble with it flickering, even when their computer is high spec like yours.
ah well, 'tis all solved now with Alex integrating scrolling as an option in v2.3 of DizzyAGE!
so as he's done that, i'll explain how i did the scrolling in my scroll demo (if anyone is interested!!).
basically i realised when coding BTD that i could change a lot of brushes en-mass, by doing a For loop from 0 up to BrushCount(). this allowed me in BTD to change the colour of every brush in the game. (BrushCount() counts the number of brushes in the map)
now it occurred to me a while back that there was a similar code for objects, ObjCount().and that if i could change the colour of all the brushes in BTD, there should be no reason at all why i couldn't change the X or Y values of all the objects in a map.
Two problems then arise. firstly you can't move static brushes (the block material). this means that in TLoD you'd be able to walk through walls, and in classic Dizzy games, that you'd fall through the map. The second problem is getting Dizzy to stay still while the entire map is moved.
the second problem was the easiest to solve. i simply wrote a new function:
func Scroll_Screen(dirx,diry)
{
//set all objects to new location
for(i=0;i < ObjCount();i++)
{
if(dirx==-1) { ObjSet(i,O_X,ObjGet(i,O_X)+CM_SMLMOVE); }
if(dirx==1) { ObjSet(i,O_X,ObjGet(i,O_X)-CM_SMLMOVE); }
if(diry==-1) { ObjSet(i,O_Y,ObjGet(i,O_Y)+CM_SMLMOVE); }
if(diry==1) { ObjSet(i,O_Y,ObjGet(i,O_Y)-CM_SMLMOVE); }
}
ObjPresentGather();
}
then called this function, instead of the code that moves dizzy. As you may be able to see, this function loops through *every single object in the map* and moves it up, down, left or right, depending on what the input is. This is what causes the slow-down and flickering on slow (and vista) computers.
The function is called by replacing this (TLoD-specific up-movement coding):
PlayerSet(P_Y, PlayerGet(P_Y)-CM_SMLMOVE);
with this:
Scroll_Screen(0,-1);
That's the easy bit. The problem then is that there are no static brushes at all in the map. this means that walls can be walked through. To counter this, i defined Object Property 45 thus:
#def O_BLOCK 45 // 2 = block but can drop items 1 = block and can't drop items, 0 = not block
then in the movement checks, where the game checks the space ahead to see if there is any block material, i changed this:
func CM_CheckWalkY()
{
x1=0;y1=0;x2=0;y2=0;
PlayerMakeBB(&x1,&y1,&x2,&y2);
//find player position
px = PlayerGet(P_X);
py = PlayerGet(P_Y);
//set box corner coords
boxx = px-8;
boxy = py-20;
boxw = px+8;
boxh = py-8;
roomw = GameGet(G_ROOMW);
roomh = GameGet(G_ROOMH);
//check if player is inside 'box'
return MaterialCheckFree(boxx%roomw,boxy%roomh,boxw%roomw ,boxh%roomh);
}
to this:
func CM_CheckWalkY()
{
//find player position
px = PlayerGet(P_X);
py = PlayerGet(P_Y);
//set box corner coords
boxx = px-12;
boxy = py-38;
boxw = px+12;
boxh = py-14;
//check if player is inside 'box'
return Check_Blocker(boxx,boxy,boxw,boxh);
}
The above code defines a 'box' 24x24 big, ahead of the player (depending on which way he is facing - the above code is for facing up). then i added a couple more functions to deal with the checking of the area ahead.
func Check_Blocker(x,y,w,h)
{
pcount = ObjPresentCount();
for(idxlayer=7;idxlayer > =0;idxlayer--)
{
for(pidx=0;pidx < =pcount-1;pidx++) // iterate present objects
{
idx = ObjPresentIdx(pidx); // object index
if( ObjGet(idx,O_DISABLE) ) continue;
if( ObjGet(idx,O_LAYER==idxlayer) )
{
if( Find_Obj_Touch(idx,x,y,w,h)==1 ) // touched objects only
{
blocktype = ObjGet(idx,O_BLOCK);
if (blocktype==1)
{
return 1;
}
if (blocktype==2)
{
return 2;
}
}
}
}
}
return 0;
}
the above code cycles through all the objects in the room (sorting through them by layer), uses function Find_Obj_Touch (shown below) to determine which ones are within the 24x24 box that was defined earlier, then checks O_BLOCK (object property 45) to see if any of those ones are 1 or 2 (blocking). if they are, it stops the function and doesn't allow him to move into that space.
func Find_Obj_Touch( idx,x,y,w,h )
{
//player positions
px1 = x;
py1 = y;
px2 = w;
py2 = h;
//object positions
ox1 = ObjGet(idx,O_X);
oy1 = ObjGet(idx,O_Y);
ox2 = ox1+ObjGet(idx,O_W);
oy2 = oy1+ObjGet(idx,O_H);
if( px1 > =ox2 || px2 < =ox1 ) return 0;
if( py1 > =oy2 || py2 < =oy1 ) return 0;
return 1;
}
(the above code was bastardised from the 'examine' code in TLoD, hence some slightly unneccessary code)
Also, the code in action.gs that checks for dropping items is changed too, to reference Check_Blocker(x,y,w,h) as well. if the property is anything other than 1, then it alows dropping of items. This is useful for dealing with tables etc that you can't walk over, but may want to drop something onto. They are simply set to have an O_BLOCK property of 2.
personally i think it's a rather elegant little solution myself, if a touch CPU-heavy. in fact the method of determining whether there's a block in the space ahead is so much better and more elegant than the method TLoD uses, that i'll probably use it in CoTM.
I hope that was of some interest to someone! Any questions regarding it, just ask.
Regards
Alex