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

时间:2018-10-15 16:01:50

标签: c++ c++builder rad-studio

我正在使用Embarcadero C ++ Builder(不是工程师,而是工程师)

我发现“睡眠”功能仅在调试模式下对我有效,而在释放模式下不起作用。 我看到StackOverFlow中的引用不是使用Sleep,而是使用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;
       }
   }
}  }

上面的代码在调试模式下可以很好地工作,但是在释放模式下,通过将前几个形状绘制到画布上,它可以正常工作,然后您可以旋转鼠标光标一会儿,然后再空白画布。

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

使用TTimer(无经验)时,将使用OnTimer事件,并将在该事件中重复运行的代码置于与Timer1时间间隔相关的延迟上,这与仅查找几秒钟的延迟并不完全相同在for循环中间

这是我的渲染效果:

animation

任何建议,非常感谢。

2 个答案:

答案 0 :(得分:0)

从您使用计时器发布了清晰动画的视频中看,方法...

根据您的描述,您船上的每个可见物体都应具有一个值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语句中。

另一个但非常有用的方案是使用选择。因此,创建对象索引列表以进行渲染...,并仅渲染/突出显示列表中存在的那些对象。这对于鼠标选择和一次使用更多容器的操作非常有用。

答案 1 :(得分:0)

为了避免for循环和if语句,这是使用Sleep方法暂停循环绘制到画布上的过程的一部分,现在我首先必须生成一个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动画方法来显示结果,但是我的游戏栏过于气质,无法将屏幕动画捕获到视频中。 “ Win G”激活游戏栏无济于事。

感谢雷米(Remy)和斯派克(Spektre)的宝贵建议。