Доступ к архиву

Переход в группу "Пользователь"

300.00 ₽
Одноразовый платёж
Быстрый переход в группу "Пользователи", без надобности написания постов и ожидания.

Покупка дает возможность:
Быть полноправным участником форума
Нормальное копирование кода
Создавать темы
Скачивать файлы
Доступ к архиву Pawno-Info

[Урок] GUI Анимация

Статус
В этой теме нельзя размещать новые ответы.

Archange

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

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

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

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

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

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

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

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

			MoveImage.Animation = 2

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

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

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

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

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

		//Обновляем позиции и размеры
		MoveImage.Image:setPosition(x, y, false)
		MoveImage.Image:setSize(w, h, false)
		
		//И закрываем цикл
		if h == 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 < 0 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(0, 2)) end)
PHP:
//Ну или по нажатию на само изображение
addEventHandler("onClientGUIClick", MoveImage.Image, function() runAnimation(1) end, false)
Конечный вид:
PHP:
local MoveImage = {}
MoveImage.Image = GuiStaticImage.create(50, 50, 100, 100, "pane.png", false)
MoveImage.Animation = 0

addEventHandler("onClientRender", root, function()

	if MoveImage.Animation == 1 then

		local x, y = MoveImage.Image:getPosition(false)
		local w, h = MoveImage.Image:getSize(false)

		x, y = x+1, y-1
		w, h = w-2, h-2
		
		MoveImage.Image:setPosition(x, y, false)
		MoveImage.Image:setSize(w, h, false)

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

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

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

		MoveImage.Image:setPosition(x, y, false)
		MoveImage.Image:setSize(w, h, false)
		
		if h == 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 < 0 or num > 4 then return false end
	MoveImage.Animation = num
end

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

addEventHandler("onClientGUIClick", MoveImage.Image, function(but) 
	if but == "left" then runAnimation(1) else runAnimation(3) end
end, false)
Автор: Arios Jentu​
 
Последнее редактирование:
Статус
В этой теме нельзя размещать новые ответы.
Сверху Снизу