Вверх ↑
Ответов: 131
Mafia
Консильери
#1: 2020-10-19 00:27:32 ЛС | профиль | цитата
Обновление принесло нам возможность менять размеры вокселей, из которых теперь получается красивый снегопад, в дополнение к ёлочке) Новый Год не за горами)

Снежинки простенькие

function init(){
    VOXELS_COUNT = 5000 // количество вокселей
    LIMIT_SPEED  = 0    // 0 - максимальная скорость, больше - медленнее
    SCALE_MIN    = 0.1  // минимальный размер
    SCALE_MAX    = 0.3  // максимальный размер
    BRIGHTNESS   = 255  // яркость снежинки от 0 до 255    
    // размеры области отображения
    X_MIN = -64 // влево от -64 до 79
    X_MAX =  79 // вправо от -64 до 79
    Z_MIN = -64 // назад от -64 до 79
    Z_MAX =  79 // вперёд от -64 до 79
    Y_MIN = -80 // вниз от -80 до 63
    Y_MAX =  63 // вверх от -80 до 63
    // смещение снежинки каждый такт
    OFFSET_X =  0 // влево-вправо
    OFFSET_Z =  0 // назад-вперёд
    OFFSET_Y = -0.2 // вверх-вниз
    // массив для вокселей
    voxel = []
    // инициализация вокселей
    for( i = 0 ; i ‹ VOXELS_COUNT ; i++ ){
        // базовые расположение и размер
        x = rc( X_MIN , X_MAX )
        y = rc( Y_MIN , Y_MAX )
        z = rc( Z_MIN , Z_MAX )
        s = rc( SCALE_MIN , SCALE_MAX )
        // создание вокселя и задание параметров
        t = display.voxel( x , y , z , color.rgb( BRIGHTNESS , BRIGHTNESS , BRIGHTNESS ) )
        t.scale = s
        // добавление вокселя в массив
        voxel.push( t )
    }
    // переменная для реализации торможения
    last_time = 0
}

function rc( min , max ){
    // случайное число в заданных пределах
    return min + Math.random() * ( max - min )
}

function update( time_now ){
    // торможение выполнения
    if( time_now - last_time ‹ LIMIT_SPEED ) return
    last_time = time_now
    // изменение параметров вокселей
    for( i = 0 ; i ‹ VOXELS_COUNT ; i++ ){
        // смещение относительно текущего расположения
        x = OFFSET_X
        y = OFFSET_Y
        z = OFFSET_Z
        voxel[i].offset( x , y , z )
        // отражение при выходе за пределы отображения
        if( voxel[i].cursorY ‹ Y_MIN ) voxel[i].cursorY = Y_MAX
    }
}

Снежинки со смещениями, но больше нагружающие комп

function init(){
    VOXELS_COUNT = 5000 // количество вокселей
    LIMIT_SPEED  = 0    // 0 - максимальная скорость, больше - медленнее
    SCALE_MIN    = 0.1  // минимальный размер
    SCALE_MAX    = 0.3  // максимальный размер
    BRIGHTNESS   = 255  // яркость снежинки от 0 до 255    
    // размеры области отображения
    X_MIN = -64 // влево от -64 до 79
    X_MAX =  79 // вправо от -64 до 79
    Z_MIN = -64 // назад от -64 до 79
    Z_MAX =  79 // вперёд от -64 до 79
    Y_MIN = -80 // вниз от -80 до 63
    Y_MAX =  63 // вверх от -80 до 63    
    // смещение снежинки каждый такт
    OFFSET_X_MIN = -0.1 // минимум влево-вправо
    OFFSET_X_MAX =  0.1 // максимум  влево-вправо
    OFFSET_Z_MIN = -0.1 // минимум назад-вперёд
    OFFSET_Z_MAX =  0.1 // максимум назад-вперёд
    OFFSET_Y_MIN = -0.1 // минимум вверх-вниз
    OFFSET_Y_MAX = -0.5 // максимум вверх-вниз    
    // массив для вокселей
    voxel = []
    // инициализация вокселей
    for( i = 0 ; i ‹ VOXELS_COUNT ; i++ ){
        // базовые расположение и размер
        x = rc( X_MIN , X_MAX )
        y = rc( Y_MIN , Y_MAX )
        z = rc( Z_MIN , Z_MAX )
        s = rc( SCALE_MIN , SCALE_MAX )
        // создание вокселя и задание параметров
        t = display.voxel( x , y , z , color.rgb( BRIGHTNESS , BRIGHTNESS , BRIGHTNESS ) )
        t.scale = s
        // добавление вокселя в массив
        voxel.push( t )
    }
    // переменная для реализации торможения
    last_time = 0
}

function rc( min , max ){
    // случайное число в заданных пределах
    return min + Math.random() * ( max - min )
}

function update( time_now ){
    // торможение выполнения
    if( time_now - last_time ‹ LIMIT_SPEED ) return
    last_time = time_now
    // изменение параметров вокселей
    for( i = 0 ; i ‹ VOXELS_COUNT ; i++ ){
        // смещение относительно текущего расположения
        x = rc( OFFSET_X_MIN , OFFSET_X_MAX )
        y = rc( OFFSET_Y_MIN , OFFSET_Y_MAX )
        z = rc( OFFSET_Z_MIN , OFFSET_Z_MAX )
        voxel[i].offset( x , y , z )
        // отражение при выходе за пределы отображения
        if( voxel[i].cursorY ‹ Y_MIN ) voxel[i].cursorY = Y_MAX
        if( voxel[i].cursorY › Y_MAX ) voxel[i].cursorY = Y_MIN
        if( voxel[i].cursorX ‹ X_MIN ) voxel[i].cursorX = X_MAX
        if( voxel[i].cursorX › X_MAX ) voxel[i].cursorX = X_MIN
        if( voxel[i].cursorZ ‹ Z_MIN ) voxel[i].cursorZ = Z_MAX
        if( voxel[i].cursorZ › Z_MAX ) voxel[i].cursorZ = Z_MIN
    }
}

Дождик, чтобы вспоминать зимой другие времена года

function init(){
    VOXELS_COUNT    = 5000 // количество частиц от 1 до 5000
    VOXELS_PER_DROP = 5    // частиц на каплю
    LIMIT_SPEED     = 0    // 0 - максимальная скорость, больше - медленнее
    SCALE           = 0.1  // размер капли
    BRIGHTNESS      = 200  // яркость капли от 0 до 255
    // размеры области отображения
    X_MIN = -64 // влево от -64 до 79
    X_MAX =  79 // вправо от -64 до 79
    Z_MIN = -64 // назад от -64 до 79
    Z_MAX =  79 // вперёд от -64 до 79
    Y_MIN = -80 // вниз от -80 до 63
    Y_MAX =  63 // вверх от -80 до 63
    // смещение капли каждый такт
    OFFSET_X =  0 // влево-вправо
    OFFSET_Z =  0 // назад-вперёд
    OFFSET_Y = -1.5 // вверх-вниз
    // массив для вокселей
    voxel = []
    // количество капель
    DROPS_COUNT = Math.floor( VOXELS_COUNT / VOXELS_PER_DROP )
    // инициализация вокселей
    for( i = 0 ; i ‹ DROPS_COUNT ; i++ ){
        // базовые расположение и размер
        x = rc( X_MIN , X_MAX )
        y = rc( Y_MIN , Y_MAX )
        z = rc( Z_MIN , Z_MAX )
        s = SCALE
        // создание капли из частиц
        for( p = 0 ; p ‹ VOXELS_PER_DROP ; p++ ){
            t = display.voxel( x , y + SCALE * p , z , color.rgb( 0 , 0 , BRIGHTNESS ) )
            t.scale = s
            voxel.push( t )
        }
    }
    // переменная для реализации торможения
    last_time = 0
}

function rc( min , max ){
    // случайное число в заданных пределах
    return min + Math.random() * ( max - min )
}

function update( time_now ){
    // торможение выполнения
    if( time_now - last_time ‹ LIMIT_SPEED ) return
    last_time = time_now
    // изменение параметров вокселей
    for( i = 0 ; i ‹ DROPS_COUNT * VOXELS_PER_DROP ; i++ ){
        // смещение относительно текущего расположения
        x = OFFSET_X
        y = OFFSET_Y
        z = OFFSET_Z
        voxel[i].offset( x , y , z )
        // отражение при выходе за пределы отображения
        if( voxel[i].cursorY ‹ Y_MIN ) voxel[i].cursorY = Y_MAX - Math.abs(voxel[i].cursorY - Y_MIN)
        if( voxel[i].cursorY › Y_MAX ) voxel[i].cursorY = Y_MIN + Math.abs(voxel[i].cursorY - Y_MAX)
        if( voxel[i].cursorX ‹ X_MIN ) voxel[i].cursorX = X_MAX - Math.abs(voxel[i].cursorX - X_MIN)
        if( voxel[i].cursorX › X_MAX ) voxel[i].cursorX = X_MIN + Math.abs(voxel[i].cursorX - X_MAX)
        if( voxel[i].cursorZ ‹ Z_MIN ) voxel[i].cursorZ = Z_MAX - Math.abs(voxel[i].cursorZ - Z_MIN)
        if( voxel[i].cursorZ › Z_MAX ) voxel[i].cursorZ = Z_MIN + Math.abs(voxel[i].cursorZ - Z_MAX)
    }
}

Глиттер (по просьбе, добавлено 30 октября 2024)

function init(){
    VOXELS_COUNT = 5000 // количество вокселей
    LIMIT_SPEED  = 0    // 0 - максимальная скорость, больше - медленнее
    FADE_SPEED = 0.01    // скорость затухания
    SCALE_MIN = 0.1  // минимальный размер
    SCALE_MAX = 0.3  // максимальный размер
    BRIGHTNESS_MIN = 255  // минимальная яркость глиттера от 0 до 255
    BRIGHTNESS_MAX = 255  // максимальная яркость глиттера от 0 до 255
    // размеры области отображения
    X_MIN = -64 // влево от -64 до 79
    X_MAX =  79 // вправо от -64 до 79
    Z_MIN = -64 // назад от -64 до 79
    Z_MAX =  79 // вперёд от -64 до 79
    Y_MIN = -80 +16 +16 +16 +16 // вниз от -80 до 63
    Y_MAX =  63 -16 -16 // вверх от -80 до 63
    // смещение глиттера каждый такт
    OFFSET_X =  0 // влево-вправо
    OFFSET_Z =  0 // назад-вперёд
    OFFSET_Y = -0.2 // вверх-вниз
    // массив для вокселей
    voxel = []
    voxel_scale = []
    // инициализация вокселей
    for( i = 0 ; i < VOXELS_COUNT ; i++ ){
        // базовые расположение и размер
        x = rc( X_MIN , X_MAX )
        y = rc( Y_MIN , Y_MAX )
        z = rc( Z_MIN , Z_MAX )
        scale = rc( SCALE_MIN , SCALE_MAX )
        // создание вокселя и задание параметров
		brightness = rc(BRIGHTNESS_MIN, BRIGHTNESS_MAX)
        t = display.voxel( x , y , z , color.rgb( brightness , brightness , brightness ) )
        t.scale = scale
        // добавление вокселя в массив
        voxel.push( t )
        voxel_scale.push( scale )
    }
    // переменная для реализации торможения
    last_time = 0
}

function rc( min , max ){
    // случайное число в заданных пределах
    return min + Math.random() * ( max - min )
}

function update( time_now ){
    // торможение выполнения
    if( time_now - last_time < LIMIT_SPEED ) return
    last_time = time_now
    // изменение параметров вокселей
    for( i = 0 ; i < VOXELS_COUNT ; i++ ){
		// затухание
		voxel_scale[i] -= FADE_SPEED
        // смена позиции после затухания
		if( voxel_scale[i] <= 0 ){
			x = rc(X_MIN, X_MAX)
			y = rc(Y_MIN, Y_MAX)
			z = rc(Z_MIN, Z_MAX)
			scale = rc( SCALE_MIN , SCALE_MAX )
			voxel_scale[i] = scale
			brightness = rc(BRIGHTNESS_MIN, BRIGHTNESS_MAX)
			voxel[i].color = color.rgb( brightness , brightness , brightness )
			voxel[i].move( x , y , z )
		}
		voxel[i].scale = voxel_scale[i]
    }
}

Торнадо (по просьбе, добавлено 30 октября 2024)

function init(){
    VOXELS_COUNT  = 5000   // количество вокселей
    CIRCLES_COUNT = 30     // количество кругов
    DISPERSION    = 0.3    // радиус разброса в круге
    CHANGE_CHANCE = 0.01   // шанс смены цвета вокселя
    DIRECTION     = -1      // направление вращения: 0 - оба, 1 - по часовой, -1 - против часовой
    HEIGHT        = 31+16     // высота ёлки, 31 = 2 куба
    CIRCLE_SPEED  = 0.0020 // шаг вращения, больше - быстрее
    MIN_R         = 8    // радиус верхнего круга
    MAX_R         = 1      // радиус нижнего круга
    MIN_CUBE      = 0.1    // минимальный размер вокселя
    MAX_CUBE      = 0.5    // максимальный размер вокселя
    POS_X         = 7.5    // влево-вправо
    POS_Z         = 7.5    // назад-вперёд
    POS_Y         = 0      // вверх-вниз
    LIMIT_SPEED   = 0      // торможение: 0 - максимальная скорость, больше - медленнее
    
    // параметры для старой ёлочки
    //VOXELS_COUNT = 240
    //CIRCLES_COUNT = 16
    //DISPERSION = 0
    //CIRCLE_SPEED  = 0.0002
    //MIN_R = 0
    //MAX_R = 8
    //MIN_CUBE = 1
    //MAX_CUBE = 1
    
    // цвета
    c0 = color.rgb( 000 , 000 , 000 )
    c1 = color.rgb( 255 , 0 , 0 )
    c2 = color.rgb( 40 , 40 , 40 )
    c3 = color.rgb( 80 , 80 , 80 )
    c4 = color.rgb( 120 , 120 , 120 )
    c5 = color.rgb( 160 , 160 , 160 )
    c6 = color.rgb( 200 , 200 , 200 )
    // шансы цветов
    colors = [
    c0 , c0 , c0 , c0 , c0 , c0 ,
    c0 , c0 , c0 , c0 , c0 , c0 ,
    c1 , c2 , c3 , c4 , c5 , c6 ]
    // массив кругов
    circles = []
    // подсчёт общей длины кругов
    ALL_CIRCLES_LENGTH = 0    
    for( i = 0 ; i < CIRCLES_COUNT ; i++ ){
        radius = MIN_R + ( MAX_R - MIN_R ) / CIRCLES_COUNT * i
        ALL_CIRCLES_LENGTH += 2 * Math.PI * radius
    }
    // вокселей на единицу расстояния, на основании длины кругов и лимита вокселей
    VOXELS_PER_LENGTH = VOXELS_COUNT / ALL_CIRCLES_LENGTH
    // задание параметров кругов
    for( i = 0 ; i < CIRCLES_COUNT ; i++ ){
        radius = MIN_R + ( MAX_R - MIN_R ) / CIRCLES_COUNT * i
        length = 2 * Math.PI * radius
        height = HEIGHT - HEIGHT / ( CIRCLES_COUNT - 1 ) * i
        number = 1 + Math.floor( length * VOXELS_PER_LENGTH )
        speed  = CIRCLE_SPEED + 0.01 / ( CIRCLES_COUNT - i )
        speed *= DIRECTION == 0 ? ( i % 2 ? 1 : -1 ) : DIRECTION
        add_circle( radius , height , number , speed )
    }
    // переменная для реализации торможения
    last_time = 0
	// переменная ось
	ox = 0
	oy = 0
	oa = 0
	oas = 0.01
	od = 10
}

function add_circle( radius, height, number, speed ){
    // структура с параметрами круга
    circle = {
        radius : radius ,
        speed  : speed ,
        voxel : [] ,
        voxel_angle : 0,
        voxel_radius : [],
		curve_angle : circles.length,
		curve_angle_step : 0.02,
		curve_distance : 1
    }
    // угол между вокселями
    circle.voxel_angle = 360 / number * ( Math.PI / 180 )
    // наполнение круга вокселями
    for( c = 0 ; c < number ; c++ ){
        voxel = display.voxel( POS_X , POS_Y + rc( height - DISPERSION , height + DISPERSION ) , POS_Z , c0 )
        voxel.scale = rc( MIN_CUBE , MAX_CUBE )
        circle.voxel.push( voxel )
        circle.voxel_radius.push( rc( radius - DISPERSION , radius + DISPERSION ) )
    }
    // добавление круга
    circles.push( circle )
}

function rc( min , max ){
    // случайное число в заданных пределах
    return min + Math.random() * ( max - min )
}

function update( time_now ){
    // торможение выполнения
    if( time_now - last_time < LIMIT_SPEED ) return
    last_time = time_now
	// отступы для оси
	oa += oas
	oa %= 360
	ox = ( Math.cos( oa ) - Math.sin( oa ) ) * od
	oy = ( Math.sin( oa ) + Math.cos( oa ) ) * od
    // проход по кругам
    for( c = 0 ; c < circles.length ; c++ ){
        circle = circles[c]
		// отступы для кривой
		circle.curve_angle += circle.curve_angle_step
		circle.curve_angle %= 360
		sx = ( Math.cos( circle.curve_angle ) - Math.sin( circle.curve_angle ) ) * circle.curve_distance
		sz = ( Math.sin( circle.curve_angle ) + Math.cos( circle.curve_angle ) ) * circle.curve_distance
        // обновление позиций вокселей
        for( v = 0 ; v < circle.voxel.length ; v++ ){
            voxel = circle.voxel[v]
            // актуальный угол на основании времени
            angle = ( circle.voxel_angle * v + time_now * circle.speed ) % 360
            // множители угла для отступа на радиус
            x = Math.cos( angle ) - Math.sin( angle )
            z = Math.sin( angle ) + Math.cos( angle )
            // смена позиции
            voxel.cursorX = POS_X + x * circle.voxel_radius[v] + sx + ox
            voxel.cursorZ = POS_Z + z * circle.voxel_radius[v] + sz + oy
            // смена цвета
            if( Math.random() < CHANGE_CHANCE ){
                voxel.color = colors[ Math.floor( Math.random() * colors.length ) ]
            }
        }
    }
}

Выбранный код вставляется в блокнот, используемый в MCGL9, который затем кладётся в проектор. Ещё вам наверняка пригодятся способы решения проблем, описанные в теме о ёлочке.

карма: -1
25
Голосовали:apl, MaJIuHa, _Karnelius_, -BROD9GA-, helpbringer, Moonlight_420, RouteVO, miratvorech, calm, BlooDStoune, miroschka, Miracle-, OTBETCTBEHHblN, DeMoNo5060, 6Sixty_nine9, Nick_Fury, CodARM, zelovo37, Chekter, lambrusco, Chydovishe, My_Adidas, tauras, Rimuru_Tempest, Vano4ok, OSNOVA_BOGA, XBocT
Редактировалось 2 раз(а), последний 2024-10-30 21:35:39