0

I am very new to the community and forgive me if I misword things but! I'm currently working on an text adventure game and I was wondering if it was possible to add pictures to specific choices.

I attached the code below in hopes someone could give me and example as to how you can attach the entry image to the first id. Will provide more code if needed.

const textElement = document.getElementById('text')
const optionButtonsElement = document.getElementById('adventure')
const backgroundMusic = new Audio('audio/1066AD.mp3')
var img = new Image();
img.src="./bonezone/entry.jpg" 
img.src="./bonezone/encounter.jpg"
img.src="./bonezone/enterflee.jpg"
img.src="./bonezone/chill.jpg"
img.src="./bonezone/betray.jpg"
img.src="./bonezone/betray2.jpg"


let state = {}

function startGame() {
  state = {}
  showTextNode(1)
}

function showTextNode(textDex) {
  const textNode = textNodes.find(textNode => textNode.id === textDex)
  textElement.innerText = textNode.text
  while (optionButtonsElement.firstChild) {
    optionButtonsElement.removeChild(optionButtonsElement.firstChild)
  }

  textNode.options.forEach(option => {
    if (showOption(option)) {
      const button = document.createElement('button')
      button.innerText = option.text
      button.classList.add('action')
      button.addEventListener('click', () => selectOption(option))
      backgroundMusic.play()
      backgroundMusic.volume = 0.5
      backgroundMusic.loop = true
      optionButtonsElement.appendChild(button)
    }
  })
}

function showOption(option) {
  return option.requiredState == null || option.requiredState(state)
}

function selectOption(option) {
  const nextTextNodeId = option.nextText
  if (nextTextNodeId <= 0) {
    return startGame()
  }
  state = Object.assign(state, option.setState)
  showTextNode(nextTextNodeId)
}
// var img = new Image();
// img.onload = function () {
// }
// img.src = "./bonezone/entry.jpg";
const textNodes = [
  {
    id: 1,
    text: 'You have entered the House of 1000 Mysteries. What will you do?',
    options: [
      {
        text: 'Stay',
        nextText: 2
      },
      {
        text: 'Leave',
        nextText: 10
      }
    ]
  },
   {
    id: 10,
    text: 'You win I guess?',
    options: [
      {
        text: 'Restart',
        nextText: -1
      }
    ]
  },
  {
    id: 2,
    text: 'You encounter a skeleTon, what do?',
    options: [
      {
      text: 'Hang out with skeleTon',
      nextText: 11
      },
      {
          text: 'Flee',
          nextText: 3 
      },
      {
          text: 'Beat its boney ass',
          nextText: 13
          }
    ]
  },
  ]
startGame()
body {
   background-image: url('https://ctl.s6img.com/society6/img/XwPVT5-2iWMchyOwGguQwyGpjyc/w_1500/coffee-mugs/swatch/~artwork,fw_4600,fh_2000,fy_-152,iw_4600,ih_2304/s6-original-art-uploads/society6/uploads/misc/cfcb876ea05e469aa8336908a988ade2/~~/dungeon-wall-twilight-mugs.jpg') ; 
   background-size: cover;
}
img {
   height: 350px;
}

body {
  padding: 0;
  margin: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100vw;
  height: 100vh;
  font-size: 25px;
  font-family: 'Yatra One', cursive;
}

.container {
  width: 650px;
  max-width: 80%;
  background-color: gray;
  padding: 10px;
  border-radius: 5px;
  box-shadow: 0 0 10px 2px;
}

.choice {
  display: grid;
  grid-template-columns: repeat(2, auto);
  gap: 10px;
  margin-top: 20px;
}

.action {
  background-color: blue;
  border: 3px solid black;
  border-radius: 5px;
  padding: 5px 10px;
  color: white;
  outline: none;
}
.action:hover {
  border-color: black;
}
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>House of 1000 Mysteries</title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="./css/style.css">
        <script defer src='./js/app.js'></script>
        <link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Yatra+One&display=swap" rel="stylesheet">
    </head>
    <body>
    <div class="container">
  <div id="text"></div>
  <img id="journey"
  src="./bonezone/entry.jpg">

  <div id="adventure" class="choice">
    <button class="action">choice 1</button>
    <button class="action">choice 2</button>
    <button class="action">choice 3</button>
    <button class="action">choice 4</button>
  </div>
    </body>
</html>
dangerdan
  • 11
  • 2
  • 1
    I believe you could make a running demo in a snippet. Try to edit your question, in the editor there's a "code snippet" button, where you can write separately HTML, JS and CSS. I can see one problem with this code already, you're overwriting `img.src` 8 times in a row – Jeremy Thille Jul 08 '21 at 14:55
  • @JeremyThille took me a minute to figure that out but there we go! – dangerdan Jul 08 '21 at 15:15

1 Answers1

0

What you could do is add an image: field to each textNode, and then display the image using journey.src = textNode.image :

const textElement = document.getElementById('text')
const optionButtonsElement = document.getElementById('adventure')
const backgroundMusic = new Audio('audio/1066AD.mp3')

let state = {}

function startGame() {
  state = {}
  showTextNode(1)
}

function showTextNode(textDex) {
  const textNode = textNodes.find(textNode => textNode.id === textDex)
  textElement.innerText = textNode.text
  while (optionButtonsElement.firstChild) {
    optionButtonsElement.removeChild(optionButtonsElement.firstChild)
  }

  journey.src = textNode.image; // <--- bam

  textNode.options.forEach(option => {
    if (showOption(option)) {
      console.log(``)
      const button = document.createElement('button')
      button.innerText = option.text
      button.classList.add('action')
      button.addEventListener('click', () => selectOption(option))
      backgroundMusic.play()
      backgroundMusic.volume = 0.5
      backgroundMusic.loop = true
      optionButtonsElement.appendChild(button)

    }
  })
}

function showOption(option) {
  return option.requiredState == null || option.requiredState(state)
}

function selectOption(option) {
  const nextTextNodeId = option.nextText
  if (nextTextNodeId <= 0) {
    return startGame()
  }
  state = Object.assign(state, option.setState)
  showTextNode(nextTextNodeId)
}

const textNodes = [{
    id: 1,
    text: 'You have entered the House of 1000 Mysteries. What will you do?',
    image: "https://picsum.photos/300/350",
    options: [{
        text: 'Stay',
        nextText: 2
      },
      {
        text: 'Leave',
        nextText: 10
      }
    ]
  },
  {
    id: 10,
    text: 'You win I guess?',
    image: "https://picsum.photos/301/350",
    options: [{
      text: 'Restart',
      nextText: -1
    }]
  },
  {
    id: 2,
    text: 'You encounter a skeleTon, what do?',
    image: "https://picsum.photos/302/350",
    options: [{
        text: 'Hang out with skeleTon',
        nextText: 11
      },
      {
        text: 'Flee',
        nextText: 3
      },
      {
        text: 'Beat its boney ass',
        nextText: 13
      }
    ]
  },
]
startGame()
body {
  background-image: url('https://ctl.s6img.com/society6/img/XwPVT5-2iWMchyOwGguQwyGpjyc/w_1500/coffee-mugs/swatch/~artwork,fw_4600,fh_2000,fy_-152,iw_4600,ih_2304/s6-original-art-uploads/society6/uploads/misc/cfcb876ea05e469aa8336908a988ade2/~~/dungeon-wall-twilight-mugs.jpg');
  background-size: cover;
}

img {
  height: 350px;
}

body {
  padding: 0;
  margin: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100vw;
  height: 100vh;
  font-size: 25px;
  font-family: 'Yatra One', cursive;
}

.container {
  width: 650px;
  max-width: 80%;
  background-color: gray;
  padding: 10px;
  border-radius: 5px;
  box-shadow: 0 0 10px 2px;
}

.choice {
  display: grid;
  grid-template-columns: repeat(2, auto);
  gap: 10px;
  margin-top: 20px;
}

.action {
  background-color: blue;
  border: 3px solid black;
  border-radius: 5px;
  padding: 5px 10px;
  color: white;
  outline: none;
}

.action:hover {
  border-color: black;
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>House of 1000 Mysteries</title>
  <meta name="description" content="">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="./css/style.css">
  <script defer src='./js/app.js'></script>
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Yatra+One&display=swap" rel="stylesheet">
</head>

<body>
  <div class="container">
    <div id="text"></div>
    <img id="journey" src="">

    <div id="adventure" class="choice">
      <button class="action">choice 1</button>
      <button class="action">choice 2</button>
      <button class="action">choice 3</button>
      <button class="action">choice 4</button>
    </div>
</body>

</html>
Jeremy Thille
  • 26,047
  • 12
  • 43
  • 63