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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 09.01.2010, 15:11   #1
-BlindGuardian-
Пользователь
 
Аватар для -BlindGuardian-
 
Регистрация: 09.01.2010
Сообщений: 14
Сообщение Проблемы в работе со временем

Доброго времени суток. Я аматор в программировании, поэтому не удивляйтесь если прогу помощи в глупых вопросах. Итак...
Пишу программу для психологических тестов - скорость реакции, и тому подобное. Есть такой вот тест - 120 раз на экран выводиться один из 9 элементов: Треугольник, круг, квадрат; Желтый, зеленый, красный обьект; название животного, растения, неживого предмета. Изначально он находится на экране 900 мс, перерыв между ними 200 мс. Пользователь должен при выведении определенного обьекта нажимать либо левый ctrl либо правый. Если он нажал правильно - мы уменьшаем время нахождения обьекта на экране на 20 мс, если неправильно, или неуспел - увеличиваем. Код прилагается, ниже расскажу о проблеме.

Код:
procedure Delay(dwMilliseconds: Longint);
 var
   iStart, iStop: DWORD;
 begin
   iStart := GetTickCount;
   repeat
     iStop := GetTickCount;
     Application.ProcessMessages;
   until (iStop - iStart) >= dwMilliseconds;
end;

procedure TForm1.RzBitBtn1Click(Sender: TObject);
begin
t1:=900;
t2:=200;
d1:=gettickcount;
for i1:=1 to 120 do
  begin
  randomize;
  a:=random(9);
  if a=0 then
    begin
    flag:=true;                         //показатель нажатия кнопки
    image1.visible:=true;           // выводим квадратик на экран
    delay(t1);                         //перерыв в 900мс
    image1.visible:=false;          //прячем квадратик
    if flag=true then                 //если кнопка не была нажата, то...
      begin
      t1:=t1+20;
      label2.caption:=inttostr(t1);
      end;
    delay(t2);                         //200 мс на экране ничего нет, а потом снова рандомайз.
    end;
  if a=1 then
    begin
    flag:=true;
    image2.visible:=true;        // Треугольник
    delay(t1);
    image2.visible:=false;
    if flag=true then
      begin
      t1:=t1+20;
      label2.caption:=inttostr(t1);
      end;
    delay(t2);
    end;
  if a=2 then
    begin
    flag:=true;
    image3.visible:=true;        // Круг
    delay(t1);
    image3.visible:=false;
    if flag=true then
      begin
      t1:=t1+20;
      label2.caption:=inttostr(t1);
      end;
    delay(t2);
    end;
//...ля-ля-ля-ля, дальше по аналогии все.
  end;
  d2:=gettickcount-1100; //Погрешность расчета в среднем составляет 1-1.2 секунд за 120 тиков. Проверено
  d:=d2-d1;
  label5.caption:='Тест пройден за'+inttostr(d)+'ms';
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
if (getkeystate(VK_LCONTROL)<0) and (flag=true){если кнопка еще не нажата} and ((image3.visible=true)
or (image4.visible=true) or (label3.visible=true)) {если один из нужных нам обьектов на экране} then
  begin
  flag:=false;
  t1:=t1-20;                         // Левый кнтрл в тему
  label2.caption:=inttostr(t1);
  end;
if (getkeystate(vk_lcontrol)<0) and (image3.visible=false) and (image4.visible=false)
and (label3.visible=false) then
  begin
  flag:=false;
  t1:=t1+20;                          // Левый кнтрл мимо
  label2.caption:=inttostr(t1);
  end;
if (getkeystate(VK_RCONTROL)<0) and (flag=true) and ((image1.visible=true)
or (image5.visible=true) or (label4.Visible=true)) then
  begin
  flag:=false;
  t1:=t1-20;                          //Правый кнтрл в тему
  label2.caption:=inttostr(t1);
  end;
if  (getkeystate(VK_RCONTROL)<0) and (image1.visible=false) and (image5.visible=false)
and (label4.Visible=false) then
  begin
  flag:=false;
  t1:=t1+20;                          //Правый кнтрл мимо
  label2.caption:=inttostr(t1);
  end;
end;


Работат усе. Почти. Теперь о проблеме - как видите, допустим мы довели программу до такого, что длительность нахождения картинки на экране равна 3 секунды. Так вот, вышла она на экран, мы на 0.3 секундах нажали на кнопку, и 2.7 секунды должны еще ждать пока картинка исчезнет. Так быть недолжно. Как сделать так, чтобы по нажатию картинка сразу исчезала. По идее должно быть чтото такое:
есть некая переменная x которая наращивает свое значение со временем - очень маленьким - таймер не подойдет.
Код:
...ля-ля-ля
if a=1 then
    begin
    flag:=true;
    x:=0;
    image2.visible:=true;  // Треугольник
    //делаем чето с переменной х
    if (flag=true) or (x=t1) then
       begin
       image2.visible:=false; 
       t1:=t1+20;
       label2.caption:=inttostr(t1);
       end;
    delay(t2);
    end;
...ля-ля-ля
Помогите бедному ученику - студенту, запарился уже
Хороший, плохой...да какая разница? Главное - у кого ружье!

Последний раз редактировалось -BlindGuardian-; 09.01.2010 в 15:16.
-BlindGuardian- вне форума Ответить с цитированием
Старый 10.01.2010, 10:36   #2
maxionans
Форумчанин
 
Аватар для maxionans
 
Регистрация: 02.01.2010
Сообщений: 254
По умолчанию

Насколько я понял из твоего опасного кода , ты используешь Flag для определения того, была ли нажата кнопка или нет. Если это так, то нужно немного изменить процедуру Delay таким образом:
Код:
procedure Delay(dwMilliseconds: Longint);
 var
   iStart, iStop: DWORD;
 begin
   iStart := GetTickCount;
   repeat
     iStop := GetTickCount;
     Application.ProcessMessages;
   until ( ( iStop - iStart) >= dwMilliseconds ) or not Flag;
end
Тогда она будет прерываться, как только Flag устанвлен в False.
maxionans вне форума Ответить с цитированием
Старый 10.01.2010, 11:23   #3
-BlindGuardian-
Пользователь
 
Аватар для -BlindGuardian-
 
Регистрация: 09.01.2010
Сообщений: 14
По умолчанию

Спасибо, прекрасное решение Премного благодарен.
Хороший, плохой...да какая разница? Главное - у кого ружье!
-BlindGuardian- вне форума Ответить с цитированием
Старый 10.01.2010, 11:25   #4
maxionans
Форумчанин
 
Аватар для maxionans
 
Регистрация: 02.01.2010
Сообщений: 254
По умолчанию

Всегда пожалуйста
maxionans вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Разница между временем asd48 Microsoft Office Excel 1 05.06.2009 23:44
Работа со временем в C++ +As+ Помощь студентам 1 02.09.2008 21:17
Работа со временем. ekzi Общие вопросы C/C++ 1 22.07.2008 15:29
Работа со временем joker Общие вопросы Delphi 4 20.04.2008 15:01
проблема со временем marat07 БД в Delphi 8 27.08.2007 09:54