PDA

View Full Version : Andorra 2d , adding very very basic gravity (sorta)



robert83
11-08-2011, 08:54 PM
Hello,

I'm trying to add some very basic gravity to my figure in andorra 2d ( this is a very early stage... trying to make it so that I understand everything... ).

Currently I'm doing it like this : (only falling down ...nothing else, constant speed for now, nothing fancy)

It kinda works wich makes me happy, but not the way I wanted it to... my character falls down the moment he is not on a Platform, but the fact that I can move while falling, if I go back and collide with the Platform I'm stuck... (but now that I think about it , this problem might go away if I finish up the part where I can't enter a platform from any angle..., hm I think it wont be a problem if I prevent my character from Entering inside the platform...currently it's not implemented...)




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;
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;
TSnow = class(TImageSprite)
private
protected
procedure DoMove(TimeGap: Double);override;
public
Speed : double;
constructor Create(AParent:TSprite);override;
end;
TBlurp = class(TImageSprite)
private
FKeys:TKeys;
X_Direction:double;
isfalling: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);
end;
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
private
{ Private declarations }
procedure AddHo;
public
{ Public declarations }
AdDraw:TAdDraw;
AdSpriteEngine:TSpriteEngine;
AdImageList:TAdImageList;
AdPerCounter:TAdPerformanceCounter;
AdPixelCollisionTester: TAdSpritePixelCollisionTester;
Blurp:TBlurp;
procedure Idle(Sender:TObject; var Done:boolean);
end;
var
Form1: TForm1;
Ido,Ido2 : integer;
ActTime : double;
implementation
{$R *.dfm}
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:=Y-2;
if kyDown in Keys then Y:=Y+2;}
if Keys = [] then x_direction:=0;
end;
procedure TForm1.AddHo;
begin
with TSnow.Create(AdSpriteEngine) do
begin
case random(3) of
0:
begin
Image := AdImageList.Find('Ho');
Speed := 1.1;
end;
1:
begin
Image := AdImageList.Find('Ho2');
Speed := 0.5;
end;
2:
begin
Image := AdImageList.Find('Ho3');
Speed := 2.1;
end;

end;
X := random(640);
Z := 1;
end;
end;

constructor TPlatform.Create(AParent: TSprite);
begin
inherited;
end;
constructor TBlurp.Create(AParent: TSprite);
begin
inherited;
end;
constructor TSnow.Create(AParent: TSprite);
begin
inherited;
end;

procedure TSnow.DoMove(TimeGap: Double);
begin
inherited;
Y:= Y + (0.1+Speed);
case random(2) of
{ 0: X:=X+0.2; }
1: X:=X-0.2;
end;
if X > 640-Image.Width then X:=0;
if Y > 480 then
begin
Randomize;
Y:=0;
X:=random(640);
end;
end;
procedure TBlurp.DoMove(TimeGap: Double);
begin
inherited;
X:=X+X_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;
procedure TPlatform.DoMove(TimeGap : Double);
begin
inherited;
Collision;
end;

procedure TBlurp.DoCollision(Sprite:TSprite; var Done:boolean);
begin
if Sprite is TSnow then
begin
TSnow(Sprite).Dead;
end;
if Sprite is TPlatform then
begin
isFalling:=false;
end;
end;
procedure TPlatform.DoCollision(Sprite:TSprite; var Done:boolean);
begin
if Sprite is TSnow then
begin
TSnow(Sprite).Dead;
end;
end;


procedure TForm1.FormCreate(Sender: TObject);
var i: integer;
begin
ido:=0;
ido2:=1;
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);
//create TImageSprite
Randomize;
for i := 0 to 30 do
begin
with TPlatForm.Create(AdSpriteEngine) do
begin
Image := AdImageList.Find('Kocka');
X:= X+(i*16);
case i of
0..9: Y:=300;
10..19: Y:=350;
20..30: Y:=400;
end;
end;
end;
Blurp := TBlurp.Create(AdSpriteEngine);
with Blurp.Create(AdSpriteEngine) do
begin
Image := AdImageList.Find('Blurp');
X := 0;
Y := 250-Image.Height;
Z := 1;
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
ido:=ido+ido2;
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 keys := keys + [kyLeft];
if GetKeyState(VK_RIGHT) < 0 then keys := keys + [kyRight];
{ if GetKeyState(VK_UP) < 0 then keys := keys + [kyUp];
if GetKeyState(VK_DOWN) < 0 then keys := keys + [kyDown]; }
Blurp.SetKeys(Keys);
ActTime := 0;
end;
if Blurp.isfalling = true then
begin
Blurp.Y:=Blurp.Y+1;
end;
Blurp.isfalling:=true;

if ido >= 50 then
begin
if AdSpriteEngine.CountOfClass(TSnow) < 680 then
begin
AddHo;
ido:=0;
ido2:=ido2+1;
end;
if ido >= 50 then ido:=50;
end;
AdSpriteEngine.Draw;
AdSpriteEngine.Move(25/1000);
AdSpriteEngine.Dead;
// debug
AdDraw.Canvas.Textout(0,20,'Ho: '+inttostr( AdSpriteEngine.CountOfClass(TSnow)));
AdDraw.Canvas.Textout(0,40,'Ido: '+inttostr(Ido));

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.



I've attached my code for review, I'm still in the process of learning so keep that in mind, I'm open to suggestions, cause there are probably a 100 things I'm doing wrong here :) , anyway I've started it real simple this time... first I've created a real simple wheel sprite with Sprite Class, created 10 wheels and made em move at different speeds... with different animations in each direction... then I've started to experiment with falling down objects...and came up with this snow effect (which I think is kinda great :) ) , then managed to get my first chacter moving (that part I'm not sure if I'm doing it the best way...) .... I'm trying to reverse the andorra 2d tutorials (demos) to very small steps (parts) so that I can better understand it...

Anyway I've attached the executable... so you can see what I mean, I think if I prevent my character from moving inside the platform this very basic gravity will be fine for now. (I know there are far better gravitys like in the Traveller's unDelphix Platform Game tutorial... but for now I find it a bit overwhelming... to much info at once :) ).

Greetings
Robert

539

Traveler
11-08-2011, 09:15 PM
My tutorial was based on this article: http://www.gamedev.net/page/resources/_/reference/programming/math-and-physics/physics-tutorials/gravity-faq-r694
It's quite easy to follow.
NB: The part after 'The REAL Equations' is not mandatory to get it to work and can be skipped it you want.

User137
12-08-2011, 03:50 PM
Maybe simply like this?


procedure TBlurp.DoMove(TimeGap: Double);
begin
inherited;
if not isfalling then begin
X:=X+X_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;
end;
Collision;
end;


but now that I think about it , this problem might go away if I finish up the part where I can't enter a platform from any angle
That may be true.