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.
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)
You are genius! I wish I thought of it like that! It is even more realistic this way! Thank you!
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.
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.
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.
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.
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.
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.
Indeed, and it's room_RepExec instead of repeatedly_execute for room scripts.
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);
}
}
}
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);
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)
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.
OOOH! Speed?! I didn't know that! Thanks for the tip!
Hmmmm....it fixed the run-time error. But it still did not move.
oStalagmiteTip.Move(oStalagmiteTip.X, 1000,10, eNoBlock, eAnywhere);
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.