- 72
- 192
Всем хай, здрасьте, привет и здарова.
Пока я работаю над луа лаунчером под GTA SA: Definitive Edition, хочу запостить некоторый сниппет, который вы можете юзать везде, где сможете получить FPS.
Суть данного скрипта заключается в удобном использовании анимаций, которые смогут сделать ваш скрипт более красивым и плавным. Перейдем к делу.
В конструкторе объекта анимаций есть 2 параметра: длительность и тип анимации.
Длительность - скорость, с которой анимация завершит свой полный цикл. Стоит выставлять значение не больше единицы, т.к. она становится слишком долгой.
Тип анимации - говорит сам за себя.
Я сделал всего 3 типа анимаций:
ANIMATION_TYPE_DEFAULT - обычный тип анимаций.
ANIMATION_TYPE_ONCE - анимация проигрывается всего один раз после апдейта ( обновления ) объекта
ANIMATION_TYPE_STEP - тот же тип, что и ANIMATION_TYPE_DEFAULT, только при окончании цикла анимации он сбросится к нулю.
Создавать объект анимации нужно вне рендер-цикла. К примеру есть какой то эвент render, который вызывается каждый фрейм, делаем так:
Далее, в самом render эвенте вам нужно обновить эту анимацию, но только при условии, что второй параметр ( animation_type ) не равен animation.type.ANIMATION_TYPE_ONCE.
Как это делается, приведу простой пример:
Теперь, когда локальный игрок жив, то цвет квадратика, располагающегося по координатам ( 250, 250 ) и с шириной ( 100, 100 ) будет белым, если же он умрет - цвет будет плавно изменяться на черный.
Теперь расскажу про ANIMATION_TYPE_ONCE
Теперь же, при первом запуске скрипта цвет квадратика, расположенного по тем же координатам, будет плавно изменен на белый и останется таким до следующего перезапуска.
Анимировать можно абсолютно любые значения, для этого есть функция self:get(), которая возвращает текущую стадию анимации в границах [0, 1], а так же можете использовать любую функцию ease-ингов. Например я использовал easeOutQuint. Полный список можете найти тут: https://easings.net/
src:
Пока я работаю над луа лаунчером под GTA SA: Definitive Edition, хочу запостить некоторый сниппет, который вы можете юзать везде, где сможете получить FPS.
Суть данного скрипта заключается в удобном использовании анимаций, которые смогут сделать ваш скрипт более красивым и плавным. Перейдем к делу.
В конструкторе объекта анимаций есть 2 параметра: длительность и тип анимации.
Длительность - скорость, с которой анимация завершит свой полный цикл. Стоит выставлять значение не больше единицы, т.к. она становится слишком долгой.
Тип анимации - говорит сам за себя.
Я сделал всего 3 типа анимаций:
ANIMATION_TYPE_DEFAULT - обычный тип анимаций.
ANIMATION_TYPE_ONCE - анимация проигрывается всего один раз после апдейта ( обновления ) объекта
ANIMATION_TYPE_STEP - тот же тип, что и ANIMATION_TYPE_DEFAULT, только при окончании цикла анимации он сбросится к нулю.
Создавать объект анимации нужно вне рендер-цикла. К примеру есть какой то эвент render, который вызывается каждый фрейм, делаем так:
Lua:
local my_superior_animation = animation( 0.1, animation.type.ANIMATION_TYPE_DEFAULT ) -- Объект анимации создан
Как это делается, приведу простой пример:
Lua:
local my_superior_animation = animation( 0.1, animation.type.ANIMATION_TYPE_DEFAULT )
events.render( function( current_frame )
local local_player = entity.get_local_player( )
my_superior_animation:update( local_player:is_alive( ) )
local rect_color = my_superior_animation:color( color( 0, 0, 0, 255 ), color( 255, 255, 255, 255 ) )
render.filled_rect( vector( 250, 250 ), vector( 100, 100 ), rect_color )
end )
Теперь расскажу про ANIMATION_TYPE_ONCE
Lua:
local my_superior_animation = animation( 0.1, animation.type.ANIMATION_TYPE_ONCE )
events.render( function( current_frame )
my_superior_animation:update( ) -- Обновление не требует параметра condition
local rect_color = my_superior_animation:color( color( 0, 0, 0, 255 ), color( 255, 255, 255, 255 ) )
render.rect( vector( 250, 250 ), vector( 100, 100 ), rect_color )
end )
Анимировать можно абсолютно любые значения, для этого есть функция self:get(), которая возвращает текущую стадию анимации в границах [0, 1], а так же можете использовать любую функцию ease-ингов. Например я использовал easeOutQuint. Полный список можете найти тут: https://easings.net/
src:
Lua:
local animation = { } do
animation.type = {
ANIMATION_TYPE_ONCE = 1,
ANIMATION_TYPE_DEFAULT = 2,
ANIMATION_TYPE_STEP = 3
}
animation.ease = function( n )
return 1 - math.pow( 1 - n, 5 );
end
animation.new = function( self, duration, animation_type )
local animation = { }
animation.duration = duration;
animation.type = animation_type;
animation.weight = 0.0;
return setmetatable( animation, {
__index = self,
__call = self.update
} );
end
animation.update = function( self, condition )
local condition = condition or false;
--frametime means 1 / fps
local clock = ui.get_frametime( ) / self.duration;
if ( self.animation_type == animation.type.ANIMATION_TYPE_ONCE ) then
self.weight = self.weight + clock;
self.weight = math.clamp( self.weight, 0, 1 );
return;
end
self.weight = self.weight + ( condition and clock or -clock );
if ( self.animation_type == animation.type.ANIMATION_TYPE_STEP ) then
self.weight = math.clamp( self.weight, 0, 1 ) % 1;
return;
end
self.weight = math.clamp( self.weight, 0, 1 );
end
animation.get = function( self )
return self.weight * self.weight * self.weight;
end
animation.value = function( self, from, to )
return from + ( to - from ) * animation.ease( self:get( ) )
end
animation.color = function( self, from, to )
return color(
from.r + ( to.r - from.r ) * animation.ease( self:get( ) ),
from.g + ( to.g - from.g ) * animation.ease( self:get( ) ),
from.b + ( to.b - from.b ) * animation.ease( self:get( ) ),
from.a + ( to.a - from.a ) * animation.ease( self:get( ) )
);
end
animation.vector = function( self, from, to )
return vector(
from.x + ( to.x - from.x ) * animation.ease( self:get( ) ),
from.y + ( to.y - from.y ) * animation.ease( self:get( ) ),
from.z + ( to.z - from.z ) * animation.ease( self:get( ) )
)
end
setmetatable( animation, {
__call = animation.new
} );
end