5. Animations (going beyond the basics)
Se we have our very basic script, woop dee doo. The purpose of
using showcharacter is so we don't need to make our own gifs and such for
the NPC. So we might as well take advantage of the sprites, and directions
it has.
Getting it to face the player
To make it face the player is quite simple, you take the script we
used in the chase portion of the script to determine the x and y distances,
and add in some stuff.
//Facing the Player
if (timeout){
this.distx=abs(playerx-x);
this.disty=abs(playery-y);
if (this.distx<=this.disty){ //if
the y distance between the player and the NPC is greater than the x distance,
the NPC needs to do the following stuff:
if (playery<y)dir=0; //if
the player's y is less than the NPC's y, the NPC needs to face up
if (playery>y)dir=2; //if
the player's y is greater than the NPC's y, the NPC needs to face down
}else{ //if the x distance between
the player and the NPC is greater than the y distance, the NPC needs to
do the following stuff:
if (playerx<x)dir=1;
//if the player's x is less than the NPC's x, the NPC needs to face left
if (playerx>x)dir=3; //if
the player's x is greater than the NPC's x, the NPC needs to face right
}
timeout=.05;
}
//End of Script
That'll do it for checking directions.
But the NPC doesn't actually walk... so, in the same set, we need add
in a sprite counter thing.
//Making it walk
if (timeout){
sprite=(sprite%8)+1; //this sets
the sprite to the remainder of the current sprite divided by 8, plus 1
timeout=.05;
}
//End of Script
This uses the % mod to allow for the sprites to cycle through.
When we add all that stuff together in the chasing script, we get:
//Latest Chasing Script
if (timeout){
sprite=(sprite%8)+1;
this.distx=abs(playerx-x);
this.disty=abs(playery-y);
if (this.distx<=this.disty){
if (playery<y)dir=0;
if (playery>y)dir=2;
}else{
if (playerx<x)dir=1;
if (playerx>x)dir=3;
}
if (this.distx==0){
this.addy=this.speed;
}else if (this.disty==0){
this.addx=this.speed;
}else if (this.distx>this.disty){
this.ratio=this.disty/this.distx;
this.addx=this.speed;
this.addy=this.speed*this.ratio;
}else if (this.disty>this.distx){
this.ratio=this.distx/this.disty;
this.addy=this.speed;
this.addx=this.speed*this.ratio;
}
if (y<playery&&!onwall(x+1.5,y+3+this.addy)) y+=this.addy;
if (y>playery&&!onwall(x+1.5,y-this.addy)) y-=this.addy;
if (x<playerx&&!onwall(x+3+this.addx,y+1.5)) x+=this.addx;
if (x>playerx&&!onwall(x-this.addx,y+1.5)) x-=this.addx;
timeout=.05;
}
//End of Script
So thats the whole chasing script, now we need to make it so when the
NPC is hit, it actually LOOKs hit.
So, back in the hit detection script, we'll add some stuff:
//New Hit detect Script
if ((washit||wasshot||exploded||waspelt)&&hearts>0){
if (washit){
hurtdx=x;
hurtdy=y;
hearts-=playerswordpower;
}
if (wasshot){
hearts--;
}
if (exploded){
hearts--;
}
if (waspelt){
if (peltwithbush) hearts-=.5;
if (peltwithsign || peltwithvase
|| peltwithstone) hearts-=1;
if (peltwithblackstone) hearts
-=1.5;
}
sprite=39; //makes
the NPC look hit
}
//End of Script
Wait a sec, this doesn't quite work... Well,
thats because we didn't make the NPC stop doing stuff even though it was
hit...
Lets add a bit more
//Newer Hit detect Script
if ((washit||wasshot||exploded||waspelt)&&hearts>0){
if (washit){
hurtdx=x;
hurtdy=y;
hearts-=playerswordpower;
}
if (wasshot){
hearts--;
}
if (exploded){
hearts--;
}
if (waspelt){
if (peltwithbush) hearts-=1;
if (peltwithsign || peltwithvase
|| peltwithstone) hearts-=2;
if (peltwithblackstone) hearts
-=3;
}
sprite=39;
sleep 1; //Now
the NPC will "sleep" for 1 second after being hit, so the sprite will stay
at 39 for a second.
timeout=.05;
// This is necessary to restart the timeout loop after the NPC has been
hit.
}
//End of Script
Thats a bit better.
Now we just need to alter one thing in the hurtdx,
hurtdy section:
//Newer hurtdx hurtdy stuff
if (hurtdx!=0||hurtdy!=0){
sprite=1;
hurtdx=0;
hurtdy=0;
}
//End of Script
Ok, now we're rolling.
One problem though, when the NPC has no hearts left, it still moves,
can still hurt the player... and stands. Lets fix that too.
//Newer Chasing Script
if (timeout){
if (hearts>0){ //Now the NPC won't
do stuff when it has no life.
sprite=(sprite%8)+1;
this.distx=abs(playerx-x);
this.disty=abs(playery-y);
if (this.distx<=this.disty){
if (playery<y)dir=0;
if (playery>y)dir=2;
}else{
if (playerx<x)dir=1;
if (playerx>x)dir=3;
}
if (this.distx==0){
this.addy=this.speed;
}else if (this.disty==0){
this.addx=this.speed;
}else if (this.distx>this.disty){
this.ratio=this.disty/this.distx;
this.addx=this.speed;
this.addy=this.speed*this.ratio;
}else if (this.disty>this.distx){
this.ratio=this.distx/this.disty;
this.addy=this.speed;
this.addx=this.speed*this.ratio;
}
if (y<playery&&!onwall(x+1.5,y+3+this.addy))
y+=this.addy;
if (y>playery&&!onwall(x+1.5,y-this.addy))
y-=this.addy;
if (x<playerx&&!onwall(x+3+this.addx,y+1.5))
x+=this.addx;
if (x>playerx&&!onwall(x-this.addx,y+1.5))
x-=this.addx;
timeout=.05;
} // Notice the timeout is within the
hearts>0 part of the script. That so the loop won't continue when
it has no life.
}
//End of Script
We still need to make it not hurt the player when it'd dead, so we
just take the old hurting scripts:
//Can't hurt when dead
if (playertouchsme&&hearts>0){
hurt this.pow;
}
if (hearts>0&&abs((x+1.5)-(playerx+1.5))<=3 &&abs((playery+1.5)-(y+1.5))<=3)
{
hurt this.pow;
}
//End of Script
So now it won't move when it has no life.
But we gotta make it LOOK dead. So we just add the following
to our script:
//Dead Part
if (timeout&&hearts<=0){
sprite=40;
}
//End of Script
This would be where you make the NPC lay some items if you would want
it to do that, as well as the whole "spin" effect. Read sections:
6.2, and 6.3
So now we have all the graphical stuff included, heres the whole script:
//Script So far
if (created){
showcharacter;
this.speed=.5;
this.pow=2;
hearts=3;
hurtdx=0;
hurtdy=0;
timeout=.05;
}
if (timeout){
if (hearts>0){
sprite=(sprite%8)+1;
this.distx=abs(playerx-x);
this.disty=abs(playery-y);
if (this.distx<=this.disty){
if (playery<y)dir=0;
if (playery>y)dir=2;
}else{
if (playerx<x)dir=1;
if (playerx>x)dir=3;
}
if (this.distx==0){
this.addy=this.speed;
}else if (this.disty==0){
this.addx=this.speed;
}else if (this.distx>this.disty){
this.ratio=this.disty/this.distx;
this.addx=this.speed;
this.addy=this.speed*this.ratio;
}else if (this.disty>this.distx){
this.ratio=this.distx/this.disty;
this.addy=this.speed;
this.addx=this.speed*this.ratio;
}
if (y<playery&&!onwall(x+1.5,y+3+this.addy))
y+=this.addy;
if (y>playery&&!onwall(x+1.5,y-this.addy))
y-=this.addy;
if (x<playerx&&!onwall(x+3+this.addx,y+1.5))
x+=this.addx;
if (x>playerx&&!onwall(x-this.addx,y+1.5))
x-=this.addx;
timeout=.05;
}
}
if (playertouchsme&&hearts>0){
hurt this.pow;
}
if (hearts>0&&abs((x+1.5)-(playerx+1.5))<=3 &&abs((playery+1.5)-(y+1.5))<=3)
{
hurt this.pow;
}
if ((washit||wasshot||exploded||waspelt)&&hearts>0){
if (washit){
hurtdx=x;
hurtdy=y;
hearts-=playerswordpower;
}
if (wasshot){
hearts--;
}
if (exploded){
hearts--;
}
if (waspelt){
if (peltwithbush) hearts-=.5;
if (peltwithsign || peltwithvase
|| peltwithstone) hearts-=1;
if (peltwithblackstone) hearts
-=1.5;
}
sprite=39;
sleep 1;
timeout=.05;
}
if (hurtdx!=0||hurtdy!=0){
sprite=39;
hurtdx=0;
hurtdy=0;
}
if (timeout&&hearts<=0){
sprite=40;
}
// End of Script
There you go. One very basic baddy. It runs to the player,
and hurts him/her. It can be hurt/killed. So from here, all
we have left is to make it even better.