Консультация № 62033
10.11.2006, 07:47
0.00 руб.
0 4 3
Здраствуйте. Я выполняю какое либо действие в таймере с интревалом 300, например двигаю точку (см в приложении). Чтобы она быстрее двигалась нужно по логике уменьшить интервал. Уменьшаем: 200,100,10 разницы никакой. Как заставить точку двигаться быстрей? Из-за чего так происходит?

Приложение:
x:=1;xx:=x+1;y:=1;...begin canvas[x,y]:=rgb(0,0,0); canvas[xx,y]:=rgb(0,0,255); x:=xx; inc(xx);end;

Обсуждение

Неизвестный
10.11.2006, 08:08
общий
это ответ
Здравствуйте, Yujin!
так происходит из за дискретности интервалов таймера. Фактически, два близких значения интервала не дадут вообще ни какой разницы. Если не ошибаюсь, дискретность равна 0,055 секунды.

Для обхождения этого используйте бесконечный цикл в котором будет стоять
sleep(10); задерка на 0,01 секунды.
application.procesmessage; обработка очереди сообщений
if application.terminated then exit; выход из цикла при закрытии приложения
Неизвестный
10.11.2006, 08:15
общий
это ответ
Здравствуйте, Yujin!

я пробовал Timer.Interval=1, также Sleep(1) толку не какого, но вот, что надумал
если при интервале таймера равном 1 увеличить шаг прохождения точки на 3, то она в 3 раза быстрее полетит !!! (см. пример)


Приложение:
procedure TForm1.Timer1Timer(Sender: TObject);var i:integer;begin canvas.Pixels[xx,y]:=ClRed; canvas.Pixels[x,y]:=clBtnFace; x:=x+3; xx:=xx+3;end;procedure TForm1.Button1Click(Sender: TObject);beginx:=1;xx:=x+3;y:=1;timer1.Enabled:=true;end;
Неизвестный
10.11.2006, 13:45
общий
это ответ
Здравствуйте, Yujin!
Я бы на вашем месте восползовался мултимедийном таймером и рисование делал в отдельном потоке в цыкле. Модуль MMSystem нужен для API функций работы с мултимедийном таймером


Приложение:
unit unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls,MMSystem;TTimerThread = class(TThread) private FCanvas:TCanvas; FTime:integer; tmEvent:THandle; StopEvent:THandle; IDTimer:UINT; Fx:integer; Fxx:integer; Fy:integer; public constructor Create(aTime:integer; //интервал времени aCanvas:TCanvas) //канвас на котором рисуют procedure Execute;override; destructor Destroy;override; end;implementationconstructor TTimerThread.Create(aTime:integer;aCanvas:TCanvas);begin inherited Create(TRUE); FreeOnTerminate:=FALSE; FCanvas:=aCanvas; FTime := aTime // Cсоздаем событие которое таймера tmEvent := CreateEvent(nil,FALSE,FALSE,Nil); Priority := tpHigher; Resume; // Создаем мултимедийный таймер IDTimer := timeSetEvent(aTime,0,Pointer(tmEvent),0, TIME_PERIODIC or TIME_CALLBACK_EVENT_SET); // Запускаем мултимедийный таймер timeBeginPeriod(aTime);end;procedure TTimerThread.Execute;var i:integer; DCmem:HDC; hBmp:HBITMAP; aEvents:array [0..1] of THandle; Event:DWORD;begin aEvents[0]:=tmEvent; while(true) begin Event:=WaitForMultipleObjects(1,@aEvents,FALSE,INFINITE)-WAIT_OBJECT_0; //Блокируем рисование в основном потоке программы fCanvas.Lock; try canvas[x,y]:=rgb(0,0,0); canvas[xx,y]:=rgb(0,0,255); x:=xx; inc(xx); finally fCanvas.Unlock; end; end;end;destructor TTimerThread.Destroy;begin// Остановка таймера timeEndPeriod(FTime);//Удаление таймера timeKillEvent(IDTimer);//Уничтожение события CloseHandle(tmEvent); inherited;end;
Неизвестный
10.11.2006, 15:00
общий
Совет с мультимедийным таймером достаточно полезный, но на самом деле вы что-то напутали с обычным. Но по вашему маленькому приложению нельзя понять, где ошибка.Я много раз делал подобные вещи и у меня все работало нужным образом. Правда, чаще я пользуюсь Sleep(), вместо Timer.OnTimer - все равно больше ничего приложению не надо делать в процессе анимации или чего-дь подобного.
Форма ответа