じ☆ve冰风 发表于 2026-7-27 18:34:01

MVQuizzer - Educational Game Engine

MVQuizzer v0.4
by Starbird

Free for non-commercial use.

This system helps game developers create educational games or in-game quizzes very quickly.

Note: This plugin is NOT plug-and-play. Detailed instructions for the simple setup steps are included.


THE BASICS:
What does it do? MVQuizzer displays and evaluates multiple choice, true/false, and short answer questions. The system allows you to create and manage a large database of questions with ease. Quickly add or change questions without having to step through maps and events.

FEATURES:

getQuestion.js
Plugin reads questions from a js file in the plugins.
questionDatabase.js
JSON-based question database. Questions can either be left human-readable or encoded to hinder cheating. Easily balance rewards/penalties in a simple text editor.

Create questions using included html forms. Just copy and paste the resulting text string into questionDatabase.js

Multiple Choice Questions
* Ask and evaluate multiple choice questions with two to five response choices displayed in randomized order
* Include image and sound files with questions
* Optional question timer

True / False Questions
* Ask and evaluate true/false questions
* Include image and sound files with questions
* Optional question timer

Short Answer Questions
* Ask and evaluate short answer questions
* Include image files with questions
* Option to check for proper capitalization
* Optional question timer
* Keyboard and mouse input

Reward / Penalty System
* Assign rewards and penalties for right and wrong answers.

Streaks/Slumps
Easily track streaks and slumps using included switches and counters to trigger event listeners.

DOCUMENTATION:
Full documentation PDF included in demo file below.

CODE
                JavaScript:       
// DON'T TOUCH ANYTHING BELOW HERE UNLESS YOU KNOW WHAT YOU'RE DOING :)

// --- MV QUIZZER ------------------------------
// MVQ Pulls questions from QuestionDatabase.js. Determines question type and calls functions to process by type. Formats text str to fit in message boxes

/*:
* @plugindesc MVQuizzer uses the associated QuestionDatabas.js file in the plugin folder to ask true/false, multiple choice, and short answer style questions. It evaluates the answers and provides in-game results.
* @author Starbird      
*
* @param Test Parameter
* @desc This is a description of a test parameter. This does not currently do anything in the plugin.
* @default 42

*/

// Game Variable 1 - Stores text input strings for answering Short Answer questions
// Game Variable 2 - Stores the question number and determines which question to pull next from the database.
// Game Variable 3 - Stores the total number of correct answers
// Game Variable 4 - Stores the total number of wrong answers
// Game Variable 5 - Stores question timer result -- not yet implemented

// Game Switch 2 - Switch that activates upon correct answer response
// Game Switch 3 - Switch that activates upon wrong answer response

// Picture 1 and 2 used


// DETERMINE QUESTION TYPE. also determines string length and sends to line break function for formatting if necessary
getQuestion = function(questionNumber){

switch (questionDatabase.Questions[(questionNumber - 1)].Q_T) {
case 1:
var str = questionDatabase.Questions[(questionNumber - 1)].Q
if (str.length > 160){
str = '\\}'+ str
var formattedQuestion = stringDivider(str, 70, '\n')
AskShortAnswerQuestion(questionNumber, formattedQuestion)
}
else{
var formattedQuestion = stringDivider(str, 37, '\n')
AskShortAnswerQuestion(questionNumber, formattedQuestion)
}
break;
case 2:
var str = questionDatabase.Questions[(questionNumber - 1)].Q
if (str.length > 200){
str = '\\}'+ str
var formattedQuestion = stringDivider(str, 95, '\n')
AskTrueOrFalseQuestion(questionNumber, formattedQuestion)
}
else{
var formattedQuestion = stringDivider(str, 56, '\n')
AskTrueOrFalseQuestion(questionNumber, formattedQuestion)
}
break;
case 3:
AskMultipleChoiceQuestion(questionNumber) // reserved for 3-choice MC questions
break;
case 4:
var str = questionDatabase.Questions[(questionNumber - 1)].Q
if (str.length > 200){
str = '\\}'+ str
var formattedQuestion = stringDivider(str, 95, '\n')
AskMultipleChoiceQuestion(questionNumber, formattedQuestion)
}
else{
var formattedQuestion = stringDivider(str, 56, '\n')
AskMultipleChoiceQuestion(questionNumber, formattedQuestion)
}
break;
case 5:
AskMultipleChoiceQuestion(questionNumber) // reserved for 5-choice MC questions
break;
default:
console.log('check question type for question #' + questionNumber + ' in database')
}

}


//--- ASK QUESTIONS -----------------------------

// BEGIN MULTIPLE CHOICE SECTION

//ASKS MULTIPLE CHOICE QUESTIONS
AskMultipleChoiceQuestion = function(questionNumber, formattedQuestion) {
var questionText = questionDatabase.Questions[(questionNumber - 1)].Q;
var correctAnswer = questionDatabase.Questions[(questionNumber - 1)].C_A;
var answerTwo = questionDatabase.Questions[(questionNumber - 1)].A2;
var answerThree = questionDatabase.Questions[(questionNumber - 1)].A3;
var answerFour = questionDatabase.Questions[(questionNumber - 1)].A4;

//Image processing for Multiple Choice questions
var isImg = questionDatabase.Questions[(questionNumber - 1)].I
if (isImg == 1) {
$gameScreen.showPicture(1, questionDatabase.Questions[(questionNumber - 1)].GUID, 0, 0, 0, 100, 100, 255, 0) || (1, 'imgError', 0, 0, 0, 100, 100, 255, 0)}   //come back to this
else {};

var isAudio = questionDatabase.Questions[(questionNumber - 1)].A


// puts question in message box
$gameMessage.add(formattedQuestion);

//Plays audio file if there is one associated with the MC question
if (isAudio == 1){
$gameScreen.showPicture(2, 'audio', 0, 747, 0, 100, 100, 255, 0);
var audioFile = questionDatabase.Questions[(questionNumber - 1)].GUID
PlayAudio1(audioFile) || ('audio');}
else {};

   
//initialize timer for answering question
var d = new Date();
var timeInitial = d.getTime();

// 4-Question Multiple Choice Question Order Randomizer
var answerOrder = Math.floor(Math.random() * (24)) + 1;
switch (answerOrder) {
case 1:
    $gameMessage.setChoices(, 0, -1);
    var answerOffset =
    checkAnswer_MC(timeInitial, questionNumber, answerOffset, isImg, isAudio);
    break;
case 2:
    $gameMessage.setChoices(, 0, -1);
    var answerOffset = ;
    checkAnswer_MC(timeInitial, questionNumber, answerOffset, isImg, isAudio);
    break;
case 3:
    $gameMessage.setChoices(, 0, -1);
    var answerOffset = ;
    checkAnswer_MC(timeInitial, questionNumber, answerOffset, isImg, isAudio);
    break;
case 4:
    $gameMessage.setChoices(, 0, -1);
    var answerOffset = ;
    checkAnswer_MC(timeInitial, questionNumber, answerOffset, isImg, isAudio);
    break;
case 5:
    $gameMessage.setChoices(, 0, -1);
    var answerOffset = ;
    checkAnswer_MC(timeInitial, questionNumber, answerOffset, isImg, isAudio);
    break;
case 6:
    $gameMessage.setChoices(, 0, -1);
    var answerOffset = ;
    checkAnswer_MC( timeInitial, questionNumber, answerOffset, isImg, isAudio);
    break;
case 7:
    $gameMessage.setChoices(, 0, -1);
    var answerOffset = [-1, 1, -1, 1];
    checkAnswer_MC(timeInitial, questionNumber, answerOffset, isImg, isAudio);
    break;
case 8:
    $gameMessage.setChoices(, 0, -1);
    var answerOffset = [-1, 1, 0, 0];
    checkAnswer_MC(timeInitial, questionNumber, answerOffset, isImg, isAudio);
    break;
case 9:
    $gameMessage.setChoices(, 0, -1);
    var answerOffset = [-1, -1, -1, 3];
    checkAnswer_MC(timeInitial, questionNumber, answerOffset, isImg, isAudio);
    break;   
case 10:
    $gameMessage.setChoices(, 0, -1);
    var answerOffset = [-1, -1, 2, 0];
    checkAnswer_MC(timeInitial, questionNumber, answerOffset, isImg, isAudio);
    break;   
case 11:
    $gameMessage.setChoices(, 0, -1);
    var answerOffset = [-1, -2, 0, 3];
    checkAnswer_MC(timeInitial, questionNumber, answerOffset, isImg, isAudio);
    break;
case 12:
    $gameMessage.setChoices(, 0, -1);
    var answerOffset = [-1, -2, 2, 1];
    checkAnswer_MC(timeInitial, questionNumber, answerOffset, isImg, isAudio);
    break;
case 13:
    $gameMessage.setChoices(, 0, -1);
    var answerOffset = [-2, 1, 1, 0];
    checkAnswer_MC(timeInitial, questionNumber, answerOffset, isImg, isAudio);
break;
case 14:
    $gameMessage.setChoices(, 0, -1);
    var answerOffset = [-2, 1, -1, 2];
    checkAnswer_MC(timeInitial, questionNumber, answerOffset, isImg, isAudio);
    break;
case 15:
    $gameMessage.setChoices(, 0, -1);
    var answerOffset = [-2, 0, 1, 0];
    checkAnswer_MC(timeInitial, questionNumber, answerOffset, isImg, isAudio);
    break;
case 16:
    $gameMessage.setChoices(, 0, -1);
    var answerOffset = [-2, 0, -1, 3];
    checkAnswer_MC(timeInitial, questionNumber, answerOffset, isImg, isAudio);
    break;
case 17:
    $gameMessage.setChoices(, 0, -1);
    var answerOffset = [-2, -2, 2, 2];
    checkAnswer_MC(timeInitial, questionNumber, answerOffset, isImg, isAudio);
    break;
case 18:
    $gameMessage.setChoices(, 0, -1);
    var answerOffset = [-2, -2, 1, 3];
    checkAnswer_MC(timeInitial, questionNumber, answerOffset, isImg, isAudio);
    break;   
case 19:
    $gameMessage.setChoices(, 0, -1);
    var answerOffset = [-3, 1, 0, 2];
    checkAnswer_MC(timeInitial, questionNumber, answerOffset, isImg, isAudio);
    break;
case 20:
    $gameMessage.setChoices(, 0, -1);
    var answerOffset = [-3, 1, 1, 1];
    checkAnswer_MC(timeInitial, questionNumber, answerOffset, isImg, isAudio);
    break;
case 21:
    $gameMessage.setChoices(, 0, -1);
    var answerOffset = [-3, 0, 0, 3];
    checkAnswer_MC(timeInitial, questionNumber, answerOffset, isImg, isAudio);
    break;   
case 22:
    $gameMessage.setChoices(, 0, -1);
    var answerOffset = [-3, 0, 2, 1];
    checkAnswer_MC(timeInitial, questionNumber, answerOffset, isImg, isAudio);
    break;   
case 23:
    $gameMessage.setChoices(, 0, -1);
    var answerOffset = [-3, -1, 1, 3];
    checkAnswer_MC(timeInitial, questionNumber, answerOffset, isImg, isAudio);
    break;
case 24:
    $gameMessage.setChoices(, 0, -1);
    var answerOffset = [-3, -1, 2, 2]
    checkAnswer_MC(timeInitial, questionNumber, answerOffset, isImg, isAudio);
    break;   
default:
console.log('something is wrong')
};
};

//CHECK ANSWER FOR MULTIPLE CHOICE QUESTION
checkAnswer_MC = function (timeInitial, questionNumber, answerOffset, isImg, isAudio){
var guid = questionDatabase.Questions[(questionNumber - 1)].GUID;
var questionText = questionDatabase.Questions[(questionNumber - 1)].Q;
var correctAnswer = questionDatabase.Questions[(questionNumber - 1)].C_A;
var answerTwo = questionDatabase.Questions[(questionNumber - 1)].A2;
var answerThree = questionDatabase.Questions[(questionNumber - 1)].A3;
var answerFour = questionDatabase.Questions[(questionNumber - 1)].A4;
var questionStandard = questionDatabase.Questions[(questionNumber - 1)].S || '';
var answerReward = questionDatabase.Questions[(questionNumber - 1)].R_A;

$gameMessage.setChoiceCallback(function (choice) {
//timer
var e = new Date();
var timeFinal = e.getTime();
var timeTaken = Math.round( ((timeFinal - timeInitial) / 1000) * 10 ) / 10;
//erases question pictures if there are any
if (isImg == 1) {
$gameScreen.erasePicture(1);
}
else {};
if (isAudio == 1) {
$gameScreen.erasePicture(2);
}
else {};
      //check and log answer response result
      var adjustedChoice = (choice - answerOffset)
      switch (adjustedChoice){
      
      case 0:                //RIGHT ANSWER ',"GUID":"' + guid in case GUID is needed
      var answerResult = '{"GUID":' +guid + ',"Q_N":' +questionNumber + ',"I_C":"Y","T":' + timeTaken + ',"Q_T":4,' + '"Q":"' + questionText + '","C_A":"' + correctAnswer + '","A2":"' + answerTwo + '","A3":"' + answerThree + '","A4":"' + answerFour + '","S":"' + questionStandard + '","R_A":'+ answerReward + '},'

      // record total correct answers
var totalCorrectAnswers = $gameVariables.value(3) + 1
$gameVariables.setValue(3, totalCorrectAnswers);

// calculate total percent correct
var percentCorrect = (totalCorrectAnswers / questionNumber) * 100;
var percentCorrect = Math.floor(percentCorrect);
saveGame(answerResult, percentCorrect);   
$gameSwitches.setValue(2, true);

// send to reward system
rewardSystem();
      
      break;
      
      case 1:                   //WRONG ANSWER
      var answerResult = '{"GUID":' +guid + ',"Q_N":' +questionNumber + ',"I_C":"N","G_A":"'+ answerTwo + '","T":' + timeTaken + ',"Q_T":4,' + '"Q":"' + questionText + '","C_A":"' + correctAnswer + '","A2":"' + answerTwo + '","A3":"' + answerThree + '","A4":"' + answerFour + '","S":"' + questionStandard + '","R_A":'+ answerReward + '},'
      console.log(answerResult);
      
       // record total wrong answers
       var totalWrongAnswers = $gameVariables.value(4) + 1
       $gameVariables.setValue(4, totalWrongAnswers);

       // calculate total percent correct
       var percentCorrect = (totalCorrectAnswers / questionNumber) * 100;
       var percentCorrect = Math.floor(percentCorrect);
      
      
       saveGame(answerResult, percentCorrect);      
       $gameSwitches.setValue(3, true);
      
      // send to penalty system
      penaltySystem();
      
      
      break;
      
      case 2:                //WRONG ANSWER
      var answerResult = '{"GUID":' +guid + ',"Q_N":' +questionNumber + ',"I_C":"N","G_A":"'+ answerThree + '","T":' + timeTaken + ',"Q_T":4,' + '"Q":"' + questionText + '","C_A":"' + correctAnswer + '","A2":"' + answerTwo + '","A3":"' + answerThree + '","A4":"' + answerFour + '","S":"' + questionStandard + '","R_A":'+ answerReward + '},'
      console.log(answerResult);
      
      // record total wrong answers
       var totalWrongAnswers = $gameVariables.value(4) + 1
       $gameVariables.setValue(4, totalWrongAnswers);

       // calculate total percent correct
       var percentCorrect = (totalCorrectAnswers / questionNumber) * 100;
       var percentCorrect = Math.floor(percentCorrect);
      
      
       saveGame(answerResult, percentCorrect);      
       $gameSwitches.setValue(3, true);
      
      // send to penalty system
      penaltySystem();
      
      
      break;
      
      case 3:                //WRONG ANSWER
      var answerResult = '{"GUID":' +guid + ',"Q_N":' +questionNumber + ',"I_C":"N","G_A":"'+ answerFour + '","T":' + timeTaken + ',"Q_T":4,' + '"Q":"' + questionText + '","C_A":"' + correctAnswer + '","Two":"' + answerTwo + '","Three":"' + answerThree + '","Four":"' + answerFour + '","S":"' + questionStandard + '","R_A":'+ answerReward + '},'
      console.log(answerResult);
      
      // record total wrong answers
       var totalWrongAnswers = $gameVariables.value(4) + 1
       $gameVariables.setValue(4, totalWrongAnswers);

       // calculate total percent correct
       var percentCorrect = (totalCorrectAnswers / questionNumber) * 100;
       var percentCorrect = Math.floor(percentCorrect);
      
      
       saveGame(answerResult, percentCorrect);      
       $gameSwitches.setValue(3, true);
      
      // send to penalty system
      penaltySystem();
      
      
      break;
      default:
      console.log('Something is wrong. The adjustedChoice value is: ' + adjustedChoice);
      };
    // save results from question response
   
   
    // $gameVariables.setValue(questionNumber, answerResult);
   
});
}
// ---------------END MULTIPLE CHOICE SECTION


// BEGIN TRUE FALSE SECTION
   
// ASKS TRUE OR FALSE QUESTION
AskTrueOrFalseQuestion = function(questionNumber, formattedQuestion){
var questionText = questionDatabase.Questions[(questionNumber - 1)].Q;
var correctAnswer = questionDatabase.Questions[(questionNumber - 1)].C_A;
var isImg = questionDatabase.Questions[(questionNumber - 1)].I;
var isAudio = questionDatabase.Questions[(questionNumber -1)].A;
//checks for any image associated with questions
if (isImg == 1) {
$gameScreen.showPicture(1, questionDatabase.Questions[(questionNumber - 1)].GUID, 0, 0, 0, 100, 100, 255, 0)}
else {};
//Plays audio file if there is one associated with the MC question
if (isAudio == 1){
$gameScreen.showPicture(2, 'audio', 0, 747, 0, 100, 100, 255, 0);
PlayAudio1(questionDatabase.Questions[(questionNumber - 1)].GUID) || ('audio');}   
else {};
$gameMessage.add(formattedQuestion);
//initialize timer
var d = new Date();
var timeInitial = d.getTime();
$gameMessage.setChoices(['True', 'False'], 0, -1);
checkAnswer_TF(questionNumber, timeInitial);
};

// CHECK ANSWER FOR TRUE OR FALSE QUESTION
checkAnswer_TF = function (questionNumber, timeInitial){
$gameMessage.setChoiceCallback(function (choice)
{
var guid = questionDatabase.Questions[(questionNumber - 1)].GUID;
var questionType = questionDatabase.Questions[(questionNumber - 1)].Q_T;
var questionText = questionDatabase.Questions[(questionNumber - 1)].Q;
var isImg = questionDatabase.Questions[(questionNumber - 1)].I;
var isAudio = questionDatabase.Questions[(questionNumber - 1)].A;
var correctAnswer = questionDatabase.Questions[(questionNumber - 1)].C_A;
var questionStandard = questionDatabase.Questions[(questionNumber - 1)].S || '';
var answerReward = questionDatabase.Questions[(questionNumber - 1)].R_A;   
//timer
var e = new Date();
var timeFinal = e.getTime();
var timeTaken = Math.round( ((timeFinal - timeInitial) / 1000) * 10 ) / 10;
//erases question pictures if there are any
if (isImg == 1) {
$gameScreen.erasePicture(1);
}
else {};
if (isAudio == 1) {
$gameScreen.erasePicture(2);
}
else {};
    if (choice == correctAnswer){                // CORRECT ANSWER
   if (correctAnswer == 0){
         correctAnswer = 'TRUE'
   }
   else {correctAnswer = 'FALSE'}
      
   var answerResult = '{"GUID":' +guid + ',"Q_N":' +questionNumber + ',"I_C":"Y","T":' + timeTaken + ',"Q_T":2,' + '"Q":"' + questionText + '","C_A":"' + correctAnswer + '","S":"' + questionStandard + '","R_A":'+ answerReward + '},'
   console.log(answerResult);
   
// record total correct answers
var totalCorrectAnswers = $gameVariables.value(3) + 1
$gameVariables.setValue(3, totalCorrectAnswers);

// calculate total percent correct
var percentCorrect = (totalCorrectAnswers / questionNumber) * 100;
var percentCorrect = Math.floor(percentCorrect);
saveGame(answerResult, percentCorrect);   
$gameSwitches.setValue(2, true);

// send to reward system
rewardSystem();
    }
      else {                                 //WRONG ANSWER
            if (correctAnswer == 0) {            
      var answerResult = '{"GUID":' +guid + ',"Q_N":' +questionNumber + ',"I_C":"N","G_A":"FALSE","T":' + timeTaken + ',"Q_T":2,' + '"Q":"' + questionText + '","C_A": "TRUE", "S":"' + questionStandard + '","R_A":'+ answerReward + '},'
      console.log(answerResult);
      
      // record total wrong answers
       var totalWrongAnswers = $gameVariables.value(4) + 1
       $gameVariables.setValue(4, totalWrongAnswers);

       // calculate total percent correct
       var percentCorrect = (totalCorrectAnswers / questionNumber) * 100;
       var percentCorrect = Math.floor(percentCorrect);
      
       saveGame(answerResult, percentCorrect);      
       $gameSwitches.setValue(3, true);   
      
       // send to penalty system
      penaltySystem();
      
      }
      else {
      var answerResult = '{"GUID":' +guid + ',"Q_N":' +questionNumber + ',"I_C":"N","G_A":"TRUE","T":' + timeTaken + ',"Q_T":2,' + '"Q":"' + questionText + '","C_A":"FALSE","S":"' + questionStandard + '","R_A":'+ answerReward + '},'   
      console.log(answerResult);
   
    // record total wrong answers
       var totalWrongAnswers = $gameVariables.value(4) + 1
       $gameVariables.setValue(4, totalWrongAnswers);

       // calculate total percent correct
       var percentCorrect = (totalCorrectAnswers / questionNumber) * 100;
       var percentCorrect = Math.floor(percentCorrect);
      
      
       saveGame(answerResult, percentCorrect);      
       $gameSwitches.setValue(3, true);

      // send to penalty system
      penaltySystem();
      
      };
      };
      // save results from question response
   // $gameVariables.setValue(questionNumber, answerResult);
   
      });
}

// ------------------END TRUE FALSE SECTION


// BEGIN SHORT ANSWER QUESTION SECTION

//CallsCmdInp.js authored by Darkkitten - used for Short Answer question

var $gameInterp = new Game_Interpreter();
function EnterText() {
$gameInterp.pluginCommand('enter_text');
}

// ASKS SHORT ANSWER QUESTION
var $gameInterp = new Game_Interpreter();
AskShortAnswerQuestion = function(questionNumber, formattedQuestion){
var correctAnswer = questionDatabase.Questions[(questionNumber - 1)].C_A;
var questionStandard = questionDatabase.Questions[(questionNumber - 1)].S;
var answerReward = questionDatabase.Questions[(questionNumber - 1)].R_A;
var imageFile = questionDatabase.Questions[(questionNumber - 1)].GUID
var isImg = questionDatabase.Questions[(questionNumber - 1)].I;
if (isImg == 0) {
var args = '1'+ ' ' + correctAnswer.length + ' ' + 'noImg' + ' ' + formattedQuestion   //answer variable, max length, image, question text
$gameInterp.pluginCommand('enter_text', args.split(' '));
console.log(formattedQuestion);
}
else {
var args = '1' + ' ' + correctAnswer.length + ' ' + imageFile + ' ' + formattedQuestion || '1' + ' ' + correctAnswer.length + ' ' + 'imgError' + ' ' + questionText
$gameInterp.pluginCommand('enter_text', args.split(' '));   
console.log(formattedQuestion);
}
}

// CHECK ANSWER FOR SHORT ANSWER QUESTION
checkAnswer_SA = function (questionNumber, answerText, timeInitial_SA) {
var guid = questionDatabase.Questions[(questionNumber - 1)].GUID;
var questionType = questionDatabase.Questions[(questionNumber - 1)].Q_T;
var questionText = questionDatabase.Questions[(questionNumber - 1)].Q;
var isImg = questionDatabase.Questions[(questionNumber - 1)].I;
var isAudio = questionDatabase.Questions[(questionNumber - 1)].A;
var correctAnswer = questionDatabase.Questions[(questionNumber - 1)].C_A;
var caseSensitive = questionDatabase.Questions[(questionNumber - 1)].C_S;
var questionStandard = questionDatabase.Questions[(questionNumber - 1)].S || '';
var answerReward = questionDatabase.Questions[(questionNumber - 1)].R_A;

// check for case sensitivity
if (caseSensitive == 0){
    var correctAnswer = correctAnswer.toLowerCase();
    var answerText = answerText.toLowerCase();
}
else {};
//timer
var e = new Date();
var timeFinal = e.getTime();
var timeTaken = Math.round( ((timeFinal - timeInitial_SA) / 1000) * 10 ) / 10;

//CHECK GIVEN ANSWER AGAINST CORRECT ANSWER

    // WHEN CORRECT ANSWER
if (answerText == correctAnswer){   

// record answer result
var answerResult = '{"GUID":' +guid + ',"Q_N":' +questionNumber + ',"I_C":"Y","T":' + timeTaken + ',"Q_T":1,' + '"Q":"' + questionText + '","C_A":"' + (correctAnswer) + '","S":"' + questionStandard + '","R_A":'+ answerReward + '},'
console.log(answerResult);

// record total correct answers
var totalCorrectAnswers = $gameVariables.value(3) + 1
$gameVariables.setValue(3, totalCorrectAnswers);

// calculate total percent correct
var percentCorrect = (totalCorrectAnswers / questionNumber) * 100;
var percentCorrect = Math.floor(percentCorrect);
saveGame(answerResult, percentCorrect);   
$gameSwitches.setValue(2, true);

// send to reward system
rewardSystem();

}
// WHEN WRONG ANSWER
else {

// record answer result
var answerResult = '{"GUID":' +guid + ',"Q_N":' +questionNumber + ',"I_C":"N","G_A":"'+ (answerText) + '","T":' + timeTaken + ',"Q_T":1,' + '"Q":"' + questionText + '","C_A":"' + (correctAnswer) + '","S":"' + questionStandard + '","R_A":'+ answerReward + '},'
console.log(answerResult);

// record total wrong answers
var totalWrongAnswers = $gameVariables.value(4) + 1
$gameVariables.setValue(4, totalWrongAnswers);

// calculate total percent correct
var percentCorrect = (totalCorrectAnswers / questionNumber) * 100;
var percentCorrect = Math.floor(percentCorrect);
saveGame(answerResult, percentCorrect);      
$gameSwitches.setValue(3, true);

// send to penalty system
penaltySystem();

}

};

// -----------END SHORT ANSWER SECTION



// UTILITY FUNCTIONS

// REWARD SYSTEM

rewardSystem = function(){
    playSoundEffect('MVQ_Wrong_Answer');
    var rewardType = questionDatabase.Questions[(questionNumber - 1)].R_T;
    var rewardId = questionDatabase.Questions[(questionNumber - 1)].R_I;
    var rewardAmount = questionDatabase.Questions[(questionNumber - 1)].R_A;
    var onlyLeader = questionDatabase.Questions[(questionNumber - 1)].O_L;
   
    if (rewardType == 'Enemy'){
      
    BattleManager.setup(rewardId, true, true);    // initiates battle but player can escape and can lose
    $gamePlayer.makeEncounterCount();
    SceneManager.push(Scene_Battle);
      
    };
   
    if (rewardType == 'Gold'){
    $gameParty.gainGold(rewardAmount);
    }
   if (rewardType == 'Armor'){
         $gameParty.gainItem($dataArmors, rewardAmount, true)
   };
   
    if (rewardType == 'Item'){
            $gameParty.gainItem($dataItems, rewardAmount);
    };
   
    if (rewardType == 'Weapon'){
            $gameParty.gainItem($dataWeapons, rewardAmount, true);
    };
   
   
    if (rewardType == 'HP'){
      
      if (onlyLeader == 1) {$gameParty.leader().gainHp(rewardAmount)}
      
      else{
            $gameParty.members().forEach(function(member){member.gainHp(rewardAmount)})
      }
      
      };
   
    if (rewardType == 'XP'){
      
      if (onlyLeader == 1) {$gameParty.leader().gainExp(rewardAmount)}
      
      else{
      $gameParty.members().forEach(function(member){member.gainExp(rewardAmount)})
      }
      
      
    };
   
    if (rewardType == 'MP'){
      if (onlyLeader == 1) {$gameParty.leader().gainHp(rewardAmount)}
      
      else{
      $gameParty.members().forEach(function(member){member.gainMp(rewardAmount)})
      }
    };
   
    if (rewardType == 'TP'){
      
      if (onlyLeader == 1) {$gameParty.leader().gainTp(rewardAmount)}
      
      else{      
      $gameParty.members().forEach(function(member){member.gainTp(rewardAmount)})
      }
    };
   
      
   if (rewardType == 'Skill'){
      if (onlyLeader == 1) {$gameParty.leader().gainHp(rewardAmount)}
      
      else{   
      $gameParty.members().forEach(function(member){member.learnSkill(rewardId)})
      }
   
   
   };
   
    if (rewardType == 'MHP'){
      if (onlyLeader == 1) {$gameParty.leader().addParam(0, rewardAmount)}
      
      else{
      $gameParty.members().forEach(function(member){member.addParam(0, rewardAmount)})
      }
      
         };
   
    if (rewardType == 'MMP') {
      if (onlyLeader == 1) {$gameParty.leader().addParam(1, rewardAmount)}
      
      else{
      $gameParty.members().forEach(function(member){member.addParam(1, rewardAmount)})
      }
    };
   
      if (rewardType == 'ATK') {
      if (onlyLeader == 1) {$gameParty.leader().addParam(2, rewardAmount)}
      
      else{
      $gameParty.members().forEach(function(member){member.addParam(2, rewardAmount)})
      }
   };
   
      if (rewardType == 'DEF') {
      if (onlyLeader == 1) {$gameParty.leader().addParam(3, rewardAmount)}
      
      else{
         $gameParty.members().forEach(function(member){member.addParam(3, rewardAmount)})
      }
   };
   
   if (rewardType == 'AddState') {
      if (onlyLeader == 1) {$gameParty.leader().addState(rewardId)}
      
      else{
      $gameParty.members().forEach(function(member){member.addState(rewardId)})
      }
         };
   

   
   if (rewardType == 'RemoveState') {
      if (onlyLeader == 1) {$gameParty.leader().removeState(rewardId)}
      
      else{
      $gameParty.members().forEach(function(member){member.removeState(rewardId)})
      }
      
         };
   

    // need to implement notetag reading to get good/bad/neutral quality of each state
    // if (rewardType == 'RemoveAllBadStates'){};   
   
   
    // no reward
    if (rewardType == 'None'){};
   
   
   
    };
   

// PENALTY SYSTEM

penaltySystem = function(){
    playSoundEffect('MVQ_Correct_Answer');
    var penaltyType = questionDatabase.Questions[(questionNumber - 1)].P_T;
    var penaltyID = questionDatabase.Questions[(questionNumber - 1)].P_I;
    var penaltyAmount = parseInt(questionDatabase.Questions[(questionNumber - 1)].P_A *-1);
    // var penaltyAmount = parseInt(penaltyAmount *-1);
    console.log(penaltyAmount)
    var onlyLeader = questionDatabase.Questions[(questionNumber - 1)].O_L;
   
    if (penaltyType == 'Enemy'){
      
    BattleManager.setup(rewardId, false, false);    // initiates battle where player cannot escape and must win or die
    $gamePlayer.makeEncounterCount();
    SceneManager.push(Scene_Battle);
      
    };
   
    if (penaltyType == 'Gold'){
    $gameParty.gainGold(penaltyAmount);
    }
   if (penaltyType == 'Armor'){
         $gameParty.gainItem($dataArmors, penaltyAmount, true)
   };
   
    if (penaltyType == 'Item'){
            $gameParty.gainItem($dataItems, penaltyAmount);
    };
   
    if (penaltyType == 'Weapon'){
            $gameParty.gainItem($dataWeapons, penaltyAmount, true);
    };
   
   
    if (penaltyType == 'HP'){
      
      if (onlyLeader == 1) {$gameParty.leader().gainHp(penaltyAmount)}
      
      else{
            $gameParty.members().forEach(function(member){member.gainHp(penaltyAmount)})
      }
      
      };
   
    if (penaltyType == 'XP'){
      
      if (onlyLeader == 1) {$gameParty.leader().gainExp(penaltyAmount)}
      
      else{
      $gameParty.members().forEach(function(member){member.gainExp(penaltyAmount)})
      }
      
      
    };
   
    if (penaltyType == 'MP'){
      if (onlyLeader == 1) {$gameParty.leader().gainHp(penaltyAmount)}
      
      else{
      $gameParty.members().forEach(function(member){member.gainMp(penaltyAmount)})
      }
    };
   
    if (penaltyType == 'TP'){
      
      if (onlyLeader == 1) {$gameParty.leader().gainTp(penaltyAmount)}
      
      else{      
      $gameParty.members().forEach(function(member){member.gainTp(penaltyAmount)})
      }
    };
   
      
   if (penaltyType == 'Skill'){
      if (onlyLeader == 1) {$gameParty.leader().gainHp(penaltyAmount)}
      
      else{   
      $gameParty.members().forEach(function(member){member.forgetSkill(penaltyId)})
      }
   
   
   };
   
    if (penaltyType == 'MHP'){
      if (onlyLeader == 1) {$gameParty.leader().addParam(0, penaltyAmount)}
      
      else{
      $gameParty.members().forEach(function(member){member.addParam(0, penaltyAmount)})
      }
      
         };
   
    if (penaltyType == 'MMP') {
      if (onlyLeader == 1) {$gameParty.leader().addParam(1, penaltyAmount)}
      
      else{
      $gameParty.members().forEach(function(member){member.addParam(1, penaltyAmount)})
      }
    };
   
      if (penaltyType == 'ATK') {
      if (onlyLeader == 1) {$gameParty.leader().addParam(2, penaltyAmount)}
      
      else{
      $gameParty.members().forEach(function(member){member.addParam(2, penaltyAmount)})
      }
   };
   
      if (penaltyType == 'DEF') {
      if (onlyLeader == 1) {$gameParty.leader().addParam(3, -penaltyType)}
      
      else{
         $gameParty.members().forEach(function(member){member.addParam(3, penaltyAmount)})
      }
   };
   
   if (penaltyType == 'AddState') {
      if (onlyLeader == 1) {$gameParty.leader().addState(penaltyId)}
      
      else{
      $gameParty.members().forEach(function(member){member.addState(penaltyId)})
      }
         };
   

   
   if (penaltyType == 'RemoveState') {
      if (onlyLeader == 1) {$gameParty.leader().removeState(penaltyId)}
      
      else{
      $gameParty.members().forEach(function(member){member.removeState(penaltyId)})
      }
      
         };
   

    // need to implement notetag reading to get good/bad/neutral quality of each state
    // if (penaltyType == 'RemoveAllBadStates'){};   
   
   
    // no penalty
    if (penaltyType == 'None'){};
   
   
   
}

playSoundEffect = function(audioFile){
   
   var se = {
            name: audioFile,
            volume: 100,
            pitch: 100,
            pan: 0
      }
   AudioManager.playSe(se);
   };

//Audio Function for MC and TF questions
PlayAudio1 = function(audioFile){
   
   var se = {
            name: questionDatabase.Questions[(questionNumber - 1)].GUID,
            volume: 100,
            pitch: 100,
            pan: 0
      }
   AudioManager.playSe(se);
   };



//--- Plugin Command call --------------------------------------------------      
var aliasPluginCommand = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args){
aliasPluginCommand.call(this, command, args);

// var parameters = PluginManager.parameters('GetQuestion');
// var variableBandwidth = parameters

console.log('GetQuestion plugin called')

//Fetches question by number
if(command == 'GetQuestion'){

// this loops the database back to the first question in the database if it gets to the end of the database
var questionNumber = $gameVariables.value(2) + 1;
var databaseLength = questionDatabase.Questions.length;
if (questionNumber > databaseLength) {
    var questionNumber = 1};

window.questionNumber = questionNumber;
console.log(questionDatabase);
console.log(questionNumber);
$gameVariables.setValue(2, (questionNumber));
getQuestion(questionNumber);
}   
}

//WORD WRAP FOR QUESTION FORMATTING
function stringDivider(str, width, spaceReplacer) {
    if (str.length>width) {
      var p=width
      for (;p>0 && str!=' ';p--) {
      }
      if (p>0) {
            var left = str.substring(0, p);
            var right = str.substring(p+1);
            return left + spaceReplacer + stringDivider(right, width, spaceReplacer);
      }
    }
    return str;
}

//ROT13 - Not currently used

function rot13(str)
{
    return (str ? str : this).split('').map(function(_)
   {
      if (!_.match(//)) return _;
      c = Math.floor(_.charCodeAt(0) / 97);
      k = (_.toLowerCase().charCodeAt(0) - 83) % 26 || 26;
      return String.fromCharCode(k + ((c == 0) ? 64 : 96));
   }).join('');
}

// dummy saveGame function

function saveGame (){}


//native save game
/*
function saveGame(answerResult, percentCorrect) {
      $gameSystem.onBeforeSave();
      var totalQuestions = $gameVariables.value(2)
      // Generate savegame data
      var json = JsonEx.stringify(DataManager.makeSaveContents());
      if (json.length >= 500001) {
            console.log('Save data too big');
      };   

      // Initialize HTTP Request
      var xhttp = new XMLHttpRequest();
      var data = "action=recordAnswer&guid="+encodeURIComponent(_guid)+"&userName="+encodeURIComponent(_userName)+"&password="+encodeURIComponent(_password)+"&gameName="+encodeURIComponent(_gameName)+"&gameVersion="+encodeURIComponent(_gameVersion)+"&gameData="+encodeURIComponent(json)+"&answerResult="+encodeURIComponent(answerResult)+"&percentRight="+encodeURIComponent(percentCorrect)+"&totalQuestions="+encodeURIComponent(totalQuestions);
      
      // Send savegame data
      xhttp.open('POST', _url+"/cloudmanager.php", false);
      xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
      xhttp.send(data);
      
      var result = xhttp.responseText;
      console.log(result);
      console.log('made it through save');
                  
    };
    */


End notes:

Known issues:
-Scene pop problem after defeating enemy on wrong answer (fix soon)
-occasional timer lag

There are a handful of features that I had intended to add to this plugin system, but with the upcoming release of MZ, I'm currently planning to revisit this plugin once I've purchased the new RPG Maker. Any further releases will probably be for that platform instead of MV.


本贴来自国际rpgmaker官方论坛作者:Starbird_Resources处,因国际论坛即将永久关站,为了存档多年珍贵资料,署名转载到本论坛存档,由于官方帖子为英文原帖,需要中文翻译请点击论坛顶部切换语言为中文就可以将帖子翻译成中文浏览,方便大家随时查看,原文地址:https://forums.rpgmakerweb.com/threads/mvquizzer-educational-game-engine.124179/
页: [1]
查看完整版本: MVQuizzer - Educational Game Engine