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
Bookmarks