diff --git a/JavaScript/code-style.md b/JavaScript/code-style.md index e9fbcbc..0802438 100644 --- a/JavaScript/code-style.md +++ b/JavaScript/code-style.md @@ -35,7 +35,7 @@ gameFunctions, etc. - getter names do not contain the word "get" (or return, etc.) - setter names do contain the word "set" (although these should be rare) - camelCase for most items - - PascalCase + - PascalCase for Objects ### New ideas from one of us: @@ -50,8 +50,8 @@ gameFunctions, etc. room.doors(), entity.inventoryList(), etc. - Procedures (change something and rarely return values other than errors/success) - - Name describes the side effects + - Name describes the side effects (changes effected outside the function) - Usually contain a verb - - Rarely contains "And" - could be a sign of too much in one procedure + - Rarely contain "And" - could be a sign of too much in one procedure - Good examples: player.setLocation(newRoom), updateDisplay(), displayMessage(message) diff --git a/JavaScript/index.html b/JavaScript/index.html index f782496..2b3b7ca 100644 --- a/JavaScript/index.html +++ b/JavaScript/index.html @@ -18,11 +18,12 @@
- +
-
+
-
+

@@ -42,6 +43,7 @@ + diff --git a/JavaScript/js/config.js b/JavaScript/js/config.js index f48e102..44ee6a9 100644 --- a/JavaScript/js/config.js +++ b/JavaScript/js/config.js @@ -148,9 +148,9 @@ const setupData = { }, { name: "pathway", - descriptions: ["A long, twisting corridor."], + descriptions: ["A long, twisting path."], connectingRooms: [{ - located: "west", + located: "east", inRoom: "Backyard" },{ located: "east", diff --git a/JavaScript/js/descriptorDefinition.js b/JavaScript/js/descriptorDefinition.js new file mode 100644 index 0000000..6c080ed --- /dev/null +++ b/JavaScript/js/descriptorDefinition.js @@ -0,0 +1,24 @@ +/** + * For displaying descriptions to the player (text about game that replaces itself) + */ +class Descriptor { + + /** + * @param descriptionArea A dom object in which to place description text + */ + constructor($descriptionArea) { + this.descriptionArea = $descriptionArea // A dom object in which to place text + + /** + * @param description An info string to display to the user + */ + this.display = description => { + // Format the description for html + const htmlDescription = `
${description}
` + + // Display the description + this.descriptionArea.children().remove() + this.descriptionArea.append(htmlDescription) + } + } +} \ No newline at end of file diff --git a/JavaScript/js/gameDefinition.js b/JavaScript/js/gameDefinition.js index c072d30..610bbf8 100644 --- a/JavaScript/js/gameDefinition.js +++ b/JavaScript/js/gameDefinition.js @@ -1,13 +1,23 @@ -// Jacob's working on this... - +/** + * Main game object that controls game flow. + */ class Game { + + /** + * @param setupData An object specifcally formatted to provide info to the game. + * See config.js for example structure. + */ constructor(setupData) { - //setup the DOM with jquery + // Link the DOM command input area using jQuery const $userInput = $("#command") - const $outputBox = $("#message") - //create a messenger with access to the dom output box - const messenger = new Messenger($outputBox) + // Link the DOM output areas using jQuery + const $messageArea = $("#message") + const messenger = new Messenger($messageArea) + const $nameArea = $("#name") + const roomNamer = new Descriptor($nameArea) + const $descriptionArea = $("#description") + const descriptor = new Descriptor($descriptionArea) //create a new interpreter/parser with availible commands and synonyms const parser = new Parser({ @@ -19,10 +29,15 @@ class Game { drop: ['drop', 'd', 'leave', 'throw', 'abandon'] }) - //init the game state + // Initialize the game state let {_player, _rooms, _doors, _currentRoom} = loadGame(setupData) - // Sets up the game data with gameData (or loads previous game) + /** + * Loads a game from a saved game state (or initializes from a default state). + * + * @param gameData Specifically formatted object that represents the game state. + * See config.js for example structure. + */ function loadGame(gameData) { const player = gameData.entities.player const gameState = { @@ -68,16 +83,15 @@ class Game { return gameState } - //debug function that shows info about room in UI - function displayRoomStats(room){ - $('#room').text(room.name()) - $('#description').text(room.description()) - $('#items').text(room.listOfItems()) + // Function to display initial info about the current room + function displayRoomInfo(room) { + roomNamer.display(room.name()) + descriptor.display(room.description()) } //run function starts the game accepting input this.run = () => { - displayRoomStats(_currentRoom) + displayRoomInfo(_currentRoom) $userInput.on('keydown', (event) => { //user presses enter @@ -107,7 +121,7 @@ class Game { //clear the input field $userInput.val('') - displayRoomStats(_currentRoom) + displayRoomInfo(_currentRoom) } else if(event.which === 38){//Up arror pushed $userInput.val(parser.getLastCommandHistory()) @@ -125,7 +139,7 @@ class Game { checkWinningConditions() } else{ - messenger.addOutput(`You can't go ${direction}.`) + messenger.addMessage(`You can't go ${direction}.`) } } @@ -136,12 +150,12 @@ class Game { $('#items').text(_currentRoom.listOfItems()) } else{ - messenger.addOutput(`There's no ${itemName} here.`) + messenger.addMessage(`There's no ${itemName} here.`) } } function inventory() { - messenger.addOutput(_player.inventory()) + messenger.addMessage(_player.inventory()) } function drop(itemName) { @@ -150,7 +164,7 @@ class Game { _currentRoom.addItem(item) } else{ - messenger.addOutput(`You don't have a ${itemName}.`) + messenger.addMessage(`You don't have a ${itemName}.`) } checkWinningConditions() diff --git a/JavaScript/js/messengerDefinition.js b/JavaScript/js/messengerDefinition.js index 899fe2f..4b6c4b5 100644 --- a/JavaScript/js/messengerDefinition.js +++ b/JavaScript/js/messengerDefinition.js @@ -1,24 +1,44 @@ -// Jacob's working on this... - +/** + * For displaying messages to the player + */ class Messenger { - constructor($outputBox) { - this.outputBox = $outputBox - this.outputHistory = [] - } - addOutput(str) { - this.outputHistory.push(str) - this.render() - } + /** + * @param messageArea A dom object in which to place message text + */ + constructor($messageArea) { + const _messageArea = $messageArea // A dom object in which to place messages + let _messageHistory = [] // A list of all previous messages, newest first + + /** + * @param message A string to display to the user + */ + this.addMessage = message => { + // Add the new message to the beginning of the history list (FILO) + _messageHistory.unshift(message) - clearHistory() { - this.outputHistory = [] - } + // And display all messages + this.render() + } + + this.clearHistory = () => { _messageHistory = [] } + + // Display the list of messages + this.render = () => { + // Trim off all but the last ten messages in the history (first ten in array) + const MAX_MESSAGES_TO_DISPLAY = 10 + let lastTenMessages = _messageHistory.slice(0, MAX_MESSAGES_TO_DISPLAY) + + // Create an html message list (using BEM css class structure) + let htmlMessages = lastTenMessages.reduce( + (acc, message) => acc + `
${message}
`, + '' + ) + let htmlMessagesGroup = `
${htmlMessages}
` - render() { - let listItems = this.outputHistory.reduce((acc, curr) => acc + `
${curr}
`, '') - let messagesList = `
${listItems}
` - this.outputBox.children().remove() - this.outputBox.append(messagesList) + // Replace current messages with the updated list + _messageArea.children().remove() + _messageArea.append(htmlMessagesGroup) + } } } \ No newline at end of file