I was working on collision, and I was getting help from DST. Thanks dood, very much appreciated for the code, but I'm a little confused with how the math behind it works.
Here's the last responding quote:
DST wrote:The simplest way to make a controlled collision movement is using the moveto() function, like this:
- Code: Select all
int i=x-collide.x; //store the offset of this actor vs. collide actor position
int j=y-collide.y; //using x-collide.x gives us negative offset (collide.x-x would create positive offset)
MoveTo("Event Actor", x+i, y+j, 10.000000, "Game Center", ""); //move to that negative offset
If he is to move farther away than that, just multiply the i/j values by whatever you wish before adding them to the moveto();
As for the animation and invincibility, you can 'changeanimation' in the collision script, and then add an 'animationfinish>hurt animation>script editor' where you restore to normal animation.
If he is to be invincible during the duration of the 'hurt', simply wrap this script in a variable check, like
if(cancollide==1){
//movetoscript here
cancollide=0;
}
Then return it to 1 on the animation finish. You can use a timer, or a 'state' switch in draw actor to more accurately set the length of time he is hurt, if you prefer, instead of using animationfinish.
The cancollide disables collisions while he is in hurt mode, and by NOT using that same 'if' in wall collisions, he'll always collide with walls no matter what.
I often like to use a state switch for actors, like this:
Actor>draw actor>
switch(state){
- Code: Select all
case 0: //normal operation
break;
case 1://hurt mode
variable++;
if(variable==10){ //stay hurt for 10 frames
variable=0;
state=0; //then return to normal mode
ChangeAnimation(etc etc);
}
break;
}
Then you can simply switch the state in the collision, and also use that same state instead of cancollide, by only allowing the collisions script to happen if the state!=1. You can also disable other events in the state, so you won't have to do it in the collision. Keep in mind that it's a good idea to set that 'variable' used as a timer to 0 upon collision, to prevent it being a wrong value if something else happened to interrupt it.
Most important part of all: If you have multiple enemies that are not clones, you would need this collision script for collision with each one. so make it a function!
Go to global script, and wrap it in a function name:
- Code: Select all
void getHurt(int cx, int cy){
//collision script here, using cx instead of collide.x, and cy instead of collide.y
}
Then just call the getHurt(collide.x, collide.y); in the collisions with each type of enemy, instead of typing it out each time. Making changes to the script will be much easier that way, as everything you do to the collide script will automatically happen to all the collisions.
Note that you have to pass the collide.x and y variables to the script but not the event actor's x and y, because a script automatically becomes part of the actor it's called in. So you'd also want to add the collide.damage, as another int in the script, and any other variable that the enemy passes on to the player.
Using these things as functions makes a game 100x easier to create.
The math behind the collision is a bit confusing to me. But it works-somewhat.
Let's say the main hero gets hit by an enemy and takes damage, he still moving, from what it looks like, leftover momentum, so he's moving a little.
If might be doing this wrong, but the code I put in as a Collision->Draw Actor is this:
- Code: Select all
i = hero.x - monster1.x;
j = hero.y - monster1.y;
MoveTo("Event Actor", hero.x+i, hero.y+j, 2, "Game Center", "");
As for the hurt animation, his "hurt" direction has to be congruent with the direction he was facing before we was hurt. ↑↓→←
How exactly would I write the code to receive the current animation (the direction he's facing)?
And then return to normal?