Hello

I'm manipulating the vx and vy on TForm1.OnIDLE like this :


Code:
    ActTime := ActTime + AdPerCounter.TimeGap;
    if ActTime > 100 then
    begin
          Blurp.vx:=0;
          Blurp.vy:=0;
          if GetKeyState(VK_LEFT) < 0 then
            begin
              Blurp.vx:=-16;
            end;
          if GetKeyState(VK_RIGHT) < 0 then
            begin
              Blurp.vx:=+16;
            end;
          if GetKeyState(VK_UP) < 0 then
            begin
              Blurp.vy:=-16
            end;
          if GetKeyState(VK_DOWN) < 0 then
            begin
              Blurp.vy:=16
            end;

      ActTime := 0;
    end;
The DoMOVE procedure for the Character object...

Code:
procedure TBlurp.DoMove(TimeGap: Double);
var
  cnrs: TCorners;
begin
  inherited;
  cnrs := Form1.GetCorners(self);
  if vy < 0 then
  // moving up
  begin
    if (not cnrs.WallUL) and (not cnrs.WallUR) then
    // not obstructed so move normally
      y := y + vy * TimeGap
    else
    // hit tile so move to edge of tile and stop
    begin
      vy := 0;
      y  := cnrs.Up * cTileH + cTileH + 16;
    end;
  end
  else
  if vy > 0 then
  // moving down
  begin
    if (not cnrs.WallDL) and (not cnrs.WallDR) then
    // not obstructed so move normally
      y := y + vy * TimeGap
    else
    // hit tile so move to edge of tile and stop
    begin
      vy := 0;
      y  := cnrs.Down * cTileH - 16;
    end;
  end;
  cnrs := Form1.GetCorners(self);
 if vx < 0 then
  // moving left
  begin
    if (not cnrs.WallUL) and (not cnrs.WallDL) then
    // not obstructed so move normally
      x := x + vx * TimeGap
    else
    // hit tile so move to edge of tile and stop
    begin
      vx := 0;
      x  := cnrs.Left * cTileW + cTileW + 16;
    end;
  end
  else
  if vx > 0 then
  // moving right
  begin
    if (not cnrs.WallUR) and (not cnrs.WallDR) then
    // not obstructed so move normally
      x := x + vx * TimeGap
    else
    // hit tile so move to edge of tile and stop
    begin
      vx := 0;
      x  := cnrs.Right * cTileW - 16;
    end;
  end;
 

//  Collision;
end;
I've also modified the code for getCorners, for some reason I did not notice HALF heihgt and HALF width, since my character is 32x32, I'm using 16 here. This part now should be ok, thanks to your ASCII art now I understand this part...

Code:
function  TForm1.GetCorners(aSpr: TSprite): TCorners;
// get object corners, includes velocity!
begin
  // calculate tile index for each object corner
  Result.Left      := Math.Floor((aSpr.x -16 + Blurp.vx) / cTileW);
  Result.Right     := Math.Floor((aSpr.x + 16 + Blurp.vx) / cTileW);
  Result.Up        := Math.Floor((aSpr.y -16 + Blurp.vy) / cTileH);
  Result.Down      := Math.Floor((aSpr.y + 16 + Blurp.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;
Problem : stops a bit further then it should LEFT and TOP, and to late RIGHT and BOTTOM, it's like the calulation is OK but Offset.

During testing I've commented out the lines that "should" put my character right beside the wall if there is a hit... because that to is working in an unexpected way.

Attached is my latest source code, meanwhile I'll play with it... hopefully I'm manipulating the vx and vy in a correct way.

test.zip

Greetings
Rob