设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 2940|回复: 5
打印 上一主题 下一主题

[通用发布] 简单同步歌词显示

[复制链接]

Lv1.梦旅人

梦石
0
星屑
76
在线时间
1379 小时
注册时间
2012-7-5
帖子
1698

开拓者

跳转到指定楼层
1
发表于 2014-4-12 17:42:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
本帖最后由 kuerlulu 于 2014-4-19 20:25 编辑

【2014年4月19日20:24:45 更新】
    @taroxd 已更新,顺便加了些没用的= =
【惯(fei)例(hua)】做音乐游戏时为了校准时间出来的副产物
【特(bu)色(zu)】
    1.在下只给出脚本没给出范例(噗
    2.免dll
    3.没有淡入淡出等特效
    4.不会自动加入update队列
    5.在下说这么多缺点肯定没人看了
    6.歌曲和歌词文件请都放到Audio/BGM里
【正(jie)文(cao)】
RUBY 代码复制下载
  1. class String
  2.   @@MultiByteToWideChar  = Win32API.new('kernel32', 'MultiByteToWideChar', 'ilpipi', 'i')
  3.   @@WideCharToMultiByte  = Win32API.new('kernel32', 'WideCharToMultiByte', 'ilpipipp', 'i')
  4.   def s2u
  5.     i = @@MultiByteToWideChar.call(0, 0, self, -1, nil, 0)
  6.     buffer = "\0" * (i*2)
  7.     @@MultiByteToWideChar.call(0, 0, self, -1, buffer, buffer.size / 2)
  8.     i = @@WideCharToMultiByte.call(65001, 0, buffer, -1, nil, 0, nil, nil)
  9.     result = "\0" * i
  10.     @@WideCharToMultiByte.call(65001, 0, buffer, -1, result, result.size, nil, nil)
  11.     result.chop!
  12.     return result
  13.   end
  14. end
  15.  
  16. class Lrc
  17.   #--------------------------------------------------------------------------
  18.   # ● 初始化
  19.   #--------------------------------------------------------------------------
  20.   def initialize(songname)
  21.     # 获取歌词
  22.     lrc = File.open("Audio/BGM/#{songname}.lrc").read.s2u.split("\n")
  23.     # 分析歌词
  24.     @content = []
  25.     for line in lrc
  26.       unless line[/(?<=\[)\d{2}:\d{2}.\d{2}(?=\])/].nil?
  27.         t = line.split(']').size - 1
  28.         txt = line.split(']').size == 1 ? "" : line[10*t..-1]
  29.         for i in 0..t
  30.           l = line[(1+10*i)..(8+10*i)]
  31.           min   = l.split(':')[0].to_i
  32.           a     = l.split(':')[1].to_s
  33.           sec   = a.split('.')[0].to_i
  34.           msec  = a.split('.')[1].to_i
  35.           unless min*60000+sec*1000+msec*10 == 0
  36.             @content.push([min*60000+sec*1000+msec*10, txt])
  37.           end
  38.         end
  39.       end
  40.     end
  41.     @content.sort!
  42.     @content.push([1800000, ''])
  43.     # 画图
  44.     @sprite = Sprite.new
  45.     @sprite.bitmap = Bitmap.new(640,22)
  46.     @sprite.x,@sprite.y = 0,458
  47.     #@content.each_with_index{|l,i|@sprite.bitmap.draw_text(0,i*22+2,640,22,l[1],1)}
  48.     # 记时开始
  49.     [url=home.php?mod=space&uid=263426]@temp[/url] = ""
  50.     start
  51.   end
  52.   #--------------------------------------------------------------------------
  53.   # ● 刷新精灵
  54.   #--------------------------------------------------------------------------
  55.   def update
  56.     @sprite.opacity += 25 unless @sprite.opacity == 255
  57.     if now_lrc != @temp
  58.       @sprite.bitmap.clear
  59.       @sprite.bitmap.draw_text(0,0,640,22,now_lrc,1)
  60.       @temp = now_lrc
  61.       @sprite.opacity = 0
  62.     end
  63.   end
  64.   #--------------------------------------------------------------------------
  65.   # ● 释放精灵
  66.   #--------------------------------------------------------------------------
  67.   def dispose
  68.     @sprite.bitmap.dispose
  69.     @sprite.dispose
  70.     @temp = nil
  71.     @content = nil
  72.     @start_time = nil
  73.   end
  74.   #--------------------------------------------------------------------------
  75.   # ● 获取当前一句歌词
  76.   #--------------------------------------------------------------------------
  77.   def now_lrc
  78.     @content.each_with_index do | t, i |
  79.       return @content[i-1][1] if current_time - t[0] <= 0
  80.     end
  81.   end
  82.   #--------------------------------------------------------------------------
  83.   # ● 调整纵坐标
  84.   #--------------------------------------------------------------------------
  85.   def y
  86.     return @sprite.y
  87.   end
  88.   def y=(int)
  89.     @sprite.y = int
  90.   end
  91.   #--------------------------------------------------------------------------
  92.   # ● 获取当前毫秒数
  93.   #--------------------------------------------------------------------------
  94.   def msec
  95.     t = Time.now
  96.     t.to_i * 1000 + t.usec / 1000
  97.   end
  98.   #--------------------------------------------------------------------------
  99.   # ● 开始 重置 start_time
  100.   #--------------------------------------------------------------------------
  101.   def start
  102.     @start_time = msec
  103.   end
  104.   #--------------------------------------------------------------------------
  105.   # ● 获取时间
  106.   #--------------------------------------------------------------------------
  107.   def current_time
  108.     msec - @start_time
  109.   end
  110. end

【测试用脚本】
RUBY 代码复制
  1. l = Lrc.new("无前缀后缀歌曲名") # 如 "周杰伦 - 枫"
  2. Audio.bgm_play("带前缀后缀的歌曲名") # 如 "Audio/BGM/周杰伦 - 枫.mp3"
  3. loop{Graphics.update;l.update}

【补(luan)救(xiang)】
    1.淡入淡出特效什么的在update那里加点东西就行了【在下就偷懒不写了
    2.加入update队列可以考虑直接alias Graphics.update【在下真是垢了
    3.范例真的就不需要了吧?!  

评分

参与人数 2星屑 +40 收起 理由
taroxd + 20
无脑之人 + 20 虽然没仔细看但是还是塞糖吧w

查看全部评分


  -fk: -azogi:

Lv3.寻梦者 (版主)

…あたしは天使なんかじゃないわ

梦石
0
星屑
2208
在线时间
4033 小时
注册时间
2010-10-4
帖子
10779

开拓者贵宾

2
发表于 2014-4-13 17:22:13 | 只看该作者
本帖最后由 taroxd 于 2014-4-13 17:39 编辑

虽然我没用脚本,但是还是认真地看了一遍。

看了那行正则表达式,貌似不支持压缩版的lrc吧?
例:
[00:01:00][00:02:00]这是一句歌词,在第一秒和第二秒各唱一遍

话说为什么不直接在正则表达式里创建名字的引用……比如(?<min>)之类的

还有啊,读取个lrc似乎不需要用到win32api的吧……?lrc不是文本文件么……

另外我没记错的话Audio.bgm_play似乎可以省略后缀。至少wav和ogg可以

咦好像看到了我的音乐游戏的痕迹之类的?顺便期待音乐游戏。再顺便说一句校准可以用goldwave和BPMAnalyzer

点评

省略后缀可能会引发读取同名歌词文件而不能播放的情况  发表于 2014-4-15 12:17
api什么的是MTV脚本里通过调用dll获取了时间,另外确实压缩版的还不支持,在下有空改一改  发表于 2014-4-15 12:14
回复 支持 反对

使用道具 举报

Lv2.观梦者

故九江太守

梦石
0
星屑
623
在线时间
2166 小时
注册时间
2012-12-5
帖子
4464
3
发表于 2014-4-14 20:02:36 | 只看该作者
歌词文件?是酷狗音乐用的那种吗?

点评

酷狗我没记错的话它的歌词文件是另一种格式。。用记事本打开是乱码  发表于 2014-4-15 12:19
回复 支持 反对

使用道具 举报

Lv3.寻梦者 (版主)

…あたしは天使なんかじゃないわ

梦石
0
星屑
2208
在线时间
4033 小时
注册时间
2010-10-4
帖子
10779

开拓者贵宾

4
发表于 2014-4-19 20:42:54 | 只看该作者
本帖最后由 taroxd 于 2014-4-19 21:07 编辑

我只吐槽乃的字符串处理为什么这么奇葩……

RUBY 代码复制
  1. # @content = []
  2. # 迭代每一行 do |line|
  3. tags = line.slice! /(?:\[\d\d:\d\d:\d\d\])+/
  4. tags.scan /\[(\d\d):(\d\d):(\d\d)\]/ do |(min, sec, msec)|
  5.   @contents.push [min.to_i * 60000 + sec.to_i * 1000 + msec.to_i * 10, line]
  6. end if tags
  7. # @content.sort!
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
310 小时
注册时间
2012-10-14
帖子
187
5
发表于 2014-12-7 15:31:27 | 只看该作者
看你这么多帖子都不给范例恨死你了啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊!~!!!!!{:4_147:}
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
131
在线时间
85 小时
注册时间
2013-7-24
帖子
219
6
发表于 2014-12-12 19:23:16 | 只看该作者
好久不来第一个就看到了您的帖子
歌词显示可以设置字体么

点评

稍微看一下F1的bitmap和font就行了  发表于 2014-12-13 12:06
终于放假了,正在尝试肝出一款新游戏
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-14 23:03

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表