KCDDP ADV综合创作站 » 技术发布区 » [原创]LRC歌词同步显示插件


2006-12-20 12:34 Miliardo
[原创]LRC歌词同步显示插件

嗯……使用方法待补完……
这个应该在ED和插曲的时候很有用处的……

[quote]
0.92更新:

通过tf.lyric_count可以得到现在执行的行数,通过tf.lyric_time可以得到现在执行到的时间,
此外,使用@waittrig name="lyric"可以等待下一句歌词被显示。

通过访问(Array) global.lyric_object.lrctimes和(Array) global.lyric_object.lrcwords可以得到每句歌词的时间和内容。

这些功能可以用于控制某些需要跟随歌曲节奏安排的场景,例如ED画面。[/quote]

下一次技术挑战的目标应该就是坦克大战了……Orz

[code]
;LRC Lyric Displaying Plugin/LRC歌词同步显示插件
;A Part of Project.FairyTale
;Version 0.92-beta(2006-12)
;Author:Miliardo (Whitefang Studio)
;Copyright 2001-2006 Whitefang Studio, All Right Reserved

@if exp="typeof(global.lyric_object) == 'undefined'"
@iscript

class LyricPlugin extends KAGPlugin
{
        var fore, back;
        var timer;
        var window;
        var dk,times;
        var lrcwords,lrctimes;
        var temp,stime;
        var l,flg;
        var t,mode;
        var ctime,lc;
        var width,height;
        var align="left";
        var delay=0;
        function LyricPlugin(window)
        {
               
                super.KAGPlugin();
                fore = new Layer(window, window.fore.base);
                back = new Layer(window, window.back.base);
                width=window.fore.base.width;
                height=window.fore.base.height;       
                fore.setImagePos(0,0);
                fore.setImageSize(width,height);
                back.setImagePos(0,0);
                fore.setImageSize(width,height);
                fore.absolute = back.absolute = 2000000-2;
                       
                fore.hitType = back.hitType = htMask;
                fore.hitThreshold = back.hitThreshold = 256;
                       
                fore.setSizeToImageSize();
                fore.fillRect(0, 0, fore.imageWidth, fore.imageHeight, 0);

                back.assignImages(fore);
                back.setSizeToImageSize();
                fore.visible = back.visible = fore.seen = back.seen = true;
                fore.font.face = back.font.face = "Arial";
                fore.font.bold = back.font.bold = true;
//                back.font.mapPrerenderedFont("SH17.tft");
//                fore.font.mapPrerenderedFont("SH17.tft");
                fore.font.height = back.font.height = 20;
                timer = new Timer(onTimer, '');
                timer.enabled=false;
                this.window = window;
        }

        function finalize()
        {
                invalidate fore;
                invalidate back;
                invalidate timer;
                super.finalize(...);
        }
       
        function LoadLyric(elm)
        {
                temp = new Array();
                lrctimes = new Array();
                lrcwords = new Array();
                var tm = new Array();
                temp.load(elm.storage,'');
                for(var i=0;i<temp.count;i++)
                {
                        tm.split("\[*:*.*\]",temp[i],,true);
                                for(var j=0;j<3;j++)
                                {
                                        if(tm[j]!=(void))
                                        {
                                                if(tm[j].charAt(0) == "0")
                                                        tm[j] = tm[j].charAt(1);
                                        }
                                }
                                lrctimes[i]=((int)tm[0])*60*1000+((int)tm[1])*1000+((int)tm[2]);
                                lrcwords[i]=tm[3];
                }
        }
       
        function Play(elm)
        {
                var tmp;
                fore.stopTransition();
                l=(int)elm.l;
                t=(int)elm.t;
                if(elm.face || elm.face!="")
                {
                        fore.font.face = back.font.face = elm.face;
                }
                if(elm.height || elm.height!="")
                {
                        fore.font.height = back.font.height=elm.height;
                }
                timer.interval=10;
                times=(int)elm.time;
                stime=System.getTickCount();
                if (elm.align!=(void))
                {
                        align=elm.align;
                }
                if (elm.delay!=(void))
                {
                        delay=(int)elm.delay;
                }
                dk=0;
                timer.enabled=true;
                tmp = back;
                back = fore;
                fore = tmp;
        }

        function Stop(elm)
        {
                timer.enabled=false;
                dk=0;
                tmp = back;
                back = fore;
                fore = tmp;
                back.fillRect(0,0,width,height,0x00000000);
                fore.fillRect(0,0,width,height,0x00000000);
        }
       
        function onTimer()
        {
                ctime=kag.bgm.currentBuffer.position-delay;
                var tmp;
                var odk=dk;
                if(dk>=lrctimes.count||kag.bgm.currentBuffer.paused==true)
                {
                        timer.enabled=false;
                        dk=0;
                        tmp = back;
                        back = fore;
                        fore = tmp;
                        back.fillRect(0,0,width,height,0x00000000);
                        fore.fillRect(0,0,width,height,0x00000000);
                }
                else
                {
                        while(dk<lrctimes.count&&ctime>lrctimes[dk])
                                dk++;
                        if (dk!=odk)
                        {
//                                if (mode=="half")
                                {
                                        tmp = back;
                                        back = fore;
                                        fore = tmp;
                                        back.fillRect(0,0,width,height,0x00000000);
                                        switch(align)
                                        {
                                                case "left":
                                                        lc=l;
                                                        break;
                                                case "center":
                                                        lc=(width-fore.font.getTextWidth(lrcwords[dk-1]))/2+l;
                                                        break;
                                                case "right":
                                                        lc=(width-fore.font.getTextWidth(lrcwords[dk-1]))-l;
                                                        break;
                                        }
                                        back.drawText(lc,t,lrcwords[dk-1],0x00A0A0);
                                        fore.stopTransition();
                                        back.stopTransition();
                                        fore.beginTransition("crossfade",false,back,%[time:times]);
                                        kag.trigger("lyric");
                                        tf.lyric_count=dk;
                                }
                                /*else
                                {
                                        if(flg==0)
                                        {
                                        tmp = back;
                                        back = fore;
                                        fore = tmp;
                                        back.fillRect(0,0,width,height,0x00000000);
                                        fore.stopTransition();
                                        back.stopTransition();
                                        fore.beginTransition("crossfade",false,back,%[time:times/2]);
                                        flg=lrctimes[dk-1];
                                        }
                                        else if (ctime>(flg+times/2))
                                        {
                                        tmp = back;
                                        back = fore;
                                        fore = tmp;
                                        back.drawText(l,t,lrcwords[dk-1],0x00A0A0);
                                        fore.stopTransition();
                                        back.stopTransition();
                                        fore.beginTransition("crossfade",false,back,%[time:times/2]);
                                        flg=0;
                                        }
                                }*/
                        }
                }
        }
        function onStore(f, elm)
        {
        }

        function onRestore(f, clear, elm)
        {
        }

        function onStableStateChanged(stable)
        {
        }

        function onMessageHiddenStateChanged(hidden)
        {
        }

        function onCopyLayer(toback)
        {

                if(toback)
                {
                        back.visible = fore.visible;
                        back.seen = fore.seen;
                }
                else
                {
                        fore.visible = back.visible;
                        fore.seen = back.seen;
                }
                var tmp;
                tmp = back;
                back = fore;
                fore = tmp;

        }

        function onExchangeForeBack()
        {
                var tmp;
                tmp = back;
                back = fore;
                fore = tmp;
        }

}

kag.addPlugin(global.lyric_object = new LyricPlugin(kag));

@endscript
@endif

@macro name="loadlrc"
@eval exp="lyric_object.LoadLyric(mp)"
@endmacro

@macro name="playlrc"
@eval exp="lyric_object.Play(mp)"
@endmacro

@macro name="stoplrc"
@eval exp="lyric_object.Stop(mp)"
@endmacro

@return

[/code]

使用例子给一个吧……(这个和MusicName同时使用的……)
样例工程我有时间另外发布……

[code]
@call storage=lyric.ks
@call storage=musicname.ks
*start
@loadlrc storage="Second Flight.lrc"
@bgm storage="Second Flight.mp3"
@musicname l=10 t=10 ch="Second Flight/KOTOKO & 佐藤裕美 ( Produced by I've Sound )" time=4000 align="right"
@playlrc time=500 l=0 t=550 align=center face="FA 丸ゴシックM"
欢迎来到Kirikiri/KAG的世界![l][r]
[/code]

2006-12-24 22:48 Miliardo
那个音乐系统我已经做过了一半了……
开发代号:Whitefang Rainbow System

现在在考虑怎么简化歌曲的制作……检讨中……

2007-6-5 15:08 kaka850309
我在调用LRC歌词文件的时候 为什么总显示一个 “net" 而没有歌词出现呢

2007-6-5 16:51 Miliardo
ORZ= =
看一下你的歌词内容吧= =

这个系统我会在近期修改使之可以对应Transition= =

2007-6-6 12:56 kaka850309
因为是直接下载的 也许有兼容问题 我自己做一个看看

2008-2-6 13:02 orpheus
拜谢,伸手党飘过

实验研究中

2009-8-21 12:12 winry
嗯……放到游戏中后发现一个问题但不晓得怎么解决……
就是歌词会被trans掉……放到第二句了会随着trans变到第一句,然后一直这样都有延迟……
请问这个问题要怎么解决啊……??><

                fore.font.face = back.font.face = "Arial";
                fore.font.bold = back.font.bold = true;
这两个地方是默认字体和粗体吧?粗体的感觉好像并不明显,尝试加上一个fore.font.shadow = back.font.shadow = true;的阴影好像没有效果……

2009-11-9 17:14 kyo
请问一下,如何停止歌词播放?

@macro name="stoplrc"
@eval exp="lyric_object.Stop(mp)"
@endmacro

我用@stoplrc 系统会提示找不到
是由于这个插件没有完善吗?
还是我从一开始就用错了……

麻烦大人告之一下~谢谢

页: [1]


Powered by Discuz! Archiver 5.5.0  © 2001-2006 Comsenz Inc.