我正在尝试为我的学校项目制作一款街机游戏。基本思想是在主线程之外的其他线程中完成所有数学和绘图,并且仅将主线程用于输入例程。绘图是通过保存在外部单元中的过程完成的,并且是通过创建位图,然后在位图上绘制部分环境,最后在主窗体的画布上绘制位图来完成的。当我完成绘图过程时,我尝试从主线程运行它,并设法使 everythink 按预期工作(除了整个应用程序窗口被冻结的事实,但由于主线程一直在不停地工作,比如这是预期的)。然后我尝试将该过程放入其他线程中,它停止工作(尽管调试例程报告该过程被重复执行,但它没有绘制任何东西)。在添加和删除一些调试例程之后,它开始无明显原因地工作,但不可靠。在大约 80% 的情况下,它运行顺利,但在其余情况下,它会在十到三十帧后停止,有时甚至不会在卡住的最后一帧中拖动某些环境部分。
主窗体单元的重要部分如下所示
procedure TForm1.Button1Click(Sender: TObject);
begin
running:=not running;
if running then AppTheard.Create(false);
end;
Procedure AppTheard.execute;
begin
form1.Button1.Caption:='running';
while running do begin view.nextframe; end;
form1.Button1.Caption:='no longer running';
end;
另一个单元中的下一帧过程如下所示
Camera = class
owner:Tform;
focus:GravityAffected;
Walls:PBlankLevel;
Creeps:MonsterList;
FrameRateCap,lastframe:integer;
Background:TBitmap;
plocha:TBitmap;
RelativePosY,RelativePosX:integer;
constructor create(owner:Tform; focus:GravityAffected; Walls:PBlankLevel; Creeps:MonsterList; FrameRateCap:integer; background:TBitmap);
procedure nextframe;
end;
procedure camera.nextframe;
var i,i1,top,topinfield, left,leftinfield: integer ;
procedure Repair
//some unimportant math here
Procedure vykresli(co:vec);
begin
if co is gravityaffected then
plocha.Canvas.Draw(co.PositionX*fieldsize+Gravityaffected(co).PosInFieldX-Left*fieldsize+leftinfield-co.getImgPosX,
co.PositionY*fieldsize+Gravityaffected(co).PosInFieldY-top*fieldsize+topinfield-co.getImgPosY,
co.image)
else
plocha.Canvas.Draw(co.PositionX*fieldsize-Left*fieldsize+leftinfield-co.getImgPosX,
co.PositionY*fieldsize-top*fieldsize+topinfield-co.getImgPosY,
co.image);
end;
begin
// some more unimportant math
vykresli(focus);
For i:= Left+1 to left+2+(plocha.Width div fieldsize) do //vykreslení zdí
For i1:= Top+1 to top+2+(plocha.Height div fieldsize) do
if (i< Walls.LevelSizeX) and (i1< Walls.LevelSizeY) and (i>=0) and (i1>=0) and walls.IsZed(i,i1) then
begin vykresli(walls^.GiveZed(i,i1)^);end;
while abs((gettickcount() mod high(word))-lastframe) < (1000 div FrameRateCap) do sleep(1);
lastframe:=gettickcount mod high (word);
owner.Canvas.Draw(-fieldsize,-fieldsize,plocha);
end;
有人可以告诉我我做错了什么吗?
编辑:我得到了我所要求的帮助,但几年后,我意识到我真正需要的建议是根本不使用线程并尝试类似的事情this https://stackoverflow.com/questions/5399928/execute-action-every-x-seconds-delphi反而。