Что нового

[Время, дата] Частота прохождения цикла While

Rain1251

Новичок
Сообщения
6
Репутация
1
Всем здравствуйте.

Есть такая задача: в игре быстро бежит цветная полоска и в какой-то момент скрывается за препятствием. Бежит всегда с разной скоростью. Как только она добегает до препятствия, то ей остается бежать еще 11% пути. Я замеряла цвет пикселя перед препятствием, чтобы узнать, через какое время послать команду. Вот так:

Код:
Func WayForT1()
   Local $begin = TimerInit()
   Local $statusT1 = "onwait"
   While $statusT1 = "onwait" 
	  $colorT1_wand = Hex(PixelGetColor(1623, 502), 6)
	  
		 If $colorT1_wand <> $colorT1_wait Then
			Local $dif = TimerDiff($begin)
			$WeWillSleep = $dif/11
			Sleep($WeWillSleep)
			Send("{t DOWN}")
			Send("{t UP}")
			WorkingT1()
		 EndIf
   WEnd	
EndFunc


Проблема в том, что каждый раз получаются разные результаты. Думаю, это за счет того, что функция срабатывает слишком медленно и не успевает вовремя замерять то, что "полоска" уже подошла. Можно ли как-то ускорить цикл while?
(Я прочла справку и искала на форуме.) Буду очень благодарна за помощь!
 

sngr

AutoIT Гуру
Сообщения
1,010
Репутация
408
Замени
Код:
$colorT1_wand = Hex(PixelGetColor(1623, 502), 6)      
 If $colorT1_wand <> $colorT1_wait

на
Код:
If PixelSearch(1623, 502,1623, 502,0x000000) Then
 
Автор
R

Rain1251

Новичок
Сообщения
6
Репутация
1
Спасибо за наводку!

Проблема в том, что я не знаю цвет полоски, которая придет. Пробовала работать по вашему примеру от противного - т.е. если цвет не совпал, то выполнить "...". Не сработало.

Переписала теперь почти как у вас, только с проверкой суммы цвета:
Код:
Func WayForT1()
   Local $begin = TimerInit()
   Local $checksumT1 = PixelChecksum(1623, 502,1623, 502)
	  While $checksumT1 = PixelChecksum(1623, 502,1623, 502)
		 Sleep(0)
	  WEnd
   Local $dif = TimerDiff($begin)
   $WeWillSleep = $dif/11
   Sleep($WeWillSleep)
   Send("{t DOWN}"); - T1_1
   Send("{t UP}")
   WorkingT1()
EndFunc


Только все равно не могу ровно попасть в точку назначения. У меня только два варианта: либо комп не успевает обработать (полоска от точки А до точки Б идет всего 100 мс), либо полоска идет чуть разной траекторией и с разным ускорением. Я пока проверяю второй вариант. Если получится/не получится - напишу.
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
А можно конкретизировать задачу?
В чем цель игры?
Бежит полоска, натыкается на препятствие и ей остаётся пройти 11% ОТ ЧЕГО ?
Вы пытаетесь нажать клавишу "t". В какой момент её нужно нажать по условиям игры?
 
Автор
R

Rain1251

Новичок
Сообщения
6
Репутация
1
Извините - попросила помощи и пропала на все выходные.

Описываю механику:
По игровому полю разбросаны круги одинакового размера. Назовем их А, Б, В и т.д.
1. При старте игры нажимается первая буква А.
2. От буквы А к букве Б бежит полоска.
3. Как только полоска подбегает к центру буквы Б, нужно нажать на клавиатуре клавишу "Б.
4. Дальше полоска бежит к В и нужно успеть нажать "В" и т.д.

Проблема заключается в том, что полоска забегает _под_ круги с буквами, так что не видно в какой момент она оказывается в центре круга. Если принять путь от А до Б за 100%, то полоска скрывается под кругом в тот момент, когда ей остается бежать 11%. Но, к сожалению, скорость меняется не линейно. Я пыталась замерить скорость на разных участках пути и вычислить центр; пыталась просчитать координаты и уловить зависимость.
Заметила, что, если игре давать приоритет реального времени, а скрипту - высокий (кстати, можно ли его автоматически запускать с высоким приоритетом?), то лаги уменьшаются, но не намного. Разброс идет в районе 50 мс, но этого достаточно, чтобы все перестало работать.

И раз мне придется постоянно замерять скорость на всем протяжении пути полоски (ее полное время пути - это примерно 650 мс), то нужно как-то ускорить обработку циклов по определению цвета пикселя. Вот не могу понять как.
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Всё равно непонятно.
Давайте по порядку.
Круг имеет размер, полоска имеет размер.
Круг полностью покрывает полоску?
"Полоска подбегает к центру круга" - это как измеряется? Может "когда полоска покрывает центр круга"?
Полоска стартует от центра круга А или от края круга А ?
Что всё таки мы принимаем за 100% ? Путь начала полоски от центра круга А до центра круга Б? Путь начала полоски от края круга А до края круга Б? Время от 'конец полоски покинул круг А' до 'начало полоски коснулось круга Б' ? Время от 'конец полоски покинул круг А' до 'конец полоски скрылся под круга Б' ?
Почему вы оперируете величиной 11%, но в скрипте берёте
Код:
$WeWillSleep = $dif/11

?
Что значит что скорость меняется нелинейно? Когда именно может меняться скорость?
Что значит что Вы не знаете цвет полоски которая придёт? Полоска меняет цвет? А фон, фон фиксированного цвета?
 
Автор
R

Rain1251

Новичок
Сообщения
6
Репутация
1
Прошу прощения, что выразилась непонятно. Спасибо за отзывчивость!
Я уже решила вопрос, так что объяснения и скриншоты выложу ниже - вдруг кому понадобится?

В некой игре нужно нажимать на клавиши, когда мимо них пробегает полоска. На скриншоте - фрагмент игры. Полоска начинает бежать от P к Т, потом от Т к F. Скриншоты убрала в спойлер ниже:
1.
bot1.jpg

2.
bot2.jpg

3.
bot3.jpg
Когда полоска пробегает мимо буквы Т, нужно успеть нажать на клавишу Т.
Проблема заключается в том (см. скрин №3), что полоску под буквой не видно и нельзя засечь ее точное прохождение через центр буквы Т.
Мне нужно было обработать цикл while как можно чаще, чтобы засечь скорость полоски и, если есть, то стандартный разброс скоростей для нее. С вашей помощью удалось настроить скрипт так, чтобы сделать пару-другую десятков итераций и собрать данные о скорости. В итоге оказалось, что эта дрянская полоска хоть и имеет линейную скорость, но рандомно скачет в пределах нескольких пикселей в пределах 100 мс. Т.е. идеальный вариант: когда можно просчитать положение полоски в зависимости от формулы движения (y = y0 - B*(1 - ( (x-x0)/A )^2)^0.5) и времени - тупо не работает.

Так что, финальный вариант выглядит вот так:
Код:
Func WayForT1()
   Local $checksumT1 = PixelChecksum(1623, 504,1623, 504)
	  While $checksumT1 = PixelChecksum(1623, 504,1623, 504)
		 Sleep(0)
	  WEnd
  
   Local $i = 0  
   Local $checksumT1_1 = PixelChecksum(1631, 539, 1631, 539)
	  While $checksumT1_1 = PixelChecksum(1631, 539, 1631, 539)		 
		 $i = $i + 1 
		 If $i = 7 Then ExitLoop
		 Sleep(1)
	  WEnd
   Send("{t DOWN}"); - T1_1
   Send("{t UP}")
EndFunc


Т.е. я постоянно поджидаю полоску в точке входа в букву Т. А потом начинаю ждать или в точке выхода, или по истечении среднего времени (уже вычислила за многочисленные итерации) долета полоски до цетра буквы Т. Приходится поджидать полоску на выходе, потому что это среднее время имеет жуткий разброс.

Вот и все.

Всем спасибо за помощь и отзывчивость!
 

C2H5OH

AutoIT Гуру
Сообщения
1,473
Репутация
333
Послесловие.

А что, букву Т можно нажать только один раз?
Если начать спамить, когда полоска дошла до круга с буквой Т, и прекратить, когда она вышла из под этого круга. Такое пройдёт?
-----------------------------------------------------
Почему формула движения в декартовой системе координат?
По-моему в данной задаче больше подошла бы радиальная система координат, причем на радиус можно забить и контролировать только угол.
:smile:
 
Автор
R

Rain1251

Новичок
Сообщения
6
Репутация
1
Это я упростила. При нажатии буквы Т начинается другое действие, которое нужно закончить нажатием клавиши Т второй раз. Так что спамить нельзя. =/
Про формулу - это начальное движение, потом полоска двигается по прямой, еще по кривой, и по всякой фигне. Так что замеряла просто скорость на разных отрезках пути. На скриншоте их всего два видно. В итоге оказалось, что в среднем на 1 пиксель пути нужно 4,76 мс независимо от участка пути.
 
Верх