Hello everyone,
This weekend I've managed to get a bit further on my road to making some platform games in the future...
Anyway using Traveler's guide for platform game + some andorra 2d examples... I've managed to create a simple level , load it, and my hero ( the big bad red block ) can move around and hits the wall... only problem is I dunno why, but sometimes he does not exactly hits it but stops a bit earlier...
I'm including my complete source + attached the zipped program so you can see what I mean, I've tried to implement my own method of detecting the edges, by defining the 4 points of the block, not much different from the original guide, but I understand this one atleast ...
this worked :Code:unit Main; interface uses Windows,Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, AdDraws, AdClasses, AdTypes, AdPerformanceCounter, AdDevIL,AdSprites; type //Types that are used to tell the character which key has been pressed TKey = (kyUp, kyDown, kyLeft, kyRight); TKeys = set of TKey; TTileInfo = Record tilenr : integer; end; 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 FKeys:TKeys; X_Direction:double; Y_Direction:double; isfalling:boolean; iswall:boolean; protected procedure DoMove(TimeGap: Double);override; procedure DoCollision(Sprite:TSprite; var Done:boolean);override; public constructor Create(AParent:Tsprite);override; procedure SetKeys(Keys:TKeys); function testForWall(spriteXpos,spriteYpos:single;spriteWidth,spriteHeight:integer):boolean; 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; TileInfo : array [1..39, 0..28 ] of TTileInfo; ActTime : 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 TileInfo[ax,ay].tilenr:=1; with TPlatform.Create(AdSpriteEngine) do begin Image := AdImageList.Find('Kocka'); x := ax*64; y := ay*64; z := 0; end; end; 'X': begin TileInfo[ax,ay].tilenr:=1; with TPlatForm.Create(AdSpriteEngine) do begin Image := AdImageList.Find('Kocka2'); x := ax*64; y := ay*64; z := 0; end; end; '-': TileInfo[ax,ay].tilenr:=2; end; end; end; level.Free; end; procedure TBlurp.SetKeys(Keys: TKeys); begin if Keys = FKeys then exit; FKeys := Keys; if kyRight in Keys then x_direction:=1.5; if kyLeft in Keys then x_direction:=-1.5; if kyUp in Keys then y_direction:=-1.5; if kyDown in Keys then y_direction:=1.5; if Keys = [] then begin x_direction:=0; y_direction:=0; end; end; constructor TPlatform.Create(AParent: TSprite); begin inherited; end; constructor TBlurp.Create(AParent: TSprite); begin inherited; end; procedure TBlurp.DoMove(TimeGap: Double); begin inherited; { X:=X+X_direction; Y:=Y+Y_direction; } { if X <= 0 then X:=0; if X > 640-Image.Width then X:=640-Image.Width; if Y < 0 then Y:=0; if Y > 480-Image.Height then Y:=480-Image.Height; } Collision; end; 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; procedure TPlatform.DoMove(TimeGap : Double); begin inherited; Collision; end; procedure TBlurp.DoCollision(Sprite:TSprite; var Done:boolean); begin if Sprite is TPlatform then begin isFalling:=false; end; end; procedure TPlatform.DoCollision(Sprite:TSprite; var Done:boolean); begin end; procedure TForm1.FormCreate(Sender: TObject); var i: integer; begin AdPerCounter := TAdPerformanceCounter.Create; AdDraw := TAdDraw.Create(self); AdDraw.DllName := 'AndorraDX93D.dll'; with AdDraw.Display do begin { Width := 640; Height := 480; BitDepth := ad16Bit; //The colour depth. The values "ad16Bit" and "ad32Bit" are allowed here. DisplayMode := dmFullscreen; } end; 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('Hero'); X := 128; Y := 128; Z := 0; CollisionTester := AdPixelCollisionTester; SetKeys([]); isfalling:=true; end; // ************* 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); var keys: TKeys; 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 > 25 then begin keys := []; if GetKeyState(VK_LEFT) < 0 then begin if not Blurp.testForWall(Blurp.X-3,Blurp.Y,Blurp.Image.Width,Blurp.Image.Height) then begin Blurp.X:=Blurp.X-3; AdSpriteEngine.X:=AdSpriteEngine.X+3; end; end; if GetKeyState(VK_RIGHT) < 0 then begin if not Blurp.testForWall(Blurp.X+3,Blurp.Y,Blurp.Image.Width,Blurp.Image.Height) then begin Blurp.X:=Blurp.X+3; AdSpriteEngine.X:=AdSpriteEngine.X-3; end; end; if GetKeyState(VK_UP) < 0 then begin if not Blurp.testForWall(Blurp.X,Blurp.Y-3,Blurp.Image.Width,Blurp.Image.Height) then begin Blurp.Y:=Blurp.Y-3; AdSpriteEngine.Y:=AdSpriteEngine.Y+3; end; end; if GetKeyState(VK_DOWN) < 0 then begin if not Blurp.testForWall(Blurp.X,Blurp.Y+3,Blurp.Image.Width,Blurp.Image.Height) then begin Blurp.Y:=Blurp.Y+3; AdSpriteEngine.Y:=AdSpriteEngine.Y-3; end; end; Blurp.SetKeys(Keys); ActTime := 0; end; { if Blurp.isfalling = true then begin Blurp.Y:=Blurp.Y+1; end; Blurp.isfalling:=true;} AdSpriteEngine.Draw; AdSpriteEngine.Move(25/1000); AdSpriteEngine.Dead; // debug AdDraw.Canvas.Textout(0,40,'Ido: '+inttostr(TileInfo[1,1].tilenr)); // AdDraw.Canvas.TextOut(0,80,'Player Collision:' +Blurp.testForWall(Blurp.X,Blurp.Y,Blurp.Image.Width,Blurp.Image.Height)); 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.
only thing was I was not able to figure it out how and whyCode:function TOurSprite.testForWall(spriteXpos,spriteYpos:single; spriteWidth,spriteHeight:integer):boolean; begin testForWall := false; //test topside if not (TileInfo[((round(spriteXpos)+spriteWidth) div 32), (round(spriteYpos) div 32)].tilenr in [6,7,100]) //test bottomside or not ((TileInfo[((round(spriteXpos)+spriteWidth) div 32), ((round(spriteYpos)+spriteHeight) div 32)].tilenr in [6,7,100]) and (TileInfo[(round(spriteXpos) div 32), ((round(spriteYpos)+spriteHeight) div 32)].tilenr in [6,7,100])) then testForWall := true;I was able to figure out that
it was checking , these coordinates in this order
X------1
| -------|
3------2 Why was it not checking 4 x,y have no idea... it worked... but I did not want to use
something I don't understand...
Anyway back to my way I defined all 4 points
X----X
| ------|
X----X
only problem is sometimes my Hero Character stops a bit earlier then it should...
I must stop him a bit sooner otherwise... I get wallhit true...and cannot move in any direction...
Please help me out a bit here ( I try to do as much as possible by myself...but I'm really stuck here...)
Egyszeru 5 figura maga.zip
Greetings
Robert


I was able to figure out that
Reply With Quote
