Intro: This is a small text adventure game created with JavaScript, HTML5, and CSS.
Demo link: https://youtube.com/shorts/F167r8qaQok?feature=share
Note: This could have been done with fewer lines of code. Anyway you take it and do as you please
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>the Old Forest</title>
<link rel="stylesheet" href="a_new_world.css">
</head>
<body>
<div id="stage">
<h1>the Old Forest</h1>
<img src="" width="400" height="367">
<p id="output"></p>
<input id="input" type="text" placeholder="Enter your action...">
<button>enter</button>
</div>
<script src="a_new_world.js"></script>
<body>
</html>
*
{
font-family: Merriweather;
font-size: 15px;
color: #000;
padding: 0px;
margin: 0px;
}
@font-face
{
font-family: Merriweather;
src: url("C:/Users/petix/AppData/Local/Microsoft/Windows/Fonts/Merriweather-Regular.ttf");
}
@font-face
{
font-family: Merriweather-Bold;
src: url("C:/Users/petix/AppData/Local/Microsoft/Windows/Fonts//Merriweather-Bold.ttf");
}
@font-face
{
font-family: Ginga;
src: url("C:/Users/petix/AppData/Local/Microsoft/Windows/Fonts//Ginga.ttf");
}
h1
{
text-align: center;
font-family: Ginga;
font-size: 80px;
padding-bottom: 10px;
padding-top: 20px;
font-weight: normal;
}
em
{
font-size: 14px;
}
p
{
width: 300px;
margin: 0px auto;
}
img
{
margin: 0px auto;
display: block;
margin-bottom: 20px;
}
input
{
position: absolute;
bottom: 30px;
left: 135px;
width: 160px;
padding: 2px 2px 2px 5px;
border: 1px solid black;
background-color: rgba(255,255,255,0.3);
-webkit-box-shadow: 5px 5px 3px rgba(0,0,0,0.5);
-moz-box-shadow: 5px 5px 3px rgba(0,0,0,0.5);
box-shadow: 3px 3px 5px rgba(0,0,0,0.4);
margin-top: 20px;
display: block;
margin-left: auto;
margin-right: auto;
}
button
{
position: absolute;
bottom: 30px;
left: 310px;
height: 25px;
width: 50px;
font-family: Merriweather;
font-size: 14px;
color: #000;
border: 1px solid #000;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
background:-webkit-linear-gradient(top, rgba(255,255,255,0.6), rgba(0,0,0,0.2));
background:-moz-linear-gradient(top, #a3a3a3, rgba(0,0,0,0.2));
background: linear-gradient(top, #a3a3a3, rgba(0,0,0,0.2));
-webkit-box-shadow: 5px 5px 3px rgba(0,0,0,0.5);
-moz-box-shadow: 5px 5px 3px rgba(0,0,0,0.5);
box-shadow: 3px 3px 5px rgba(0,0,0,0.4);
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
display: block;
margin: 10px auto 0 auto;
}
body{
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
#stage
{
width: 500px;
height: 700px;
background-color: gray;
position: relative;
background-image: url("C:/Users/petix/Downloads/page1.png");
text-align: center;
padding-bottom: 50px;
}
// Create the map
var map = [];
map[0] = "An old stone keep.";
map[1] = "A deep well.";
map[2] = "A sunny glade.";
map[3] = "A sleeping dragon.";
map[4] = "A narrow pathway.";
map[5] = "A bridge.";
map[6] = "An ancient gate.";
map[7] = "The edge of a river.";
map[8] = "A lonely wooden bench.";
map[9] = "An isolated cottage. Faint music comes from inside.";
// Set the player's start location
var mapLocation = 4;
// Set the images
var images = [];
images[0] = "keep.jpg";
images[1] = "well.jpg";
images[2] = "glade.jpg";
images[3] = "dragon.jpeg";
images[4] = "path.jpg";
images[5] = "bridge.jpg";
images[6] = "gate.jpg";
images[7] = "river.jpg";
images[8] = "bench.jpg";
images[9] = "cottage.jpg";
// Set the new images for when riddles are solved
var solvedImages = [];
solvedImages[0] = "solved_bridge.png"; // Image after solving the first riddle
solvedImages[1] = "solved_river.png"; // Image after solving the second riddle
solvedImages[2] = "solved_dragon.jpeg"; // Image after solving the third riddle
// Set the blocked-path messages
var blockedPathMessages = [];
blockedPathMessages[0] = "The path is blocked by thick brambles.";
blockedPathMessages[1] = "A steep cliff prevents you from going east.";
blockedPathMessages[2] = "The path is flooded and impassable.";
blockedPathMessages[3] = "A large boulder blocks your way.";
blockedPathMessages[4] = "A landslide blocks the path.";
blockedPathMessages[5] = "The way is blocked by a raging fire.";
blockedPathMessages[6] = "The path is covered in ice.";
blockedPathMessages[7] = "A magical barrier blocks your way.";
blockedPathMessages[8] = "A fallen tree blocks the path.";
var riddleSolved = [false, false, false]; // Track which riddles have been solved
var riddleAttempts = [3, 3, 3]; // Track remaining attempts for each riddle
//sets the text that is displayed when the user is at the riddle location
var riddleLocationMessages = [];
riddleLocationMessages[0] = "A huge troll stands in the middle of the bridge blocking your way to the other side. He asks you a riddle.";
riddleLocationMessages[1] = "An eerie looking water nymph stands in the river and prevents you from moving with her magical powers.<br>She asks you a riddle.";
riddleLocationMessages[2] = "You are now in an old castle standing before a dragon sleeping on treasure. A sinister dwarf appears before you and asks you a riddle.";
// Set the positive fate Messages
var positiveFateMessages = [];
positiveFateMessages[0] = "<br>" + "The troll disappears. Now you can walk safely over the bridge.";
positiveFateMessages[1] = "<br>" + "The river nymph disappears.";
positiveFateMessages[2] = "You are suddenly transported back home safely standing in your backyard.";
//set the negative fate messages
var negativeFateMessages = [];
negativeFateMessages[0] = "The troll stomps on the bridge and the bridge broke sending you into the fast-flowing river.";
negativeFateMessages[1] = "The river nymph calls for her other friends and they drown you in the river.";
negativeFateMessages[2] = "The dwarf steals a golden goblet from the dragon and disappears. The dragon wakes up, sees you, and burns you to a crisp.";
// Create the riddles and set their locations
var riddles = [];
riddles[0] = "<em><br>Riddle: Walk right through me, never feel me. Always lurking, never seen. What am I?</em>";
riddles[1] = "<em>Riddle: What always runs but never walks,<br>has a bed but never sleeps?</em>";
riddles[2] = "<em>Riddle: I am always hungry, I must always be fed,<br>The finger I touch will soon turn red.</em>";
var riddleLocations = [5, 7, 3];
var gameLost = false;
var answeredRight = false;
// Create an array of correct answers for the riddles
var riddleAnswers = ["air", "river", "fire"];
// Initialize the player's input
var playersInput = "";
// Initialize the gameMessage
var gameMessage = "";
// Create an array of actions the game understands
// and a variable to store the current action
var actionsIKnow = ["north", "east", "south", "west"];
var action = "";
// An array of items the game understands
// and a variable to store the current item
var answer = "";
// The img element
var image = document.querySelector("img");
// The input and output fields
var output = document.querySelector("#output");
var input = document.querySelector("#input");
// The button
var button = document.querySelector("button");
button.style.cursor = "pointer";
button.addEventListener("click", clickHandler, false);
// Display the player's location
render();
//when the button is pressed this fucntion is called
function clickHandler() {
playGame();
}
//create a function called playGame
function playGame() {
// Get the player's input and convert it to lowercase
playersInput = input.value.toLowerCase();
// Reset these variables from the previous turn
gameMessage = "";
action = "";
answer = "";
// Figure out the player's action
for (var i = 0; i < actionsIKnow.length; i++) {
if (playersInput.indexOf(actionsIKnow[i]) !== -1) {
action = actionsIKnow[i];
break;
}
}
// Figure if the player answered the riddle correctly
for (var i = 0; i < riddleAnswers.length; i++) {
if (playersInput.indexOf(riddleAnswers[i]) !== -1) {
//if the user answers the riddle correctly then
//the answer variable gets one of the riddle answers
answer = riddleAnswers[i];
}
}
// if the player arrives at a riddle location and if it's not solved
if (riddleLocations.includes(mapLocation) && !riddleSolved[riddleLocations.indexOf(mapLocation)]) {
//get the index of the riddle location
var riddleIndex = riddleLocations.indexOf(mapLocation);
//if the player answered the riddle correctly
if (answer === riddleAnswers[riddleIndex]) {
//display a positive fate message
gameMessage = positiveFateMessages[riddleIndex];
//mark the riddle as solved
riddleSolved[riddleIndex] = true;
riddles[riddleIndex] = ""; // Remove the riddle
riddleLocationMessages[riddleIndex] = ""; // Remove the riddle location message
images[mapLocation] = solvedImages[riddleIndex]; // Change the image
if (riddleIndex === 2) { // Check if the final riddle is solved
//answeredRight gets true as its value
answeredRight = true;
}
} else {
//if the player gives a wrong answer attempt will be decreased by one
riddleAttempts[riddleIndex]--;
//if the player uses all their attempts
if (riddleAttempts[riddleIndex] <= 0) {
//if the riddle location is 5
if (mapLocation === 5) {
//display a negative message
gameMessage = negativeFateMessages[0] + "<br>" + " Game over!!";
//set gameLost to true
gameLost = true;
//if the riddle location is 7
} else if (mapLocation === 7) {
//display a negative message
gameMessage = negativeFateMessages[1] + "<br>" + " Game over!!";
//set gameLost to true
gameLost = true;
//if the riddle location is 3
} else if (mapLocation === 3) {
//display a negative message
gameMessage = negativeFateMessages[2] + "<br>" + " Game over!!";
//set gameLost to true
gameLost = true;
}
} else {
gameMessage = "Incorrect answer. You have " + riddleAttempts[riddleIndex] + " attempts left.";
}
}
} else {
// Determine the target location based on the action
var targetLocation = mapLocation;
//set the value of blockedPathMessage to an empty string
var blockedPathMessage = "";
//display block messages if the user wants to go outside the map area
switch (action) {
case "north":
//move the player up
if (mapLocation >= 3) {
//
targetLocation -= 3;
} else {
blockedPathMessage = blockedPathMessages[0];
}
break;
case "east":
//move the player right
if (mapLocation % 3 != 2) {
targetLocation += 1;
} else {
blockedPathMessage = blockedPathMessages[1];
}
break;
case "south":
//move the player down
if (mapLocation < 6) {
targetLocation += 3;
} else {
blockedPathMessage = blockedPathMessages[2];
}
break;
case "west":
//move the player left
if (mapLocation % 3 != 0) {
targetLocation -= 1;
} else {
blockedPathMessage = blockedPathMessages[3];
}
break;
}
//if the
if (targetLocation === mapLocation) {
gameMessage = blockedPathMessage;
// Ensure that the player can only access riddle locations sequentially
} else if (targetLocation === riddleLocations[1] && !riddleSolved[0]) {
gameMessage = "You must solve the first riddle before you can proceed.";
} else if (targetLocation === riddleLocations[2] && !riddleSolved[1]) {
gameMessage = "You must solve the second riddle before you can proceed.";
} else {
mapLocation = targetLocation; // Update the player's location
}
}
// Reset the player's input field to an empty string
input.value = "";
// Disable input and button if game is lost or final riddle is solved
if (gameLost || answeredRight) {
output.innerHTML = "<br><em>" + gameMessage + "</em>";
input.disabled = true;
button.disabled = true;
}
// Render the game
render();
}
function render() {
// Render the location
output.innerHTML = " Try any of these words: " + "<br>" + "north, east, south, west";
image.src = "C:/Users/petix/OneDrive/Desktop/" + images[mapLocation];
// Display an item if there's one in this location
var riddleIndex = riddleLocations.indexOf(mapLocation);
if (riddleIndex !== -1 && riddles[riddleIndex] !== "") {
output.innerHTML = riddleLocationMessages[riddleIndex] + '<br>' + riddles[riddleIndex];
}
// Display the game message
if (gameLost) {
output.innerHTML = "<br><em>" + gameMessage + "</em>";
}
//if the gameMessage is still empty then display this
else if(gameMessage) {
output.innerHTML += "<br><em>" + gameMessage + "</em>";
}
}