Wandering Creatures

Started by Yuri Patrick, Tue 18/09/2012 20:47:28

Previous topic - Next topic

Yuri Patrick

How does one make a crocodile wander aimlessly around a mote without leaving the mote's area or having to make him walk onto the screen? I did a search through the manual and found AddWayPoint.

AddWayPoint appears clumsy for what I am trying to do. Simply have the crocodile swim aimlessly around a rectangular moat. I would think there would be a way to just tell AGS to aim him randomly and keep him within the moat.

Crimson Wizard

Quote from: wolverine79936 on Tue 18/09/2012 20:47:28
AddWayPoint appears clumsy for what I am trying to do. Simply have the crocodile swim aimlessly around a rectangular moat. I would think there would be a way to just tell AGS to aim him randomly and keep him within the moat.
Yes there's.
Since moat is defined as rectangle, most basic way to do this would be this algorythm:
- each game tick check if croc is moving now;
- if he does, don't do anything yet;
- if he doesn't, then choose a random point in the given rectangle and send him there in non-blocking fashion.
- repeat.
Algorythms like that are usually implemented inside "repeatedly_execute" functions. Since the crocodile appears in certain room only, it should be "Repeatedly execute" event handler function for that room.
In the following example I put crocodile code in a separate function that is being called from rep_exec in sake of code readability.
Code: ags

function UpdateCrododile()
{
   if (cCrocodile.Moving)
      return;
   int x = MOAT_RECT_X1 + Random(MOAT_RECT_X2 - MOAT_RECT_X1);
   int y = MOAT_RECT_Y1 + Random(MOAT_RECT_Y2 - MOAT_RECT_Y1);
   cCrocodile.Walk(x, y, eNoBlock, eWalkableAreas); // don't block, stay and moat's walkable area (I assume there's one prepared for him)
}

// Then in room's rep_exec
function room_RepExec()
{
    // call croco update
    UpdateCrododile();
}


Sort of that...

Yuri Patrick

I loath ASCII art, but here goes:

I'm trying to picture your code working in my mind. It looks like a swimming pool more than what I have designed for my croc. Here's how I picture your code:

__________
|                    |
|                    |
|__________|

And here is what I have laid out:

__     CASTLE          __
|  |_______|______|  |
|_________|_______|

I need my crock to go a little up the left side of the moat, across the moat and then up the right side, all randomly. Just remembered I have the visible moat set up across two screens. Lemme add a divider real quick. ;)

There we go.

Perhaps this will help: Think King's Quest I, I need a castle and a moat and crocs randomly swimming throughout the visible moat.

PS: Posted and then realized, "Wow! ASCII art without a monospace font is difficult. ;)

Yuri Patrick

#3
So, with that wonderful example of my artistic skills, back to the code at hand. You put up:

Code: AGS
function UpdateCrododile()
{
   if (cCrocodile.Moving)
      return;
   int x = MOAT_RECT_X1 + Random(MOAT_RECT_X2 - MOAT_RECT_X1);
   int y = MOAT_RECT_Y1 + Random(MOAT_RECT_Y2 - MOAT_RECT_Y1);
   cCrocodile.Walk(x, y, eNoBlock, eWalkableAreas); // don't block, stay and moat's walkable area (I assume there's one prepared for him)
}
 
// Then in room's rep_exec
function room_RepExec()
{
    // call croco update
    UpdateCrododile();
}


And now I'm thinking about maybe splitting the moat within the code. But now I'm wondering how difficult that might be. Perhaps a xa, xb, ya and yb set of coordinates depending on which quarter of the moat the croc is in and then redesignating boarder coords for each section of the moat. Hrm.

I must concede, this is twice in one day you got me thinking, Crimson. :)

OH! I got it! One croc in the bottom right, one in the right, one in the bottom left and one in the far left. And each one has their own set of coords. Since each croc is it's own object, that should be doable. I can just have functions for each quarter of the moat. DUH!

Crimson Wizard

#4
Well... there's definitely numerous options for that.
Yeah, right few days ago I was playing KQ1, so I know what you are up to :).
Crododile could be done either by character, or by object (in which case different function is used, not Walk, but Move). Although I think that character is better because it is easier to do swimming animation. Also you may use same character in any number of rooms, wile object is staying in one room all the time.
Regarding moat geometry - you may split moat into rectangular parts and first randomly choose one of them, secondly choose coordinates inside choosen rect.

Yuri Patrick

Heh. Cool. Someone who gets me. ;)

And as for the moat thing, I was thinking about two croc functions on each screen. One at the bottom and one at the top so that they can both run at the same time. But you are getting me to think again.

You just reminded me how to work with if and numbers and now you are reminding me how to work with random generators. So... I'm having more ideas. :) I might be able to get the one Croc to swim the majority of the moat on the one screen instead of two. Still want two on each screen, but I think I get it now. :)

Let's see how I fair.

Khris

Even with an L-shaped moat, the code still applies. The crocodile can't leave the walkable area, so if the target is outside, he'll approach it as closely as he can, then stop.
One could also do this:
Code: ags
  bool not_found = true;
  int x,y;
  while (not_found) {
    x = 100 + Random(150);
    y = 100 + Random(70);
    if (GetWalkableAreaAt(x, y) == 2) not_found = false;
  }
  // x,y is within moat


To have the croc realistically roam a moat that stretches across two screens, one could use a bit of a "hack".
Each screen contains a walkable area near the top that's half as big as the actual moat. In there, an invisible dummy character moves around, using the same randomized walking.
The coordinates, loop and frame of this character are transferred directly to the actual crocodile character, mapping the coordinates to the actual moat. It takes a bit of housekeeping in the rooms' before fadein events but isn't too hard. That way, the crocodile would occasionally leave the room and move back in view, too.

Yuri Patrick

Thanks, Khris. I have to double-check, haven't created the other side of the castle, yet, but I think my crocodiles already go onto the half of the moat. ;) Sheer accident.

Yuri Patrick

ARGH! AGS hates me. :(

Here's my code:
Code: AGS
function UpdateCrocodile2()
{
  bool not_found = true;
  
  while (not_found) {
  if (cCroc2.Moving)
    return;
  int x = 171 + Random(179);
  int y = 14 + Random(274);
  
  if (GetWalkableAreaAt(x,  y) == 2) not_found = false;
  }
}


The second croc won't wander. He just sits there like moat scum... Until I remove the last line: if (GetWalkableAreaAt(x, y) == 2) not_found = false;

As long as that last line is there, his code breaks and I can't, for the life of me, figure out why. I'm not even getting a compile time error. :(

Heh, btw. Yesterday all my crocs were swimming just fine yesterday with Crimson's code. I started working on my game some more today and they swam right out of the mote. Hrmph. They went right into walkable area 1 from walkable area 2. 2 is the moat 1 is some field space.

Yuri Patrick

#9
Hrm. Think I might have just found my problem. BRB.

I can't delete posts of my own. How rude. ;)

Anyway, didn't fix it. I thought maybe if I split the last line of code and bracketed it, it might work right, but no dice.

Gotta run, but gonna keep eyeballing this thread and working on my problem. :)

---

ACK! I just got done filling in all of the walkable areas in my room and now my crocodiles are swimming all over the screen. One even swam off the screen never to return. (ROTFL!) How can I confine them to one specific walkable area?

Crimson Wizard

Quote from: wolverine79936 on Wed 19/09/2012 19:24:36
ACK! I just got done filling in all of the walkable areas in my room and now my crocodiles are swimming all over the screen. One even swam off the screen never to return. (ROTFL!) How can I confine them to one specific walkable area?
That is something I would certainly like to see in the next versions of AGS. Unfortunately I never heard about the general solution for current version :/

You may try making sure there's always some space between two walkable areas.

Khris

Just to be clear, my code assumes that the rectangle specified by the coordinates contains most of, if not all of walkable area #2. If not even a small part of area #2 is inside it, the loop will of course run indefinitely, since the random coordinates will never hit area #2.
You have to change the 2 to the ID of the area you're using. I just used 2 because I assumed that 1 is the area where the player and NPCs walk and thus 2 is being used for the moat.
If this is done correctly, this should also solve the problem of the crocodiles leaving the area, unless there are situations in which two points of area 2 are connected by another area (and that distance is shorter).

Yuri Patrick

Hrm. That's frustrating since 2 overlaps 1. I'll have to work on this some more. So, as long as 2 is touching any other walkable area, 1, 3, 4, etc, it will not work. But as long as 2 is separated, even by a thin line, it will work then...?

Didn't notice that. It's been a while since I coded in any language. :(

Khris

Walkable areas can't overlap. Still, I'm wondering what exactly the problem is; didn't you set the area for the random coordinate generation to a rectangle that closely encompasses the walkable area?

Could you make a screenshot of your walkable areas and show it to us?

SMF spam blocked by CleanTalk