JUMP INTO JAVASCRIPT PART 6

In which we exit the scene.

  • Trihan
  • 04/09/2017 05:56 PM
  • 4192 views
Enjoyers of physical activity! It is once again time to put on your coder hats and delve into the gooey innards of another episode of


Jump into Javascript

What's in a name? Well, this.

Scene_Name

Scene_Name.prototype.prepare = function(actorId, maxLength) {
    this._actorId = actorId;
    this._maxLength = maxLength;
};


Our prepare function takes two parameters: actorId and maxLength. We set the scene's _actorId and _maxLength properties to their respective parameters: actorId as the name suggests contains the ID of the actor being named, and maxLength is the maximum number of characters the chosen name can be.

Scene_Name.prototype.create = function() {
    Scene_MenuBase.prototype.create.call(this);
    this._actor = $gameActors.actor(this._actorId);
    this.createEditWindow();
    this.createInputWindow();
};


The create function is nothing particularly special: we call the create function of Scene_MenuBase's prototype, then set the scene's _actor property to the actor from $gameActors with an ID matching the scene's _actorId property. Then, we create the edit window and input window.

Scene_Name.prototype.start = function() {
    Scene_MenuBase.prototype.start.call(this);
    this._editWindow.refresh();
};


The start function calls Scene_MenuBase's prototype's start function and then refreshes the edit window. This is because the window contains a face graphic, and windows with face graphics need to be refreshed when the scene starts or they won't be visible when it first opens.

Scene_Name.prototype.createEditWindow = function() {
    this._editWindow = new Window_NameEdit(this._actor, this._maxLength);
    this.addWindow(this._editWindow);
};


In createEditWindow we create a new instance of Window_NameEdit called _editWindow, passing in an actor object of the scene's _actor and a max length of the scene's _maxLength, then add it to the window layer.

Scene_Name.prototype.createInputWindow = function() {
    this._inputWindow = new Window_NameInput(this._editWindow);
    this._inputWindow.setHandler('ok', this.onInputOk.bind(this));
    this.addWindow(this._inputWindow);
};


createInputWindow is nothing special at this point. We create a new instance of Window_NameInput, passing in the scene's _editWindow object. We set the ok handler of the input window to the bound onInputOk function, and then add the input window to the window layer. The new instance is assigned to _inputWindow.

Scene_Name.prototype.onInputOk = function() {
    this._actor.setName(this._editWindow.name());
    this.popScene();
};


The onInputOk function is the one we bound to the input window's ok handler; it calls the setName function of the scene's _actor, passing in the result of calling the name() function of _editWindow, which gets the name the player input for the actor. Then we return to the previous scene.

Pretty short and sweet, eh?

Scene_Debug

This should be an interesting one. :)

Scene_Debug.prototype.create = function() {
    Scene_MenuBase.prototype.create.call(this);
    this.createRangeWindow();
    this.createEditWindow();
    this.createDebugHelpWindow();
};


Again a pretty standard create function. We call the create function of Scene_MenuBase, then create the range window, edit window and debug help window.

Scene_Debug.prototype.createRangeWindow = function() {
    this._rangeWindow = new Window_DebugRange(0, 0);
    this._rangeWindow.setHandler('ok',     this.onRangeOk.bind(this));
    this._rangeWindow.setHandler('cancel', this.popScene.bind(this));
    this.addWindow(this._rangeWindow);
};


In createRangeWindow, we create a new Window_DebugRange (assigning it to _rangeWindow) passing in (0, 0) for the X and Y coordinates (so it will be at the top left). We set its ok handler to the bound onRangeOk function, and the cancel handler to a binding of popScene so if we hit cancel it will return to the previous scene. Then we add _rangeWindow to the window layer.

Scene_Debug.prototype.createEditWindow = function() {
    var wx = this._rangeWindow.width;
    var ww = Graphics.boxWidth - wx;
    this._editWindow = new Window_DebugEdit(wx, 0, ww);
    this._editWindow.setHandler('cancel', this.onEditCancel.bind(this));
    this._rangeWindow.setEditWindow(this._editWindow);
    this.addWindow(this._editWindow);
};


createEditWindow sets a var called wx to the width of the range window, and one called ww to the width of the game window less wx. We create a new instance of Window_DebugEdit (assigned to _editWindow) passing in wx, 0 and ww for x, y and width respectively (this will place the edit window to the right of the range window at the top of the screen, taking up the rest of the screen width).

We set the cancel handler of the edit window to the bound onEditCancel function, set the range window's edit window to _editWindow (so that when a new range is selected the edit window will update too), and then add _editWindow to the window layer.

Scene_Debug.prototype.createDebugHelpWindow = function() {
    var wx = this._editWindow.x;
    var wy = this._editWindow.height;
    var ww = this._editWindow.width;
    var wh = Graphics.boxHeight - wy;
    this._debugHelpWindow = new Window_Base(wx, wy, ww, wh);
    this.addWindow(this._debugHelpWindow);
};


createDebugHelpWindow creates...well, a help window for the debug scene! We set wx to the x coordinate of the edit window, wy to the edit window's height, ww to the edit window's width, and wh to the height of the game window less wy. Then we create a new instance of Window_Base (assigned to _debugHelpWindow) passing in wx and wy for the X/Y coordinates and ww and wh for the width/height. This will place the help window at the same x as and underneath the edit window taking up the same width and the remaining screen height.

Scene_Debug.prototype.onRangeOk = function() {
    this._editWindow.activate();
    this._editWindow.select(0);
    this.refreshHelpWindow();
};


onRangeOk is the function we bound to the 'ok' handler of the range window. It activates the edit window, selects its first item, and refreshes the help window.

Scene_Debug.prototype.onEditCancel = function() {
    this._rangeWindow.activate();
    this._editWindow.deselect();
    this.refreshHelpWindow();
};


onEditCancel is the function we bound to the 'cancel' handler of the edit window. It activates the range window, deselects the edit window, and refreshes the help window.

Scene_Debug.prototype.refreshHelpWindow = function() {
    this._debugHelpWindow.contents.clear();
    if (this._editWindow.active) {
        this._debugHelpWindow.drawTextEx(this.helpText(), 4, 0);
    }
};


refreshHelpWindow creates the help text seen in the help window while in the debug scene. First, we clear the contents of the debug help window, then if the edit window is active we call drawTextEx on the debug help window passing in the result of the scene's helpText function, 4 for the X coordinate, and 0 for the Y.

Scene_Debug.prototype.helpText = function() {
    if (this._rangeWindow.mode() === 'switch') {
        return 'Enter : ON / OFF';
    } else {
        return ('Left     :  -1\n' +
                'Right    :  +1\n' +
                'Pageup   : -10\n' +
                'Pagedown : +10');
    }
};


helpText is just a function to get the text to show in the debug help window. If the range window mode is 'switch', it just shows that you can press Enter to turn a switch ON or OFF. Otherwise (meaning the mode is 'variable') it shows that the right/left keys increase/decrease the variable by 1, and page down/page up increase/decrease the variable by 10.

Okay, maybe not that interest. But now...

Scene_Battle

A few people have probably been waiting for this one. Let's get to it.

Scene_Battle.prototype.create = function() {
    Scene_Base.prototype.create.call(this);
    this.createDisplayObjects();
};


Not much to see in the create function rather than a call to the createDisplayObjects function, which is coming up soon.

Scene_Battle.prototype.start = function() {
    Scene_Base.prototype.start.call(this);
    this.startFadeIn(this.fadeSpeed(), false);
    BattleManager.playBattleBgm();
    BattleManager.startBattle();
};


The start function calls the prototype start function of Scene_Base, then we call startFadeIn passing in the result of calling fadeSpeed and false as parameters (which as you probably don't remember from Scene_Base, will make the fade last 24 frames with no white). After that, we call the playBattleBgm function of BattleManager to start playing the battle music, and then call its startBattle function which starts off battle processing.

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);
};


The frame update function for the battle scene does a number of things. First, set set temp var active to the result of calling the scene's isActive function. Then we call $gameTimer's update method passing in the value of active and $gameScreen's update method. We then call updateStatusWindow and updateWindowPositions to update the status window and update the positions of the windows (sometimes function names are pretty self-explanatory) and then if the scene is active AND NOT busy, we call updateBattleProcess which we'll look at in a sec. Finally, we call the prototype update function of Scene_Base.

Scene_Battle.prototype.updateBattleProcess = function() {
    if (!this.isAnyInputWindowActive() || BattleManager.isAborting() ||
            BattleManager.isBattleEnd()) {
        BattleManager.update();
        this.changeInputWindow();
    }
};


updateBattleProcess, which as we've seen above is called when the battle scene is active and not busy, first checks if no input window is active OR the battle manager is aborting OR it's the end of battle. If any of these conditions is met, we call BattleManager's update function and then the changeInputWindow function.

Scene_Battle.prototype.isAnyInputWindowActive = function() {
    return (this._partyCommandWindow.active ||
            this._actorCommandWindow.active ||
            this._skillWindow.active ||
            this._itemWindow.active ||
            this._actorWindow.active ||
            this._enemyWindow.active);
};


isAnyInputWindowActive checks to see whether an input window is active. Returns true if the party command window is active OR the actor command window is active OR the skill window is active OR the item window is active OR the actor window is active OR the enemy window is active.

Scene_Battle.prototype.changeInputWindow = function() {
    if (BattleManager.isInputting()) {
        if (BattleManager.actor()) {
            this.startActorCommandSelection();
        } else {
            this.startPartyCommandSelection();
        }
    } else {
        this.endCommandSelection();
    }
};


changeInputWindow handles processing when the input window changes. If BattleManager.isInputting() returns true (which is to say actions are currently being selected) then we check whether BattleManager has an actor object currently, and if so we call startActorCommandSelection. Otherwise we call startPartyCommandSelection as this must mean we're in the party commands stage (we'll see this when we cover managers). If actions are NOT being selected, we call endCommandSelection.

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();
};


The overwrite of the stop function first calls the prototype stop function of Scene_Base. Then if needsSlowFadeOut returns true, we call startFadeOut passing in the result of calling slowFadeSpeed as the number of frames, and false for the white parameter. Otherwise, we call the same function but with the result of fadeSpeed instead.

After this check, we close the status, party command and actor command windows.

Scene_Battle.prototype.terminate = function() {
    Scene_Base.prototype.terminate.call(this);
    $gameParty.onBattleEnd();
    $gameTroop.onBattleEnd();
    AudioManager.stopMe();
};


The overwrite of the terminate function first calls the prototype terminate function of Scene_Base. Then we call the onBattleEnd functions of both $gameParty and $gameTroop, and call AudioManager's stopMe function to stop the victory jingle playing.

Scene_Battle.prototype.needsSlowFadeOut = function() {
    return (SceneManager.isNextScene(Scene_Title) ||
            SceneManager.isNextScene(Scene_Gameover));
};


This function tells us whether we need a slow fadeout effect. Returns true if the next scene is Scene_Title or Scene_Gameover.

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();
    }
};


updateStatusWindow is a function that, well, updates the status window. If the game message object is busy (i.e. showing text), we close the status, party command and actor command windows. Otherwise, if the battle scene is active AND the message window is not in the process of closing, we open the status window. The end result of this, obviously, is that when text is being shown the status and command windows disappear.

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;
        }
    }
};


updateWindowPositions is a function that makes sure the status window appears at the correct size/position.

First, we set temp var statusX to 0. If actions are being selected, statusX is set to the width of the party command window. Otherwise, it's set to half the width of the party command window.

If the x position of the status window is less than statusX, we add 16 to it, then if it's greater than statusX we set it to statusX.

If the x position of the status window is greater than statusX, we subtract 16 from it, then if it's less than statusX we set it to statusX.

This is what causes the status window to move to the center of the screen when all actor commands are in and the turn starts executing.

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);
};


This function creates the display objects, which is to say everything you can see on the battle scene. First we create the spriteset, then the window layer, then all the windows. We call the setLogWindow, setStatusWindow and setSpriteset functions of BattleManager to _logWindow, _statusWindow and _spriteset respectively (which provides BattleManager with data it needs to do its own processing, as we'll see when we look at managers). Then we also call setSpriteset on the _logWindow object, passing in _spriteset (as we'll see when we get to windows, this is only really to allow the battle log window to properly update its wait mode).

Scene_Battle.prototype.createSpriteset = function() {
    this._spriteset = new Spriteset_Battle();
    this.addChild(this._spriteset);
};


Creating the battle spriteset is pretty simple: we create a new instance of Spriteset_Battle (assigned to _spriteset) and then add it as a child of the scene object.

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();
};


createAllWindows is just a wrapper function for calls to all the other window creation functions. This will create the battle log window, status window, party command window, actor command window, help window, skill window, item window, actor window, enemy window, message window and scrolling text window. Note that although many of these will be invisible for the majority of battles they are still present in the scene from the beginning.

Scene_Battle.prototype.createLogWindow = function() {
    this._logWindow = new Window_BattleLog();
    this.addWindow(this._logWindow);
};


createLogWindow creates the battle log window. We create a new instance of Window_BattleLog (assigned to _logWindow) and add it to the window layer.

Scene_Battle.prototype.createStatusWindow = function() {
    this._statusWindow = new Window_BattleStatus();
    this.addWindow(this._statusWindow);
};


Same thing, but for an instance of Window_BattleStatus assigned to _statusWindow.

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);
};


createPartyCommandWindow creates the base window for party commands initially visible when the battle starts; by default, it only consists of "Fight" and "Escape". First, we create a new instance of Window_PartyCommand (assigned to _partyCommandWindow). Then we set the handlers for 'fight' and 'escape' to the bound commandFight and commandEscape functions respectively, and deselect the party command window. Finally, we add the party command window to the window layer.

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('guard',  this.commandGuard.bind(this));
    this._actorCommandWindow.setHandler('item',   this.commandItem.bind(this));
    this._actorCommandWindow.setHandler('cancel', this.selectPreviousCommand.bind(this));
    this.addWindow(this._actorCommandWindow);
};


createActorCommandWindow creates the command list for actors that you'll see when selecting the "fight" party command. First, we create a new instance of Window_ActorCommand (assigned to _actorCommandWindow). Then we set the handlers, for 'attack', 'skill', 'guard', 'item' and 'cancel' to the bound commandAttack, commandSkill, commandGuard, commandItem and selectPreviousCommand functions respectively. Finally, we add the actor command window to the window layer.

Scene_Battle.prototype.createHelpWindow = function() {
    this._helpWindow = new Window_Help();
    this._helpWindow.visible = false;
    this.addWindow(this._helpWindow);
};


createHelpWindow creates the battle scene help window. We create a new instance of Window_Help (assigned to _helpWindow), set its visible property to false so that it won't be visible right away, and add it to the window layer.

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);
};


createSkillWindow creates the window from which actors will select their skills when choosing the 'skill' command. We set temp var wy to the y coordinate plus height of the help window, and wh to the y coordinate of the status window less wy. Then we create a new instance of Window_BattleSkill (assigned to _skillWindow), passing in 0 and wy for the x and y (so it will be at the far left of the screen just below the help window) and Graphics.boxWidth and wh for the width and height (so it will be the full width of the screen and take up the remaining space between the help window and the status window).

We set the skill window's help window to _helpWindow and its 'ok' and 'cancel' handlers to the bound onSkillOk and onSkillCancel functions respectively, then add it to the window layer.

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);
};


Practically identical to the above, only using item instead of skill and Window_BattleItem instead of Window_BattleSkill.

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);
};


createActorWindow creates the window listing the party and its stats. First we create a new instance of Window_BattleActor (assigned to _actorWindow) passing in 0 for the x coordinate and the same y coordinate as the status window (to show it at the same vertical position). Then we set its 'ok' and 'cancel' handlers to the bound onActorOk and onActorCancel functions respectively, and add it to the window layer.

"But Trihan, if it creates the actor window at x coordinate 0, how come it's positioned to the right of the command window in actual battles?" I don't hear you cry because you didn't think of that until I mentioned it. Well, astute reader, the positioning magic is actually done by the window itself, as we'll see when we look at the window classes.

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);
};


Creating the enemy window is pretty much the same as the actor one, but because Window_BattleEnemy doesn't use the same prototype it has to be repositioned manually; there's an extra line there to set its x coordinate to the width of the game window less its own width (which positions it on the right side of the screen). In every other respect, it's identical, though it obviously replaces all occurrences of actor with enemy.

Scene_Battle.prototype.createMessageWindow = function() {
    this._messageWindow = new Window_Message();
    this.addWindow(this._messageWindow);
    this._messageWindow.subWindows().forEach(function(window) {
        this.addWindow(window);
    }, this);
};


To create the message window, first we create a new instance of Window_Message (assigned to _messageWindow) and add it to the window layer. Then we iterate through each element returned by its subWindows function (which returns an array consisting of the gold, choice, number and item selection windows) using 'window' as the iteration variable, and passing in a function that adds window to the window layer as well.

Scene_Battle.prototype.createScrollTextWindow = function() {
    this._scrollTextWindow = new Window_ScrollText();
    this.addWindow(this._scrollTextWindow);
};


Creating the scroll text window is much simpler. We create a new instance of Window_ScrollText (assigned to _scrollTextWindow) and add it to the window layer.

Scene_Battle.prototype.refreshStatus = function() {
    this._statusWindow.refresh();
};


The refreshStatus function just refreshes _statusWindow.

Scene_Battle.prototype.startPartyCommandSelection = function() {
    this.refreshStatus();
    this._statusWindow.deselect();
    this._statusWindow.open();
    this._actorCommandWindow.close();
    this._partyCommandWindow.setup();
};


startPartyCommandSelection should be self-explanatory in terms of its function. We refresh the status window, then deselect and open it, then close the command window and call the setup function of the party command window.

Scene_Battle.prototype.commandFight = function() {
    this.selectNextCommand();
};


commandFight is the function we bound to the 'fight' party command, and it just calls selectNextCommand so that the player can start giving actors their battle actions.

Scene_Battle.prototype.commandEscape = function() {
    BattleManager.processEscape();
    this.changeInputWindow();
};


commandEscape is the function we bound to the 'escape' party command. We call the processEscape function of BattleManager, and then the scene's changeInputWindow function to end the command selection.

Scene_Battle.prototype.startActorCommandSelection = function() {
    this._statusWindow.select(BattleManager.actor().index());
    this._partyCommandWindow.close();
    this._actorCommandWindow.setup(BattleManager.actor());
};


startActorCommandSelection does exactly what it says on the tin. First, in the status window, we select the index corresponding to the BattleManager's current actor. Then, we close the party command window and call the setup function of the actor command window passing in BattleManager's actor.

Scene_Battle.prototype.commandAttack = function() {
    BattleManager.inputtingAction().setAttack();
    this.selectEnemySelection();
};


commandAttack is the function bound to the 'attack' handler in the actor command window. We set the BattleManager's inputting action to attack, then put up the enemy selection window.

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();
};


commandSkill is the function bound to the 'skill' handler in the actor command window. We set the skill window's actor to the actor object in BattleManager, and the skill window's stype ID to the current ext data in the actor command window. Then we refresh, show and activate the skill window. Basically, this will display a list of skills the current actor knows which are of the same skill type as the command that was chosen.

Scene_Battle.prototype.commandGuard = function() {
    BattleManager.inputtingAction().setGuard();
    this.selectNextCommand();
};


commandGuard is the function bound to the 'guard' handler in the actor command window. We set BattleManager's inputting action to guard, then select the next command.

Scene_Battle.prototype.commandItem = function() {
    this._itemWindow.refresh();
    this._itemWindow.show();
    this._itemWindow.activate();
};


commandItem is the function bound to the 'item' handler in the actor command window. We simply refresh, show and activate the item window.

Scene_Battle.prototype.selectNextCommand = function() {
    BattleManager.selectNextCommand();
    this.changeInputWindow();
};


selectNextCommand is the function called when the input of an action is complete, as seen in commandGuard (the only default command that doesn't require further input). We call the selectNextCommand function of BattleManager and then changeInputWindow.

Scene_Battle.prototype.selectPreviousCommand = function() {
    BattleManager.selectPreviousCommand();
    this.changeInputWindow();
};


selectPreviousCommand is the function bound to the 'cancel' handler of the actor command window. We call the selectPreviousCommand function of BattleManager and then changeInputWindow.

Scene_Battle.prototype.selectActorSelection = function() {
    this._actorWindow.refresh();
    this._actorWindow.show();
    this._actorWindow.activate();
};


selectActorSelection begins the process of selecting an actor as the target of an action. We just refresh, show and activate the actor window.

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();
};


onActorOk is the function bound to the 'ok' handler of the actor window. We set temp variable action to the BattleManager's inputting action. Then we set the target of that action to the index of the actor window. Next, we hide the actor, skill and item windows. Finally, we select the next command.

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;
    }
};


onActorCancel is the function bound to the 'cancel' handler of the actor window. Set hide the actor window, then execute a switch statement against the current symbol in the actor command window. In the case that the current symbol is 'skill', we show and activate the skill window. If it's 'item', we show and activate the item window.

Scene_Battle.prototype.selectEnemySelection = function() {
    this._enemyWindow.refresh();
    this._enemyWindow.show();
    this._enemyWindow.select(0);
    this._enemyWindow.activate();
};


This function is called when an enemy needs to be selected as a target. We refresh and show the enemy window, select its first index, and then activate it.

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();
};


This is the function bound to the 'ok' handler of the enemy window. First, we set temp variable action to the BattleManager's inputting action, then set the target of that action to the index of the enemy window. Then, we hide the enemy, skill and item windows, and finally select the next command.

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;
    }
};


This is the function bound to the 'cancel' handler of the enemy window. We hide the enemy window, then execute a switch statement on the current symbol of the actor command window. If it's 'attack', we activate the actor command window. If it's 'skill', we show and activate the skill window. If it's 'item', we show and activate the item window.

Scene_Battle.prototype.onSkillOk = function() {
    var skill = this._skillWindow.item();
    var action = BattleManager.inputtingAction();
    action.setSkill(skill.id);
    BattleManager.actor().setLastBattleSkill(skill);
    this.onSelectAction();
};


This is the function bound to the 'ok' handler of the skill window. We set temp variable skill to the item selected in the skill window, then temp variable action to the BattleManager's inputting action. Then we set the skill associated with action to skill's ID, the last battle skill of BattleManager's actor to skill, and then we call onSelectAction, which we'll look at shortly.

Scene_Battle.prototype.onSkillCancel = function() {
    this._skillWindow.hide();
    this._actorCommandWindow.activate();
};


This is the function bound to the 'cancel' handler of the skill window. We hide the skill window and activate the actor command window.

Scene_Battle.prototype.onItemOk = function() {
    var item = this._itemWindow.item();
    var action = BattleManager.inputtingAction();
    action.setItem(item.id);
    $gameParty.setLastItem(item);
    this.onSelectAction();
};


This is the function bound to the 'ok' handler of the item window. We set temp variable item to the item selected in the item window, and action to the BattleManager's inputting action. We set the item associated with action to item's ID and the last item used by the party to item. Then we call onSelectAction.

Scene_Battle.prototype.onItemCancel = function() {
    this._itemWindow.hide();
    this._actorCommandWindow.activate();
};


This is the function bound to the 'cancel' handler of the item window. We hide the item window and activate the actor command window.

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();
    }
};


onSelectAction is a function called when an actor has been selected, which determines the next action to take. We set temp variable action to the BattleManager's inputting action. Then, we hide the skill and item windows. If the action does not need a selection, we go to the next command. Otherwise, if the action has an opponent scope, we move to enemy selection. Otherwise (meaning the scope must be for friendly units) we move to actor selection.

Scene_Battle.prototype.endCommandSelection = function() {
    this._partyCommandWindow.close();
    this._actorCommandWindow.close();
    this._statusWindow.deselect();
};


This function is called when BattleManager no longer has inputting actions (in other words, all actors have chosen what they're doing that turn). We close the party command and actor command windows and deselect the status window.

Phew! A lot to cover for the battle scene. Obviously, we still have to look at the other parts of the equation (BattleManager and the battle windows) but this covers a fair amount of the inner workings of MV's battle system.

Scene_GameOver

We'll end with something a bit smaller.

Scene_Gameover.prototype.create = function() {
    Scene_Base.prototype.create.call(this);
    this.playGameoverMusic();
    this.createBackground();
};


Other than the standard Scene_Base prototype create call, we start playing the game over music and create the background.

Scene_Gameover.prototype.start = function() {
    Scene_Base.prototype.start.call(this);
    this.startFadeIn(this.slowFadeSpeed(), false);
};


start is overwritten to include a fade in at slow fade speed (as the previous scene is faded out when the game over scene is called, we need to fade it back in so that it's visible).

Scene_Gameover.prototype.update = function() {
    if (this.isActive() && !this.isBusy() && this.isTriggered()) {
        this.gotoTitle();
    }
    Scene_Base.prototype.update.call(this);
};


We also need to overwrite update to add an additional check: if the scene is active, and not busy, and the player presses OK or touches the screen, we go to Scene_Title. Then we call the standard Scene_Base update function.

Scene_Gameover.prototype.stop = function() {
    Scene_Base.prototype.stop.call(this);
    this.fadeOutAll();
};


We also overwrite stop to fade out the screen for a more gradual transition after calling the standard Scene_Base stop function.

Scene_Gameover.prototype.terminate = function() {
    Scene_Base.prototype.terminate.call(this);
    AudioManager.stopAll();
};


And we also overwrite terminate! This one is to stop all audio using the stopAll function of AudioManager after calling the standard Scene_Base terminate.

Scene_Gameover.prototype.playGameoverMusic = function() {
    AudioManager.stopBgm();
    AudioManager.stopBgs();
    AudioManager.playMe($dataSystem.gameoverMe);
};


This function plays the game over music. First, we stop any currently-playing BGM or BGS, and then we play the game over ME as defined in the database.

Scene_Gameover.prototype.createBackground = function() {
    this._backSprite = new Sprite();
    this._backSprite.bitmap = ImageManager.loadSystem('GameOver');
    this.addChild(this._backSprite);
};


This function creates the background for the game over scene. We set a local variable called _backSprite to a new instance of Sprite, then set its bitmap to the system graphic 'GameOver' loaded by ImageManager. Finally, we add _backSprite as a child of the scene.

Scene_Gameover.prototype.isTriggered = function() {
    return Input.isTriggered('ok') || TouchInput.isTriggered();
};


This function determines whether the player has triggered input for the purposes of ending the game over scene. Returns true if the player has pressed the OK key, or touched a touch screen.

Scene_Gameover.prototype.gotoTitle = function() {
    SceneManager.goto(Scene_Title);
};


This function returns the player to the title screen, by using SceneManager's goto function passing in Scene_Title.

WE ARE DONE. Scenes are completely covered now. Angels will descend from on high, basking in the awe of your amazing scene-based knowledge. Bards will sing of this day for eons to come.

So what's next?

Well, as I said last issue, I'm still thinking of doing rpg_objects.js next, but feel free to make alternative suggestions. If I have no comments or suggestions when I go to write the next part, I'll just stick with that.

Until next time!