JavaScript Checkout
// accesses html elements
const textElement = document.getElementById('text')
const optionButtonsElement = document.getElementById('option-buttons')
let state = {} // some options will result in modifications to character state
// start or restart function, sets html to first dialogue node
function startGame() {
state = {}
showTextNode(1)
}
function showTextNode(textNodeIndex) {
state.currentNode = textNodeIndex; // Store the current node id in the state object
const textNode = textNodes.find(textNode => textNode.id === textNodeIndex) // makes sure text node id updates as you move nodes
textElement.innerText = textNode.text // displays the text of the node on the html
// there can be a max of three option choices, if there are less listed in the node then the html element will not display
while (optionButtonsElement.firstChild) {
optionButtonsElement.removeChild(optionButtonsElement.firstChild)
}
// sets up option buttons and inputs the node text in the html element
textNode.options.forEach(option => {
if (showOption(option)) {
const button = document.createElement('button')
button.innerText = option.text
button.classList.add('btn')
button.addEventListener('click', () => selectOption(option)) // registers the user input of which option is clicked
optionButtonsElement.appendChild(button)
}
})
}
// some options only show up if the user's state has been altered by a certain action
function showOption(option) {
return option.requiredState == null || option.requiredState(state)
}
// Modifies the `selectOption` function
function selectOption(option) {
const nextTextNodeId = option.nextText;
if (nextTextNodeId <= 0) { // if the user clicks an option labeled Restart then the game will run again from the beginning
return startGame();
}
if (option.previousText === true) { // if the user clicks an option labeled Go Back then the game will go back to the previous text node the user had viewed
previous(); // Call the previous function directly
return;
}
state = Object.assign(state, option.setState); // if an answer choice modifies the state of the user it will be put into place here
showTextNode(nextTextNodeId);
}
function previous() {
const previousTextNodeId = findPreviousTextNodeId(state.currentNode); // Pass the current node id
showTextNode(previousTextNodeId); // shows the last node viewer viewed
}
// Modifies the `findPreviousTextNodeId` function
function findPreviousTextNodeId(textNodeIndex) {
const previousTextNode = textNodes.find(node =>
node.options && node.options.some(option => option.nextText === textNodeIndex) // finds and saves the id of the last node the viewer viewed
);
return previousTextNode ? previousTextNode.id : -1; // Updates the default value to -1
}
const textNodes = [
{
id: 1,
text: 'What\'s this, you want to challenge me on my Java knowledge of Unit 1: Primitive Types? \n\n(Marlene will ask you two conceptual questions and explain several concepts. Pay close attention as they will be useful to you later on. Estimated time: 10 minutes.)',
options: [
{
text: 'Yes, It\'ll be an equal exchange.',
nextText: 2
},
{
text: 'I heard you were the best in the class on this unit.',
nextText: 2
}
]
},
{
id: 3,
text: 'Tell me some key characteristic of Primitives Data Types.',
options: [
{
text: 'Primitives are predefined, can be null, can call methods, and have all the same sizes.',
nextText: 10
},
{
text: 'Primitives are predefined, always have a value, can\'t call methods, and have type dependent sizes.',
nextText: 4
},
{
text: 'Primitives are defined by you, can be null, can call methods, and have type dependent sizes.',
nextText: 10
}
]
},
{
id: 10,
text: 'That\'s not quite right. Try Again.',
options: [
{
text: 'Go Back',
previousText: true
},
{
text: 'Restart',
nextText: -1
}
]
}
]