Skip to content

Instantly share code, notes, and snippets.

@ZumiKua
Created March 8, 2026 16:42
Show Gist options
  • Select an option

  • Save ZumiKua/9030083e358c16e6e8358fc1bc32009c to your computer and use it in GitHub Desktop.

Select an option

Save ZumiKua/9030083e358c16e6e8358fc1bc32009c to your computer and use it in GitHub Desktop.
剑与魔法的女主角们2双语显示插件
/*:
* @plugindesc v.1.0.0 Dual Language Display (English)
* @author Junie
* @help
* This plugin shows English translation alongside the current language in messages.
* Requires DKTools_Localization plugin.
*
* @param Enabled
* @desc Enable dual language display by default?
* @type boolean
* @default true
*/
(function() {
if (!Imported['DKTools_Localization']) {
console.error('DKTools_Localization_DualLanguage: DKTools_Localization is not found!');
return;
}
const parameters = PluginManager.parameters('DKTools_Localization_DualLanguage');
let dualLanguageEnabled = true;//String(parameters['Enabled']) === 'true';
// 扩展 DKTools.Localization
DKTools.Localization._englishData = null;
const _DKTools_Localization_loadData = DKTools.Localization.loadData;
DKTools.Localization.loadData = async function() {
await _DKTools_Localization_loadData.call(this);
// 如果当前不是英文,则加载英文数据
if (this._locale !== 'en') {
this._englishData = await this._loadData('en');
} else {
this._englishData = this._data;
}
};
const _DKTools_Localization_onLocaleChange = DKTools.Localization._onLocaleChange;
DKTools.Localization._onLocaleChange = async function(previousLocale) {
await _DKTools_Localization_onLocaleChange.call(this, previousLocale);
if (this._locale !== 'en') {
this._englishData = await this._loadData('en');
} else {
this._englishData = this._data;
}
};
// 助手函数:获取英文文本
DKTools.Localization.getEnglishText = function(text) {
if (!this._englishData) return '';
const regexTag = this.regexTag;
const data = this._englishData;
// 简单替换标签
return text.replace(regexTag, (string, match) => {
if (data.hasOwnProperty(match)) {
return data[match];
} else {
const value = _.get(data, match);
if (DKTools.Utils.isString(value)) {
return value;
}
}
return match;
});
};
//-----------------------------------------------------------------------------
// Game_Message
// 拦截 add 方法以捕获原始文本(包含标签)
const _Game_Message_clear = Game_Message.prototype.clear;
Game_Message.prototype.clear = function() {
_Game_Message_clear.call(this);
this._englishTexts = [];
};
const _Game_Message_add = Game_Message.prototype.add;
Game_Message.prototype.add = function(text) {
_Game_Message_add.call(this, text);
if (!this._englishTexts) {
this._englishTexts = [];
}
if (dualLanguageEnabled && DKTools.Localization._locale !== 'en' && DKTools.Localization._englishData) {
this._englishTexts.push(DKTools.Localization.getEnglishText(text));
} else {
this._englishTexts.push('');
}
};
Game_Message.prototype.allEnglishText = function() {
return this._englishTexts.join('\n');
};
//-----------------------------------------------------------------------------
// Window_EnglishMessage
//
// 新的窗口类,用于显示英文翻译
function Window_EnglishMessage() {
this.initialize.apply(this, arguments);
}
Window_EnglishMessage.prototype = Object.create(Window_Base.prototype);
Window_EnglishMessage.prototype.constructor = Window_EnglishMessage;
Window_EnglishMessage.prototype.initialize = function() {
const width = Graphics.boxWidth;
const height = this.fittingHeight(4);
Window_Base.prototype.initialize.call(this, 0, 0, width, height);
this.openness = 0;
this._text = '';
};
Window_EnglishMessage.prototype.update = function() {
Window_Base.prototype.update.call(this);
this.updateInput();
};
Window_EnglishMessage.prototype.updateInput = function() {
if (this.isOpen()) {
if (Input.isPressed('shift')) {
this.visible = false;
} else {
this.visible = true;
}
}
};
Window_EnglishMessage.prototype.setText = function(text) {
if (this._text !== text) {
this._text = text;
this.refresh();
}
};
Window_EnglishMessage.prototype.refresh = function() {
this.contents.clear();
if (this._text) {
this.drawTextEx(this._text, this.textPadding(), 0);
}
};
Window_EnglishMessage.prototype.updatePlacement = function(messageWindow) {
this.height = messageWindow.height;
if (messageWindow.y >= Graphics.boxHeight / 2) {
// 主窗口在下方,英文窗口在上方
this.y = 0;
} else {
// 主窗口在上方或中间,英文窗口在下方
this.y = Graphics.boxHeight - this.height;
}
};
Window_EnglishMessage.prototype.isOpennessChanged = function() {
return false; // Dummy, can be improved if needed
};
//-----------------------------------------------------------------------------
// Scene 挂载
const _Scene_Map_createMessageWindow = Scene_Map.prototype.createMessageWindow;
Scene_Map.prototype.createMessageWindow = function() {
_Scene_Map_createMessageWindow.call(this);
this._englishMessageWindow = new Window_EnglishMessage();
this.addWindow(this._englishMessageWindow);
this._messageWindow._englishMessageWindow = this._englishMessageWindow;
};
const _Scene_Battle_createMessageWindow = Scene_Battle.prototype.createMessageWindow;
Scene_Battle.prototype.createMessageWindow = function() {
_Scene_Battle_createMessageWindow.call(this);
this._englishMessageWindow = new Window_EnglishMessage();
this.addWindow(this._englishMessageWindow);
this._messageWindow._englishMessageWindow = this._englishMessageWindow;
};
//-----------------------------------------------------------------------------
// Window_Message 拦截
const _Window_Message_startMessage = Window_Message.prototype.startMessage;
Window_Message.prototype.startMessage = function() {
_Window_Message_startMessage.call(this);
if (this._englishMessageWindow) {
if (dualLanguageEnabled && DKTools.Localization._locale !== 'en' && DKTools.Localization._englishData) {
const englishText = $gameMessage.allEnglishText();
if (englishText && englishText.trim() !== "") {
this._englishMessageWindow.setText(englishText);
this._englishMessageWindow.updatePlacement(this);
this._englishMessageWindow.open();
} else {
this._englishMessageWindow.close();
}
} else {
this._englishMessageWindow.close();
}
}
};
const _Window_Message_terminateMessage = Window_Message.prototype.terminateMessage;
Window_Message.prototype.terminateMessage = function() {
_Window_Message_terminateMessage.call(this);
if (this._englishMessageWindow) {
this._englishMessageWindow.close();
}
};
const _Window_Message_update = Window_Message.prototype.update;
Window_Message.prototype.update = function() {
_Window_Message_update.call(this);
if (this._englishMessageWindow) {
// 同步 openness 可能不需要,因为 Window_Message 有自己的 update
}
};
// 也可以通过 $gameMessage 同步 background
const _Window_Message_updateBackground = Window_Message.prototype.updateBackground;
Window_Message.prototype.updateBackground = function() {
_Window_Message_updateBackground.call(this);
if (this._englishMessageWindow) {
this._englishMessageWindow.setBackgroundType($gameMessage.background());
}
};
// 公开 API
DKTools.Localization.setDualLanguage = function(enabled) {
dualLanguageEnabled = !!enabled;
};
DKTools.Localization.isDualLanguageEnabled = function() {
return dualLanguageEnabled;
};
})();
  1. 将上面的DKTools_Localization_DualLanguage.js文件保存在游戏安装目录的www/js/plugins文件夹内。

  2. 将以下内容连带开头的逗号插在游戏安装目录的www/js/plugins.js末尾反方括号]的前面

,{"name":"DKTools_Localization_DualLanguage","status":true,"description":"","parameters":{}}

现在进入游戏应该就应该会同时有中英文对话显示。有时候会出现英文显示不全的情况,这个没办法解决。有时候会出现英文对话框遮挡住了关键内容的情况,这种时候请按住shift,可以临时隐藏英文对话框。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment