睡眠仅在调试模式下工作,而不是在发布模式下工作(Embarcadero C++ Builder)

Sleep only working in debug mode, and not release mode (Embarcadero C++ Builder)

我正在使用 Embarcadero C++ Builder(工程师而非程序员)

我发现睡眠功能只在调试模式下对我有效,在发布模式下无效。 我在 Whosebug 中看到引用不使用睡眠,而是使用 TTimer。

我只是希望我的应用程序根据 Sleep(500) 在绘制对象之间暂停几秒钟;在下面的代码中,这样我就可以看到正在绘制的每个对象并可以检查它们是否正确,否则检查速度很快。

DrawSelectedShape(k,Side,AddOrDeduct,Color); 在下面的代码中,是需要暂停的过程

for (int n=0; n<LiquidLoads->TankBasicData->NoLiquidTypes; ++n){
  for (int m=0; m<LiquidLoads->TankBasicData->NumberOfTanks[n]; ++m)
  {
    for (int l=1; l<LongStrengths->TotalNumberOfParts+1; ++l)
     {
       if (LiquidLoads->TankHeaderArray[n][m]->GhsName == LongStrengths->PartHeader[l]->PartName)
       {

         for (int j=0; j<LongStrengths->PartHeader[l]->NoOfComponents; ++j)
         {
            int k = LongStrengths->PartData[l][j]->ShapeNumber;
            int Side = LongStrengths->PartData[l][j]->Side;
            float AddOrDeduct = LongStrengths->PartData[l][j]->Effectiveness;
            AnsiString Color = LiquidLoads->TankBasicData->LiquidTypeColor[n];
            DrawSelectedShape(k,Side,AddOrDeduct,Color);

            Canvas->TextOut(1200, 300+(n*25),LiquidLoads->TankBasicData->LiquidType[n]);
            Sleep(300);
         }
       break;
       }
   }
}  }

上面的代码在调试模式下运行良好,但在发布模式下,通过将前几个形状绘制到 canvas,它运行良好,然后你会得到一个旋转的鼠标光标,然后是一个空白 canvas.

所以我正在寻找 Sleep 的替代品。

当使用 TTimer 时(没有经验),人们会使用 OnTimer 事件,并将重复运行的代码放在事件中,并带有与 Timer1 Interval 相关的延迟,这与只寻找一些不太一样for循环中间的秒延迟

我的渲染是这样的:

任何建议,不胜感激。

从您发布的视频来看,使用计时器的清晰动画是正确的方法...

根据你的描述,你应该为船上的每个可见物体提供一些值 ix。告诉对象的图层或渲染顺序。

因此,将 render_ix 值添加到您的呈现代码(全局或您要呈现的表单的成员),然后将您的绘图例程重新编码为:

int render_ix=0; // order/layer number for object to render up to

void draw()
 {
 // here clear&render background
 for (int i=0;i<objects;i++)
  if (object[i].ix<=render_ix)
   object[i].draw(); // render i-th object
 // here render HUD
 }

现在只需在您的计时器中设置所需的时间间隔

void OnTimerAnimation()
 {
 render_ix++;
 if (render_ix>=objects) render_ix=0;
 // here force repaint either by calling Paint, Refresh,Update ... or what ever way you are using
 }

您还可以通过滚动条或编程方式更改 render_ix。如您所见,不需要 SleepDelay,因此不会阻止执行。

如果您的渲染不是基于对象的顺序而是通过某些过滤而不是仅仅更改 render_ix 与您正在过滤的变量。这样您就可以将更多变量(体积、质量、位置...)嵌套到嵌套的 if 语句中。

另一个非常有用的方案是使用选择。因此,创建一个对象索引列表以呈现...并且 render/highlight 仅呈现列表中的对象索引。这对于鼠标选择和一次操作更多容器非常有用。

为了避免 for 循环和 if 语句,这是使用 Sleep 方法暂停循环绘制到 canvas 的过程的一部分,我现在首先必须为 Struct 生成渲染序列,然后我可以在 TTimer

中使用单个顺序计数器

如下

//---------------------------------------------------------------------------
void __fastcall TShipGraphic::DrawSelectedTanksBtnClick(TObject *Sender)
{
    GenerateRenderSequence();
    Timer1->Interval = StrToInt(Edit1->Text);
    CloseButton->Enabled = false;
    render_ix=0; //Initialised globally

     Timer1->Enabled = true;

}
//---------------------------------------------------------------------------
void __fastcall TShipGraphic::Timer1Timer(TObject *Sender)
{
 render_ix++;
 Timer1->Interval = StrToInt(Edit1->Text);
 if (render_ix<=TankShapeCounter)
 {
    DrawSelectedComponentShape(render_ix); // render i-th object
    Canvas->Refresh();
 }
 else
 {
   Timer1->Enabled = false;
   CloseButton->Enabled = true;
 }
}
//---------------------------------------------------------------------------
void TShipGraphic::GenerateRenderSequence()
{
   TankShapeCounter = 0;

  for (int n=0; n<LiquidLoads->TankBasicData->NoLiquidTypes; ++n)
  {
    if ((CheckListBox1->Checked[n]) || (CheckListBox1->Checked[LiquidLoads->TankBasicData->NoLiquidTypes]))
    {
      for (int m=0; m<LiquidLoads->TankBasicData->NumberOfTanks[n]; ++m)
      {

        for (int l=1; l<LongStrengths->TotalNumberOfParts+1; ++l)
         {
           if (LiquidLoads->TankHeaderArray[n][m]->GhsName == LongStrengths->PartHeader[l]->PartName)
           {

             for (int j=0; j<LongStrengths->PartHeader[l]->NoOfComponents; ++j)
             {
                ++TankShapeCounter;
                int k = LongStrengths->PartData[l][j]->ShapeNumber;
                int Side = LongStrengths->PartData[l][j]->Side;
                float AddOrDeduct = LongStrengths->PartData[l][j]->Effectiveness;
                AnsiString Color = LiquidLoads->TankBasicData->LiquidTypeColor[n];
                RenderSequence[TankShapeCounter]->ShapeNumber = k;
                RenderSequence[TankShapeCounter]->Side = Side;
                RenderSequence[TankShapeCounter]->AddOrDeduct = AddOrDeduct;
                RenderSequence[TankShapeCounter]->Color = Color;
             }
           break;
           }
         }
      }
    }
  }
}
//---------------------------------------------------------------------------

我想用@Spectre 简洁的动画gif 方法来显示结果,但我的Game Bar 太气质了,无法将屏幕动画捕捉到视频中。 "Win G"激活游戏栏什么都不做。

感谢 Remy 和 Spektre 的宝贵建议。