RPG Maker MV: 简单实现 TickBased 战斗系统

所谓 TickBased

RMMV 原生的战斗系统是基于回合的,速度只决定行动顺序。在 Tick Based 系统中,战斗时每个角色在单位时间(一般称为 Tick)内都会积累行动值,当行动值达到满值时就可以行动,行动会消耗行动值。行动后行动值继续积累,直到下一次满再次行动。

实现

写个对象方便重写方法。

// Battle System
var System = System || {};
System.Battle = System.Battle || {};

Game_BattlerBase 添加行动值(CT)属性,并定义操作它的方法和临界值。

System.Battle.Game_BattlerBase_initMembers = Game_BattlerBase.prototype.initMembers;
Game_BattlerBase.prototype.initMembers = function() {
    this._ct = 0;
    System.Battle.Game_BattlerBase_initMembers.call(this);
};

Game_BattlerBase.prototype.actionCT = function() {
    return 1000;
};

Game_BattlerBase.prototype.addCT = function(value) {
    if (this.isAlive()) {
        this._ct += value;
    }
};

去掉原本的和 Turn 相关的方法,因为在本站战斗系统中不需要回合。新增一个 'waiting' 阶段,在本阶段计算ct增长。新增 'acting' 阶段,在此阶段决定行动的角色。

BattleManager.update = function() {
    if (!this.isBusy() && !this.updateEvent()) {
        switch (this._phase) {
            case 'start':
                this.startInput();
                break;
            case 'waiting':
                this.think();
                break;
            case 'acting':
                this.updateActing();
                break;
            case 'action':
                this.updateAction();
                break;
            case 'battleEnd':
                this.updateBattleEnd();
                break;
        }
    }
};

修改战斗开始方法,直接进入 'waiting' 阶段。

BattleManager.startBattle = function() {
    this._phase = 'waiting';
    $gameSystem.onBattleStart();
    $gameParty.onBattleStart();
    $gameTroop.onBattleStart();
    this.displayStartMessages();
};

think方法,计算CT值的自然增长

BattleManager.think = function() {
    var battlers = this.allBattleMembers();
    var readies = [];
    var hasActor = false;
    battlers.forEach(function(b) {
        b.addCT(b.agi);
        if (b._ct >= b.actionCT()) {
            b.addCT(-1000);
            readies.push(b);
            b.makeActions();
            if (b.isActor()) {
                hasActor = true;
            } else {
                b._actionState = 'waiting';
            }
        }
    }, this);
    if (readies.length < 1) return;
    this._actionBattlers = readies;
    if (hasActor) { //如果有玩家角色可以行动,则进入输入阶段,如果只有敌人行动,则不需要输入。
        this._phase = 'input';
    } else {
        this._phase = 'acting';
    }
};

修改剩下的相关方法,使之符合现在的逻辑

//完成一次行动后,再次进入 'acting' 阶段,进行下一个行动
BattleManager.endAction = function() {
    this._logWindow.endAction(this._subject);
    this._phase = 'acting';
};

//所有行动结束后 'acting' 阶段结束, 回到 'waiting' 阶段
BattleManager.updateActing = function() {
    if (!this._subject) {
        this._subject = this.getNextSubject();
    }
    if (this._subject) {
        this.processTurn();
    } else {
        this._phase = 'waiting';
    }
};

BattleManager.startTurn = function() {
    this._phase = 'acting';
    this.clearActor();
};

BattleManager.updateEvent = function() {
    switch (this._phase) {
        case 'start':
        case 'waiting':
            if (this.isActionForced()) {
                this.processForcedAction();
                return true;
            } else {
                return this.updateEventMain();
            }
    }
    return this.checkAbort2();
};

修改can input 方法,让每个角色的行动输入分开进行。

Game_BattlerBase.prototype.canInput = function() {
    return this.isAppeared() && !this.isRestricted() && !this.isAutoBattle() && BattleManager._actionBattlers.indexOf(this) > -1;
};

你可能感兴趣的:(RPG Maker MV: 简单实现 TickBased 战斗系统)