Witam. Piszę gierkę pod Delphi 7 i mam pewien problem. Otóż w trakcie gry, gdy minie odpowiednia ilość czasu, wywala mi EOutOfResources (Nieprawidłowe dojście). Po krótkim debugowaniu, odkryłem iż problem występuje gdy liczba obiektów GDI osiągnie 10000 (!!!), czyli coś się nieprawidłowo czyści. Po dalszych poszukiwaniach odkryłem że jest to problem z procedurą
procedure TSHIPS_Asteroide.AnimationNext;
var BMP: TBitmap;
Recta: TRect;
begin
Inc(ANI_Frame);
if ANI_Frame>16 then ANI_Frame:=1;
Self.GUI_Bitmap.LoadFromResourceName(hInstance,'IBMP_'+IntToStr(50+ANI_Frame));
Self.GUI_Bitmap.TransparentColor:=clBlack;
Self.GUI_Bitmap.Transparent:=True;
case Self.Kind of
0: begin end;
1: Self.ChangeRGB(GUI_Bitmap,50,-50,-50);
2: Self.ChangeRGB(GUI_Bitmap,-80,50,-50);
3: Self.ChangeRGB(GUI_Bitmap,-80,-60,50);
4: Self.ChangeRGB(GUI_Bitmap,-100,-40,30);
5: Self.ChangeRGB(GUI_Bitmap,-100,-50,100);
6: Self.ChangeRGB(GUI_Bitmap,-30,45,60);
7: Self.ChangeRGB(GUI_Bitmap,-30,-80,60);
8: Self.ChangeRGB(GUI_Bitmap,-10,30,20);
end;
if Faza>0 then
begin
BMP:=TBitmap.Create;
Recta.TopLeft.X:=0;
Recta.TopLeft.Y:=0;
Recta.BottomRight.X:=Self.GUI_Bitmap.Width div (Faza*2);
Recta.BottomRight.Y:=Self.GUI_Bitmap.Height div (Faza*2);
BMP.Assign(Self.GUI_Bitmap);
BMP.Width:=Recta.BottomRight.X;
BMP.Height:=Recta.BottomRight.Y;
BMP.Canvas.StretchDraw(Recta,Self.GUI_Bitmap);
Self.GUI_Bitmap.FreeImage;
Self.GUI_Bitmap.Assign(BMP);
BMP.Free;
Self.Area:=Rect(-1*(GUI_Bitmap.Width div 2),-1*(GUI_Bitmap.Height div 2),
(GUI_Bitmap.Width div 2),(GUI_Bitmap.Height div 2));
end;
Self.GUI_Alpha:=0;
end;
Co najciekawsze, gdy wezmę w klamrę
BMP.Canvas.StretchDraw(Recta,Self.GUI_Bitmap);
problem nie występuje i wszystko ładnie się czyści.
I tu mam pytanie: czy to przeoczenie twórców Delphi, czy ja mam jakiś paskudny błąd w tej procedurce ?
Mam Delphi 7 Personal, WinXP Home
EDIT: Winę nie ponosi sam StretchDraw gdyż gdy zastosowałem alternatywną funkcję do skalowania, również był podobny problem. Oznacza to, że za wycieki odpowiada Canvas. Tylko czy nie powinien on być zwalniany z pamięci przez BMP.Free ?
EDIT2: Problem rozwiązany. Wystarczyło umieścić Self.GUI_Bitmap.Dormant; Temat do zamknięcia