Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.01.2012, 08:52   #1
myg
 
Регистрация: 22.12.2011
Сообщений: 7
По умолчанию Не ждет завершения процедуры.

Экспериментирую на кошках, т.е. на тетрисе.
Написал программу в Delphi 2010. Но одна проблема.
Опишу одно из ея проявлений:

// выше проверяетсо, можно ли опустить фигуру, если нет, то

CheckFill;
// проверка заполненности рядов и удаление заполненных

FigDown:=False;
// опустить фигуру не получилось

Fig:= FigNext;
// присваиваем фигуре следующую из очереди

Bc:=(MaxColumns div 2)-2; Bl:=0;
// смещение фигуры относительно стакана

AssignCoordinate(Fig, Bc, Bl);
// назначаем координаты фигуре

FigNext:=CreateFig;
// создаем новую фигуру в очереди

AssignCoordinate(FigNext, 0, 0);
// назначаем коорд. фигуре из очереди на дополнительном поле
// для показа следующей фигуры

ClearFieldNext;
// очищаем поле

DrawFigNext(Helper);
// и рисуем след. фигуру (если вкл. подсказка)

Все вроде просто, прозрачно и работает. Но!
Если в процедуре CheckFill при удалении заполненных рядов добавить красивости, т.е. замедленного удаления с эффектами, порядка нескольких ms, то, не дожидаясь ея завершения, начинают исполнятся следующие строки кода. И получается каша. В других местах программы, при перехвате клавиатуры, я это обошел. А тут не знаю как. И убирать красивости не хочу. Почему программа не работает линейно, а разбивается на потоки? Я ей таких указаний не давал.
myg вне форума Ответить с цитированием
Старый 17.01.2012, 08:57   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
Почему программа не работает линейно, а разбивается на потоки?
как минимум нужно показать CheckFill.
возможно сами команды таковы.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 17.01.2012, 09:10   #3
myg
 
Регистрация: 22.12.2011
Сообщений: 7
По умолчанию

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
как минимум нужно показать CheckFill.
возможно сами команды таковы.
Код:
procedure CheckFill;

var i, j, Counter, Deleted, DeleteLine: integer;

begin
 Deleted:=0;                               // удаленных линий
 for j:= 1 to MaxLines - 1 do
  begin
  Counter:=0;                          // счетчик заполненных позиций в строке
  for i := 0 to MaxColumns - 1 do
    begin
     Counter:= Counter + Shape[i, j].Tag;
    end;
   if Counter = MaxColumns then
    begin
     DeleteLine:=j;                         // удаляемая строка
     DelLine(DeleteLine);
     inc(Deleted, (Deleted+1));        // для целей ведения счета
    end;
  end;
end;

procedure DelLine(var DelL: integer);
var k, l, m: integer;
begin
 m:=DelL;
 PlaySound('Laser.wav', 0, SND_ASYNC);
 for k := 0 to MaxColumns - 1 do           // удаление строки с эффектами
 begin
  Shape[k, DelL].Brush.Color:=clFuchsia;
  Delay(2);
  Shape[k, DelL].Visible:=False;
  Shape[k, DelL].Tag:=0;
  Shape[k, DelL].Brush.Color:=clYellow;
 end;

 for l := m downto 1 do        // опускание вышележащих строк
  begin
   for k := 0 to MaxColumns - 1 do
    begin
     Shape[k, l].Tag:=Shape[k, l-1].Tag;
     Shape[k, l].Visible:=Shape[k, l-1].Visible;
    end;
  end;
end;
где,
Shape - массив TShape создающий игровое поле
Tag = 1 означает, что позиция занята ранее упавшей фигурой



___________
Код нужно оформлять по правилам:
тегом [CODE]..[/СODE] (это кнопочка с решёточкой #)
Не забывайте об этом!
Модератор.

Последний раз редактировалось Serge_Bliznykov; 17.01.2012 в 10:24.
myg вне форума Ответить с цитированием
Старый 17.01.2012, 09:16   #4
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

форма просто не пересовывается в это время.(при изменении видимости, цвета(скорее всего тоже), лишь посылается сообщение о пересовке, которое будет обработано как выйдете из события, или по Application.ProcessMessage)
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 17.01.2012, 09:50   #5
myg
 
Регистрация: 22.12.2011
Сообщений: 7
По умолчанию

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
форма просто не пересовывается в это время.(при изменении видимости, цвета(скорее всего тоже), лишь посылается сообщение о пересовке, которое будет обработано как выйдете из события, или по Application.ProcessMessage)
Да прыгал я вокруг этого Application.ProcessMessages
Проблема не в отрисовке, а в том, что действительно выполняются следующие процедуры до завершения длительной.
myg вне форума Ответить с цитированием
Старый 18.01.2012, 07:15   #6
3D Hunter
Сумрачная тень
Форумчанин
 
Аватар для 3D Hunter
 
Регистрация: 05.03.2009
Сообщений: 689
По умолчанию

Язык линейный, и если вы пишите код в одном потоке (главный поток программы), то все должно выполнятся линейно. Что за метод Delay(2), не подскажете?
"ковыряю изнутри" (с)
3D Hunter вне форума Ответить с цитированием
Старый 18.01.2012, 11:49   #7
myg
 
Регистрация: 22.12.2011
Сообщений: 7
По умолчанию

Цитата:
Сообщение от 3D Hunter Посмотреть сообщение
Язык линейный, и если вы пишите код в одном потоке (главный поток программы), то все должно выполнятся линейно. Что за метод Delay(2), не подскажете?
В том-то и проблема! Не могу понять как при еще не отработавшей процедуре запускается следующая.

Цитата:
procedure Delay(MSecs: Longint);
var
FirstTickCount, Now: Longint;
begin
FirstTickCount := GetTickCount;
repeat
Application.ProcessMessages;
{ allowing access to other controls, etc. }
Now := GetTickCount;
until (Now - FirstTickCount >= MSecs) or (Now < FirstTickCount);
end;
из RxLibrary
myg вне форума Ответить с цитированием
Старый 18.01.2012, 18:05   #8
3D Hunter
Сумрачная тень
Форумчанин
 
Аватар для 3D Hunter
 
Регистрация: 05.03.2009
Сообщений: 689
По умолчанию

ИМХО, сомнительный метод. Вместо Delay() пишите уж так:
Код:
Application.ProcessMessages;
Sleep(55);
"ковыряю изнутри" (с)
3D Hunter вне форума Ответить с цитированием
Старый 18.01.2012, 19:57   #9
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
Проблема не в отрисовке, а в том, что действительно выполняются следующие процедуры до завершения длительной.
именно в этом и проблема.
так как при необходимости пересовки вы лишь сообщение получаете, не более.
а его нужно обработать.(можно попробовать кстати ручной репаинт вызывать, хотя шейпы поидее должны сами это делать).
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Коллайдер. Что нас ждет? SunKnight Свободное общение 28 25.08.2017 09:32
access violation после завершения работы процедуры Dreanks Помощь студентам 4 15.10.2011 14:02
ScreenMaker ждет вашей оценки Marsik Софт 12 23.02.2010 18:39
Как дождаться завершения процедуры? Hintman Win Api 6 14.10.2009 14:46
Прога ждет от меня ответа... какого? Василий Win Api 2 16.01.2009 13:28