Плазма на Pixilang 3.0

Pixilang по русски
Post Reply
User avatar
NightRadio
Site Admin
Posts: 3944
Joined: Fri Jan 23, 2004 12:28 am
Location: Ekaterinburg. Russia
Contact:

Плазма на Pixilang 3.0

Post by NightRadio »

Расскажу о некоторых особенностях новой версии на примере эффекта плазмы.

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

В версии 3.0 я добавил специальные функции для генерации и обработки массивов (pixi-контейнеров). Например, функция generator() генерирует 1D или 2D сигнал с указанными параметрами (фаза, амплитуда, дельта фазы, типы волны: синус, быстрый синус, шум). А функция op_ccn() выполняет математическую операцию над несколькими 1D или 2D контейнерами.

Используя вышеописанные функции по следующему алгоритму можно нарисовать плазму. Создаем два 8-битных 2D контейнера. Оба заполняем значениями 8-битного синуса с разными параметрами через generator(). Далее два этих контейнера перемножаем (с последующим делением) при помощи op_ccn(). Результат превращаем в картинку используя функцию replace_values(), которая заменяет 8-битные значения на цвета из палитры. Палитра - это отдельный 1D контейнер с 256 значениями цветов.

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

Code: Select all

start_timer( 0 )

palette = new( 256 )
i = 0 while( i < 128 )
{
    v = i
    v * 2
    palette[ i ] = get_color( v / 8, v, v / 2 )
    i + 1
}

i = 128 while( i < 256 )
{
    v = 256 - i
    v * 2
    palette[ i ] = get_color( v, v / 4, v / 2 )
    i + 1
}

scr = get_screen()
img1 = new( get_xsize( scr ), get_ysize( scr ), INT8 )
img2 = clone( img1 )

while( 1 )
{
    t = get_timer( 0 ) / 1000

    clear()

    generator( OP_SIN8, img1, t, 128, cos( t / 2 ) / 53, cos( t / 4 ) / 44 )
    generator( OP_SIN8, img2, t / 2, 128, sin( t / 3 ) / 50, sin( t / 3 ) / 48 )
    op_ccn( OP_MUL_DIV, img1, img2, 128 )
    generator( OP_SIN8, img2, t / 3, 128, cos( t / 4 ) / 23, sin( t / 5 ) / 88 )
    op_ccn( OP_MUL_DIV, img1, img2, 128 / 2 )
    replace_values( scr, img1, palette )

    ts = ""
    sprintf( ts, "FPS:%u", FPS )
    print( ts, -get_xsize( scr ) / 2 + 8, -get_ysize( scr ) / 2 + 8, WHITE, TOP | LEFT )

    while( get_event() ) { if EVT[ EVT_TYPE ] == EVT_QUIT { halt } }

    frame()
}
В итоге программа более-менее шустро работает даже на стареньком наладоннике.
Post Reply