灵符lingfu

soul-symphony-ling

↓ 0 downloads

Soul Symphony — Ling Edition. A spiritual 3D adventure in the soul realm: collect the letters of the world-song, clear the monster lattice, and duel in the arcade arena. Wind Waker-style toon renderer with volumetric light pools, SSAO, bloom and oil-slick tilt-shift — all ling-lang vectors.

Keywords game, 3d, toon, music, soul-symphony
lingfu install soul-symphony-ling
AuthorsLing Lin <taellinglin@gmail.com>
READMECode / FilesVersionsDependency GraphDependentsSecurityBuildsSettings

Code / Files (1947)

game/title_midi.ling
# ════════════════════════════════════════════════════════════════════════════
# title_midi.ling — MIDI-Driven Wave Title Screen (Marionette Style)
# ════════════════════════════════════════════════════════════════════════════
# Features:
# - "SOUL SYMPHONY 2" displayed as waving letters at top of screen
# - Each letter moves in slow wave motion (up/down)
# - Letters bank/rotate subtly like marionettes on strings
# - Multi-language support (changes with language setting)
# - 2D liquid ink background (no mixing)
# - MIDI-synced color pulses

ใช้ "../font/English3D"

# ── Title Text Data (per language) ───────────────────────────────────────────
# Indices: a=0..z=25, -1=space, 28=number "2"
bind titleEN = [18,14,20,11,-1,18,24,12,15,7,14,13,24,-1,28]  # SOUL SYMPHONY 2
bind titleLength = 15

# ── Wave Motion Parameters ───────────────────────────────────────────────────
bind WAVE_SPEED = 0.4          # How fast the wave travels
bind WAVE_HEIGHT = 2.5         # Vertical amplitude of wave
bind WAVE_LENGTH = 3.0         # Distance between wave peaks
bind LETTER_SPACING = 2.8      # Horizontal space between letters
bind BASE_Y = -8.0             # Base Y position (top of screen)
bind BASE_Z = -35.0            # Z depth
bind BANK_AMOUNT = 15.0        # Rotation banking angle (degrees)

# ── Liquid Background ────────────────────────────────────────────────────────
bind inkBG = 0
bind bgInit = 0
bind currentPulse = 0.0

ฟังก์ชัน initBackground() {
    ถ้า bgInit == 0 {
        bind inkBG = liquid_new(96.0, 96.0)
        สีของเหลว(inkBG, 220, 60, 120, 40, 100, 220)
        bind bgInit = 1
    }
}

ฟังก์ชัน drawBackground(t, pulse, beatHit) {
    liquid_step(inkBG, 0.016)
    # ambient drifting ink splats
    bind splatInterval = 0.5
    bind splatPhase = t - floor(t / splatInterval) * splatInterval
    ถ้า splatPhase < 0.05 {
        bind sx = (ไซน์(t * 0.6) * 0.5 + 0.5) * 88.0 + 4.0
        bind sy = (โคไซน์(t * 0.4) * 0.5 + 0.5) * 88.0 + 4.0
        bind kind = floor(t / splatInterval) - floor(floor(t / splatInterval) / 2.0) * 2.0
        liquid_splat(inkBG, sx, sy, kind, 0.85, 1.6)
    }
    # MIDI beat -> ink burst (mirrored splats ripple across the canvas on each note)
    ถ้า beatHit > 0.5 {
        bind ba = t * 1.7
        bind bx = โคไซน์(ba) * 34.0 + 48.0
        bind by = ไซน์(ba * 1.3) * 34.0 + 48.0
        bind bkind = floor(t * 7.0) - floor(floor(t * 7.0) / 2.0) * 2.0
        liquid_splat(inkBG, bx, by, bkind, 1.2, 2.6)
        liquid_splat(inkBG, 96.0 - bx, 96.0 - by, 1.0 - bkind, 1.0, 2.2)
    }
    # ink surface "breathes" with the music; un-flatten so the metaball shades (3D wet ink)
    bind ex = 64.0 + pulse * 9.0
    bind ey = 50.0 + pulse * 7.0
    set_flat_shade(0.0)
    liquid_draw_surface(inkBG, 0.0, 0.0, 2.0, -95.0, ex, ey)
    set_flat_shade(1.0)
}

ฟังก์ชัน drawWavingTitle(t, lang, pulse) {
    bind titleText = titleEN
    bind totalWidth = (titleLength - 1) * LETTER_SPACING
    bind startX = 0.0 - totalWidth * 0.5

    # ── pass 1: liquid-ink glow aura behind each letter (additive, blooms on beats) ──
    โหมดผสม(1)
    bind i = 0
    ขณะที่ i < titleLength {
        bind charIdx = list_get(titleText, i)
        ถ้า charIdx >= 0 {
            bind lx = startX + i * LETTER_SPACING
            bind wavePhase = (i * WAVE_LENGTH) + (t * WAVE_SPEED)
            bind ly = BASE_Y + ไซน์(wavePhase) * WAVE_HEIGHT
            bind lz = BASE_Z + ไซน์(t * 0.7 + i * 0.5) * 2.0
            bind beat = pulse * (0.5 + 0.5 * ไซน์(i * 0.8 - t * 4.0))
            bind cp = (i * 0.13) + (t * 0.22)
            bind ar = floor((ไซน์(cp * 6.28) * 0.5 + 0.5) * 180 + 60)
            bind ag = floor((ไซน์(cp * 6.28 + 2.09) * 0.5 + 0.5) * 180 + 60)
            bind ab = floor((ไซน์(cp * 6.28 + 4.19) * 0.5 + 0.5) * 180 + 60)
            อนุภาคทรงกลม(lx, ly, lz - 1.0, 1.4 + beat * 2.0, floor(10 + beat * 16), t * 1.3 + i, ar, ag, ab)
        }
        bind i = i + 1
    }
    flush_3d()

    # ── pass 2: 3D extruded letters (wave + marionette bank + beat-scale + ROYGBIV) ──
    โหมดผสม(0)
    bind i = 0
    ขณะที่ i < titleLength {
        bind charIdx = list_get(titleText, i)
        ถ้า charIdx >= 0 {
            bind lx = startX + i * LETTER_SPACING
            bind wavePhase = (i * WAVE_LENGTH) + (t * WAVE_SPEED)
            bind ly = BASE_Y + ไซน์(wavePhase) * WAVE_HEIGHT
            bind lz = BASE_Z + ไซน์(t * 0.7 + i * 0.5) * 2.0
            bind beat = pulse * (0.5 + 0.5 * ไซน์(i * 0.8 - t * 4.0))
            bind pitch = โคไซน์(wavePhase) * BANK_AMOUNT * 0.01745
            bind roll = ไซน์(wavePhase + 1.5708) * BANK_AMOUNT * 0.5 * 0.01745
            bind yaw = ไซน์(t * 0.3 + i * 0.5) * 6.0 * 0.01745
            bind cp = (i * 0.13) + (t * 0.22)
            bind boost = 1.0 + beat * 0.9 + pulse * 0.25
            bind r = floor((ไซน์(cp * 6.28) * 0.5 + 0.5) * 150 + 100)
            bind g = floor((ไซน์(cp * 6.28 + 2.09) * 0.5 + 0.5) * 150 + 100)
            bind b = floor((ไซน์(cp * 6.28 + 4.19) * 0.5 + 0.5) * 150 + 100)
            bind r = floor(r * boost);  ถ้า r > 255 { bind r = 255 }
            bind g = floor(g * boost);  ถ้า g > 255 { bind g = 255 }
            bind b = floor(b * boost);  ถ้า b > 255 { bind b = 255 }
            สีดินสอ(r, g, b)
            bind scale = 1.8 + ไซน์(wavePhase * 0.5) * 0.15 + beat * 0.6
            bind totalRot = yaw + pitch + roll
            bind cosR = โคไซน์(totalRot);  bind sinR = ไซน์(totalRot)
            bind rx = cosR;  bind ry = sinR * 0.3;  bind rz = 0.0
            bind ux = 0.0 - sinR * 0.3;  bind uy = cosR;  bind uz = 0.0
            วาดอักขระEnglish3D(charIdx, lx, ly, lz, rx, ry, rz, ux, uy, uz, scale)
        }
        bind i = i + 1
    }
}

ฟังก์ชัน runMIDITitle(t, frame, midiClockOn, musicOn, noteIndex, noteTimes, noteCount, musicPosition, musicLength, mainTrack, volumeBGM, language) {
    initBackground()
    bind skyR = floor(8 + ไซน์(t * 0.06) * 6)
    bind skyG = floor(12 + ไซน์(t * 0.09 + 1.0) * 8)
    bind skyB = floor(28 + ไซน์(t * 0.07 + 2.0) * 12)
    เติม(skyR, skyG, skyB)
    # ── MIDI sync: scan note onsets vs song position -> pulse + beatHit (always on) ──
    bind beatHit = 0.0
    ถ้า musicLength > 1.0 {
        ถ้า musicPosition >= musicLength - 0.5 {
            ค้นหาเพลง(0)
            ถ้า musicOn == 1 { เล่นเพลง(mainTrack) }
            bind noteIndex = 0
        }
    }
    bind tpos = musicPosition
    ถ้า tpos < 0.05 { bind noteIndex = 0 }
    bind scanning = 1
    ขณะที่ scanning == 1 {
        ถ้า noteIndex >= noteCount {
            bind scanning = 0
        }
        มิฉะนั้น {
            bind noteTime = list_get(noteTimes, noteIndex)
            ถ้า noteTime <= tpos {
                bind currentPulse = 1.0
                bind beatHit = 1.0
                bind noteIndex = noteIndex + 1
            }
            มิฉะนั้น {
                bind scanning = 0
            }
        }
    }
    bind currentPulse = currentPulse * 0.86

    # ── camera: slow orbit + gentle push-in on each beat ──
    bind radius = 18.0 - currentPulse * 1.6
    bind camX = ไซน์(frame * 0.002) * radius
    bind camZ = 0.0 - โคไซน์(frame * 0.002) * radius
    bind camY = 5.0 + ไซน์(frame * 0.0015) * 3.0
    ตั้งกล้องมอง(camX, camY, camZ, 0.0, -6.0, 0.0)
    ตั้งระยะห่าง(2.8 + currentPulse * 0.12)
    ตั้งแสงรอบข้าง(0.45)
    ล้างแสง()
    เพิ่มแสง(12.0, -5.0, 8.0, 1.0, 0.9, 0.8, 2.8, 32.0)
    เพิ่มแสง(-8.0, -8.0, -10.0, 0.8, 0.85, 1.0, 2.2, 26.0)

    drawBackground(t, currentPulse, beatHit)
    drawWavingTitle(t, language, currentPulse)
    flush_3d()
    ตั้งกล้องมอง(0.0, 0.0, -22.0, 0.0, 0.0, 0.0)
    ตั้งระยะห่าง(2.8)
    โหมดผสม(1)
    bind hintPulse = (ไซน์(t * 3.0) * 0.5 + 0.5)
    สีดินสอ(floor(180 * hintPulse + 75), floor(200 * hintPulse + 55), floor(240 * hintPulse + 15))
    วาดสตริง("press enter to start", 0.0, 8.8, 0.0, 0.58, 1)
    flush_3d()
    โหมดผสม(0)
    แสดงผล()
    คืน noteIndex
}

← Back to index