Yes the code was quite complex. I Also know it wasn't really the best way, I expect, to actually do it.
I have sent Grandad a modified version of his game, with the climbing added so he can play about with it. I stripped the multi switching code out as well.
here is the code I added and i'll try to explain how it works
First I had to add the 2 tiles that show daisy turning and climbing.
on the map there are 2 new action object blocks. they are ID:-
8900 bottom of ivy
8901 top of ivy
there are 2 new daisy objects, pasted outside the play area
2002 daisy turning
2020 daisy climbing (animation needs to be stopped)
the action objects 8900-8901
1st they set the x and y coords for the object that will replace the player
next it enters a scripted state, stopping key control of the player
then replaces the player with the turning object 2002
it makes sure the tile animation is set at the 1st frame of the animation
and it slows the animation down with a delay
it show the animation for 12 game frames, then replaces the turn object 2002, with the climb object 2020
it then activates the climb control by setting the status of the bottom of ivy action 8900 to 1
//top bottom action
func ActionObject_8900()
{
idx = ObjFind(8900);
if(ObjGet(idx,O_STATUS)==0)
{
chrx = ObjFind(2002);
x = 3008; //you need to set this at climb location
y = PlayerGet(P_Y);
PlayerSet(P_STATUS,STATUS_SCRIPTED);
PlayerSet(P_DISABLE,1);
ObjSet(chrx,O_X,x);
ObjSet(chrx,O_Y,y-14);
ObjSet(chrx,O_DISABLE,0);
ObjSet(chrx,O_FRAME,0);
ObjPresent(chrx);
ObjSet(chrx,O_DELAY,6);
WaitFrames(12);
ObjSet(chrx,O_DISABLE,1);
chrx = ObjFind(2020);
ObjSet(chrx,O_X,x);
y-=2;
ObjSet(chrx,O_Y,y-14);
ObjSet(chrx,O_DISABLE,0);
ObjSet(chrx,O_FRAME,0);
ObjPresent(chrx);
f=0;
idx = ObjFind(8900);
ObjSet(idx,O_STATUS,1);
}
}
//top ivy action
func ActionObject_8901()
{
chrx = ObjFind(2002);
x = 3008; //you need to set x as climb location
y = 258; //you need to set y<>8 pixels lower to drop down
PlayerSet(P_STATUS,STATUS_SCRIPTED);
PlayerSet(P_DISABLE,1);
ObjSet(chrx,O_X,x);
ObjSet(chrx,O_Y,y-14);
ObjSet(chrx,O_DISABLE,0);
ObjSet(chrx,O_FRAME,0);
ObjPresent(chrx);
ObjSet(chrx,O_DELAY,6);
WaitFrames(12);
ObjSet(chrx,O_DISABLE,1);
chrx = ObjFind(2020);
ObjSet(chrx,O_X,x);
ObjSet(chrx,O_Y,y-14);
ObjSet(chrx,O_DISABLE,0);
ObjSet(chrx,O_FRAME,0);
ObjPresent(chrx);
f=0;
idx = ObjFind(8900);
ObjSet(idx,O_STATUS,1);
}
Room Updates
there are 3 room updates here, as you will climb through 3 rooms
they all check if the bottom of ivy action 8900 status is set at 1.
if it is, then it calls the ivy1 function, which is the movement control.
else it reenables the player
func UpdateRoom_12_3()
{
idx = ObjFind(8900);
if(ObjGet(idx,O_STATUS)==1)
{
Ivy1();
ClearKeys();
}
idx = ObjFind(8900);
if(ObjGet(idx,O_STATUS)==2)
{
PlayerSet(P_DIR, 0);
PlayerSet(P_POW, 0);
idx = ObjFind(8900);
ObjSet(idx,O_STATUS,0);
}
}
func UpdateRoom_12_2()
{
idx = ObjFind(8900);
if(ObjGet(idx,O_STATUS)==1)
{
Ivy1();
ClearKeys();
}
idx = ObjFind(8900);
if(ObjGet(idx,O_STATUS)==2)
{
PlayerSet(P_DIR, 0);
PlayerSet(P_POW, 0);
idx = ObjFind(8900);
ObjSet(idx,O_STATUS,0);
}
}
func UpdateRoom_12_1()
{
idx = ObjFind(8900);
if(ObjGet(idx,O_STATUS)==1)
{
Ivy1();
ClearKeys();
}
idx = ObjFind(8900);
if(ObjGet(idx,O_STATUS)==2)
{
PlayerSet(P_DIR, 0);
PlayerSet(P_POW, 0);
idx = ObjFind(8900);
ObjSet(idx,O_STATUS,0);
}
}
Movement Control
This handles player input. for when the player presses cursor up, it will first check which frame of the animation is currently being shown on variable f and it's y coordinate. it then reduces both numbers by 1 (on the down key it adds 1 to them). So basically it is running the animation in reverse. the next few lines of code checks if has f has gone below 0. As this would cause an error it resets it to 8 (the animation has 8 frames).
it now checks if has reached the top of the climb (in this the top is set when y goes below 248). If it has then it removes the climb tile, resets the key checker and re-places the player into position. The last part will check if you are moving out of screen. If you didn't check, as you continue the climb he would walk off screen but you wouldn't follow. this code checks if you cross the coordinate it moves the player (that is hidden) into the new room.
func Ivy1()
{
//up
if(GetKey(KEY_UP)==1)
{
ClearKeys();
chrx = ObjFind(2020);
f = ObjGet(chrx,O_FRAME);
y = ObjGet(chrx,O_Y);
y-=1;
f-=1;
if(f<0)
{
f=8;
}
if(y<248) //this is the top point where he/she steps off
{
idx = ObjFind(8900);
ObjSet(idx,O_STATUS,2);
PlayerSet(P_X,3016);
PlayerSet(P_Y,240);
ClearKeys();
PlayerSet(P_DIR, 0);
PlayerSet(P_POW, 0);
PlayerSet(P_DISABLE,0);
PlayerEnterIdle();
chrx = ObjFind(2020);
ObjSet(chrx,O_DISABLE,1);
}
chrx = ObjFind(2020);
ObjSet(chrx,O_FRAME,f);
ObjSet(chrx,O_Y,y);
if(y==400)
{
PlayerSet(P_Y,380);
}
if(y==264)
{
PlayerSet(P_Y,250);
}
}
//down
if(GetKey(KEY_DOWN)==1)
{
ClearKeys();
chrx = ObjFind(2020);
f = ObjGet(chrx,O_FRAME);
y = ObjGet(chrx,O_Y);
y+=1;
f+=1;
if(f>8)
{
f=0;
}
if(y==488) //lowest point to get off
{
idx = ObjFind(8900);
ObjSet(idx,O_STATUS,2);
PlayerSet(P_X,3016);
PlayerSet(P_Y,y+14);
ClearKeys();
PlayerSet(P_DIR, 0);
PlayerSet(P_POW, 0);
PlayerSet(P_DISABLE,0);
PlayerEnterIdle();
chrx = ObjFind(2020);
ObjSet(chrx,O_DISABLE,1);
}
chrx = ObjFind(2020);
ObjSet(chrx,O_FRAME,f);
ObjSet(chrx,O_Y,y);
if(y==538)
{
PlayerSet(P_Y,500);
}
if(y==401)
{
PlayerSet(P_Y,480);
}
if(y==265)
{
PlayerSet(P_Y,380);
}
}
}