【原神】乐器演奏脚本AHK打谱工具

许多实用脚本和封装函数, 可以让您编写脚本更加便捷高效

Moderators: tmplinshi, arcticir

Post Reply
Best
Posts: 7
Joined: 30 Mar 2021, 02:58

【原神】乐器演奏脚本AHK打谱工具

Post by Best » 24 Nov 2024, 01:37

使用AHK2.0重新编写了之前的风物之诗琴打谱工具,并加入了晚风圆号的支持。功能做了一些优化。
详细介绍见B站视频:【原神】乐器自动演奏脚本制作教程v2.0
打谱工具:

Code: Select all

;-------------------------------打谱工具全局设置
#Requires AutoHotkey >=2.0
#SingleInstance force
;-----快捷键
#SuspendExempt
^!P::Suspend
^!R::Reload
^!Esc::Exit
^!B::{
	global BPM
	BPMChange:=InputBox("单位:每分钟拍数(BPM)`n当前曲速:" . BPM.Value,"请输入曲速")
try{
    BPMChange.Value:=BPMChange.Value*1
}
catch{
    MsgBox "未检测到有效输入。`nBPM的值应为大于零的数字。","曲速输入无效"
    return
}
if(BPMChange.Value<=0){
    MsgBox "未检测到有效输入。`nBPM的值应为大于零的数字。","曲速输入无效"
    return
	}
	BPM:=BPMChange
	ComputeTime()
}
^!M::{
	global Meter
	global MeterName
	MeterGui:=Gui()
if(Meter=1){
	MeterName:='四分音符'
}else if(Meter=2){
	MeterName:='八分音符'
}else if(Meter=4){
	MeterName:='十六分音符'
}
    MeterGui.Title:="指定拍号"
    MeterGui.AddText("",'请选择拍子的时值(即以几分音符为一拍)`n当前拍号:' . MeterName . '为一拍')
    CrotchetMeter:=MeterGui.AddRadio("WP Y+15","四分音符")
    QuaverMeter:=MeterGui.AddRadio("WP","八分音符")
    SemiquaverMeter:=MeterGui.AddRadio("WP","十六分音符")
    MeterComfirm:=MeterGui.AddButton("WP Y+20 Default","确定").OnEvent("Click",MeterChoice)
    MeterGui.Show()
    MeterChoice(*){
if(QuaverMeter.Value=1){
    Meter:=2
}else if(SemiquaverMeter.Value=1){
    Meter:=4
}
else if(CrotchetMeter.Value=1){
	Meter:=1
}
	ComputeTime()
	MeterGui.Destroy()
}
}

#SuspendExempt False
;-----托盘图标修改
if(A_isCompiled){
    A_TrayMenu.Rename('&Suspend Hotkeys','暂停/继续脚本(Ctrl+Alt+P)')
    A_TrayMenu.Insert('暂停/继续脚本(Ctrl+Alt+P)','重启脚本(Ctrl+Alt+R)',ReloadScript)
    ReloadScript(ItemName, ItemPos, MyMenu){
        Reload
    }
    ;托盘菜单重启脚本
	A_TrayMenu.Delete('&Pause Script')
	A_TrayMenu.Rename('E&xit','退出(Ctrl+Alt+Esc)')
    A_TrayMenu.Insert('重启脚本(Ctrl+Alt+R)','修改曲速(Ctrl+Alt+B)',ChangeBPM)
    ChangeBPM(ItemName, ItemPos, MyMenu){
	global BPM
    BPM:=InputBox("单位:每分钟拍数(BPM)`n当前曲速:" . BPM.Value,"请输入曲速")
try{
    BPM.Value:=BPM.Value*1
}
catch{
    MsgBox "未检测到有效输入。`nBPM的值应为大于零的数字。","曲速输入无效"
    return
}
if(BPM.Value<=0){
    MsgBox "未检测到有效输入。`nBPM的值应为大于零的数字。","曲速输入无效"
    return
}else{
	ComputeTime()
}
    }
    A_TrayMenu.Insert('修改曲速(Ctrl+Alt+B)','修改拍号(Ctrl+Alt+M)',ChangeMeter)
    ChangeMeter(ItemName, ItemPos, MyMenu){
	global Meter
if(Meter=1){
	MeterName:='四分音符'
}else if(Meter=2){
	MeterName:='八分音符'
}else if(Meter=4){
	MeterName:='十六分音符'
}
    MeterGui:=Gui()
    MeterGui.Title:="指定拍号"
    MeterGui.AddText("",'请选择拍子的时值(即以几分音符为一拍)`n当前拍号:' . MeterName . '为一拍')
    CrotchetMeter:=MeterGui.AddRadio("WP Y+20","四分音符")
    QuaverMeter:=MeterGui.AddRadio("WP","八分音符")
    SemiquaverMeter:=MeterGui.AddRadio("WP","十六分音符")
    MeterComfirm:=MeterGui.AddButton("WP Y+20 Default","确定").OnEvent("Click",MeterChoice)
    MeterGui.Show()
    MeterChoice(*){
if(QuaverMeter.Value=1){
    Meter:=2
}else if(SemiquaverMeter.Value=1){
    Meter:=4
}
else if(CrotchetMeter.Value=1){
    Meter:=1
}
    MeterGui.Destroy()
}
	ComputeTime()
    }
}else{
	A_TrayMenu.Rename('E&xit','退出')
	A_TrayMenu.Rename('&Suspend Hotkeys','暂停脚本')
    A_TrayMenu.Rename('&Reload Script','重启脚本')
	A_TrayMenu.Delete('&Help')
	A_TrayMenu.Delete('&Window Spy')
	A_TrayMenu.Delete('&Pause Script')
	A_TrayMenu.Delete('&Edit Script')

}

;-----音符持续时间初始值
Demisemiquaver:=1
Semiquaver:=1
Quaver:=1
Crotchet:=1
Minim:=1
Semibreve:=1
TripletSemibreve:=1
TripletMinim:=1
TripletCrotchet:=1
TripletQuaver:=1
TripletSemiquaver:=1
TripletDemisemiquaver:=1

;-----曲速输入窗口
BPM:=InputBox("单位:每分钟拍数(BPM)","请输入曲速")
try{
    BPM.Value:=BPM.Value*1
}
catch{
    MsgBox "未检测到有效输入。`nBPM的值应为大于零的数字。","曲速输入无效"
    Reload
}
if(BPM.Value<=0){
    MsgBox "未检测到有效输入。`nBPM的值应为大于零的数字。","曲速输入无效"
    Reload
}

;-----拍子选择窗口
Meter:=1
MeterGui:=Gui()
MeterGui.Title:="指定拍号"
MeterGui.AddText("","请选择拍子的时值(即以几分音符为一拍)")
CrotchetMeter:=MeterGui.AddRadio("Checked WP Y+20","四分音符")
QuaverMeter:=MeterGui.AddRadio("WP","八分音符")
SemiquaverMeter:=MeterGui.AddRadio("WP","十六分音符")
MeterComfirm:=MeterGui.AddButton("Default WP Y+20 ","确定").OnEvent("Click",MeterChoice)

MeterGui.OnEvent("Close",CloseTip)
CloseTip(*){
    MsgBox "必须为打谱工具指定拍号。`n如果不确定如何选择,请尝试选择四分音符。这是大部分流行音乐使用的节拍。","检测到窗口意外关闭"
    return true
}

MeterChoice(*){
	global Meter
if(QuaverMeter.Value=1){
    Meter:=2
}else if(SemiquaverMeter.Value=1){
    Meter:=4
}
else if(CrotchetMeter.Value=1){
    Meter:=1
}
    ComputeTime()
	MeterGui.Destroy()
}
MeterGui.Show()

;-----音符持续时间计算
ComputeTime(){
	global
	Demisemiquaver:=Floor(60000/BPM.Value/8/Meter)
	Semiquaver:=Floor(60000/BPM.Value/4/Meter)
	Quaver:=Floor(60000/BPM.Value/2/Meter)
	Crotchet:=Floor(60000/BPM.Value/Meter)
	Minim:=Floor(60000/BPM.Value*2/Meter)
	Semibreve:=Floor(60000/BPM.Value*4/Meter)
	TripletSemibreve:=Floor(60000/BPM.Value*4/3/Meter)
	TripletMinim:=Floor(60000/BPM.Value*2/3/Meter)
	TripletCrotchet:=Floor(60000/BPM.Value/3/Meter)
	TripletQuaver:=Floor(60000/BPM.Value/2/3/Meter)
	TripletSemiquaver:=Floor(60000/BPM.Value/4/3/Meter)
	TripletDemisemiquaver:=Floor(60000/BPM.Value/8/3/Meter)
}
;-------------------------------表头
^down::{
old_clip := ClipboardAll()
    A_Clipboard := "
(
#Requires AutoHotkey >=2.0-
#SingleInstance force
full_command_line := DllCall("GetCommandLine", "str")
if not (A_IsAdmin or RegExMatch(full_command_line, " /restart(?!\S)"))
{
try{
    if A_IsCompiled
    Run '*RunAs "' A_ScriptFullPath '" /restart'
else
    Run '*RunAs "' A_AhkPath '" /restart "' A_ScriptFullPath '"'
}Msgbox "未检测到管理员权限,脚本无法正常运行。请以管理员身份运行脚本。"
    Exitapp
}
^#p::{
    MsgBox '脚本已暂停'
    Pause
}
^#Esc::{
    MsgBox '脚本已退出'
    ExitApp
}
^#r::Reload
MsgBox '脚本准备就绪!请打开乐器弹奏页面,然后按下Ctrl+Enter开始演奏。'
^Enter::
^NumpadEnter::{
Sleep 2001

)"
	Send "^V"
	Sleep 500
	A_Clipboard := old_clip
}
;-------------------------------表尾
^up::{
old_clip := ClipboardAll()
    A_Clipboard := "
(
	Sleep 2001
	MsgBox '脚本播放完毕'
}
)"
	Send "^V"
	Sleep 500
	A_Clipboard := old_clip
}

;-------------------------------快速释放音(小字组)
^!Numpad1::
^!NumpadEnd::
+Q::{
	Send "{Blind}{Text}Send 'Z'"
	Send "{Enter}"
}

^!Numpad2::
^!NumpadDown::
+W::{
	Send "{Blind}{Text}Send 'X'"
	Send "{Enter}"
}

^!Numpad3::
^!NumpadPgDn::
+E::{
	Send "{Blind}{Text}Send 'C'"
	Send "{Enter}"
}

^!Numpad4::
^!NumpadLeft::
+R::{
	Send "{Blind}{Text}Send 'V'"
	Send "{Enter}"
}

^!Numpad5::
^!NumpadClear::
+T::{
	Send "{Blind}{Text}Send 'B'"
	Send "{Enter}"
}

^!Numpad6::
^!NumpadRight::
+Y::{
	Send "{Blind}{Text}Send 'N'"
	Send "{Enter}"
}

^!Numpad7::
^!NumpadHome::
+U::{
	Send "{Blind}{Text}Send 'M'"
	Send "{Enter}"
}

;-------------------------------快速释放音(小字一组)
^Numpad1::
^NumpadEnd::
+A::{
	Send "{Blind}{Text}Send 'A'"
	Send "{Enter}"
}

^Numpad2::
^NumpadDown::
+S::{
	Send "{Blind}{Text}Send 'S'"
	Send "{Enter}"
}

^Numpad3::
^NumpadPgDn::
+D::{
	Send "{Blind}{Text}Send 'D'"
	Send "{Enter}"
}

^Numpad4::
^NumpadLeft::
+F::{
	Send "{Blind}{Text}Send 'F'"
	Send "{Enter}"
}

^Numpad5::
^NumpadClear::
+G::{
	Send "{Blind}{Text}Send 'G'"
	Send "{Enter}"
}

^Numpad6::
^NumpadRight::
+H::{
	Send "{Blind}{Text}Send 'H'"
	Send "{Enter}"
}

^Numpad7::
^NumpadHome::
+J::{
	Send "{Blind}{Text}Send 'J'"
	Send "{Enter}"
}
;-------------------------------快速释放音(小字二组)
^#Numpad1::
^#NumpadEnd::
+Z::{
	Send "{Blind}{Text}Send 'Q'"
	Send "{Enter}"
}

^#Numpad2::
^#NumpadDown::
+X::{
	Send "{Blind}{Text}Send 'W'"
	Send "{Enter}"
}

^#Numpad3::
^#NumpadPgDn::
+C::{
	Send "{Blind}{Text}Send 'E'"
	Send "{Enter}"
}

^#Numpad4::
^#NumpadLeft::
+V::{
	Send "{Blind}{Text}Send 'R'"
	Send "{Enter}"
}

^#Numpad5::
^#NumpadClear::
+B::{
	Send "{Blind}{Text}Send 'T'"
	Send "{Enter}"
}

^#Numpad6::
^#NumpadRight::
+N::{
	Send "{Blind}{Text}Send 'Y'"
	Send "{Enter}"
}

^#Numpad7::
^#NumpadHome::
+M::{
	Send "{Blind}{Text}Send 'U'"
	Send "{Enter}"
}
;-------------------------------保持音(小字一组)
;-----按下
PgDn & Q::
PgDn & Numpad1::
PgDn & NumpadEnd::{
	Send "{Blind}{Text}Send '{Q down}'"
	Send "{Enter}"
}

PgDn & W::
PgDn & Numpad2::
PgDn & NumpadDown::{
	Send "{Blind}{Text}Send '{W down}'"
	Send "{Enter}"
}

PgDn & E::
PgDn & Numpad3::
PgDn & NumpadPgDn::{
	Send "{Blind}{Text}Send '{E down}'"
	Send "{Enter}"
}

PgDn & R::
PgDn & Numpad4::
PgDn & NumpadLeft::{
	Send "{Blind}{Text}Send '{R down}'"
	Send "{Enter}"
}

PgDn & T::
PgDn & Numpad5::
PgDn & NumpadClear::{
	Send "{Blind}{Text}Send '{T down}'"
	Send "{Enter}"
}

PgDn & Y::
PgDn & Numpad6::
PgDn & NumpadRight::{
	Send "{Blind}{Text}Send '{Y down}'"
	Send "{Enter}"
}

PgDn & U::
PgDn & Numpad7::
PgDn & NumpadHome::{
	Send "{Blind}{Text}Send '{U down}'"
	Send "{Enter}"
}
;-----抬起
PgUp & Q::
PgUp & Numpad1::
PgUp & NumpadEnd::{
	Send "{Blind}{Text}Send '{Q up}'"
	Send "{Enter}"
}

PgUp & W::
PgUp & Numpad2::
PgUp & NumpadDown::{
	Send "{Blind}{Text}Send '{W up}'"
	Send "{Enter}"
}

PgUp & E::
PgUp & Numpad3::
PgUp & NumpadPgDn::{
	Send "{Blind}{Text}Send '{E up}'"
	Send "{Enter}"
}

PgUp & R::
PgUp & Numpad4::
PgUp & NumpadLeft::{
	Send "{Blind}{Text}Send '{R up}'"
	Send "{Enter}"
}

PgUp & T::
PgUp & Numpad5::
PgUp & NumpadClear::{
	Send "{Blind}{Text}Send '{T up}'"
	Send "{Enter}"
}

PgUp & Y::
PgUp & Numpad6::
PgUp & NumpadRight::{
	Send "{Blind}{Text}Send '{Y up}'"
	Send "{Enter}"
}

PgUp & U::
PgUp & Numpad7::
PgUp & NumpadHome::{
	Send "{Blind}{Text}Send '{U up}'"
	Send "{Enter}"
}
;-------------------------------保持音(小字组)
;-----按下
PgDn & A::
End & Numpad1::
End & NumpadEnd::{
	Send "{Blind}{Text}Send '{A down}'"
	Send "{Enter}"
}

PgDn & S::
End & Numpad2::
End & NumpadDown::{
	Send "{Blind}{Text}Send '{S down}'"
	Send "{Enter}"
}

PgDn & D::
End & Numpad3::
End & NumpadPgDn::{
	Send "{Blind}{Text}Send '{D down}'"
	Send "{Enter}"
}

PgDn & F::
End & Numpad4::
End & NumpadLeft::{
	Send "{Blind}{Text}Send '{F down}'"
	Send "{Enter}"
}

PgDn & G::
End & Numpad5::
End & NumpadClear::{
	Send "{Blind}{Text}Send '{G down}'"
	Send "{Enter}"
}

PgDn & H::
End & Numpad6::
End & NumpadRight::{
	Send "{Blind}{Text}Send '{H down}'"
	Send "{Enter}"
}

PgDn & J::
End & Numpad7::
End & NumpadHome::{
	Send "{Blind}{Text}Send '{J down}'"
	Send "{Enter}"
}
;-----抬起
PgUp & A::
Home & Numpad1::
Home & NumpadEnd::{
	Send "{Blind}{Text}Send '{A up}'"
	Send "{Enter}"
}

PgUp & S::
Home & Numpad2::
Home & NumpadDown::{
	Send "{Blind}{Text}Send '{S up}'"
	Send "{Enter}"
}

PgUp & D::
Home & Numpad3::
Home & NumpadPgDn::{
	Send "{Blind}{Text}Send '{D up}'"
	Send "{Enter}"
}

PgUp & F::
Home & Numpad4::
Home & NumpadLeft::{
	Send "{Blind}{Text}Send '{F up}'"
	Send "{Enter}"
}

PgUp & G::
Home & Numpad5::
Home & NumpadClear::{
	Send "{Blind}{Text}Send '{G up}'"
	Send "{Enter}"
}

PgUp & H::
Home & Numpad6::
Home & NumpadRight::{
	Send "{Blind}{Text}Send '{H up}'"
	Send "{Enter}"
}

PgUp & J::
Home & Numpad7::
Home & NumpadHome::{
	Send "{Blind}{Text}Send '{J up}'"
	Send "{Enter}"
}

PgUp & PgDn::{
	SendText 'Sleep 50'
	Send "{Enter}"
}

PgUp::Send "{PgUp}"
PgDn::Send "{PgDn}"
;-------------------------------时值
;发送三十二分音符时值
^`::{
	SendText 'Sleep ' . Demisemiquaver
	Send "{Enter}"
}
;发送十六分音符时值
^1::{
	SendText 'Sleep ' . Semiquaver
	Send "{Enter}"
}
;发送八分音符时值
^2::{
	SendText 'Sleep ' . Quaver
	Send "{Enter}"
}
;发送四分音符时值
^3::{
	SendText 'Sleep ' . Crotchet
	Send "{Enter}"
}
;发送二分音符时值
^4::{
	SendText 'Sleep ' . Minim
	Send "{Enter}"
}
;发送全音符时值
^5::{
	SendText 'Sleep ' . Semibreve
	Send "{Enter}"
}
;发送三十二分音符三连音时值
^!`::{
	SendText 'Sleep ' . TripletDemisemiquaver
	Send "{Enter}"
}
;发送十六分音符三连音时值
^!1::{
	SendText 'Sleep ' . TripletSemiquaver
	Send "{Enter}"
}
;发送八分音符三连音时值
^!2::{
	SendText 'Sleep ' . TripletQuaver
	Send "{Enter}"
}
;发送四分音符三连音时值
^!3::{
	SendText 'Sleep ' . TripletCrotchet
	Send "{Enter}"
}
;发送二分音符三连音时值
^!4::{
	SendText 'Sleep ' . TripletMinim
	Send "{Enter}"
}
;发送全音符三连音时值
^!5::{
	SendText 'Sleep ' . TripletSemibreve
	Send "{Enter}"
}
;发送小节线
^;::{
old_clip := ClipboardAll()
    A_Clipboard := "
(
;--------------------------------------------

)"
	Send "^V"
	Sleep 500
	A_Clipboard := old_clip
}
旧版脚本升级工具:

Code: Select all

#Requires AutoHotkey v2.0
SelectedFiles := FileSelect('M27','A_WorkingDir\','选择需要转换的1.X版本脚本文件','AHK脚本文件(*.txt;*.ahk)')
for FileName in SelectedFiles
{
	NewHeader:= "
	(
#Requires AutoHotkey >=2.0-
#SingleInstance force
full_command_line := DllCall("GetCommandLine", "str")
if not (A_IsAdmin or RegExMatch(full_command_line, " /restart(?!\S)"))
{
try{
    if A_IsCompiled
    Run '*RunAs "' A_ScriptFullPath '" /restart'
else
    Run '*RunAs "' A_AhkPath '" /restart "' A_ScriptFullPath '"'
}Msgbox "未检测到管理员权限,脚本无法正常运行。请以管理员身份运行脚本。"
    Exitapp
}
^#p::{
    MsgBox '脚本已暂停'
    Pause
}
^#Esc::{
    MsgBox '脚本已退出'
    ExitApp
}
^#r::Reload
MsgBox '脚本准备就绪!请打开乐器弹奏页面,然后按下Ctrl+Enter开始演奏。'
^Enter::
^NumpadEnter::{
Sleep 2001

	)"
	Footer:= "
	(

Sleep 2001
MsgBox '脚本播放完毕'
}
	)"
	FileContent := FileRead(FileName,"UTF-8")
	ReplacedContent := StrReplace(FileContent,'<^enter::',"")
	ReplacedContent := StrReplace(ReplacedContent,'^enter::',"")
	ReplacedContent := StrReplace(ReplacedContent,'sleep`s2000',"")
	ReplacedContent := StrReplace(ReplacedContent,'#SingleInstance`sforce',"")
	ReplacedContent := StrReplace(ReplacedContent,'send`sq',"Send`s'Q'")
	ReplacedContent := StrReplace(ReplacedContent,'send`sw',"Send`s'W'")
	ReplacedContent := StrReplace(ReplacedContent,'send`se',"Send`s'E'")
	ReplacedContent := StrReplace(ReplacedContent,'send`sr',"Send`s'R'")
	ReplacedContent := StrReplace(ReplacedContent,'send`st',"Send`s'T'")
	ReplacedContent := StrReplace(ReplacedContent,'send`sy',"Send`s'Y'")
	ReplacedContent := StrReplace(ReplacedContent,'send`su',"Send`s'U'")
	ReplacedContent := StrReplace(ReplacedContent,'send`sa',"Send`s'A'")
	ReplacedContent := StrReplace(ReplacedContent,'send`ss',"Send`s'S'")
	ReplacedContent := StrReplace(ReplacedContent,'send`sd',"Send`s'D'")
	ReplacedContent := StrReplace(ReplacedContent,'send`sf',"Send`s'F'")
	ReplacedContent := StrReplace(ReplacedContent,'send`sg',"Send`s'G'")
	ReplacedContent := StrReplace(ReplacedContent,'send`sh',"Send`s'H'")
	ReplacedContent := StrReplace(ReplacedContent,'send`sj',"Send`s'J'")
	ReplacedContent := StrReplace(ReplacedContent,'send`sz',"Send`s'Z'")
	ReplacedContent := StrReplace(ReplacedContent,'send`sx',"Send`s'X'")
	ReplacedContent := StrReplace(ReplacedContent,'send`sc',"Send`s'C'")
	ReplacedContent := StrReplace(ReplacedContent,'send`sv',"Send`s'V'")
	ReplacedContent := StrReplace(ReplacedContent,'send`sb',"Send`s'B'")
	ReplacedContent := StrReplace(ReplacedContent,'send`sn',"Send`s'N'")
	ReplacedContent := StrReplace(ReplacedContent,'send`sm',"Send`s'M'")
	ReplacedContent := StrReplace(ReplacedContent,'sleep',"Sleep")
	ReplacedContent := StrReplace(ReplacedContent,'SoundBeep,',"SoundBeep`s")
	NewFileName := StrReplace(FileName,'.txt','`s V2.txt')
	NewFileName := StrReplace(NewFileName,'.ahk','`s V2.ahk')
	try FileDelete NewFileName
	FileAppend(NewHeader,NewFileName,"`n UTF-8")
	FileAppend(ReplacedContent,NewFileName,"`n UTF-8")
	FileAppend(Footer,NewFileName,"`n UTF-8")
}

Post Reply

Return to “脚本函数”