Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: xboxown on Wed 21/06/2023 04:04:19

Title: How to do collision detection between tentacle and player?
Post by: xboxown on Wed 21/06/2023 04:04:19
  Hey guys,

I have one other question to ask. I want when the tentacle collides with the player it is considered game over. The player is crushed and dies out. How do I make the collision detection for that? Another thing, how do I replace a character in the map, add another character in the map and make that new character after reaching its destination disappear and be removed from the map?

I will explain. I have a Frail Stalagmite. It comes into two part. One is the full frail stalagmite, once the tentacle hits it, the full stalagmite is replaced with broken stalagmite one and another piece is added and falls down to the water and disappears once it hits the water.
Title: Re: How to do collision detection between tentacle and player?
Post by: Khris on Wed 21/06/2023 06:31:51
First of all, you don't need to use a (global) character for everything. Rooms have (local) objects, so unless you need walking animations, those are fine.

Next, you can do a simple coordinate check. Since the tentacles only move sideways, you only need to compare the x coordinates of the tentacle and the stalactite.

Again inside repeatedly_execute:

  int dist = cTentacle.x - (oStalactite.X + Game.SpriteWidth[oStalactite.Graphic] / 2);
  if (dist < 0) dist = -dist;
  if (dist < 20 && oStalactite.Y == 123) { // adjust these numbers, replace 123 with proper Y coordinate
    oStalactiteTip.Move(oStalactiteTip.X, 10000, eNoBlock);
  }
  // tip reaches water
  if (oStalactiteTip.Y >= 250) {
    oStalactite.StopMoving();
    oStalactite.Visible = false;
  }
Objects are positioned using their bottom left corner, so we add half the sprite width to get to the center and compare that to the tentacle by checking whether the difference is below a threshold.

As for the piece breaking off, just start with the stalactite already in pieces. This way you simply need to move the tip object down and not replace anything.

(once again the code might now work as-is and is primarily meant to show a way how this can be done in general)
Title: Re: How to do collision detection between tentacle and player?
Post by: xboxown on Wed 21/06/2023 07:06:22
You are genius! I wish I thought of it like that! It is even more realistic this way! Thank you!
Title: Re: How to do collision detection between tentacle and player?
Post by: xboxown on Wed 21/06/2023 20:59:05
Quote from: Khris on Wed 21/06/2023 06:31:51First of all, you don't need to use a (global) character for everything. Rooms have (local) objects, so unless you need walking animations, those are fine.

Next, you can do a simple coordinate check. Since the tentacles only move sideways, you only need to compare the x coordinates of the tentacle and the stalactite.

Again inside repeatedly_execute:

  int dist = cTentacle.x - (oStalactite.X + Game.SpriteWidth[oStalactite.Graphic] / 2);
  if (dist < 0) dist = -dist;
  if (dist < 20 && oStalactite.Y == 123) { // adjust these numbers, replace 123 with proper Y coordinate
    oStalactiteTip.Move(oStalactiteTip.X, 10000, eNoBlock);
  }
  // tip reaches water
  if (oStalactiteTip.Y >= 250) {
    oStalactite.StopMoving();
    oStalactite.Visible = false;
  }
Objects are positioned using their bottom left corner, so we add half the sprite width to get to the center and compare that to the tentacle by checking whether the difference is below a threshold.

As for the piece breaking off, just start with the stalactite already in pieces. This way you simply need to move the tip object down and not replace anything.

(once again the code might now work as-is and is primarily meant to show a way how this can be done in general)


Visible and graphics are producing error. There is no way of making the character disappear as a command.
Title: Re: How to do collision detection between tentacle and player?
Post by: Khris on Wed 21/06/2023 21:32:57
1. please do not quote the entire post; you can click the Reply button at the bottom.

2. in my code, oStalactite is an Object, not a Character. Please show your code and error messages as they appear, ideally verbatim.

3. once again: the code might not work as-is and is primarily meant to show a way how this can be done in general; there's no way around studying the manual and familiarizing yourself with the AGS scripting language.
Title: Re: How to do collision detection between tentacle and player?
Post by: xboxown on Wed 21/06/2023 22:48:48
Quote1. please do not quote the entire post; you can click the Reply button at the bottom.

Apologies for that. Not doing it again.

Quote2. in my code, oStalactite is an Object, not a Character. Please show your code and error messages as they appear, ideally verbatim.

OK...this is the source code modified:

int dist = cTentacle.x - (cStalagmiteTip.x+ Game.SpriteWidth[cStalagmiteTip.Frame] / 2);
   if (dist < 0) dist = -dist;
  // Display(String.Format("%d", dist));
   if (dist<10) { // adjust these numbers, replace 123 with proper Y coordinate
    Display("Uh oh...look like that tentacle hit something it should not have hit!!");
    cStalagmiteTip.Walk(cStalagmiteTip.x, 80, eBlock, eAnywhere);
    }
    // tip reaches water
    if (cStalagmiteTip.y >= 64) {
      cStalagmiteTip.StopMoving();
      cStalagmiteTip.ChangeRoom(1, 0, 0, eDirectionDown);
      Display("The stalagmite falls and sinks into the ocean. The monster shrieks in pain....");
      cSeaMonster.LockView(VWROARINGMONSTER);
      cSeaMonster.Animate(false,  5, eOnce);
      cSeaMonster.UnlockView(eStopMoving);
    }

I couldn't make it invisible so I decided to make a void room and just the unwanted characters there where the player can never visit as means of destroying them.

Quote3. once again: the code might not work as-is and is primarily meant to show a way how this can be done in general; there's no way around studying the manual and familiarizing yourself with the AGS scripting language.

Yeah, for sure, I can read the manual. If I am stuck though, I will post here in hopes great people like you :D well take their time to help me out. But you are right, I should read the manual and try hard to figure it out on myself first. Best to way to learn, right?

Thank you so much for helping me and replying my to plea. I appreciate your time and effort, especially since it is coming out of your time to helping a stranger like me.
Title: Re: How to do collision detection between tentacle and player?
Post by: Crimson Wizard on Wed 21/06/2023 22:54:18
Quote from: xboxown on Wed 21/06/2023 22:48:48I couldn't make it invisible so I decided to make a void room and just the unwanted characters there where the player can never visit as means of destroying them.

You can move NPCs to a non-existant rooms too. cSeaMonster.ChangeRoom(-1) will work.

Other ways to hide characters are:
* moving behind room edges, like cSeaMonster.x = -1000;
* cSeaMonster.Transparency = 100;
* cSeaMonster.on = false; but I think this requires to enable a backwards compatibility option, because "on" variable was not ported to the modern scripting API.
Title: Re: How to do collision detection between tentacle and player?
Post by: xboxown on Wed 21/06/2023 23:29:13
I understood what Khris was doing. Add a new object and then use the object for the room. I just checked youtube and learned now how to add object.

I did and reused his code again:

if (dist<10) { // adjust these numbers, replace 123 with proper Y coordinate
    Display("Uh oh...look like that tentacle hit something it should not have hit!!");
    oStalagmiteTip.Move(oStalagmiteTip.X, 1000, eNoBlock);
    }
    // tip reaches water
    if (cStalagmiteTip.y >= 200) {
      oStalagmiteTip.StopMoving();
      oStalagmiteTip.Visible=false;
      //cStalagmiteTip.ChangeRoom(1, 0, 0, eDirectionDown);
      Display("The stalagmite falls and sinks into the ocean. The monster shrieks in pain....");
      cSeaMonster.LockView(VWROARINGMONSTER);
      cSeaMonster.Animate(false,  5, eOnce);
      cSeaMonster.UnlockView(eStopMoving);
     
    }
  }

Problem now..the thing does not move at all. I don't know what mistake I made here.
Title: Re: How to do collision detection between tentacle and player?
Post by: Crimson Wizard on Wed 21/06/2023 23:39:45
Quote from: xboxown on Wed 21/06/2023 23:29:13Problem now..the thing does not move at all. I don't know what mistake I made here.

You probably need to re-add eAnywhere to Move.
Title: Re: How to do collision detection between tentacle and player?
Post by: Khris on Thu 22/06/2023 00:03:52
Indeed, and it's room_RepExec instead of repeatedly_execute for room scripts.
Title: Re: How to do collision detection between tentacle and player?
Post by: xboxown on Thu 22/06/2023 00:07:52
Aaah! Actually it is under repeated exec:


(https://i.ibb.co/kh6p7kZ/Untitled.png)

function room_RepExec()

This the entire code in case I made a bug somewhere.

function room_RepExec()
{
  if (!SeaMonsterAttack)
  {
    // Not close to the monster
    cTentacle.x = cSeaMonster.x - 47;
    cSecondTentacle.x = cSeaMonster.x + 57;
    if (IsTimerExpired(1)) {
      int newX, diff;
      do {
        newX = Random(160) + 40; // range 40 - 200
        diff = newX - cSeaMonster.x; if (diff < 0) diff = -diff;
      } while (diff < 30); // move by at least 30 pixels
      cSeaMonster.Move(newX, cSeaMonster.y, eNoBlock, eAnywhere);
      SetTimer(1, (Random(5) + 5) * GetGameSpeed()); // 5 - 10 seconds
    }
  }
  else if (SeaMonsterAttack)
  {
    if (!oStalagmiteTip.Moving)
    {
      cSeaMonster.Say("ROOOAAARR");
      // swing tentacle
      cRobotLE.Say("Eeeeeek!!");
      cRobotLE.Walk(cRobotLE.x,  cRobotLE.y+24, eBlock, eWalkableAreas);
      // Close to the monster
      cSeaMonster.LockView(VWROARINGMONSTER);
      cSeaMonster.Animate(false,  5, eOnce);
      cSeaMonster.UnlockView(eStopMoving);
      cTentacle.LockView(VWRAISINGTENTACLE);
      cTentacle.Animate(false,  15, eOnce);
      cTentacle.UnlockView(eStopMoving);
      cSecondTentacle.LockView(VWRAISINGTENTACLE);
      cSecondTentacle.Animate(false,  20, eOnce);
      cSecondTentacle.UnlockView(eStopMoving);
      cTentacle.y=cTentacle.y+48;
      cTentacle.LockView(VWSWINGTENTACLE);
      cTentacle.Animate(false,  20, eOnce);
      cTentacle.UnlockView(eStopMoving);
      cSecondTentacle.y=cSecondTentacle.y+48;
      cSecondTentacle.LockView(VWSWINGTENTACLE);
      cSecondTentacle.Animate(false,  25, eOnce);
      cSecondTentacle.UnlockView(eStopMoving);
      cSecondTentacle.y=cSecondTentacle.y-48;
      cTentacle.y=cTentacle.y-48;
   // if (cTentacle.x>=75 && cTentacle.x<=85)
    //{
      // Here monster dies and be replaced with a body log.
     // Display("The tentancle damages the frail ....");
   // }
    }
   int dist = cTentacle.x - (cStalagmiteTip.x+ Game.SpriteWidth[cStalagmiteTip.Frame] / 2);
   if (dist < 0) dist = -dist;
  // Display(String.Format("%d", dist));
   if (dist<10) { // adjust these numbers, replace 123 with proper Y coordinate
    Display("Uh oh...look like that tentacle hit something it should not have hit!!");
    oStalagmiteTip.Move(oStalagmiteTip.X, 1000, eNoBlock);
    }
    // tip reaches water
    if (oStalagmiteTip.Y >= 200) {
      oStalagmiteTip.StopMoving();
      oStalagmiteTip.Visible=false;
      //cStalagmiteTip.ChangeRoom(1, 0, 0, eDirectionDown);
      Display("The stalagmite falls and sinks into the ocean. The monster shrieks in pain....");
      cSeaMonster.LockView(VWROARINGMONSTER);
      cSeaMonster.Animate(false,  5, eOnce);
      cSeaMonster.UnlockView(eStopMoving);
     
    }
  }
}

Title: Re: How to do collision detection between tentacle and player?
Post by: Khris on Thu 22/06/2023 07:40:15
That's fine, I was referring to the function's name not the event's. You still didn't add eAnywhere though, line 57 in that snippet needs to be
  oStalagmiteTip.Move(oStalagmiteTip.X, 1000, eNoBlock, eAnywhere);
Title: Re: How to do collision detection between tentacle and player?
Post by: xboxown on Thu 22/06/2023 17:56:14
I did. It gave me an error that I added an extra parameter block that does not exist with object. Here let me show you the error message via screenshot:

(https://i.ibb.co/hC3j4JJ/Untitled.png)
Title: Re: How to do collision detection between tentacle and player?
Post by: Snarky on Thu 22/06/2023 18:00:32
The problem is that you're missing the speed parameter, so the eNoBlock gets interpreted as the speed, and then eAnywhere gets interpreted as the blocking parameter, and is an illegal value for it.

For this kind of error, you should consult the built-in help. There's a quick-help tooltip when you edit the parameters or hover the mouse over the function that tells you the right format, or if you press F1 it should bring you to the relevant article in the manual.
Title: Re: How to do collision detection between tentacle and player?
Post by: xboxown on Thu 22/06/2023 18:11:43
OOOH! Speed?! I didn't know that! Thanks for the tip!
Title: Re: How to do collision detection between tentacle and player?
Post by: xboxown on Thu 22/06/2023 18:16:22
Hmmmm....it fixed the run-time error. But it still did not move.

oStalagmiteTip.Move(oStalagmiteTip.X, 1000,10,  eNoBlock, eAnywhere);
Title: Re: How to do collision detection between tentacle and player?
Post by: Khris on Thu 22/06/2023 18:29:23
Try replacing
  if (dist<10)with
  if (dist < 10 && !oStalagmiteTip.Moving)
Also, basic debugging. You have already done this yourself:
// Display(String.Format("%d", dist));Just keep doing that to check values and whether lines run at all, etc.

You might also want to fix the indentation, it's all over the place currently which makes debugging much harder.