Napisałem programik w DelphiX, który przesuwa literki. I dlaczego to działa z różną prędkością na różnych komputerach. Jednak na kompie z 400Mhz i Direct 9 działa tak samo jak na 2400Mhz i Direct 9, ale na kompie 433Mhz i Direct 6 działa wolniej. Jak zrobić aby było tak samo na kazdym kompie?
musisz zrobić, aby program skakał. Tzn, wybierz sobie odpowiedni FPS, następnie pobieraj go spod programu (zakladam, że te literki wyświetla jakaś pętla) i jeżeli jest większy o X razy od twojego 'standardu' to o tyle samo razy wolniej powinna wykonywać się pętla.
Przykład na ruchu samochodzika:
Jest procedura dla ruchu w prawo (np:)
RysujSamochodzik(x+2,y);
Zmień ją na [MojFPSStandardowy - const, func PobierzFPS():int]
przyspieszenie:=MojFPSStandardowy / PobierzFPS;
RysujSamochodzik(x+(2*przyspieszenie),y);
Tyle. Jak pobrać FPS oraz o w podanym 'algorytmie' poszukaj na stronach polskich o DelphiX... Stukam z kawiarenki i nie pamiętam adresu. W przypadku w/podanym będzie się wydawało, że samochodzik jedzie zawsze w tym samym tępie, aczkolwiek na słabszych komputerach będzie 'skakał' (widocznie).
Nie za bardzo to działa albo coś źle zrobiłem. Dlatego opiszę to dokładie, może wtedy....
Na formie mam:
DXDraw1, DXImageList1, DXTimer1, DXSpriteEngine1, DXImageList2
W OnCreate Formy jest kodzik tworzący obrazki z literkami:
sW := TImageSprite.Create(DXSpriteEngine1.Engine);
sW.Image := DXImageList1.Items.Find('W');
sW.Width := sW.Image.Width;
sW.Height := sW.Image.Height;
sW.X := 33;
sW.Y := -60;
sW to zmienna globalna TImageSprite - literka W. Potem jest identycznie z innymi literkami.
Są też zmienne globalne stepY i stepX - obie po 10 w OnCreate;
Zrobiłem też (tylko mi tu bez wyzwisk) 24 zmienne boolean, które są potrzebne do przesówania odpowiedich liter - zrobiłęm te zmienne bo nie lubie goto.
potem w DXTimer1OnTimer:
var
sWW, sHH: integer;
speed: Extended;
begin
sww := DXDraw1.SurfaceWidth;
sHh := DXDraw1.SurfaceHeight;
if VW then // i jeśli zmienna ma true to przesuń tą a nie inna literkę
begin
sW.Y := sW.Y + stepY; // tutaj jeszcze bez frameRate bo na początku jest 0 w FrameRate DXTimer.
if (sW.Y > 40) then
begin
stepY := -stepY;
PO := true; // oznacza, że już więcej się nie cofnie
end
else
if (sW.Y <=8) and (PO) then
begin
PO := false;
vW := false;
vI := true;
vT := false;
{...}
speed := 85 / DXTimer1.FrameRate;
stepY := 12; // niewielkie zwiększenie prędkości;
end;
DXImageList2.Items.Find('TTLO').StretchDraw(DXDraw1.Surface, Rect(0,0,sww,shh), 0); // ustawienie tła;
DXSpriteEngine1.Draw;
DXDraw1.Surface.Canvas.Release;
DXDraw1.Flip;
end;
i teraz druga literka już z FrameRate:
if Vi then
begin
si.Y := si.Y + stepY * speed;
if (si.Y > 40) then
begin
stepY := -stepY;
PO := true; // oznacza, że już więcej się nie cofnie
end
else
if (si.Y <=8) and (PO) then
begin
PO := false;
vW := false;
vI := false;
vT := true;
{...}
speed := 85 / DXTimer1.FrameRate;
stepY := 13;
end;
DXImageList2.Items.Find('TTLO').StretchDraw(DXDraw1.Surface, Rect(0,0,sww,shh), 0); // ustawienie tła;
DXSpriteEngine1.Draw;
DXDraw1.Surface.Canvas.Release;
DXDraw1.Flip;
end;
i tak dalej jeszcze 24 literki;
puźniejsze literki przesuwaja się po osi X w poziomi i korzystają ze stepX, ale one nie mają takiego efektu cofania się, tam jest po prostu:
sA.X := sa.X + stepX * speed;
if (si.Y <=8) then
{...}
i jak są warunki: jesli Y >= 40, czy X<=8 to są one jakbu całkowicie ignorowane bo wszystkie literki z osi X są ponakładane na siebie w jednym punkcie, i tak samo z osią Y. Jesli by tego było mało to nie ma zadnego efektu animacji tylko wszystko się pojawia Od razu poaztym jesli sprawdzałem wartość zmiennej speed do raz (na poczatku) nie wiedomo skąd osiąga ona wartość -984654342543562,645. [???]
Mam nadzieję że dorze napisałem kod bo piszę z pamięci, i oczywiście że mi pomożecie.
Z góry dzięki. [cya]