Показано с 1 по 1 из 1

Тема: [Урок] GUI: Примитивная анимация

  1. #1
    Проверенный Аватар для Arios Jentu
    Регистрация
    15.02.2012
    Адрес
    Таанаб - Пандат
    Сообщений
    2,433
    Репутация: 319

    Звание: как роза среди колючек

    [Урок] GUI: Примитивная анимация

    Приветствую всех, дорогие читатели
    Сегодняшний день давайте посвятим МТА, а именно анимации GUI (перемещение, размеры, и прочее). Я думаю перемещение GUI мышью для далёких от Lua будет трудновато, так что напишу для него отдельный урок.
    В этом уроке почти весь код будет написан на ООП в МТА.
    Для этого нам понадобятся:
    1) Прямые ручки (ну куда-ж без них то)
    2) Базовое знание MTA Lua (а именно - построение функций, строение ресурса, события, переменные, частично - ООП)

    Начнём:

    Для начала создадим просто изображение на экране. Я буду использовать файл pane.png размером 1х1px, так как я его использую везде
    PHP код:
    local MoveImage = {}
    MoveImage.Image GuiStaticImage.create(5050100100"pane.png"false
    Мы создали переменную MoveImage (тип table), и в этой таблице создали переменную Image (тип userdata - gui-staticimage), которая является изображением на экране, располагающаяся на позициях 50,50 с размером 100х100. Вызывать это изображение мы будем именно через MoveImage.Image

    Далее нам понадобится переменная, отвечающая за активацию какой-либо анимации. Я, например, сделаю 2 анимации для данного изображения, следовательно мне понадобится тип integer для переменной. Если мне бы нужна была одна анимация, то я бы воспользовался типом boolean.
    PHP код:
    MoveImage.Animation 
    Мы создали переменную Animation в уже существующей таблице MoveImage. Сразу определим её значения:
    0 - Анимация отключена
    1 - Первая анимация
    2 - Вторая анимация

    После создания переменной, нам нужно будет её где-то использовать. Анимацию делать будем в событии onClientRender. Замечу, что скорость выполнения анимации будет зависеть от FPS (так как onClientRender выполняется покадрово)
    PHP код:
    addEventHandler("onClientRender"root, function()
        
    //Здесь будет проверка на переменную Animation

        
    if MoveImage.Animation == 1 then //Если переменная Animation равна 1 (если используем первую анимацию)

            //Получаем позиции и размеры исходного изображения на каждый кадр, пока анимация равна 1
            
    local xMoveImage.Image:getPosition(false)
            
    local wMoveImage.Image:getSize(false)

            
    xx+1y-//Обновляем значения переменных позиции таким образом, чтобы изображение перемещалось вверх
            
    ww-2h-//Обновляем значения переменных размера таким образом, чтобы изображение при перемещении уменьшалось
            
            //Обновляем позиции и размеры
            
    MoveImage.Image:setPosition(xyfalse)
            
    MoveImage.Image:setSize(whfalse)

            
    //Это будет длиться бесконечно, пока переменная Animation не поменяет своё значение
            //Для этого мы будем отталкиваться относительно размеров
            //Так как размеры уменьшаются на 2 пикселя за кадр, мы не сможем определить, когда нужно точно остановиться, так что проверка будет с учётом желаемого результата
            //Ну точнее можем, но дополнительные расчёты нам не нужны

            
    if <= 0 then //Так как уменьшаем размеры, значит <, желаемый результат учитываем
                //Когда размеры нулевые, изображение на экране уже найти будет практически невозможно
                //Следовательно сия цикл должен быть закончен, поэтому меняем значение переменной

                
    MoveImage.Animation 2

                
    //Чтобы совсем закончить анимацию, можно поставить 0, но я решил сразу выполнить вторую анимацию, которая будет выполнять обратное действие

            
    end
        
        
    elseif MoveImage.Animation == 2 then //Сразу тут-же делаю проверку на использование второй анимации

            //Точно так-же получаем позиции и размеры исходного изображения
            
    local xMoveImage.Image:getPosition(false)
            
    local wMoveImage.Image:getSize(false)
            
            
    //Точно так-же меняем размеры, но уже в обратном направлении
            
    xx-1y+1
            w
    w+2h+2

            
    //Только сделаем проверки на размеры, ибо всё таки это изображение будет видимо, и если оно превысит желаемые позиции и размеры, это будет растянуто (Некрасиво :D)

            
    if <= 50 then x 50 end
            
    if >= 50 then y 50 end
            
    if >= 100 then w 100 end
            
    if >= 100 then h 100 end

            
    //Обновляем позиции и размеры
            
    MoveImage.Image:setPosition(xyfalse)
            
    MoveImage.Image:setSize(whfalse)
            
            
    //И закрываем цикл
            
    if == 100 then
                
    //Полностью прекратим выполнение анимации. Для бесконечного цикла можно использовать в первой анимации значение второй анимации, а здесь - значение первой анимации

                
    MoveImage.Animation 0
            end

        end
    end




    Так-же можно сделать с изменением прозрачности. Я не буду здесь расписывать комментарии, думаю всё будет понятно (алгоритм тот-же, что и выше).
    Здесь будет бесконечный цикл - постоянная анимация увеличения и снижения уровня прозрачности
    PHP код:
    addEventHandler("onClientRender"root, function()
        if 
    MoveImage.Animation == 1 then

            MoveImage
    .Image:setAlpha(
                
    MoveImage.Image:getAlpha()-0.05
            
    )

            if 
    MoveImage.Image:getAlpha() <= 0 then
                MoveImage
    .Animation 2
            end

        
    elseif MoveImage.Animation == 2 then

            MoveImage
    .Image:setAlpha(
                
    MoveImage.Image:getAlpha()+0.05
            
    )

            if 
    MoveImage.Image:getAlpha() >= 1 then
                MoveImage
    .Animation 1
            end        

        end
    end



    Здесь мы уяснили, что за анимацию отвечает переменная Animation в таблице MoveImage (Аля MoveImage.Animation)
    Теперь давайте разберёмся, как можно вызывать анимацию. Для начала я предлагаю создать функцию для того, чтобы вызывать анимацию
    PHP код:
    function runAnimation(num)
        if 
    num or num 2 then return false end //Если номер вызова анимации не принадлежит участку от 0 до 2, то просто закончить выполнение функции
        //Иначе просто начать или закончить выполнение анимации
        
    MoveImage.Animation num
    end 
    Теперь как вызывать функцию для того, чтобы вызвать анимацию
    PHP код:
    runAnimation(0//Остановить выполнение анимации
    runAnimation(1//Выполнить первую анимацию
    runAnimation(2//Выполнить вторую анимацию 
    Ну и как теперь это можно использовать
    PHP код:
    //Например по нажатию какой-либо кнопки
    bindKey("m""up", function() runAnimation(math.random(02)) end
    PHP код:
    //Ну или по нажатию на само изображение
    addEventHandler("onClientGUIClick"MoveImage.Image, function() runAnimation(1endfalse
    Конечный вид:
    PHP код:
    local MoveImage = {}
    MoveImage.Image GuiStaticImage.create(5050100100"pane.png"false)
    MoveImage.Animation 0

    addEventHandler
    ("onClientRender"root, function()

        if 
    MoveImage.Animation == 1 then

            local x
    MoveImage.Image:getPosition(false)
            
    local wMoveImage.Image:getSize(false)

            
    xx+1y-1
            w
    w-2h-2
            
            MoveImage
    .Image:setPosition(xyfalse)
            
    MoveImage.Image:setSize(whfalse)

            if 
    <= 0 then 
                MoveImage
    .Animation 2
            end
        
        
    elseif MoveImage.Animation == 2 then

            local x
    MoveImage.Image:getPosition(false)
            
    local wMoveImage.Image:getSize(false)
            
            
    xx-1y+1
            w
    w+2h+2

            
    if <= 50 then x 50 end
            
    if >= 50 then y 50 end
            
    if >= 100 then w 100 end
            
    if >= 100 then h 100 end

            MoveImage
    .Image:setPosition(xyfalse)
            
    MoveImage.Image:setSize(whfalse)
            
            if 
    == 100 then
                MoveImage
    .Animation 0
            end

        
    elseif MoveImage.Animation == 3 then

            MoveImage
    .Image:setAlpha(
                
    MoveImage.Image:getAlpha()-0.05
            
    )

            if 
    MoveImage.Image:getAlpha() <= 0 then
                MoveImage
    .Animation 4
            end

        
    elseif MoveImage.Animation == 4 then

            MoveImage
    .Image:setAlpha(
                
    MoveImage.Image:getAlpha()+0.05
            
    )

            if 
    MoveImage.Image:getAlpha() >= 1 then
                MoveImage
    .Animation 0
            end

        end
    end
    )

    function 
    runAnimation(num)
        if 
    num or num 4 then return false end
        MoveImage
    .Animation num
    end

    bindKey
    ("m""up", function() runAnimation(math.random(12) == and or 3end)

    addEventHandler("onClientGUIClick"MoveImage.Image, function(but
        if 
    but == "left" then runAnimation(1) else runAnimation(3end
    end
    false
    Спасибо за прочтение, и, если будут вопросы, задавайте

  2. 6 пользователей сказали cпасибо Arios Jentu за это полезное сообщение:

    Disinterpreter (30.06.2015), Lampo7 (30.06.2015), MacMailler (30.06.2015), Seregamil (30.06.2015), КабанчиК (30.06.2015), Меша (30.06.2015)

Похожие темы

  1. Анимация
    от Johurt в разделе Вопросы по скриптингу
    Ответов: 3
    Последнее сообщение: 27.09.2014, 17:36
  2. Анимация
    от BenStiven в разделе Ищу скрипт/мод/функцию/программу/плагин...
    Ответов: 3
    Последнее сообщение: 15.05.2014, 19:04
  3. [Урок] HTML - Урок 2. Структура html
    от All в разделе HTML, JavaScript
    Ответов: 0
    Последнее сообщение: 07.08.2013, 17:49
  4. Анимация
    от M1RoN в разделе Вопросы по скриптингу
    Ответов: 5
    Последнее сообщение: 14.07.2013, 19:39
  5. Анимация
    от Endo в разделе Вопросы по скриптингу
    Ответов: 0
    Последнее сообщение: 03.06.2013, 21:36

Ваши права

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