Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 02.10.2015, 16:23
Аватар для Alloc
Alloc Alloc вне форума
Начинающий
 
Регистрация: 17.09.2014
Сообщения: 104
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию Быстрое определение цвета пикселя по 4-ем позициям

Приветствую!

Очень прошу понимающих людей объяснить мне как реализовать поставленную задачу.

Определить цвет пикселя (одного) не проблема, цвет программа определяет мгновенно, а вот если мониторить сразу 4 - проблема.. программа часто не срабатывает при нахождение цвета...

Я делаю так:

Код:
var
  bmp: TBitmap;
  h1: HWND;
  DC: HDC;
  dx,dy,fx,fy,jx,jy,kx,ky: Integer;

procedure TForm1.FormCreate(Sender: TObject);
begin
  bmp := TBitmap.Create;
  bmp.Width := 1; bmp.Height := 1;
  bmp.PixelFormat := pf32bit;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  ReleaseDC(h1,DC);
end;

procedure TForm1.btn1Click(Sender: TObject);
begin
  h1 := FindWindow(ProgName, nil);
  DC := GetDC(FindWindow(ProgName,''));
  
  //Если программа запущена задаем координаты которые будем проверять. Кстати таймеры все стоят на интервале равным = 1
  if h1 <> 0 then
     begin
       dx:=646;
       dy:=715; 
       fx:=724; 
       fy:=715; 
       jx:=802;
       jy:=715; 
       kx:=843; 
       ky:=715;

       //Включаем таймеры которые будут это делать (каждый будет смотреть свой пиксель)

       tmr1.Enabled:=True;
       tmr2.Enabled:=True;
       tmr3.Enabled:=True;
       tmr4.Enabled:=True;
     end else
     begin
       ShowMessage('Game Not Started');
     end;
end;

//Таких таймеров 4 штуки. Код в них похож, только координаты пикселей разные и сравниваемый цвет.

procedure TForm1.tmr1Timer(Sender: TObject);
var
  c: TColor;
  rr,gg,bb: Integer;
begin
  BitBlt(bmp.Canvas.Handle,0,0,1,1,dc,dx,dy,SRCCOPY);
  //releasedc(h1,dc);
  c := pinteger(bmp.Scanline[0])^;
  c := ((c and $FF) shl 16) or (c and $FF00) or ((c shr 16) and $FF);
  rr:=GetRValue(c);
  gg:=GetGValue(c);
  bb:=GetBValue(c);

  if (rr>80) and (gg>80) and (bb>100) then EmulateKey(h1, Ord('D'));

end;

...
procedure TForm1.tmr2Timer(Sender: TObject);
...
procedure TForm1.tmr3Timer(Sender: TObject);
...
procedure TForm1.tmr4Timer(Sender: TObject);
...

Если один таймер стоит - все работает. Два - более или менее тоже а вот 4 уже то срабатывает то нет...
Как лучше и правильнее сделать? Я буду вам очень благодарен за помощь.

Последний раз редактировалось Alloc, 02.10.2015 в 16:27.
Ответить с цитированием
  #2  
Старый 02.10.2015, 17:16
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Эм... что это за ...фигня? А если тебе понадобится проверять 10 тысяч пикселей, ты сделаешь 10 тысяч таймеров?
Что помешало загнать координаты и цвета в массивы и в одном таймере один раз брать картинку, пробегать в цикле по массиву и проверять сразу все нужные пиксели?
Да и не очень понятно, зачем 1 мс в таймере. Человек видит 24 кадра в секунду, т.е. минимальная различаемая человеком задержка - 40 миллисекунд. В хороших играх FPS обычно делается в районе 60 (16 мс), так обеспечивается большая зрительная гладкость, однако для робота это уже лишено смысла. Ну а быстрее вообще никто не рисует, кроме случаев 3Д-изображения для специальных очков. Какой смысл проверять каждую миллисекунду, если игра перерисовывает не чаще, чем раз в 40?
__________________
jmp $ ; Happy End!
The Cake Is A Lie.

Последний раз редактировалось Bargest, 02.10.2015 в 17:22.
Ответить с цитированием
Этот пользователь сказал Спасибо Bargest за это полезное сообщение:
Alloc (02.10.2015)
  #3  
Старый 02.10.2015, 20:01
Аватар для Alloc
Alloc Alloc вне форума
Начинающий
 
Регистрация: 17.09.2014
Сообщения: 104
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Спасибо за ответ. Я понимаю, для Вас этот код полная жесть, но я только в начале пути познания программирования. Я примерно представляю, что Вы имеете в виду, попытался воспроизвести Ваши советы, но не выходит что то.. Я был бы Вам очень признателен если Вы напишите небольшой пример того, как должен выглядеть массив координат и цветов и как пробегать по нему циклом... Если Вам не трудно, буду очень признателен
Ответить с цитированием
  #4  
Старый 02.10.2015, 21:05
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Ну простейший вариант (если не использовать структуры) - 3 массива
Код:
var x, y: array of integer;
colors: array of Longint;
Заполнять соответственно координатами и цветами. x[0], y[0] - координаты первой точки, colors[0] - цвет первой точки. Ну и потом взять картинку и как-то так.
Код:
for i := 0 to pointsCount-1 do begin
  c := ColorToRGB(bmp.Canvas.Pixels[x[i], y[i]]);
  if abs(GetRValue(c) - GetRValue(colors[i]))< delta and
     abs(GetGValue(c) - GetGValue(colors[i]))< delta and
     abs(GetBValue(c) - GetBValue(colors[i]))< delta then
      EmulateKey(h1, Ord('D'));
end;
Где delta - максимальная мера отличия по каждому цвету.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.

Последний раз редактировалось Bargest, 02.10.2015 в 21:10.
Ответить с цитированием
Этот пользователь сказал Спасибо Bargest за это полезное сообщение:
Alloc (02.10.2015)
  #5  
Старый 02.10.2015, 21:18
Аватар для Alloc
Alloc Alloc вне форума
Начинающий
 
Регистрация: 17.09.2014
Сообщения: 104
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Bargest, Большое спасибо за помощь, Вы мне очень помогли. Буду пробовать. А как быть насчет ReleaseDC? Я слышал его обязательно нужно ставить так как может быть утечка памяти. Если его все так и необходимо прописывать, то куда? Тоже в таймер или достаточно в событие Form.Destroy?

Да, и переменные i, pointsCount и delta - объявить как Integer? В этом случае почему то компилятор указывая на знак "<" говорит о "Incompatible types"

Последний раз редактировалось Alloc, 02.10.2015 в 21:43.
Ответить с цитированием
  #6  
Старый 02.10.2015, 23:08
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Цитата:
Если его все так и необходимо прописывать, то куда?
Есть такая шуточная поговорка: 7 раз NEW, 7 раз DELETE. Сколько раз выделил, столько раз и освобождаешь. Если DC создаешь один раз при нажатии кнопки, а удалять его будешь в таймере, то сколько раз удалится то, что создано 1 раз?
Цитата:
Да, и переменные i, pointsCount и delta - объявить как Integer?
ABS возвращает дробное. Это функция "модуль". И сравнивается оно с delta. Значит delta какого типа?
Можно было и справку почитать на этот случай.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
Этот пользователь сказал Спасибо Bargest за это полезное сообщение:
Alloc (02.10.2015)
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра
Комбинированный вид Комбинированный вид

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 13:20.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025