PDA

View Full Version : Link Turn Animation (With Dummy Tile Mods)



CJC
04-05-2009, 12:30 AM
Before we begin, I'm going to give you a heads up on my vocabulary. When I script an action in which Link's animation is intended to change, I do so by adding a "dummy" item called an "Anima" to Link's inventory. The anima is a useless invisible item who's sole purpose is to change Link's Tile Modifier.


BTW, it's a good idea to always use the "Expanded Link Tile Modifiers" rule with these kinds of scripts, as well as the "Link keeps Old Items" rule if you aren't careful with your custom item classes.


So, here's the score. This code, when used, makes Link have to turn to switch directions. While he is turning, a tile modification is applied to his sprites to make it look like he's turning.
For example, if you're facing north and you press Right, you will not move right but instead start to rotate until you are facing right. Once facing right, you will be able to move in that direction.

If you are facing north and you press down, you will rotate in a counterclockwise direction until you cease pressing down or you are facing south, and then you will move in that direction.


Things you'll need:

A standard set of Link sprites
A set of Link sprites that face north by north-east
A set that faces east by north-east
A set that faces east by south-east
A set that faces south by south-east
A set that faces south by south-west
A set that faces west by south-west
A set that faces west by north-west
A set that faces north by north-west
Patience
And a smile


Here's the code.


ffc script DiagonalAnima{

void run(){
int TurnGrade;
int PosSlopeAnima = 16; //Sets the number for the dummy item
//that makes Link animate for up-right and down-left.
//Don't bother changing the slash and action tiles, though,
//just the walking ones.
//Set as Bait for testing
int NegSlopeAnima = 12; //Sets the number for the dummy item
//that makes Link animate for down-right and up-left.
//Set as Letter for testing

while(true){
if(Link->Dir == 0){ //Facing Up
if(Link->InputRight || Link->InputDown){
Link->InputRight = false; Link->InputDown = false;
TurnGrade++; //Makes the turn more gradual, so you can actually see it.
if(!Link->Item[PosSlopeAnima]){ Link->Item[PosSlopeAnima] = true;}
//Adds the Positive Slope Anima. At this point, Link will
//appear to be facing north by north-east.
if(Link->Item[NegSlopeAnima]){ Link->Item[NegSlopeAnima] = false;}
//Removes the Negative Slope Anima. This is to prevent the player
//from owning both at the same time, which they can achieve by
//mashing the keyboard. The result of owning both is a big ugly mess.
if(TurnGrade >= 6){
Link->Dir = 3;
//Sets Link's official direction to Right. He'll still appear
//to be turning at this point, but the turn will be east by north-east
//instead.
TurnGrade = 5;
}
}
if(Link->InputLeft){
Link->InputLeft = false;
TurnGrade--; //Same as above, but in the opposite direction.
//At this point, Link would be facing north by north-west.
if(!Link->Item[NegSlopeAnima]){ Link->Item[NegSlopeAnima] = true;}
if(Link->Item[PosSlopeAnima]){ Link->Item[PosSlopeAnima] = false;}
if(TurnGrade <= -6){
Link->Dir = 2;
//Sets Link's official direction to Left. He will appear
//to be facing west by north-west.
TurnGrade = -5;
}
}
if(TurnGrade > 0 && Link->InputUp){
Link->InputUp = false;
TurnGrade--;
//Used to revert back to neutral if you decide to
//press up again after the turn right begins.
}
if(TurnGrade < 0 && Link->InputUp){
Link->InputUp = false;
TurnGrade++;
//Used to revert back to neutral if you decide to
//press up again after the turn left begins.
}
if(TurnGrade == 0 && (Link->Item[PosSlopeAnima] || Link->Item[NegSlopeAnima])){
Link->Item[PosSlopeAnima] = false;
Link->Item[NegSlopeAnima] = false;
//Removes the Anima if you are facing the cardinal
//direction... in this case, north.
}
}
if(Link->Dir == 1){ //Facing Down
if(Link->InputRight){
Link->InputRight = false;
TurnGrade--;
if(!Link->Item[NegSlopeAnima]){ Link->Item[NegSlopeAnima] = true;}
if(Link->Item[PosSlopeAnima]){ Link->Item[PosSlopeAnima] = false;}
if(TurnGrade <= -6){
Link->Dir = 3;
TurnGrade = -5;
}
}
if(Link->InputLeft || Link->InputUp){
Link->InputLeft = false; Link->InputUp = false;
TurnGrade++;
if(!Link->Item[PosSlopeAnima]){ Link->Item[PosSlopeAnima] = true;}
if(Link->Item[NegSlopeAnima]){ Link->Item[NegSlopeAnima] = false;}
if(TurnGrade >= 6){
Link->Dir = 2;
TurnGrade = 5;
}
}
if(TurnGrade > 0 && Link->InputDown){
Link->InputDown = false;
TurnGrade--;
}
if(TurnGrade < 0 && Link->InputDown){
Link->InputDown = false;
TurnGrade++;
}
if(TurnGrade == 0 && (Link->Item[PosSlopeAnima] || Link->Item[NegSlopeAnima])){
Link->Item[PosSlopeAnima] = false;
Link->Item[NegSlopeAnima] = false;
}
}
if(Link->Dir == 2){ //Facing Left
if(Link->InputUp || Link->InputRight){
Link->InputUp = false; Link->InputRight = false;
TurnGrade--;
if(!Link->Item[NegSlopeAnima]){ Link->Item[NegSlopeAnima] = true;}
if(Link->Item[PosSlopeAnima]){ Link->Item[PosSlopeAnima] = false;}
if(TurnGrade <= -6){
Link->Dir = 0;
TurnGrade = -5;
}
}
if(Link->InputDown){
Link->InputDown = false;
TurnGrade++;
if(!Link->Item[PosSlopeAnima]){ Link->Item[PosSlopeAnima] = true;}
if(Link->Item[NegSlopeAnima]){ Link->Item[NegSlopeAnima] = false;}
if(TurnGrade >= 6){
Link->Dir = 1;
TurnGrade = 5;
}
}
if(TurnGrade > 0 && Link->InputLeft){
Link->InputLeft = false;
TurnGrade--;
}
if(TurnGrade < 0 && Link->InputLeft){
Link->InputLeft = false;
TurnGrade++;
}
if(TurnGrade == 0 && (Link->Item[PosSlopeAnima] || Link->Item[NegSlopeAnima])){
Link->Item[PosSlopeAnima] = false;
Link->Item[NegSlopeAnima] = false;
}
}
if(Link->Dir == 3){ //Facing Right
if(Link->InputUp){
Link->InputUp = false;
TurnGrade++;
if(!Link->Item[PosSlopeAnima]){ Link->Item[PosSlopeAnima] = true;}
if(Link->Item[NegSlopeAnima]){ Link->Item[NegSlopeAnima] = false;}
if(TurnGrade >= 6){
Link->Dir = 0;
TurnGrade = 5;
}
}
if(Link->InputDown || Link->InputLeft){
Link->InputDown = false; Link->InputLeft = false;
TurnGrade--;
if(!Link->Item[NegSlopeAnima]){ Link->Item[NegSlopeAnima] = true;}
if(Link->Item[PosSlopeAnima]){ Link->Item[PosSlopeAnima] = false;}
if(TurnGrade <= -6){
Link->Dir = 1;
TurnGrade = -5;
}
}
if(TurnGrade > 0 && Link->InputRight){
Link->InputRight = false;
TurnGrade--;
}
if(TurnGrade < 0 && Link->InputRight){
Link->InputLeft = false;
TurnGrade++;
}
if(TurnGrade == 0 && (Link->Item[PosSlopeAnima] || Link->Item[NegSlopeAnima])){
Link->Item[PosSlopeAnima] = false;
Link->Item[NegSlopeAnima] = false;
}
}
Waitframe();
} // end of while loop
} // end of void run
}

FYI, for those of you unfamiliar with scripts, if you use them they all must be in the same file (With file extension .z, which you can save while using notepad by selecting "All Files" on the filetype pulldown and then typing in the extension).
Also, any .z file you use should have

import "std.zh"
at the top. This loads all the variables pre-defined by Zelda Classic.


It is an FFC. I prefer to use them for Link actions because I can test them on a screen basis compared to the original game functions. Also, I find I prefer placing the FFC on each screen. It forces me to double-check my work.

If you want a global version, I'm sure it wouldn't be too hard to adapt. Someone just needs to annotate the sections of the code to instruct where in Slot_2.z they go.

Enjoy!
-CJC