战斗场景制作

RPG Maker 中战斗场景的UI是比较经典的日式RPG的UI布局,现在尝试将它变成仙剑这样的布局看看。。。

原版仙剑战斗UI

这里只截图了开始的战斗UI其余部分会在制作时放出
【RPG Maker MV 仿新仙剑 战斗场景UI (一)】-LMLPHP

原版RPG Maker MV战斗UI

【RPG Maker MV 仿新仙剑 战斗场景UI (一)】-LMLPHP
初始看着还是挺简陋的,当然现在是没有开启侧视战斗场景的。
【RPG Maker MV 仿新仙剑 战斗场景UI (一)】-LMLPHP
从这里就可以看出需要改的地方有不少了。
有个问题,由于之前法术的菜单已经修改了,因此使用会进行报错,需要进行名称的修改,虽然在法术的场景中是正常的,但在战斗的法术中就会出现错误找不到对应的初始化方法,这应该就是名称导致的解释器找不到对应的方法,因为继承时是按照原有的类进行继承的,所以需要进行名称上的变更,这点也是通过好几次调试发现就是过不去才想起来的!!!
由于涉及到的窗口过多,因此进行分场景及窗口来进行更新吧!

启航

战斗的菜单可以简单划分为战斗指令菜单、额外战斗指令菜单、物品操作菜单、人物状态菜单这几项,另外的物品使用、物品装备、法术使用、物品投掷、人物具体状态菜单等,可以用额外场景进行实现或后期修改对应的菜单项完成UI操作。

战斗菜单

战斗指令菜单中有攻击、合击、法术、其他,这四个选项,其中合击是优先级最高的操作,后期会进行正式战斗的测试时进行完善,现在只会用于普通攻击的操作。
初期完成菜单图片:
【RPG Maker MV 仿新仙剑 战斗场景UI (一)】-LMLPHP
战斗场景代码:

function Pal_Scene_Battle() {
    this.initialize.apply(this, arguments);
}
Pal_Scene_Battle.prototype = Object.create(Scene_Base.prototype);
Pal_Scene_Battle.prototype.constructor = Pal_Scene_Battle;

Pal_Scene_Battle.prototype.initialize = function() {
    Scene_Base.prototype.initialize.call(this);
};
Pal_Scene_Battle.prototype.create = function() {
    Scene_Base.prototype.create.call(this);
    this.createDisplayObjects();
};
Pal_Scene_Battle.prototype.start = function() {
    Scene_Base.prototype.start.call(this);
    this.startFadeIn(this.fadeSpeed(), false);
    BattleManager.playBattleBgm();
    BattleManager.startBattle();
};
Pal_Scene_Battle.prototype.update = function() {
    var active = this.isActive();
    $gameTimer.update(active);
    $gameScreen.update();
    this.updateStatusWindow();
    this.updateWindowPositions();
    if (active && !this.isBusy()) {
        this.updateBattleProcess();
    }
    Scene_Base.prototype.update.call(this);
};
/** 更新作战流程
 * 
 */
Pal_Scene_Battle.prototype.updateBattleProcess = function() {
    if (!this.isAnyInputWindowActive() || BattleManager.isAborting() ||
            BattleManager.isBattleEnd()) {
        BattleManager.update();
        this.changeInputWindow();
    }
};
/** 是否有任何输入窗口处于活动状态
 * 
 */
Pal_Scene_Battle.prototype.isAnyInputWindowActive = function() {
    return (this._partyCommandWindow.active ||
            this._actorCommandWindow.active ||
            this._skillWindow.active ||
            this._itemWindow.active ||
            this._actorWindow.active ||
            this._enemyWindow.active);
};
/** 更改输入窗口
 *  
 */
Pal_Scene_Battle.prototype.changeInputWindow = function() {
    if (BattleManager.isInputting()) {
        if (BattleManager.actor()) {
            this.startActorCommandSelection();
        } else {
            this.startPartyCommandSelection();
        }
    } else {
        this.endCommandSelection();
    }
};

//停止
Pal_Scene_Battle.prototype.stop = function() {
    Scene_Base.prototype.stop.call(this);
    if (this.needsSlowFadeOut()) {
        this.startFadeOut(this.slowFadeSpeed(), false);
    } else {
        this.startFadeOut(this.fadeSpeed(), false);
    }
    this._statusWindow.close();
    this._partyCommandWindow.close();
    this._actorCommandWindow.close();
};
/** 结束战斗
 * 
 */
Pal_Scene_Battle.prototype.terminate = function() {
    Scene_Base.prototype.terminate.call(this);
    $gameParty.onBattleEnd();
    $gameTroop.onBattleEnd();
    AudioManager.stopMe();
    ImageManager.clearRequest();
};

//需要慢速淡出
Pal_Scene_Battle.prototype.needsSlowFadeOut = function() {
    return (SceneManager.isNextScene(Scene_Title) ||
            SceneManager.isNextScene(Scene_Gameover));
};

//更新状态窗口
Pal_Scene_Battle.prototype.updateStatusWindow = function() {
    if ($gameMessage.isBusy()) {
        this._statusWindow.close();
        this._partyCommandWindow.close();
        this._actorCommandWindow.close();
    } else if (this.isActive() && !this._messageWindow.isClosing()) {
        this._statusWindow.open();
    }
};

//更新窗口位置
Pal_Scene_Battle.prototype.updateWindowPositions = function() {
    var statusX = 0;
    if (BattleManager.isInputting()) {
        statusX = this._partyCommandWindow.width;
    } else {
        statusX = this._partyCommandWindow.width / 2;
    }
    if (this._statusWindow.x < statusX) {
        this._statusWindow.x += 16;
        if (this._statusWindow.x > statusX) {
            this._statusWindow.x = statusX;
        }
    }
    if (this._statusWindow.x > statusX) {
        this._statusWindow.x -= 16;
        if (this._statusWindow.x < statusX) {
            this._statusWindow.x = statusX;
        }
    }
};
/** 创建显示对象
 * 
 */
Pal_Scene_Battle.prototype.createDisplayObjects = function() {
    this.createSpriteset();
    this.createWindowLayer();
    this.createAllWindows();
    BattleManager.setLogWindow(this._logWindow);
    BattleManager.setStatusWindow(this._statusWindow);
    BattleManager.setSpriteset(this._spriteset);
    this._logWindow.setSpriteset(this._spriteset);
};
/** 创建精灵集
 * 
 */
Pal_Scene_Battle.prototype.createSpriteset = function() {
    this._spriteset = new Spriteset_Battle();
    this.addChild(this._spriteset);
};
/** 创建全部战斗窗口
 * 
 */
Pal_Scene_Battle.prototype.createAllWindows = function() {
    this.createLogWindow();
    this.createStatusWindow();
    this.createPartyCommandWindow();		
    this.createActorCommandWindow();		
    this.createHelpWindow();
    this.createSkillWindow();
    this.createItemWindow();
    this.createActorWindow();
    this.createEnemyWindow();
    this.createMessageWindow();
    this.createScrollTextWindow();
};
/** 创建战斗日志窗口
 * 
 */
Pal_Scene_Battle.prototype.createLogWindow = function() {
    this._logWindow = new Window_BattleLog();
    this.addWindow(this._logWindow);
};
/** 创建战斗状态窗口
 * 
 */
Pal_Scene_Battle.prototype.createStatusWindow = function() {
    this._statusWindow = new Window_BattleStatus();
    this.addWindow(this._statusWindow);
};
/** 创建队伍战斗命令窗口
 * 
 */
Pal_Scene_Battle.prototype.createPartyCommandWindow = function() {
    this._partyCommandWindow = new Window_PartyCommand();
    this._partyCommandWindow.setHandler('fight',  this.commandFight.bind(this));//战斗
    this._partyCommandWindow.setHandler('escape', this.commandEscape.bind(this));//撤退
    this._partyCommandWindow.deselect();//取消选择
    this.addWindow(this._partyCommandWindow);
};
/** 创建角色战斗命令窗口
 * 
 */
Pal_Scene_Battle.prototype.createActorCommandWindow = function() {
    this._actorCommandWindow = new Window_ActorCommand();
    this._actorCommandWindow.setHandler('attack', this.commandAttack.bind(this));
    this._actorCommandWindow.setHandler('skill',  this.commandSkill.bind(this));
    this._actorCommandWindow.setHandler('jointAttack',  this.commandJointAttack.bind(this));
    this._actorCommandWindow.setHandler('other',   this.commandOther.bind(this));
    this.addWindow(this._actorCommandWindow);
};
/** 创建战斗帮助窗口
 *  
 */
Pal_Scene_Battle.prototype.createHelpWindow = function() {
    this._helpWindow = new Window_Help();
    this._helpWindow.visible = false;
    this.addWindow(this._helpWindow);
};
/** 创建魔法战斗窗口
 * 
 */
Pal_Scene_Battle.prototype.createSkillWindow = function() {
    var wy = this._helpWindow.y + this._helpWindow.height;
    var wh = this._statusWindow.y - wy;
    this._skillWindow = new Window_BattleSkill(0, wy, Graphics.boxWidth, wh);
    this._skillWindow.setHelpWindow(this._helpWindow);
    this._skillWindow.setHandler('ok',     this.onSkillOk.bind(this));
    this._skillWindow.setHandler('cancel', this.onSkillCancel.bind(this));
    this.addWindow(this._skillWindow);
};
/** 创建物品战斗窗口
 * 
 */
Pal_Scene_Battle.prototype.createItemWindow = function() {
    var wy = this._helpWindow.y + this._helpWindow.height;
    var wh = this._statusWindow.y - wy;
    this._itemWindow = new Window_BattleItem(0, wy, Graphics.boxWidth, wh);
    this._itemWindow.setHelpWindow(this._helpWindow);
    this._itemWindow.setHandler('ok',     this.onItemOk.bind(this));
    this._itemWindow.setHandler('cancel', this.onItemCancel.bind(this));
    this.addWindow(this._itemWindow);
};
/** 创建战斗角色窗口
 * 
 */
Pal_Scene_Battle.prototype.createActorWindow = function() {
    this._actorWindow = new Window_BattleActor(0, this._statusWindow.y);
    this._actorWindow.setHandler('ok',     this.onActorOk.bind(this));
    this._actorWindow.setHandler('cancel', this.onActorCancel.bind(this));
    this.addWindow(this._actorWindow);
};
/** 创建战斗敌人窗口
 * @description 创建战斗敌人窗口
 * @
 */
Pal_Scene_Battle.prototype.createEnemyWindow = function() {
    this._enemyWindow = new Window_BattleEnemy(0, this._statusWindow.y);
    this._enemyWindow.x = Graphics.boxWidth - this._enemyWindow.width;
    this._enemyWindow.setHandler('ok',     this.onEnemyOk.bind(this));
    this._enemyWindow.setHandler('cancel', this.onEnemyCancel.bind(this));
    this.addWindow(this._enemyWindow);
};
/** 创建战斗消息窗口
 * 
 */
Pal_Scene_Battle.prototype.createMessageWindow = function() {
    this._messageWindow = new Window_Message();
    this.addWindow(this._messageWindow);
    this._messageWindow.subWindows().forEach(function(window) {
        this.addWindow(window);
    }, this);
};
/** 创建战斗滚动文本窗口
 * 
 */
Pal_Scene_Battle.prototype.createScrollTextWindow = function() {
    this._scrollTextWindow = new Window_ScrollText();
    this.addWindow(this._scrollTextWindow);
};
/** 刷新战斗状态
 * 
 */
Pal_Scene_Battle.prototype.refreshStatus = function() {
    this._statusWindow.refresh();
};
/** 开始队伍命令选择
 * 
 */
Pal_Scene_Battle.prototype.startPartyCommandSelection = function() {
    this.refreshStatus();
    this._statusWindow.deselect();
    this._statusWindow.open();
    this._actorCommandWindow.close();
    this._partyCommandWindow.setup();
};
//战斗命令
Pal_Scene_Battle.prototype.commandFight = function() {
    this.selectNextCommand();
};
//逃跑
Pal_Scene_Battle.prototype.commandEscape = function() {
    BattleManager.processEscape();
    this.changeInputWindow();
};
/** 开始角色命令选择
 * 
 */
Pal_Scene_Battle.prototype.startActorCommandSelection = function() {
    this._statusWindow.select(BattleManager.actor().index());
    this._partyCommandWindow.close();
    this._actorCommandWindow.setup(BattleManager.actor());
};
//攻击命令
Pal_Scene_Battle.prototype.commandAttack = function() {
    BattleManager.inputtingAction().setAttack();
    this.selectEnemySelection();
};
//魔法命令
Pal_Scene_Battle.prototype.commandSkill = function() {
    this._skillWindow.setActor(BattleManager.actor());
    this._skillWindow.setStypeId(this._actorCommandWindow.currentExt());
    this._skillWindow.refresh();
    this._skillWindow.show();
    this._skillWindow.activate();
};
//防御命令
Pal_Scene_Battle.prototype.commandJointAttack = function() {
    BattleManager.inputtingAction().setGuard();
    this.selectNextCommand();
};
//物品命令
Pal_Scene_Battle.prototype.commandOther = function() {
    this._itemWindow.refresh();
    this._itemWindow.show();
    this._itemWindow.activate();
};
/** 选择下一个命令
 * 
 */
Pal_Scene_Battle.prototype.selectNextCommand = function() {
    BattleManager.selectNextCommand();
    this.changeInputWindow();
};
//选择上一个命令
Pal_Scene_Battle.prototype.selectPreviousCommand = function() {
    BattleManager.selectPreviousCommand();
    this.changeInputWindow();
};
Pal_Scene_Battle.prototype.selectActorSelection = function() {
    this._actorWindow.refresh();
    this._actorWindow.show();
    this._actorWindow.activate();
};
Pal_Scene_Battle.prototype.onActorOk = function() {
    var action = BattleManager.inputtingAction();
    action.setTarget(this._actorWindow.index());
    this._actorWindow.hide();
    this._skillWindow.hide();
    this._itemWindow.hide();
    this.selectNextCommand();
};
Pal_Scene_Battle.prototype.onActorCancel = function() {
    this._actorWindow.hide();
    switch (this._actorCommandWindow.currentSymbol()) {
    case 'skill':
        this._skillWindow.show();
        this._skillWindow.activate();
        break;
    case 'item':
        this._itemWindow.show();
        this._itemWindow.activate();
        break;
    }
};
/** 选择敌人
 * 
 */
Pal_Scene_Battle.prototype.selectEnemySelection = function() {
    this._enemyWindow.refresh();
    this._enemyWindow.show();
    this._enemyWindow.select(0);
    this._enemyWindow.activate();
};
/** 敌人确定选择
 * 
 */
Pal_Scene_Battle.prototype.onEnemyOk = function() {
    var action = BattleManager.inputtingAction();
    action.setTarget(this._enemyWindow.enemyIndex());
    this._enemyWindow.hide();
    this._skillWindow.hide();
    this._itemWindow.hide();
    this.selectNextCommand();
};
/** 敌人取消选择
 * 
 */
Pal_Scene_Battle.prototype.onEnemyCancel = function() {
    this._enemyWindow.hide();
    switch (this._actorCommandWindow.currentSymbol()) {
    case 'attack':
        this._actorCommandWindow.activate();
        break;
    case 'skill':
        this._skillWindow.show();
        this._skillWindow.activate();
        break;
    case 'item':
        this._itemWindow.show();
        this._itemWindow.activate();
        break;
    }
};
Pal_Scene_Battle.prototype.onSkillOk = function() {
    var skill = this._skillWindow.item();
    var action = BattleManager.inputtingAction();
    action.setSkill(skill.id);
    BattleManager.actor().setLastBattleSkill(skill);
    this.onSelectAction();
};
Pal_Scene_Battle.prototype.onSkillCancel = function() {
    this._skillWindow.hide();
    this._actorCommandWindow.activate();
};
Pal_Scene_Battle.prototype.onItemOk = function() {
    var item = this._itemWindow.item();
    var action = BattleManager.inputtingAction();
    action.setItem(item.id);
    $gameParty.setLastItem(item);
    this.onSelectAction();
};
Pal_Scene_Battle.prototype.onItemCancel = function() {
    this._itemWindow.hide();
    this._actorCommandWindow.activate();
};
Pal_Scene_Battle.prototype.onSelectAction = function() {
    var action = BattleManager.inputtingAction();
    this._skillWindow.hide();
    this._itemWindow.hide();
    if (!action.needsSelection()) {
        this.selectNextCommand();
    } else if (action.isForOpponent()) {
        this.selectEnemySelection();
    } else {
        this.selectActorSelection();
    }
};
Pal_Scene_Battle.prototype.endCommandSelection = function() {
    this._partyCommandWindow.close();
    this._actorCommandWindow.close();
    this._statusWindow.deselect();
};

相信大家的基础都是OK的,因此这些代码就不过多的赘述了,下一篇着重的介绍战斗指令菜单具体的效果及代码,包含战斗场景的一起贴出来。

02-21 05:26