Results 1 to 10 of 31

Thread: Collission detection on level ( source Travels doc + some other examples)

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    ok, thanks

    cheers,
    Paul

  2. #2
    Hello,

    I've changed the movement from 3 to 4 now, so that it can be divided correctly... since my level is made of 64x64 tiles ...

    I think the problem is here but don't know how to fix....

    Left and Top works always on my level everywhere... it stops right there when it reaches the wall (no pixel left out...) , and I can continue to move in any other direction ...

    Left = works
    Top = works
    Right = stops 4 pixels sooner then it should...always
    Bottom = stops 4 pixels sooner then it should...always

    meanwhile I've also found out that it's important where my character starts... so I've set the starting position to

    X (3x64)-32
    Y (3x64)-32

    I hope I'm not wrong here, but currently my tiles are 64x64, whereas my character is 32x32.

    I've checked the Right and Bottom testwall functions... it works as it should because it is right that if it lets another +4 to x or +4 to y ... it is true... only thing is I can't seem to firugre it out... how the heck does it work correctly for Left and Top...
    Code:
     
     
               if GetKeyState(VK_LEFT) < 0 then
                begin
                  if not Blurp.testForWall(Blurp.X-4,Blurp.Y,Blurp.Image.Width,Blurp.Image.Height) then
                    begin
                      Blurp.X:=Blurp.X-4;
                      AdSpriteEngine.X:=AdSpriteEngine.X+4;
                    end;
                end;
              if GetKeyState(VK_RIGHT) < 0 then
                begin
                  if not Blurp.testForWall(Blurp.X+4,Blurp.Y,Blurp.Image.Width,Blurp.Image.Height) then
                    begin
                      Blurp.X:=Blurp.X+4;
                      AdSpriteEngine.X:=AdSpriteEngine.X-4;
                    end;
                end;
              if GetKeyState(VK_UP) < 0 then
                begin
                  if not Blurp.testForWall(Blurp.X,Blurp.Y-4,Blurp.Image.Width,Blurp.Image.Height) then
                    begin
                      Blurp.Y:=Blurp.Y-4;
                      AdSpriteEngine.Y:=AdSpriteEngine.Y+4;
                    end;
                end;
              if GetKeyState(VK_DOWN) < 0 then
                begin
                  if not Blurp.testForWall(Blurp.X,Blurp.Y+4,Blurp.Image.Width,Blurp.Image.Height) then
                    begin
                      Blurp.Y:=Blurp.Y+4;
                      AdSpriteEngine.Y:=AdSpriteEngine.Y-4;
                    end;
    Code:
    function TBlurp.testForWall(spriteXpos,spriteYpos:single;spriteWidth,spriteHeight:integer):boolean;
    begin
      testForWall := false;
      if not (TileInfo[round(spriteXpos) div 64, round(spriteYpos) div 64].tilenr in [2]) or not
      (TileInfo[(round(spriteXpos)+spriteWidth) div 64, round(spriteYpos) div 64].tilenr in [2]) or not
      (TileInfo[round(spriteXpos)div 64, (round(spriteYpos)+spriteHeight) div 64].tilenr in [2]) or not
      (TileInfo[(round(spriteXpos)+spriteWidth) div 64, (round(spriteYpos)+spriteHeight) div 64].tilenr in [2]) then testForWall :=true;
    end;
    Greetings
    Rob

  3. #3
    I'll throw out this kind of suggestion:
    Code:
              if GetKeyState(VK_LEFT) < 0 then
                begin
                  if not Blurp.testForWall(Blurp.X-4,Blurp.Y) then
                    begin
                      Blurp.X:=Blurp.X-4;
                      AdSpriteEngine.X:=AdSpriteEngine.X+4;
                    end;
                end;
              if GetKeyState(VK_RIGHT) < 0 then
                begin
                  if not Blurp.testForWall(Blurp.X+4+Blurp.Image.Width,Blurp.Y) then
                    begin
                      Blurp.X:=Blurp.X+4;
                      AdSpriteEngine.X:=AdSpriteEngine.X-4;
                    end;
                end;
              if GetKeyState(VK_UP) < 0 then
                begin
                  if not Blurp.testForWall(Blurp.X,Blurp.Y-4) then
                    begin
                      Blurp.Y:=Blurp.Y-4;
                      AdSpriteEngine.Y:=AdSpriteEngine.Y+4;
                    end;
                end;
              if GetKeyState(VK_DOWN) < 0 then
                begin
                  if not Blurp.testForWall(Blurp.X,Blurp.Y+4+Blurp.Image.Height) then
                    begin
                      Blurp.Y:=Blurp.Y+4;
                      AdSpriteEngine.Y:=AdSpriteEngine.Y-4;
                    end;
                end;
    Code:
    function TBlurp.testForWall(pointX,pointY:single):boolean;
    var tilenr: integer;
    begin
      tilenr:=TileInfo[trunc(pointX) div 64, trunc(pointY) div 64].tilenr;
      case tilenr of
        2: result:=true;
        else result:=false;
      end;
    end;
    Last edited by User137; 16-08-2011 at 03:58 PM. Reason: trunc

  4. #4
    Thank you! It's so simple and works wonderfully... I had to modify it a bit :

    Right :

    Code:
              if GetKeyState(VK_RIGHT) < 0 then
                begin
                  if not Blurp.testForWall(Blurp.X+Blurp.Image.Width,Blurp.Y) then
                    begin
                      Blurp.testForWall(Blurp.X+4+Blurp.Image.Width,Blurp.Y);
                      Blurp.X:=Blurp.X+4;
                      AdSpriteEngine.X:=AdSpriteEngine.X-4;
                    end;
                end;
    Down

    Code:
              if GetKeyState(VK_DOWN) < 0 then
                begin
                  if not Blurp.testForWall(Blurp.X,Blurp.Y+Blurp.Image.Height) then
                    begin
                      Blurp.testForWall(Blurp.X,Blurp.Y+4+Blurp.Image.Height);
                      Blurp.Y:=Blurp.Y+4;
                      AdSpriteEngine.Y:=AdSpriteEngine.Y-4;
                    end;
                end;
    removed +4 otherwise it stopped 4 pixels sooner as before to the right and bottom, now it stops when it hits the wall and I can move in any other direction ... GREAT!

    Only thing is there are two bugs, which I'll look into tonight for some reason the following is possible :

    Attachment 557


    If I approach the tile from bellow, and hit it... keep pressing UP...and start moving to the
    left... the moment a small part of my character sprite is "free" it allows me to go up and
    down inside the wall ( I'm still happy tough, this is a better BUG atleast )
    Right side is not affected by this... if I find another wall sprite, and keep pressing top
    and try to go right...I can only go up once my character is completely free.


    Attachment 556

    Same here, if I approach a Wall sprite from left or right, and my Character is a bit Higher ... it can go trough...and move Left and Right... if I do the same with my character being lover then the Wall sprite it is not happening...

    Think this has something to do with only using X,Y maybe... anyway I'll play with it tonight.

    Attached is my modified "demo" thing.

    Thank you again for "spoon feeding" this to me, thank you VERY VERY much!!!
    Attachment 555

    Greetings
    Robert

  5. #5
    Hey Robert, have you looked at that tile game tutorial site I posted earlier? That might really help you get this all working

    Maybe this site can help?
    http://www.tonypa.pri.ee/tbw/tut05.html

    It is using action script (Flash) but I managed to folow the tutorials, especially "Hit the Wall" and "Jumping" to make a simple platform game with collision that worked quite well
    cheers,
    Paul

  6. #6
    Hey Robert, I have whipped up some code (NOT tested) based on that tutorial if you want to study it?

    Code:
    // based on tutorial here:
    // http://www.tonypa.pri.ee/tbw/tut05.html
    uses
      Math;
    
    const
      cTileW = 32; // tile width
      cTileH = 32; // tile height
    
      cMapW = 20;  // map width in tiles
      cMapH = 20;  // map height in tiles
    
    type
      TTile = record
        Id     : Integer; // tile Id - not applicaple in this exercise
        IsWall : Boolean; // True = wall, False = no wall
      end;
    
      TSprite = record
        w,h   : Integer; //half object width and height in pixels
        x,y   : Single;  //current location (centre of object)
        vx,vy : Single;  //current velocity in pixels/second
      end;
    
      TCorners = record
        Up     : Integer; // object's top edge map tile index
        Down   : Integer; // object's bottom edge map tile index
        Left   : Integer; // object's left edge map tile index
        Right  : Integer; // object's right edge map tile index
    
        WallUL : Boolean; // is or isn't a wall at object's top left corner
        WallUR : Boolean; // is or isn't a wall at object's top right corner
        WallDL : Boolean; // is or isn't a wall at object's bottom left corner
        WallDR : Boolean; // is or isn't a wall at object's bottom right corner
      end;
    
    var
      Map: array[0..cMapH - 1,0..cMapW - 1] of TTile;
    
    function  WallAt(x,y: Integer): Boolean;
    // tests for the presence of a wall at a tile location
    begin
      Result := True;
    
      if (x < 0) or (x >= cMapW) then Exit; // returns true if location is out of bounds (safety reasons, object can't pass out of bounds)
      if (y < 0) or (y >= cMapH) then Exit; // returns true if location is out of bounds (safety reasons, object can't pass out of bounds)
    
      Result := Map[x,y].IsWall;
    end;
    
    function  GetCorners(aSpr: TSprite): TCorners;
    // get object corners, includes velocity!
    begin
      // calculate tile index for each object corner
      Result.Left      := Math.Floor((aSpr.x - aSpr.w + aSpr.vx) / cTileW);
      Result.Right     := Math.Floor((aSpr.x + aSpr.w + aSpr.vx) / cTileW);
      Result.Up        := Math.Floor((aSpr.y - aSpr.h + aSpr.vy) / cTileH);
      Result.Down      := Math.Floor((aSpr.y + aSpr.h + aSpr.vy) / cTileH);
    
      // if true then there is a wall there
      Result.WallUL    := WallAt(Result.Left  ,Result.Up);
      Result.WallUR    := WallAt(Result.Right ,Result.Up);
      Result.WallDL    := WallAt(Result.Left  ,Result.Down);
      Result.WallDR    := WallAt(Result.Right ,Result.Down);
    end;
    
    procedure MoveSprite(var aSpr: TSprite; aTimeDelta: Single);
    var
      cnrs: TCorners;
    begin
      cnrs := GetCorners(aSpr);
    
      if aSpr.vy < 0 then
      // moving up
      begin
        if not cnrs.WallUL and not cnrs.WallUR then
        // not obstructed so move normally
          aSpr.y := aSpr.y + aSpr.vy * aTimeDelta
        else
        // hit tile so move to edge of tile and stop
        begin
          aSpr.vy := 0;
          aSpr.y  := cnrs.Up * cTileH + cTileH + aSpr.h;
        end;
      end
      else
      if aSpr.vy > 0 then
      // moving down
      begin
        if not cnrs.WallDL and not cnrs.WallDR then
        // not obstructed so move normally
          aSpr.y := aSpr.y + aSpr.vy * aTimeDelta
        else
        // hit tile so move to edge of tile and stop
        begin
          aSpr.vy := 0;
          aSpr.y  := cnrs.Down * cTileH - aSpr.h;
        end;
      end;
    
      cnrs := GetCorners(aSpr);
    
      if aSpr.vx < 0 then
      // moving left
      begin
        if not cnrs.WallUL and not cnrs.WallDL then
        // not obstructed so move normally
          aSpr.x := aSpr.x + aSpr.vx * aTimeDelta
        else
        // hit tile so move to edge of tile and stop
        begin
          aSpr.vx := 0;
          aSpr.x  := cnrs.Left * cTileW + cTileW + aSpr.w;
        end;
      end
      else
      if aSpr.vx > 0 then
      // moving right
      begin
        if not cnrs.WallUR and not cnrs.WallDR then
        // not obstructed so move normally
          aSpr.x := aSpr.x + aSpr.vx * aTimeDelta
        else
        // hit tile so move to edge of tile and stop
        begin
          aSpr.vx := 0;
          aSpr.x  := cnrs.Right * cTileW - aSpr.w;
        end;
      end;
    end;
    cheers,
    Paul

  7. #7
    Hello,

    thank you very much, I'll be doing some reading on that site you've posted the link to.

    Thank you for the code as well!

    Greetings
    Rob

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
  •