problem with Char-Obj-collision

Started by timeus, Fri 04/07/2003 22:14:57

Previous topic - Next topic

timeus

hi!

i'm working on a SQ3 remake, and i have a problem in the very first screen with the warp motivator (object). i would like the character to stop when he walks against the object, so i've tried:

if (AreCharObjColliding(EGO, 0) == 1)
   StopMoving(EGO);

only problem is that he obviously gets stuck, because he's colliding the whole time. i'm implementing a solution, where the character is moved out of the collision (using directional variables, etc), but this is tedious and i say to myself there must be an easier way to do it :-)

is there a function i'm missing that someone could point out to me?

thanks!
-tim

Scorpiorus

the next should work...

//room script

int prev_x, prev_y;

function room_*() {
// room's repeatedly

if (AreCharObjColliding(EGO, 0) == 1) {

 StopMoving(EGO);
 character[EGO].x = prev_x;
 character[EGO].y = prev_y;

}
else {

prev_x = character[EGO].x;
prev_y = character[EGO].y;

}


}

-Cheers

timeus

ah! thanks for that elegant solution :-)

-tim

timeus

hi again!

it seems character[].x and .y are read-only. i replaced it with MoveCharacter (and -Direct and -Straight) but the character still gets stuck. here's the code (all global, i can't see a local repeatedly_execute function)

========<snip>=======

int prev_x, prev_y;        // these are initialized in game_start()

function collideMotivator() {
 if (AreCharObjColliding(EGO, 0) == 1) {
   MoveCharacter(EGO, prev_x, prev_y);
 }
 else {
   prev_x = character[EGO].x;
   prev_y = character[EGO].y;
 }
}

function repeatedly_execute() {
 // put anything you want to happen every game cycle here
 collideMotivator();
}

========<snip>======

any ideas would be appreciated :-)

-tim

timeus

ok, i'm an idiot. i've figured out how local repeatedly_executes work, but i still have that problem where the character gets stuck. :-)

-tim

Scorpiorus

Quoteit seems character[].x and .y are read-only.
Yep, read-only, but it's because if you change them while the character is moving it may mess the things and he will go in wrong direction etc. However you can change them while the character is stationary. See a note under the global variable's list in the manual. So as you can see StopMoving() function ensures the character isn't moving.

Quotefunction collideMotivator() {
if (AreCharObjColliding(EGO, 0) == 1) {
MoveCharacter(EGO, prev_x, prev_y);
}
Oh, yes in theory what you did should work but in reality it doesn't. The problem here is that MoveCharacter() function starts moving after 1-2 loops actually whereas repeatedly_execute is called every loop so the script works so:

- collision is detected (by checking char's position)
- MoveCharacter() has been called, but actuall moving isn't started yet.
- processing next game loop and call repeatedly_execute again
- as the char's position isn't changed collision is detected again
- so MoveCharacter() will be called again but it doesn't start moving right now
- ...... etc

Of course to avoid this problem you could set a timer counter so you collideMotivator() will be called once in three-four loops:

int timer = 3;
function repeatedly_execute() {
// put anything you want to happen every game cycle here

if (timer < 0) { collideMotivator(); timer = 3; } else timer--;

}

but again if for some reason char won't have time to leave the area the collision gets triggered again.

therefore I would advice you to use character[].x = prev_x; thingy because placing the char to the (prev_x, prev_y) position guarantees the collision won't occur since that position is saved while he isn't colliding with an object.

-Cheers

timeus

hi!

this is giving me a headache. if i use a timer variable, the 'region' of the object grows and impairs walking around it (plus Roger still gets stuck). all i want is that the character musn't be able to walk through the object (i.e. a non-walkable area of a line). seems i'll have to write my own collision function for this.

thanks for the help.

-tim

Scorpiorus

hmm, why don't you want to use that code?

if (AreCharObjColliding(EGO, 0) == 1) {

StopMoving(EGO);
character[EGO].x = prev_x;
character[EGO].y = prev_y;

}
else {

prev_x = character[EGO].x;
prev_y = character[EGO].y;

}

timeus

hi!

i don't use it, because, firstly, the character still gets stuck. it works if he collides once or so, but it doesn't take much to get stuck. secondly, the collision area is too big.

if i click at the edge of the screen, and the character collides with the object on his way there, he stops. unfortunately i can't create or destroy walkable areas on the fly.

here's the entire room script as it is at the moment. if you can see an obvious error, please scream :-)

=========<snip>===============
// room script file

int prev_x, prev_y, timer;

function room_a() {
 // script for room: Repeatedly execute
 
   if (timer == 0) {
      if (AreCharObjColliding(EGO, 0) == 1) {
         StopMoving(EGO);
         character[EGO].x = prev_x;
         character[EGO].y = prev_y;
      }
      else {
         prev_x = character[EGO].x;
         prev_y = character[EGO].y;
      }
      timer = 3;
   }
   else
      timer--;
}

function room_b() {
 // script for room: Player enters screen (before fadein)
   timer = 3;
   prev_x = character[EGO].x;
   prev_y = character[EGO].y;
}
=========<snip>============

thanks!

-tim

timeus

i made it a character. now it works 100% maybe there'll be complications later, but at the moment i'm ecstatic :-)

-tim

Scorpiorus

Glad for you :)

Quoteit works if he collides once or so, but it doesn't take much to get stuck.
I think I know what's wrong. You see the script itself is correct as we save prev_x/y co-ordinates only if the character isn't colliding so far. But when you make him move he turns first and seems like that is a problem. I ticked character don't turn before walking option which helped to avoid stucking.

Yeah, probably using another char is a good idea. Actually char-char and char-obj collisions are detected in different ways.

-Cheers

timeus

hey scorpiorus!

the nice thing about char-char is that if there is a collision, the character doesn't stop - he glides on to the destination. i don't know how to code that with char-obj :-)

-tim

Scorpiorus

Oh, since there is built-in char-char collision detection in AGS you even needn't use the code at all... ;D

TerranRich

Wait...what's wrong with just not putting a walkable area where the object is? This way, the character will simply walk around it. Or did you want the character to stop completely? Because, unless you're using keyboard-controlled movement, that wouldn't make much sense. :)
Status: Trying to come up with some ideas...

timeus

Quote from: terranRICH on Sat 05/07/2003 23:43:33
Wait...what's wrong with just not putting a walkable area where the object is? This way, the character will simply walk around it.

in SQ3, the grabber can put the warp motivator (object) at various places, so there'd have to be 10+ walkable areas (probably implemented with hotspots) which have to be toggled. characters rule!

-tim

TerranRich

#15
Oh.
* terranRICH slaps his forehead.
I totally forgot about that. Sorry. :)
Status: Trying to come up with some ideas...

SMF spam blocked by CleanTalk