Адрес: ул. Б. Очаковская 32 Москва Россия
Наши официальные канал и чат в telegram, группа в ВКонтакте

Интерактивный 3D-куб на yabasic: цвета, автономный полет и управление

Настоящий 3D-рендеринг на yabasic! Вращающийся куб с цветами, сортировкой граней, отскоками от стенок и управлением стрелкам

Скачать бесплатные программы для Yabasic на Windows, Linux, MacOS, PlayStation 2
Аватара пользователя
Anton
Site Admin
Сообщения: 261
Зарегистрирован: Чт фев 08, 2024 7:03 pm
Откуда: Москва

Интерактивный 3D-куб на yabasic: цвета, автономный полет и управление

Сообщение Anton »

Интерактивный 3D-куб на yabasic: цвета, автономный полет и управление
Обычно yabasic воспринимают как что-то базовое для текстовых программ, но на нём можно строить вполне серьёзные ретро 3D-сцены 8-)

В этой программе реализован вращающийся 3D-куб, который:
  • Летает сам по себе: он отскакивает от невидимых границ экрана и плавно приближается/удаляется.
  • Имеет два режима: каркасный (Wireframe) и сплошной (Solid) с красивой цветной заливкой граней.
  • Правильно отрисовывает глубину: здесь используется Алгоритм художника (Painter's Algorithm). Программа вычисляет среднюю глубину каждой грани, сортирует их от дальних к ближним и рисует именно в таком порядке. Благодаря этому ближние грани перекрывают дальние, и куб всегда выглядит объёмным.


🎮 Управляется с клавиатуры.
  • Пробел — переключение между каркасом и цветными гранями.
  • Стрелки ← / → — толкнуть куб влево или вправо (меняет скорость полета).
  • Стрелки ↑ / ↓ — принудительно приблизить или отдалить куб.
  • + / - — изменить скорость вращения.
  • Esc — выход (нажимать, когда фокус на окне терминала).
Листинг кода:

Код: Выделить всё

open window 400, 400
clear screen

// Вершины куба (от -1 до 1)
dim vertices(8,3)
vertices(1,1) = -1: vertices(1,2) = -1: vertices(1,3) = -1
vertices(2,1) = 1: vertices(2,2) = -1: vertices(2,3) = -1
vertices(3,1) = 1: vertices(3,2) = 1: vertices(3,3) = -1
vertices(4,1) = -1: vertices(4,2) = 1: vertices(4,3) = -1
vertices(5,1) = -1: vertices(5,2) = -1: vertices(5,3) = 1
vertices(6,1) = 1: vertices(6,2) = -1: vertices(6,3) = 1
vertices(7,1) = 1: vertices(7,2) = 1: vertices(7,3) = 1
vertices(8,1) = -1: vertices(8,2) = 1: vertices(8,3) = 1

// Ребра
dim edges(12,2)
edges(1,1) = 1: edges(1,2) = 2
edges(2,1) = 2: edges(2,2) = 3
edges(3,1) = 3: edges(3,2) = 4
edges(4,1) = 4: edges(4,2) = 1
edges(5,1) = 5: edges(5,2) = 6
edges(6,1) = 6: edges(6,2) = 7
edges(7,1) = 7: edges(7,2) = 8
edges(8,1) = 8: edges(8,2) = 5
edges(9,1) = 1: edges(9,2) = 5
edges(10,1) = 2: edges(10,2) = 6
edges(11,1) = 3: edges(11,2) = 7
edges(12,1) = 4: edges(12,2) = 8

// Грани
dim faces(6,4)
data 1, 2, 3, 4, 6, 7, 8, 5, 1, 5, 8, 4, 2, 3, 7, 6, 1, 2, 6, 5, 4, 3, 7, 8
for f = 1 to 6
    for v = 1 to 4
        read faces(f,v)
    next v
next f

// Цвета
dim colors(6,3)
data 255, 0, 0, 0, 255, 0, 0, 0, 255, 255, 255, 0, 255, 0, 255, 0, 255, 255
for f = 1 to 6
    for c = 1 to 3
        read colors(f,c)
    next c
next f

dim px(8), py(8), pz(8)
dim face_z(6), order(6)

backcolor 0,0,0
color 255,255,255

// Параметры анимации
angle_x = 0.5
angle_y = 0.5
angle_z = 0
speed = 1.0
mode = 1
focal_length = 100

// НОВЫЕ ПАРАМЕТРЫ ДВИЖЕНИЯ
center_x = 200
center_y = 200
zoom_scale = 4000
vel_x = 3.0       // Скорость полета влево/вправо
vel_zoom = 50.0   // Скорость приближения

do
    clear window
    
    angle_x = angle_x + 0.02 * speed
    angle_y = angle_y + 0.03 * speed
    angle_z = angle_z + 0.01 * speed
    
    // ЛОГИКА АВТОДВИЖЕНИЯ
    // Двигаем куб
    center_x = center_x + vel_x
    zoom_scale = zoom_scale + vel_zoom
    
    // Отскок от стенок (учитывая размер куба, примерно 80-100 пикселей)
    if center_x > 280 or center_x < 120 then
        vel_x = -vel_x
    end if
    
    // Отскок по глубине (зум)
    if zoom_scale > 6000 or zoom_scale < 1500 then
        vel_zoom = -vel_zoom
    end if

    // 1. Поворот и проецирование
    for i = 1 to 8
        x = vertices(i,1)
        y = vertices(i,2)
        z = vertices(i,3)
    
        ny = y * cos(angle_x) - z * sin(angle_x)
        nz = y * sin(angle_x) + z * cos(angle_x)
        y = ny : z = nz

        nx = x * cos(angle_y) - z * sin(angle_y)
        nz = x * sin(angle_y) + z * cos(angle_y)
        x = nx : z = nz
        
        nx = x * cos(angle_z) - y * sin(angle_z)
        ny = x * sin(angle_z) + y * cos(angle_z)
        x = nx : y = ny
    
        px(i) = zoom_scale * x / (z + focal_length) + center_x
        py(i) = zoom_scale * y / (z + focal_length) + center_y
        pz(i) = z
    next i

    // 2. Отрисовка
    if mode = 1 then
        color 255, 255, 255
        for j = 1 to 12
            v1 = edges(j,1)
            v2 = edges(j,2)
            line px(v1), py(v1) to px(v2), py(v2)
        next j
    else
        for f = 1 to 6
            v1 = faces(f,1)
            v2 = faces(f,2)
            v3 = faces(f,3)
            v4 = faces(f,4)
            face_z(f) = (pz(v1) + pz(v2) + pz(v3) + pz(v4)) / 4
            order(f) = f
        next f
        
        for i = 1 to 5
            for j = i + 1 to 6
                if face_z(order(i)) < face_z(order(j)) then
                    tmp = order(i)
                    order(i) = order(j)
                    order(j) = tmp
                end if
            next j
        next i
        
        for i = 1 to 6
            f = order(i)
            v1 = faces(f,1)
            v2 = faces(f,2)
            v3 = faces(f,3)
            v4 = faces(f,4)
            
            color colors(f,1), colors(f,2), colors(f,3)
            fill triangle px(v1),py(v1) to px(v2),py(v2) to px(v3),py(v3)
            fill triangle px(v1),py(v1) to px(v3),py(v3) to px(v4),py(v4)
            
            color 0,0,0
            line px(v1),py(v1) to px(v2),py(v2)
            line px(v2),py(v2) to px(v3),py(v3)
            line px(v3),py(v3) to px(v4),py(v4)
            line px(v4),py(v4) to px(v1),py(v1)
        next i
    end if

    // 3. Интерфейс
    color 255, 255, 255
    if mode = 1 then
        text 10, 380, "Mode: Wireframe"
    else
        text 10, 380, "Mode: Solid Colors"
    end if
    text 10, 365, "Speed: " + str$(speed) + " | X-Vel: " + str$(vel_x)
    text 10, 350, "Keys: SPACE (mode), +/- (spin), Arrows (push/zoom), ESC"

    pause 0.02
    
    // 4. Обработка клавиш
    k$ = inkey$(0.001)
    if k$ = "esc" or k$ = chr$(27) then
        break
    elseif k$ = " " or k$ = "space" then
        mode = 3 - mode
    elseif k$ = "+" or k$ = "=" then
        speed = speed + 0.2
    elseif k$ = "-" then
        speed = speed - 0.2
    elseif k$ = "left" then
        // Толкаем влево
        vel_x = vel_x - 2.0
    elseif k$ = "right" then
        // Толкаем вправо
        vel_x = vel_x + 2.0
    elseif k$ = "up" then
        // Приближаем
        zoom_scale = zoom_scale + 500
    elseif k$ = "down" then
        // Отдаляем
        zoom_scale = zoom_scale - 500
    end if
    
    // Ограничители, чтобы не улетел в космос
    if speed < 0.2 speed = 0.2
    if speed > 5.0 speed = 5.0
    if vel_x > 12.0 vel_x = 12.0
    if vel_x < -12.0 vel_x = -12.0
    if zoom_scale < 500 zoom_scale = 500
    if zoom_scale > 8000 zoom_scale = 8000
loop

close window
end
1.png
2.png
У вас нет необходимых прав для просмотра вложений в этом сообщении.