1 (изменено: Скиталец, 2010-12-21 03:13:58)

Тема: AHK: Обращение к основному блоку скрипта из цикла

Написал скрипт (не без некоторой помощи форумчан), и он, на удивление, работает Причем, учитывая, что это мой первый скрипт, работает хорошо. Наверное, можно его было бы и поэлегантней сделать, но не суть. Вот сам скрипт:

F5::
Block0:
; Цикл проверяет точку на изменение цвета
; Как только цвет изменился, запускается первый блок
    Loop
    {
        Sleep, 1000
        PixelGetColor, color, 512, 243, BGR
        If color <> 0x5E5449
            Gosub, Block1
    }

Block1:
; Проверяет, активно ли нужное окно, и активирует его, если нет
; Проверяет в определенной точке окна, нет ли там активного конрола, и закрывает его, ели есть
; Идет поиск в области окна, где курсор изменит тип
; Как только тип курсора изменился, запускается второй блок
    Loop
    {
    WinWait, --------
    IfWinNotActive, --------, , WinActivate, ---------
    WinWaitActive, --------
    MouseMove, 470, 460
    PixelGetColor, color, 610, 415, BGR
    If color = 0x2A2A30
    MouseClick, left, 630, 390,,5
    Sleep, 100
    MouseMove, 490, 452
    Gosub, Block2
    Sleep, 10
        -------------------------
        -------------------------
    MouseMove, 640, 480
    Gosub, Block2
    Sleep, 10
    MouseMove, 640, 494
    Gosub, Block2
    }
    Return

Block2:
    if A_Cursor = Unknown
    {
        MouseClick, left
        Sleep, 100
        SendInput, 3
        Sleep, 1000
        SendInput, q
        Sleep, 2000
        SendInput, 2
        --------------------------
                --------------------------
        Sleep, 12000
; По завершению некоторых действий, проверяется цвет заданной точки
; Если цвет вернулся в исходное значение, запускается блок 3
; Если цвет по прежнему другой, повторно запускается блок 2
        PixelGetColor, color, 512, 243, BGR
        If color = 0x5E5449
            {
            Gosub, Block3
            If color <> 0x5E5449
            Return
            }
    }
    Return

Block3:
; Идет поиск в области окна, где курсор изменит тип
; Как только тип курсора изменился, запускается блок 4
    Loop
    {
    MouseMove, 490, 452
    Gosub, Block4
    Sleep, 10
    --------------------------
    --------------------------
    MouseMove, 640, 494
    Gosub, Block4
    }
    Return

Block4:
; Как только тип курсора изменился, выполняются некоторые действия 
; Проверяется цвет пикселя в заданных координатах, и в соответствии с тем, совпадает, или нет, производятся действия
; По завершении, скрипт начинает работу с начала
    if A_Cursor = Unknown
    {
        Sleep, 200
        MouseMove, 15, -20, 10, R
        MouseClick, left    
        Sleep, 500
        MouseMove, 470, 460, 10
        Sleep, 300
        PixelGetColor, color, 610, 415, BGR
        Sleep, 100
        If color = 0x2A2A30
            {
            MouseClick, left, 565, 525,,5
            Sleep, 500
            MouseClick, left, 940, 700,,5
            Sleep, 300
            MouseClick, left, 780, 520,,5
            Sleep, 200
            MouseClick, left, 780, 520
            Sleep, 300
            MouseClick, left, 940, 700,,5
            Sleep, 100
            }
            Else
            {
                If color <> 0x2A2A30
                Gosub, Block0
            }
    }
    Return

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

Скрипт
    MouseClick, left, 320, 690
Скрипт
    MouseClick, left, 370, 580
Скрипт
    MouseClick, left, 450, 730
В начало, к первым координатам

Я уже голову сломал, как это сделать, не вставляя после каждого клика весь текст скрипта с измененными метками. Буду признателен за помощь.

И сразу еще вопрос, уже посложнее. Есть еще один рабочий блок скрипта:

; Цикл проверяет точку на изменение цвета
; Как только цвет изменился, запускается блок 10
    Loop
    {
        Sleep, 500
        PixelGetColor, color, 342, 227, BGR
        If color <> 0x0000CC
        {
            Gosub, Block10
        }
    }

Block10:
; выполняются некоторые действия
    Sleep, 110000
    MouseMove, 470, 460
    PixelGetColor, color, 610, 415, BGR
    If color = 0x2A2A30
    MouseClick, left, 630, 390,,5
    Sleep, 100
    MouseClick, left, 940, 700,,5
    Sleep, 300
    MouseClick, left, 780, 520,,5
    Sleep, 200
    MouseClick, left, 780, 520
    Sleep, 10000
    MouseClick, left, 780, 520
    Sleep, 200
    MouseClick, left, 780, 520
    Sleep, 300
    MouseClick, left, 940, 700,,5
    Sleep, 100    
    PixelSearch, OutputVarX, OutputVarY, 750, 450, 950, 550, 0x266BD2 
    MouseMove, OutputVarX, OutputVarY
    MouseMove, 30, -181,, R
    Gosub, Block11
    MouseMove, 847, 303
    Gosub, Block11
    Sleep, 70000
    MouseMove, 888, 629
    Gosub, Block11
    MouseMove, 860, 534
    Gosub, Block11
    MouseMove, 715, 680
    Gosub, Block11
    MouseMove, 715, 475
    Gosub, Block11
    Click down 900, 283
    Sleep, 50000
    Click up
    PixelSearch, OutputVarX3, OutputVarY3, 280, 350, 820, 670, 0x052532 
    MouseMove, OutputVarX3, OutputVarY3
    MouseMove, -105, 80,, R
    Gosub, Block11
    MouseMove, 238, 632
    Gosub, Block11
    PixelSearch, OutputVarX4, OutputVarY4, 230, 520, 380, 640, 0x2C445B
    MouseMove, OutputVarX4, OutputVarY4
    MouseMove, 180, 67,, R
    Gosub, Block11
    MouseClick, left,  86,  511    

Block11:
    {
    MouseClick, left
    Sleep, 6000
    Return
    }

Как связать вместе эти 2 скрипта? Нужно, чтобы второй скрипт постоянно проверял выполнение условия заданное в его начале. Как только условие выполнится и цвет станет отличным от заданного, нужно чтобы второй скрипт останавливал работу первого, выполнялся до конца сам, по завершении своей работы запускал первый скрипт с начала, и сам возвращался в исходное состояние.

2 (изменено: Скиталец, 2010-12-23 20:57:04)

Re: AHK: Обращение к основному блоку скрипта из цикла

Ммм... Так никто не подскажет? Хотя бы, в каком направлении двигаться?
По первому вопросу, в общем-то, все у меня работает. Просто, громоздко очень. Поэтому и интересно, существует ли более элегантное решение. И со вторым вопросом я частично справился. Сделал все не одним, а двумя скриптами. И второй скрипт отключает/включает первый. Но вот тут бывают необъяснимые сбои, пока что... И тоже интересно, можно ли это осуществить в рамках одного скрипта?

3

Re: AHK: Обращение к основному блоку скрипта из цикла

Собственно вопрос такой. В конце каждого полного цикла скрипта должен производиться клик мышью в определенных координатах окна. То есть, есть несколько координат, в которых осуществляется клик, и это тоже происходит в цикле.

По первому вопросу. Вопросительное предложение должно заканчиваться вопросительным знаком.
Что Вы в своём коде называете полным циклом? Где у него конец? Как определяются "определённые координаты окна"? Задайте вопрос правильно.

4

Re: AHK: Обращение к основному блоку скрипта из цикла

читайте в хелпе про Gosub и Goto

; оснвоной скрипт
GoSub script  ; вызов подпрограммы
mouseclick ...
GoSub script
mouseclick ...
GoSub script
return

script:
тут нужные команды для скрипта
return

5 (изменено: Скиталец, 2010-12-24 04:15:00)

Re: AHK: Обращение к основному блоку скрипта из цикла

ypppu пишет:

Что Вы в своём коде называете полным циклом? Где у него конец? Как определяются "определённые координаты окна"? Задайте вопрос правильно.

Аааааа!!!! Строчку потерял! Сорри. Вот так выглядит последняя часть скрипта:

F5::
Block0:
-------------------------------------------
-------------------------------------------
-------------------------------------------
Block4:
    if A_Cursor = Unknown
    {
        Sleep, 200
        MouseMove, 15, -20, 10, R
        MouseClick, left    
        Sleep, 500
        MouseMove, 470, 460, 10
        Sleep, 300
        PixelGetColor, color, 610, 415, BGR
        Sleep, 100
        If color = 0x2A2A30
            {
            MouseClick, left, 565, 525,,5
            Sleep, 500
            MouseClick, left, 940, 700,,5
            Sleep, 300
            MouseClick, left, 780, 520,,5
            Sleep, 200
            MouseClick, left, 780, 520
            Sleep, 300
            MouseClick, left, 940, 700,,5
            Sleep, 100
            Gosub, Block0
            }
            Else
            {
                If color <> 0x2A2A30
                Gosub, Block0
            }
    }
    Return

То есть, при совпадении цвета выполняются некоторые действия и команда  Gosub, Block0 возвращает выполнение скрипта в начало. Если же цвет не совпадает, то сразу же возврат в начало скрипта такой же командой. Нужно чтобы вместо предпоследней команды Gosub, Block0 (это и является окончанием скрипта)

-----------------------------------
 MouseClick, left, 940, 700,,5
            Sleep, 100
            Gosub, Block0
            }
            Else
            {
                If color <> 0x2A2A30
                Gosub, Block0
            }
    }
    Return

осуществился клик мышкой (координаты я сам задаю), и только после этого началось выполнение скрипта с самого начала. По окончании второго цикла, клик мышкой в другом месте, по окончании третьего, еще в другом месте. И так по кругу. Пробовал такую конструкцию, не работает :-(


F5::
Block0:
-------------------------------------------
-------------------------------------------
-------------------------------------------
Block4:
    if A_Cursor = Unknown
    {
        Sleep, 200
        MouseMove, 15, -20, 10, R
        MouseClick, left    
        Sleep, 500
        MouseMove, 470, 460, 10
        Sleep, 300
        PixelGetColor, color, 610, 415, BGR
        Sleep, 100
        If color = 0x2A2A30
            {
            MouseClick, left, 565, 525,,5
            Sleep, 500
            MouseClick, left, 940, 700,,5
            Sleep, 300
            MouseClick, left, 780, 520,,5
            Sleep, 200
            MouseClick, left, 780, 520
            Sleep, 300
            MouseClick, left, 940, 700,,5
            Sleep, 100
            Gosub, Block5
            }
            Else
            {
                If color <> 0x2A2A30
                Gosub, Block0
            }
    }
    Return

Block5:
Loop
    {
    MouseClick, left, x1,y1
    Sleep, 200
    Gosub, Block0
    MouseClick, left, x2, y2
    Sleep, 200
    Gosub, Block0
    MouseClick, left, x3, y3
    Sleep, 200
    Gosub, Block0
    }

В принципе, даже наверное понимаю, почему не работает. Но как правильно сделать, уже переклинило, не сообразить


InFlames пишет:

читайте в хелпе про Gosub и Goto

; оснвоной скрипт
GoSub script  ; вызов подпрограммы
mouseclick ...
GoSub script
mouseclick ...
GoSub script
return

script:
тут нужные команды для скрипта
return

Увы, читал. И команду Gosub активно использую в скрипте. Ваш вариант, если я правильно все понял, тоже не работает :-(

6

Re: AHK: Обращение к основному блоку скрипта из цикла

Если честно, обычно читаю форум с утра и на лету. Трудно разбираться в куче кода.
Вам надо понимать как работает скрипт.
Когда нажимаете горячую клавишу (F5 у Вас), скрипт начинает выполнять код до ближайшего Return. Когда скрипт доходит до Return, он перестает работать.
Что бы скрипт продолжил работать необходимо задействовать еще одну горячую клавишу, или перед Return поставить вызов подпрограммы.
Опять же после вызова подпрограммы скрипт выполняет подпрограмму начиная с самой метки подпрограммы и до Return, потом скрипт возвращается в то место, от куда был вызов Return.
Схема, которую я написал, вполне рабочая, если соблюдать синтаксис.

7

Re: AHK: Обращение к основному блоку скрипта из цикла

InFlames пишет:

Схема, которую я написал, вполне рабочая, если соблюдать синтаксис.

Да, рабочая. Когда еще сам даже проверял на более простом скрипте, все работало. Правда, я там через Loop сделал. А вот сейчас не работает. Знаю, что сам где-то что-то лишнее в скрипт воткнул, скорее всего, потому и не работает.
В очередной раз буду сидеть разбираться, где и что не так

8

Re: AHK: Обращение к основному блоку скрипта из цикла

Посмотрел скрипт. Я думаю его надо привести в более менее читаемый вид.
Вот пример. Если надо ждать цвет, то как только нужный цвет на пикселе появился надо выйти из цикла.
Это делается командой break. У вас это сделано через Gosub

Вот так у Вас.

    Loop
    {
        Sleep, 1000
        PixelGetColor, color, 512, 243, BGR
        If color <> 0x5E5449
            Gosub, Block1
    }
Block1:

Вот так я думаю будет лучше

    Loop
    {
        Sleep, 1000
        PixelGetColor, color, 512, 243, BGR
        If color <> 0x5E5449
            break
    }
Block1:

Т.е. как только выполнилось условие, скрипт выходит из Loop и переходит на следующую строку скрипта, т.е. на Block1:

Попробуйте написать скрипт используя только "ключевые" команды, такие как If, gosub, loop и т.д.
Команды типа sleep, mouseclick и т.п. можно заменить на коментарии, например это

        Sleep, 1000
        PixelGetColor, color, 512, 243, BGR

можно заменить коментарием "промежуточные действия"
И так объединять по несколько команд, что бы упростить весь скрипт.
Потом просто все коментарии замените обратно на код.