Перейти к контенту

Язык Lua. Общие вопросы программирования


Рекомендуемые сообщения

С чего начинать и где взять.

 

Установка Lua:
http://www.amk-team.ru/forum/index.php?showtopic=11584&p=629106

 

Руководство «Программирование на языке Lua», третье издание:
http://www.amk-team.ru/forum/index.php?showtopic=11584&p=905308

Изменено пользователем Kirgudu
Ссылка на комментарий

 

Solomon753, скорее всего тут тебе не помогут, надо хоть немного знать документацию по твоему случаю.

Да со смещением мыши я разобрался, там всё элементарно, меня только прерывание цикла интересует, всё остальное знаю как.

На форумах нет ничего путного, ужасно реализована поддержка Lua лоджитеком, до всего самому докапываться надо.

 

Инструкция API вот: http://www.scribd.com/doc/228594915/G-SeriesLuaAPIтолько там ни слова про прерывание.

Один я тут цикл не вижу?

 

И зачем несколько раз вызывается

 

Sleep(delay)

MoveMouseRelative(x,y)

Да это в примере я кусок тестового макроса дал, х и у в каждом шаге разные, на каждом выстреле отдача кидает куда попало.

 

Вот например другой аналогичный скрипт из инета

 

 

EnablePrimaryMouseButtonEvents(true);
local recoil = not true;
function OnEvent(event, arg)
if (event == "MOUSE_BUTTON_PRESSED" and arg == 5)    then
      recoil = not recoil
	 OutputLogMessage("AK47 No Recoil", 2014)
end
 if IsMouseButtonPressed(3) and recoil then
Sleep(1)
if (event == "MOUSE_BUTTON_PRESSED" and arg == 1) then 
Sleep(98)
MoveMouseRelative(0,8)
Sleep(98)
MoveMouseRelative(5,21)
Sleep(98)
MoveMouseRelative(-5,26)
Sleep(98)
MoveMouseRelative(0,23)
Sleep(98)
MoveMouseRelative(10,33)
Sleep(98)
MoveMouseRelative(12,20)
Sleep(98)
MoveMouseRelative(8,33)
Sleep(98)
MoveMouseRelative(-14,15)
Sleep(98)
MoveMouseRelative(-35,4)
Sleep(98)
MoveMouseRelative(-16,2)
Sleep(98)
MoveMouseRelative(5,3)
Sleep(98)
MoveMouseRelative(-12,2)
Sleep(98)
MoveMouseRelative(-18,2)
Sleep(98)
MoveMouseRelative(-10,2)
Sleep(98)
Sleep(98)
end
end
end

 

 

Там для прерывания цикла предлагают такое решение, только я в него пока что не въехал, 3 день только в Lua разобраться пытаюсь.

 

 

sleep_duration = 98
recoil_coords = {
	{ x = 0, y = 8 },
	{ x = 5, y = 21 },
	{ x = -5, y = 26 },
}

function OnEvent(event, arg)
	if event == "PROFILE_ACTIVATED" then
		EnablePrimaryMouseButtonEvents(true);
	end
	if (event == "MOUSE_BUTTON_PRESSED" and arg == 5)    then
		recoil = not recoil
		if recoil then
			ClearLCD()
			OutputLCDMessage("AK47 No Recoil - ON", 2014)
		else
			ClearLCD()
			OutputLCDMessage("AK47 No Recoil - OFF", 2014)
		end
	end
	if IsMouseButtonPressed(3) and recoil then
		if (event == "MOUSE_BUTTON_PRESSED" and arg == 1) then 
			for i, v in ipairs(recoil_coords) do
				Sleep(sleep_duration)
				if not (IsMouseButtonPressed(1) and IsMouseButtonPressed(3)) then
					break
				end
				MoveMouseRelative( recoil_coords[i].x, recoil_coords[i].y )
			end
		end
	end
end

 

 

 

  • EnablePrimaryMouseButtonEvents(true) -- видимо включение событий

Это разрешение использовать левую кнопку для макрома, API требует. Оператор while разумное решение, уже думал на этим, только именно к циклу его нужно приделать. А MoveMouseRelative тоже API требует это писать. В предыдущем посте ссылка на API.

Изменено пользователем Solomon753
Ссылка на комментарий

Оператор while разумное решение, уже думал на этим, только именно к циклу его нужно приделать

while это и есть цикл. Зачем его ещё куда-то приделывать? Код-то тестил, который я выше привел?
Ссылка на комментарий
while это и есть цикл. Зачем его ещё куда-то приделывать? Код-то тестил, который я выше привел?

 

Код принимает, только мышь ничего не делает при нажатии, подозреваю что из-за этого:

 

local LEFT_BTN = 1

if event == "MOUSE_BUTTON_PRESSED" and arg == LEFT_BTN

 

В API не упоминается что вместо номера кнопки можно переменную поставить

 

Убрал переменную, сделал так, тоже ничего

local delay = 54 -- задержка между выстрелами
local x, y = 0, 50

EnablePrimaryMouseButtonEvents(true) -- видимо включение событий

function OnEvent(event, arg)
     if (event == "MOUSE_BUTTON_PRESSED" and arg == 1) then
          while IsMouseButtonPressed(1) do
               Sleep(delay)
               MoveMouseRelative(x, y)
          end
     end
end

Для эксперимента поменял "MOUSE_BUTTON_PRESSED" на "MOUSE_BUTTON_RELEASED" , при отжатии цикл выполняется полностью(добавил еще несколько шагов), только как while разрешает это делать если кнопка не нажата.

Изменено пользователем Solomon753
Ссылка на комментарий

В API не упоминается что вместо номера кнопки можно переменную поставить

Зато в луа упоминается. Работать не хочет не из-за этого.

 

Выводи в лог на экран что-нибудь (вроде там функция была), проверь вообще идет ли выполнение кода внутри цикла.

Изменено пользователем Shadows
Ссылка на комментарий

Выводи в лог на экран что-нибудь (вроде там функция была), проверь вообще идет ли выполнение кода внутри цикла.

dddee8b9ae182488a4af950a4ef31f95.png

 

Как видишь While не выполняется. Но что странно, консоль приняла код на загрузку в мышь, про ошибки молчит.

Изменено пользователем Dennis_Chikin
Ссылка на комментарий

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

Дык синтаксических ошибок нет, чего ему ругаться?

 

local delay = 54 -- задержка между выстрелами
local x, y = 0, 50
local LEFT_BTN = 1 -- ЛКМ
local is_pressed = false

EnablePrimaryMouseButtonEvents(true)

function OnEvent(event, arg)
     if arg == LEFT_BTN then
          if event == "MOUSE_BUTTON_PRESSED" then
               is_pressed = true
               start_cycle()
          elseif event == "MOUSE_BUTTON_RELEASED" then
               is_pressed = false
          end
     end
end

function start_cycle()
     while is_pressed do
          Sleep(delay)
          MoveMouseRelative(x, y)
     end
end
Пробуй так. Изменено пользователем Shadows
Ссылка на комментарий

Я тоже на этом споткнулся. Возможно в while is_pressed do цикл получается бесконечеый.

Не известно как работает OnEvent . У неё независимый поток? Будет ли обрабатывать кнопки во время цикла? Никто тут пока не знает.

У меня был вариант:

function OnEvent(event, arg)
    local mouse_down = (event == "MOUSE_BUTTON_PRESSED" and arg == 1)
    while mouse_down do
        Sleep(delay)
        MoveMouseRelative(x, y)
    end
end

Вероятно проверка IsMouseButtonPressed(1) ещё не определяется на этом цикле апдейта. При отпускании (через несколько циклов???) она уже есть, а ( IsMouseButtonReleased???) нет  . Вот и срабатывает "прошлая" - на нажатие.

Нужно больше информации. Есть ли метод типа OnUpdate, или события удержания клавиши.

Изменено пользователем Nazgool
Ссылка на комментарий
@Nazgool, а, ну раз так, значит да, без апдейта или других, постоянно вызывающихся методов, никак не сделать. А их судя по всему нет, если я правильно прочитал тот мануал. Изменено пользователем Shadows
Ссылка на комментарий

Глянул по ссылкам. Тоже начал было на coroutin-ах делать. Но вроде тот же хрен, только в профиль.

Хотя можно попробовать.

Подскажи пожалуйста ссылку на API

Изменено пользователем Nazgool
Ссылка на комментарий
Подскажи пожалуйста ссылку на API

 

http://www.scribd.com/doc/228594915/G-SeriesLuaAPI

 

 

Пробуй так.

 

Попробовал, мышь тянет вниз как бешеную, никакие нажатия не останавливают, до того как успел нажать alt-f4 консоль вместе с драйвером аварийно завершила работу. :)

Изменено пользователем Solomon753
Ссылка на комментарий

@Solomon753

Ну тогда попробуй ещё такое.

local delay = 54 -- задержка между выстрелами
local x, y = 0, 50

function OnEvent(event, arg)
    if (event == "MOUSE_BUTTON_PRESSED" and arg == 1) then
        Sleep(30) -- тут нужно подобрать оптимальное время задержки (как можно меньшее)
        while IsMouseButtonPressed(1) do
            Sleep(delay)
            MoveMouseRelative(x, y)
        end
    end
end

Вот же вроде  написано для PressKey, что при нажатии есть задержка в несколько миллисекунд 

NOTE: Calling IsModifierPressed or

IsKeyLockOn  immediately afterwards for a simulated modifier or lock key will likely retur
 the previous state. It will take a few milliseconds for the operation to complete
Думаю это распространяется и на кнопки мыши.
Изменено пользователем Nazgool
Ссылка на комментарий

Сделал чтобы действие каждой операции выводилось на дебаггер, вот что получилось:

 

0f7e0fe730422986d5ac49d9158a3f51.png

 

 

fe780ec267edfacbc8abdd365056dd4d.png

 

 

 

Как видим на 4 операции циклу благополучно передаётся управление, а отжатие кнопки не определятся вообще.

Ссылка на комментарий

@Solomon753

Скрипт, который ты тестировал (как мы уже выяснили) не годится.

Попробуй мой вариант чуть выше.

И поиграйся со временем задержки в

Sleep(30) -- тут нужно подобрать оптимальное время задержки

Изменено пользователем Nazgool
Ссылка на комментарий
Скрипт, который ты тестировал (как мы уже выяснили) не годится. Попробуй мой вариант чуть выше. И поиграйся со временем задержки в Sleep(30) -- тут нужно подобрать оптимальное время задержки

При всех задержках тело цикла выполняется полностью, повторяется пока зажата кнопка, как если бы использовались операторы repeat и until not, эффект точно такой же. Ставил задержку даже 1000, драйвер точно бы успел перехватить отжатие.

 

 

Сюда бы Break как-то запихнуть, он в цикле While должен делать полное прерывание тела. В скриптах в инете много вижу такое сочетание как пример прерывания. Только там другие задачи решаются. Надо бы что-то вроде:

if not IsMouseButtonPressed(1) then break
end

только и здесь тело не прерывается, хотя по логике обязано.

Эврика!!! Получилось... :beach:

Вот решение :) :

local delay = 54 -- задержка между выстрелами
local x, y = 0, 50

function OnEvent(event, arg)
if (event == "MOUSE_BUTTON_PRESSED" and arg == 1) then
Sleep(7) -- БЕЗ ЭТОЙ ЗАДЕРЖКИ СКРИПТ НЕ РАБОТАЕТ, СПАСИБО Nazgool ЗА ИДЕЮ

while IsMouseButtonPressed(1) do   
Sleep(delay)
MoveMouseRelative(x, y)
if not IsMouseButtonPressed(1) then break end
Sleep(delay)
MoveMouseRelative(x,y)
if not IsMouseButtonPressed(1) then break end
Sleep(delay)
MoveMouseRelative(x,y)
if not IsMouseButtonPressed(1) then break end

end
end
end

Конечно увидев это профессиональный программист упадёт со смеху, но оно работает. Идея Nazgool с задержкой тоже оказалась верна, поставил 7мс, при 5 слегка подлагивает при очень быстрых нажатиях(может исполнение проигнорировать), а на 3 уже не работает. Теперь хотелось бы найти более грамотное решение задачи, как одной строкой объяснить циклу что после каждой итерации нужно проверять состояние кнопки. Но конечно предпочтительнее параллельное отслеживание состояния как в предыдущих скриптах, видимо дело именно в отсутствии задежки в них, надо будет поэкспериментировать.

Изменено пользователем Solomon753
Ссылка на комментарий

 

 

тело цикла выполняется полностью, повторяется пока зажата кнопка

А разве не это требовалось?

 

Сюда бы Break как-то запихнуть, он в цикле While должен делать полное прерывание тела

 

как одной строкой объяснить циклу что после каждой итерации нужно проверять состояние кнопки
while IsMouseButtonPressed(1) do как раз и проверяет на каждом новом круге "нажата ли кнопка?"

Ну если хочется с break-ом, то можно переписать так :

local delay = 54 -- задержка между выстрелами
local x, y = 0, 50

function OnEvent(event, arg)
    if (event == "MOUSE_BUTTON_PRESSED" and arg == 1) then
        while true do   
        Sleep(delay)
        MoveMouseRelative(x, y)
        if not IsMouseButtonPressed(1) then break end
    end
end

end забыл. Почему-то не могу редактировать. Глючит что-то. Вот:

local delay = 54 -- задержка между выстрелами
local x, y = 0, 50

function OnEvent(event, arg)
    if (event == "MOUSE_BUTTON_PRESSED" and arg == 1) then
        while true do   
            Sleep(delay)
            MoveMouseRelative(x, y)
            if not IsMouseButtonPressed(1) then break end
        end
    end
end
Ссылка на комментарий
Solomon753 сказал(а) тело цикла выполняется полностью, повторяется пока зажата кнопка А разве не это требовалось?

Мне прерывание выполнения именно тела нужно по отжатию, т.е остановка после любой итерации, без завершения выполнения тела.

 

 

 

while IsMouseButtonPressed(1) do как раз и проверяет на каждом новом круге "нажата ли кнопка?" Ну если хочется с break-ом, то можно переписать так :

А тут вот именно что "на каждом новом круге", т.е всё тело выполняется полностью в любом случае, не рубится по событию, я этот код давно пробовал, он работает так же как цикл  "repeat - until not", об этом выше упоминал уже. В таком варианте не происходит проверки после каждой итерации состояния кнопки, пока всё тело не выполнится.

 

Кстати сегодня задержку между "if (event == "MOUSE_BUTTON_PRESSED" and arg == 1) then" и "while IsMouseButtonPressed(1) do" пришлось до 15 увеличить, видимо от загрузки процессора и приоритетности зависит как быстро драйвер о состоянии кнопки узнает.

 

Меня ещё вот что интересует, можно ли в этом коде задать повышение приоритета процесса?

Изменено пользователем Solomon753
Ссылка на комментарий

@Solomon753

Ты видимо не понимаешь как работает цикл while.

Давай по шагам вот с таким кодом:

function OnEvent(event, arg)
    if (event == "MOUSE_BUTTON_PRESSED" and arg == 1) then
        while true do   
            Sleep(delay)
            if not IsMouseButtonPressed(1) then break end
            MoveMouseRelative(x, y)
        end
    end
end
1.  Нажимается ЛКМ
 
2.  После проверки if (event == "MOUSE_BUTTON_PRESSED" and arg == 1) then...
    NOTE: На данный момент IsMouseButtonPressed(1) возвратит false, т.к. ещё нее прошло N миллисекунд.
 
3.  Запускается цикл while
    NOTE: В этоже время, по видимому, происходит выстрел
 
4.  Производится задержка Sleep(delay) 54 миллисекунды.
    За это время отдача изменяет координаты X.Y
    Также этого времени вполне достаточно для того, чтобы IsMouseButtonPressed(1) показывала реальное положение кнопки.
 
5.  Если на данный момент ЛКМ ещё нажата, то проверка - if not IsMouseButtonPressed(1) then - будет отрицательна.
    Переходим к пункту 6.
 
    Если же на данный момент ЛКМ отпущена, то if not IsMouseButtonPressed(1) then сработает и цикл прекратиться.
    NOTE: Максимум продлится ещё на один цикл до нового вызова Sleep(delay), за время которого произойдёт переключение
    из состояния "нажатая" в "отпущеная" (или наоборот)
 
6.  А значит вызывается MoveMouseRelative(x, y) - и координаты восстанавливаются
    И цикл начинается снова с пункта 3.

 

 

В таком варианте не происходит проверки после каждой итерации состояния кнопки

Вот же она эта проверка - if not IsMouseButtonPressed(1) then. Находится в теле блока.

Так уж lua устроена.

Не пойму я эту API, почему за время Sleep(delay) т.е. 54 , не успевает переключаться состояние кнопок. Какое тогда время для этого нужно?

Ссылка на комментарий

@Solomon753

Ты видимо не понимаешь как работает цикл while.

 

Да именно так я и понимаю происходящее, может изъяснился запутанно, только 5 день в язык вникаю. И по логике тоже сразу считал что if not IsMouseButtonPressed(1) then проверяет состояние кнопки на каждом шаге цикла, но вот именно что с API мыши это не работает, состояние кнопки становится известно только после последнего шага и принимается решение повторить ли цикл. Но при этом если прописывать "if not IsMouseButtonPressed(1) then break end" после каждого шага цикла, то драйвер прекрасно успевает понять в каком состоянии кнопка и принять решение делать ли следующий шаг. И так и так должно работать, но работает почему-то только во втором случае, видимо у лоджитека так реализована работа драйвера, что не все операторы работают как должны. У меня в реальном коде шагов "MoveMouseRelative(x, y)" будет 30(в абойме 30 патронов), точнее 30-1, отклонения начинаются после первого выстрела, и на каждом шаге x,y разные, поэтому придётся прописывать после каждого шага проверку состояния кнопки, если API упорно отказывается понимать другие способы. Возможно лоджитек намеренно ограничила возможности оператора, может быть при очень быстрых нажатиях будет надёжнее проверять состояние кнопки по отдельной команде на каждом шаге цикла.

Изменено пользователем Solomon753
Ссылка на комментарий

Не пойму я эту API, почему за время Sleep(delay) т.е. 54 , не успевает переключаться состояние кнопок. Какое тогда время для этого нужно?

Скорее всего пока вызов OnEvent обрабатывается состояния кнопок не обновляются.

 

Ну и Sleep`ы использовать не стоит.

Ссылка на комментарий

Подскажите пожалуйста в Lua есть возможность определения цвета пикселя по заданным координатам? То есть мне нужно чтобы условие выполнялось только в том случе, если определённые места на экране имеют определённый цвет. Скачал книгу Programming in Lua, Third Edition by Roberto Ierusalimschy, но там про это ничего нет, только как цвета на эране менять,  хотя по логике вещей, если на этом языке игры пишут, то должно быть что-то подобное.

И ещё вопрос про coroutines, это полностью параллельное вычисление происходящее в реальном времени с основным кодом? И если это так, то когда корутинов несколько они могут все одновременно выполняются или один уступает ресурсы процессора дугому?

Изменено пользователем Solomon753
Ссылка на комментарий

Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

Создать аккаунт

Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!

Зарегистрировать новый аккаунт

Войти

Есть аккаунт? Войти.

Войти
  • Недавно просматривали   0 пользователей

    • Ни один зарегистрированный пользователь не просматривает эту страницу.
×
×
  • Создать...