Page 1 of 2 12 LastLast
Results 1 to 10 of 16

Thread: Weird problems with collision in Super Heli Land

  1. #1

    Weird problems with collision in Super Heli Land

    I thought this'd be most appropriate board to ask. I have fixed crashes (and hopefully there won't be more for a time), but now I have more mundane and less critical problem, namely shaking (and occasional stuck) in collision detection.

    To reproduce and help debug me issue, clone my git repository: https://github.com/darkhog/SuperHeliLand and follow instructions found in COMPILING.txt

    You'll need to get to debug mode (right CTRL+left Shift+D) and then collide into other Marine Pop (submarine) to see it.

    Here's the code that handles movement and reacting to collisions:
    Code:
    //movement  if al_key[Options.binding_up]<>0 then begin MarioGO.y:=MarioGO.y-4; lastup:=true; end;
      if al_key[Options.binding_down]<>0 then begin MarioGO.y:=MarioGO.y+4; lastdown:=true; end;
      if al_key[Options.binding_left]<>0 then begin MarioGO.x:=MarioGO.x-4; lastleft:=true; end;
      if al_key[Options.binding_right]<>0 then begin MarioGO.x:=MarioGO.x+4; lastright:=true; end;
    
    
      //reacting to collisions;
      if ((MarioGO.isColliding(OtherMarioGO)) and (lastup)) then MarioGO.y:=MarioGO.y+8;
      if ((MarioGO.isColliding(OtherMarioGO)) and (lastdown)) then MarioGO.y:=MarioGO.y-8;
      if ((MarioGO.isColliding(OtherMarioGO)) and (lastleft)) then MarioGO.x:=MarioGO.x+8;
      if ((MarioGO.isColliding(OtherMarioGO)) and (lastright)) then MarioGO.x:=MarioGO.x-8;
    
    
      //if ESC was pressed, return to main menu
      if al_key[AL_KEY_ESC]<>0 then CurrentState:=MainMenuState;
      inherited Update;
    All of it is in TDebugState.Update (States unit).
    Problem is that when I'm trying to subtract/add in reacting to collisions phase exact same amount that was added to position in movement phase, object get stuck and can't get out of it by other means than going sideways if that was collision from top/bottom or by moving vertically, if I was moved horizontally when collision occurred. When I'm subtract 8 instead of 4, I get object shaking, like it has epilepsy. What gives?

    Can someone help me debug that issue? I also can't move object by smaller/bigger amount that 4 as my game is scaled up and single pixel is 4x4 square on screen and as you know, it'd look weird if character can move by half of pixel.

    //edit: Blue square that sometimes pops on screen means that collision between both objects has been detected. Collision itself is fine, just reaction to it is not.
    Last edited by Darkhog; 08-08-2013 at 12:03 AM.

  2. #2
    I'll try to compile this when I get home from work, but looking at the code, I must give a simple suggestion: You should either check for collision right after moving in every single direction, or check for collision once and then retract in all directions.

  3. #3
    I tested this and have no clue why this is happening.
    The thing that caught my curiosity is that sometimes TDebugState.Update fires several times even if I press key once for short time. So if you are lucky you can get two characters to overlap each other for more than 4 pixels even if you are moving it only by 4 pixels each time the TDebugState.Update fires.

  4. #4
    Quote Originally Posted by Super Vegeta View Post
    You should either check for collision right after moving in every single direction, or check for collision once and then retract in all directions.
    Tried that, now it is always stuck. My code looks like this now, will check that in so you can check if you can help:
    Code:
    if al_key[Options.binding_up]<>0 then begin    MarioGO.y:=MarioGO.y-4;
        if MarioGO.isColliding(OtherMarioGO) then MarioGO.y:=MarioGO.y+4;
      end;
      if al_key[Options.binding_down]<>0 then begin
        MarioGO.y:=MarioGO.y+4;
        if MarioGO.isColliding(OtherMarioGO) then MarioGO.y:=MarioGO.y-4;
      end;
      if al_key[Options.binding_left]<>0 then begin
        MarioGO.x:=MarioGO.x-4;
        if MarioGO.isColliding(OtherMarioGO) then MarioGO.x:=MarioGO.x+4;
      end;
      if al_key[Options.binding_right]<>0 then begin
        MarioGO.x:=MarioGO.x+4;
        if MarioGO.isColliding(OtherMarioGO) then MarioGO.x:=MarioGO.x-4;
      end;

  5. #5
    I did some debugging with this kind of code:
    Code:
      //oldX:=MarioGO.x;
      oldY:=MarioGO.y;
      oldX:=10; // TEST
    
      //movement
      if al_key[Options.binding_up]<>0 then begin
        MarioGO.y:=MarioGO.y-4;
      end;
      if al_key[Options.binding_down]<>0 then begin
        MarioGO.y:=MarioGO.y+4;
      end;
      if al_key[Options.binding_left]<>0 then begin
        MarioGO.x:=MarioGO.x-4;
      end;
      if al_key[Options.binding_right]<>0 then begin
        MarioGO.x:=MarioGO.x+4;
      end;
      if MarioGO.isColliding(OtherMarioGO) then begin
        MarioGO.x:=oldX;
        MarioGO.y:=oldY;
      end;
    End effect is that player is no longer stuck but warps to left side, and i can clearly see that the pixel collision, if that is the intention, is not accurate. Character moves well inside the other until collision triggers. Also debugger says that MarioGO is nil for some reason. Clearly it is not nil because this code doesn't stop the procedure
    Code:
    if MarioGO=nil then exit;

  6. #6
    It may be bug in debugger - it may think it is nil, but since MarioGO is instantiated in another method (constructor)...

    Hm... but I don't know why it might make it few pixels inside, unless it is related to my recent fix for crash bug (see alletest.lpr)... I'm kinda confused.

  7. #7
    Quote Originally Posted by User137 View Post
    Also debugger says that MarioGO is nil for some reason. Clearly it is not nil because this code doesn't stop the procedure
    For some reason the Lazarus has trouble debuging SuperHeliLand. I don't know why since I don't have much expirience with Lazarus.
    Yesterday when I played a bit with project options I managed to athleast get insifght into Mario.X variable. But don't ask me how as I have no idea. Maybe this might help those of you who has more expirience with Lauzarus.

  8. #8
    Yeah, it might be that it has problems with projects that refer to C code, like Allegro? Or project that contains allegro.pas. Anyone tried to test that?

  9. #9
    Co-Founder / PGD Elder WILL's Avatar
    Join Date
    Apr 2003
    Location
    Canada
    Posts
    6,107
    Blog Entries
    25
    Try setting a debugger breakpoint before where it crashes on you when your game gets to that point it'll stop and allow you to use the Evaluate & Modify tool. Go to Run -> Evaluate / Modify... and the tool will come up. In the Expression textbox you will want to put the name of your declared object in here.

    It should either tell you it's null for sure or give you a list of all it's contents. If it is null then you may be referencing it improperly or freeing unknowingly.

    What version of Lazarus are you using and on what OS? (I'm guessing Windows most likely?)
    Jason McMillen
    Pascal Game Development
    Co-Founder





  10. #10
    @Will
    I folowed your advice but I had no much sucsess in debugging Drkhog's code.
    When I use Evalueate tool it usually shows that object is "nil" which is verry strange as the object gets destroyed only on one place and that code isn't called.
    Other times the Evaluate tool shows that memory at adress "x" cant be acsessed.
    But based on the fact that the character is moving without the problem even when Evaluate tool shows that MarioGO is either "nil" or that its memory can't be read it clearly shows that something is wrong with debugging.

    I'm using Lazarus 1-0.10 with FPC 2.6.2.


    BTW: Does Lazarus have auto-evaluate functionality like Delphi has?

Page 1 of 2 12 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •