Code:
unit Main;
interface
uses
Windows,Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, AdDraws, AdClasses, AdTypes, AdPerformanceCounter, AdDevIL,AdSprites,Math;
const
TileW = 32; // tile width
TileH = 32; // tile height
PlayerH = 60; // Player Height
PlayerW = 30; // Player Width
type
TPlatform = class(TImageSprite)
private
protected
procedure DoMove(TimeGap: Double); override;
procedure DoCollision(Sprite:TSprite; var Done:boolean); override;
public
constructor Create(AParent:TSprite);override;
end;
TBlurp = class(TImageSprite)
private
vx,vy : Single; //current velocity in pixels/second
FLeft, FTop, FRight, FBottom: double;
nextv,v : double;
jumping : boolean;
protected
procedure DoMove(TimeGap: Double);override;
procedure DoCollision(Sprite:TSprite; var Done:boolean);override;
public
constructor Create(AParent:Tsprite);override;
property Left: double read FLeft write FLeft;
property Top: double read FTop write FTop;
property Right: double read FRight write FRight;
property Bottom: double read FBottom write FBottom;
end;
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
private
{ Private declarations }
public
{ Public declarations }
AdDraw:TAdDraw;
AdSpriteEngine:TSpriteEngine;
AdImageList:TAdImageList;
AdPerCounter:TAdPerformanceCounter;
AdPixelCollisionTester: TAdSpritePixelCollisionTester;
Blurp:TBlurp;
procedure Idle(Sender:TObject; var Done:boolean);
procedure LoadLevel;
end;
var
Form1: TForm1;
ActTime : double;
// camera positions
camera_x : double;
camera_y : double;
implementation
{$R *.dfm}
procedure TForm1.LoadLevel;
var
level:TStringList;
ax,ay:integer;
begin
level := TStringList.Create;
level.LoadFromFile(ExtractFilePath(Application.ExeName)+'level2.txt');
for ay := 0 to level.Count-1 do
begin
for ax := 1 to length(level[ay]) do
begin
case level[ay][ax] of
'x':
begin
with TPlatform.Create(AdSpriteEngine) do
begin
Image := AdImageList.Find('WALL');
x := ax*TileW;
y := ay*TileH;
z := 0;
CollisionTester := AdPixelCollisionTester;
end;
end;
'X':
begin
with TPlatForm.Create(AdSpriteEngine) do
begin
Image := AdImageList.Find('WALL');
x := ax*TileW;
y := ay*TileH;
z := 0;
CollisionTester := AdPixelCollisionTester;
end;
end;
end;
end;
end;
level.Free;
end;
constructor TPlatform.Create(AParent: TSprite);
begin
inherited;
end;
constructor TBlurp.Create(AParent: TSprite);
begin
inherited;
vx:=128;
vy:=128;
V := 10; // starting velocity, used for calculating gravity effect on our little hero
jumping:=true; // cause our character is not jumping right now
end;
procedure TBlurp.DoMove(TimeGap: Double);
begin
inherited;
Left := X;
Top := Y;
Right := X + Image.Width;
Bottom := Y + Image.Height;
// setting the camera to follow our HERO
if (X > 320) and (X < (40*TileW)-320-TileW) then
begin
// - 64 , because when loading the level my entire background is starting from 64 instead of 0
// looks better if there is no black line at the edge of the level...
camera_x:=(X*-1)+320-TileW;
end;
if (Y > 240) and (Y < (29*TileH)-240) then
begin
// 29 tiles down * 64 tile.height -240 half of the screen, only moving when at center of the screen
// well not really the center...but close anyway :)
camera_y:=(Y*-1)+240;
end;
// jump
{ if (jumping = true) then
begin
Y:=Y-5; // the kick in the but
end; }
// gravity done here
{ if jumping = true then
begin
if nextv < 15 then nextv:=nextv+(v*TimeGap);
Y:=Y+nextv;
end
else
begin
nextV:=0;
jumping:=true;
end; }
if GetKeyState(VK_LEFT) < 0 then
begin
x := x - vx * TimeGap;
end;
if GetKeyState(VK_RIGHT) < 0 then
begin
x := x + vx * TimeGap;
end;
if GetKeyState(VK_UP) < 0 then
begin
y := y - vy * TimeGap;
end;
if GetKeyState(VK_DOWN) < 0 then
begin
y := y + vy * TimeGap;
end;
Collision;
end;
procedure TPlatform.DoMove(TimeGap : Double);
begin
inherited;
end;
procedure TBlurp.DoCollision(Sprite:TSprite; var Done:boolean);
var
TileLeft, TileRight,
TileTop, TileBottom: double;
begin
if Sprite is TPlatform then
begin
TileLeft := TPlatform(Sprite).X;
TileTop := TPlatform(Sprite).Y;
TileRight := TPlatform(Sprite).X + TPlatform(Sprite).Image.Width;
TileBottom := TPlatform(Sprite).Y + TPlatform(Sprite).Image.Height;
// up
if (GetKeyState(VK_UP) < 0) then
begin
if (Self.Top+1 > TileBottom) and
(Self.Right > TileLeft) and
(Self.Left < TileRight) then
begin
Y := TileBottom;
end;
end;
// down
if (GetKeyState(VK_DOWN) < 0) then
begin
if (Self.Bottom -1 < TileTop ) and
(Self.Right > TileLeft) and
(Self.Left < TileRight) then
begin
Y := TileTop-PlayerH;
end;
end;
// left
if GetKeyState(VK_LEFT) < 0 then
begin
if (Self.Left+1 > TileRight) and
(Self.Top< TileBottom) and
(Self.Bottom>TileTop) then
begin
X := TileRight;
end;
end;
// right
if GetKeyState(VK_RIGHT) < 0 then
begin
if (Self.Right-1 < TileLeft )and
(Self.Top< TileBottom) and
(Self.Bottom>TileTop) then
begin
X := TileLeft -PlayerW;
end;
end;
end;
end;
procedure TPlatform.DoCollision(Sprite:TSprite; var Done:boolean);
begin
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
AdPerCounter := TAdPerformanceCounter.Create;
AdDraw := TAdDraw.Create(self);
AdDraw.DllName := 'AndorraDX93D.dll';
if AdDraw.Initialize then
begin
Application.OnIdle := Idle;
AdImageList := TAdImageList.Create(AdDraw);
AdImageList.LoadFromFile('BackGround.ail');
//create the SpriteEngine
AdSpriteEngine := TSpriteEngine.Create(nil);
AdSpriteEngine.Surface := AdDraw;
//Create the collision tester
AdPixelCollisionTester := TAdSpritePixelCollisionTester.Create(AdDraw);
LoadLevel;
//create TImageSprite
Randomize;
Blurp := TBlurp.Create(AdSpriteEngine);
with Blurp.Create(AdSpriteEngine) do
begin
Image := AdImageList.Find('TallHero2');
X := 144;
Y := 144;
Z := 0;
CollisionTester := AdPixelCollisionTester;
end;
// The Entire Engine is moved left by -64 , this is because of the Level Loader ...
Camera_X:=-TileW;
Camera_Y:=0;
AdSpriteEngine.X:=camera_x;
AdSpriteEngine.Y:=camera_y;
// ************* hater *********************************
end
else
begin
ShowMessage('Error while initializing Andorra 2D. Try to use another display'+
'mode or use another video adapter.');
halt; //<-- Completely shuts down the application
end;
end;
procedure TForm1.Idle(Sender: TObject; var Done: boolean);
begin
if AdDraw.CanDraw then // Only continue, if drawing is possible
begin
AdPerCounter.Calculate;
AdPerCounter.MaximumFrameRate:=60;
AdDraw.ClearSurface(clBlack); // Fill the surface with black color
AdDraw.BeginScene;
// Here you need to perform all drawing operations later
ActTime := ActTime + AdPerCounter.TimeGap;
if ActTime > 10 then
begin
AdSpriteEngine.X:=camera_x;
AdSpriteEngine.Y:=camera_y;
ActTime := ActTime-10;
end;
AdSpriteEngine.Draw;
AdSpriteEngine.Move(AdPerCounter.TimeGap/1000);
AdSpriteEngine.Dead;
// debug
AdDraw.EndScene;
AdDraw.Flip; // Draws you result on the screen. Otherwise, you would not see anything
end;
Done := false; // Important, otherwise the function will not be called in every loop
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
AdSpriteEngine.Free;
AdImageList.Free;
AdPerCounter.Free;
AdDraw.Free;
end;
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key = VK_ESCAPE then Close;
end;
end.
Works like a charm, round trunc was my problem, and now I understand why I need +1 or -1 for x or y. Only needed to draw it down.
Greetings
Robert
Bookmarks