Hey all, hope you had a good Christmas.
I'm doing a sub-game in which the player controls a big fish swimming around which has to eat smaller fish. It does this by running into them. This is my code for the collision:
if (cEgo.IsCollidingWithChar(cfish)){
if (cEgo.Loop == 0){ //if facing direction, eg down
player.ChangeView(194);//change to bite anim
player.Animate(0, 1, eOnce, eBlock);//play bite anim
player.ChangeView(101);//returns to original view
}
if (cEgo.Loop == 1){
player.ChangeView(194);
player.Animate(1, 1, eOnce, eBlock);
player.ChangeView(101);
}
if (cEgo.Loop == 2){
player.ChangeView(194);
player.Animate(2, 1, eOnce, eBlock);
player.ChangeView(101);
}
if (cEgo.Loop == 2){
player.ChangeView(194);
player.Animate(2, 1, eOnce, eBlock);
player.ChangeView(101);
}
cfish.ChangeRoom(-1); //fish disappears
It works fine.
HOWEVER - fishes usually just eat through their mouths and as you can probably guess this interaction plays no matter what part of the big fish sprite my little fish come into contact with.
So here's the question - is there some way to have this interaction only play when the little fish collide with the head area of my big fish? Sort of like assigning a hotspot or region to the sprite.
Thanks for your time, hope you're all having a good one.
The easier way would be breaking the bigger fish sprite in two, head and rest.
Or
You could play around with and add if cEgo.y in relation to cFish.y
Or check which loop your fish is facing and only eat if the loop is facing the small fish... which might end up having to check loop and y position for the fishes... but should work fine. (nod)
Quote from: eri0o on Sat 29/12/2018 07:13:15
The easier way would be breaking the bigger fish sprite in two, head and rest.
Actually thought of doing this - using "follow exactly" - I'm considering it as a last resort if I can't get anything else working as it'd necessitate me redrawing a bunch of art. Cheers for the suggestion!
Slasher, could you elaborate? As I understand it this would involve checking coordinates on the sprite itself rather than the room/screen? Apologies if this is a dumb question.
Quote from: Cassiebsg on Sat 29/12/2018 09:00:38
Or check which loop your fish is facing and only eat if the loop is facing the small fish... which might end up having to check loop and y position for the fishes... but should work fine. (nod)
This makes sense, I'll have a try!
You can mark rectangular region that will cover mouth part of the fish and check collisions between it and other fishes (using AABB if sprites are not rotated).
Just store XYs relative to sprite origin point and width, height somewhere for each facing directions.
Quote from: Slasher on Sat 29/12/2018 07:15:13
Or
You could play around with and add if cEgo.y in relation to cFish.y
This is how I would do it. Adding extra sprites might get messy and slow.
You can replace those four blocks with:
if (player.IsCollidingWithChar(cfish)) {
player.LockView(194); // change to bite anim
player.Animate(player.Loop, 1, eOnce, eBlock); // play bite anim
player.UnlockView(); // returns to original view
}
I too would use a coordinate check. First, calculate the coordinates of the mouth's bottom center by adding a loop-based offset to the player's position:
int x = player.x, y = player.y - 20; // base offset
if (player.Loop == 0) y -= 10; // down
else if (player.Loop == 3) y -= 50; // up
else if (player.Loop == 1) x -= 40; // left
else x += 40; // right
Now you can use the Pythagorean theorem to calculate the distance between the player's mouth base coords and another fish's base coords.
If distance < x, small fish collides with mouth.
Khris, thanks for the shortcut on those initial loops, that's made things a lot simpler and less cluttered.
Quote from: Khris on Sun 30/12/2018 13:18:23
int x = player.x, y = player.y - 20; // base offset
if (player.Loop == 0) y -= 10; // down
else if (player.Loop == 3) y -= 50; // up
else if (player.Loop == 1) x -= 40; // left
else x += 40; // right
Now you can use the Pythagorean theorem to calculate the distance between the player's mouth base coords and another fish's base coords.
If distance < x, small fish collides with mouth.
Yeah sorry, you lost me at Pythagorean Theorem I'm afraid! Can you throw me a quick example? Thanks for your time as always.
You're going to need x and y distance first:
int dx = cFish.x - player.x;
int dy = cFish.y - player.y;
According to the theorem, the distance between player and cFish squared is dx² + dy². Accordingly:
if (dx * dx + dy * dy < 20 * 20) // distance is less than 20 pixels
Quote from: Khris on Mon 31/12/2018 09:45:59
You're going to need x and y distance first:
int dx = cFish.x - player.x;
int dy = cFish.y - player.y;
According to the theorem, the distance between player and cFish squared is dx² + dy². Accordingly:
if (dx * dx + dy * dy < 20 * 20) // distance is less than 20 pixels
Got this working great, with a couple of adjustments! Thanks as always Khris, this was more or less exactly what I was after.