-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.js
More file actions
1526 lines (1286 loc) · 56 KB
/
Copy pathmain.js
File metadata and controls
1526 lines (1286 loc) · 56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
window.addEventListener("DOMContentLoaded", main);
/**
* Global variable containing an array of propertys for the game
* @typedef {Object} GameState
* @property {string} name Player's name for the character
* @property {number} money Player's current amount of money
* @property {string[]} inventory Player's current inventory items
* @property {string} scene Current scene name
* @property {Audio} audio Audio files used in the game
*/
/**
* @type {GameState}
*/
let gameState = {
name: "",
money: 50,
unlockedPaths: {
forestPathOne: false,
forestPathTwo: false,
cavePathOne: false,
cavePathTwo: false,
},
inventory: {
"Knife": 1,
},
scene: "StartScene",
audio: [
"assets/music/tawny-owl-in-molkom-sweden.mp3",
"assets/music/dark-mystery-cinematic-melody.mp3"
],
isMusicPlaying: false,
currentTrack: 0 // 0 = tawny-owl, 1 = dark-mystery
};
function createMusicToggle(container) {
const musicBtn = document.createElement("button");
musicBtn.textContent = gameState.isMusicPlaying ? "🔊" : "🔈";
musicBtn.classList.add("btn", "music-toggle");
musicBtn.setAttribute("aria-label", gameState.isMusicPlaying ? "Turn music off" : "Turn music on");
musicBtn.setAttribute("aria-pressed", gameState.isMusicPlaying);
musicBtn.addEventListener("click", () => {
gameState.isMusicPlaying = !gameState.isMusicPlaying;
if (gameState.isMusicPlaying) {
musicBtn.textContent = "🔊";
musicBtn.setAttribute("aria-label", "Turn music off");
playLoopAudio(gameState.currentTrack);
} else {
musicBtn.textContent = "🔈";
musicBtn.setAttribute("aria-label", "Turn music on");
audioTracks.forEach(track => {
track.pause();
track.currentTime = 0;
});
}
musicBtn.setAttribute("aria-pressed", gameState.isMusicPlaying);
saveGameState();
});
container.appendChild(musicBtn);
return musicBtn;
}
/**
* Create array of Audio objects from the files listed in the game state audio property
* @typedef {string} Audio
*/
const audioTracks = gameState.audio.map(audioFile => new Audio(audioFile));
/**
* Array of button names
*/
const buttonNames = ["West", "East", "North", "South", "Pick up", "Give coins", "Touch Orb", "Retry", "New character", "Start", "Play again"];
/**
* Set name and save state to local storage
* @param {string} name Username in the game to be set
*/
function setName(name) {
gameState.name = name;
saveGameState();
}
/**
* Set current money and save state to local storage
* @param {string} name - Amount of money
*/
function setMoney(name) {
gameState.money = name;
saveGameState();
}
/**
* Set current inventory and save state to local storage
* @param {string} name Inventory object
*/
function setInventory(name) {
gameState.inventory = name;
saveGameState();
}
/**
* Set current scene name and save state to local storage
* @param {string} name - Scene name to be set
*/
function setScene(name) {
gameState.scene = name;
saveGameState();
}
/**
* Update display of money and inventory
*/
function updateDisplay() {
const inventoryContainer = document.getElementById("inventory-container");
// Ensure the ul element exists
let itemList = inventoryContainer.querySelector("ul");
if (!itemList) {
itemList = document.createElement("ul");
itemList.classList.add("item-list");
inventoryContainer.appendChild(itemList);
}
// Update money item
const moneyItem = itemList.querySelector("li:first-child");
if (!moneyItem) {
const moneyItem = document.createElement("li");
moneyItem.textContent = "Coins (" + gameState.money + ")";
itemList.appendChild(moneyItem);
} else {
moneyItem.textContent = "Coins (" + gameState.money + ")";
}
// Clear inventory items (except the first one)
const inventoryItems = itemList.querySelectorAll("li:not(:first-child)");
inventoryItems.forEach(item => item.remove());
// Add new inventory items
for (const [item, quantity] of Object.entries(gameState.inventory)) {
const inventoryItem = document.createElement("li");
inventoryItem.textContent = `${item} (${quantity})`;
itemList.appendChild(inventoryItem);
}
saveGameState();
}
/**
* Increases the player's money if triggered
* @param {number} amount
*/
function increaseMoney(amount) {
gameState.money += amount;
saveGameState();
updateDisplay();
}
/**
* Decrease the player's money if triggered
* @param {number} amount The amount to decrease
*/
function decreaseMoney(amount) {
// Tries to decrease money, but also prevent negative number
if (gameState.money >= amount) {
gameState.money -= amount;
saveGameState();
updateDisplay();
} else {
console.log("Not enough money");
alert("Not enough money");
}
}
/**
* Adds item to player's inventory if new one or increment its quantity
* @param {string} item The name of the item to add
*/
function addItemToInventory(item) {
gameState.inventory[item] = (gameState.inventory[item] || 0) + 1;
saveGameState();
updateDisplay();
}
/**
* Removes item from the player's inventory if triggered
* @param {string} item The item name to be removed
*/
function removeItemFromInventory(item) {
if (gameState.inventory[item] > 0) {
gameState.inventory[item]--;
updateDisplay();
saveGameState();
} else {
console.log("Item not found in inventory");
alert("Item not found in inventory");
}
}
function createInventoryButton(index, action, value, container) {
// Check if this path is already unlocked
let isPathUnlocked = false;
switch (action) {
case "decreaseMoneyOne":
isPathUnlocked = gameState.unlockedPaths.forestPathOne;
break;
case "decreaseMoneyTwo":
isPathUnlocked = gameState.unlockedPaths.forestPathTwo;
break;
case "decreaseMoneyThree":
isPathUnlocked = gameState.unlockedPaths.cavePathOne;
break;
case "decreaseMoneyFour":
isPathUnlocked = gameState.unlockedPaths.cavePathTwo;
break;
}
// If path is already unlocked, create the corresponding navigation button instead
if (isPathUnlocked) {
switch (action) {
case "decreaseMoneyOne":
createButton(3, "south", createSceneForestTwo, container);
break;
case "decreaseMoneyTwo":
case "decreaseMoneyFour":
createButton(6, "movecloser", createSceneFinal, container);
break;
case "decreaseMoneyThree":
createButton(1, "east", createSceneCaveTwo, container);
break;
}
return;
}
const button = document.createElement("button");
button.classList.add("btn");
button.textContent = buttonNames[index];
switch (action) {
case "increaseMoney":
button.addEventListener("click", () => {
increaseMoney(value);
});
break;
case "decreaseMoneyOne":
button.addEventListener("click", () => {
decreaseMoney(value);
gameState.unlockedPaths.forestPathOne = true;
saveGameState();
updateDisplay();
createButton(3, "south", createSceneForestTwo, container);
button.remove();
});
break;
case "decreaseMoneyTwo":
button.addEventListener("click", () => {
decreaseMoney(value);
gameState.unlockedPaths.forestPathTwo = true;
saveGameState();
updateDisplay();
createButton(6, "movecloser", createSceneFinal, container);
button.remove();
});
break;
case "decreaseMoneyThree":
button.addEventListener("click", () => {
decreaseMoney(value);
gameState.unlockedPaths.cavePathOne = true;
saveGameState();
updateDisplay();
createButton(1, "east", createSceneCaveTwo, container);
button.remove();
});
break;
case "decreaseMoneyFour":
button.addEventListener("click", () => {
decreaseMoney(value);
gameState.unlockedPaths.cavePathTwo = true;
saveGameState();
updateDisplay();
createButton(6, "movecloser", createSceneFinal, container);
button.remove();
});
break;
case "addItem":
button.addEventListener("click", () => {
addItemToInventory(value);
});
break;
default:
console.error("Invalid action", action);
}
container.appendChild(button);
}
/**
* Starts the game and loads the saved game state and current scene
*/
function main() {
const savedState = loadGameState();
if (savedState) {
gameState = savedState;
}
// Create music toggle in the dedicated container
const musicContainer = document.getElementById("musicControl");
createMusicToggle(musicContainer);
// If past start scene, ensure second track is playing (track 1)
if (gameState.scene !== "StartScene" && gameState.scene !== "") {
gameState.currentTrack = 1;
if (gameState.isMusicPlaying) {
fadeOutAudio(audioTracks[0], 800);
playLoopAudio(1);
}
} else {
// At start scene, ensure first track is playing (track 0)
gameState.currentTrack = 0;
if (gameState.isMusicPlaying) {
fadeOutAudio(audioTracks[1], 800);
playLoopAudio(0);
}
}
loadScene(gameState.scene);
}
/**
* Load current scene based on scene name
* @param {string} sceneName Scene name to load
*/
function loadScene(sceneName) {
switch (sceneName) {
case "SceneMain":
createSceneMain();
break;
case "SceneAltMain":
createSceneAltMain();
break;
case "SceneAltMainForestEdge":
createSceneAltMainForestEdge();
break;
case "SceneForestOne":
createSceneForestOne();
break;
case "SceneForestTwo":
createSceneForestTwo();
break;
case "SceneForestThree":
createSceneForestThree();
break;
case "SceneCaveOne":
createSceneCaveOne();
break;
case "SceneCaveTwo":
createSceneCaveTwo();
break;
case "SceneCaveThree":
createSceneCaveThree();
break;
case "SceneCaveDeath":
createSceneCaveDeath();
break;
case "SceneFinal":
createSceneFinal();
default:
loadStartScene();
}
}
/**
* Function to save the username from form input and trigger the game
* @param {Event} event Form input
* @returns {void}
*/
function saveUserInfo(event) {
event.preventDefault();
const nameInput = document.getElementById("storyName");
const name = nameInput.value;
// If user entered a name the property will be that name, else use "Stranger"
if (name) {
gameState.name = name;
} else {
gameState.name = "Stranger";
}
const node = document.getElementById("formStoryName");
if (node.parentNode) {
node.parentNode.removeChild(node);
}
// Save username to the property name, then creates the Main Scene
setName(gameState.name);
createSceneMain();
}
/**
* Load the users name
* @returns {string} - The username
*/
function loadUserInfo() {
let name = gameState.name;
return name;
}
/**
* Save the game state
*/
function saveGameState() {
localStorage.setItem("gameState", JSON.stringify(gameState));
}
/**
* Load the game state from local storage and returns the state
* @returns {Object|null} The loaded game state object or null
*/
function loadGameState() {
const gameStateData = JSON.parse(localStorage.getItem("gameState"));
if (gameStateData) {
return gameStateData;
}
return null;
}
/**
* Reset game state in memory and optionally keep the player name.
* @param {{keepName?: boolean}} [opts]
*/
function resetGameState(opts = {}) {
const keepName = !!opts.keepName;
const name = keepName ? (gameState.name || "") : "";
const wasPlaying = gameState.isMusicPlaying;
gameState = {
name: name,
money: 50,
unlockedPaths: {
forestPathOne: false,
forestPathTwo: false,
cavePathOne: false,
cavePathTwo: false,
},
inventory: {
"Knife": 1,
},
scene: "StartScene",
audio: [
"assets/music/tawny-owl-in-molkom-sweden.mp3",
"assets/music/dark-mystery-cinematic-melody.mp3"
],
isMusicPlaying: wasPlaying,
currentTrack: 0 // Reset to start track (0 = tawny-owl)
};
// Persist the fresh state (or cleared state)
saveGameState();
updateDisplay();
}
/**
* Clear persisted game state and reset in-memory state (completely).
*/
function clearGameState() {
localStorage.removeItem("gameState");
// Reset runtime state as well
resetGameState({ keepName: false });
}
/**
* Start a completely new game (clear name too) and go to start scene.
*/
function newGame() {
resetGameState({ keepName: false });
loadStartScene();
}
/**
* Restart game but keep the current name, then go to the main scene.
*/
function playAgainSameName() {
resetGameState({ keepName: true });
// Choose which scene you want the player to see next when replaying.
// I used the alternate main scene to mimic previous "retry" behaviour.
createSceneAltMain();
}
/**
* Play Audio and loop
* @param {number} index The index of the audio track that will be played
*/
function playAudio(index) {
audioTracks[index].play();
}
/**
* Pause Audio
* @param {number} index The index of the audio to be paused
*/
function pauseAudio(index) {
audioTracks[index].pause();
}
/**
* Play and loop Audio
* @param {number} index The index of the audio to be played and looped
*/
function playLoopAudio(index) {
audioTracks[index].loop = true;
audioTracks[index].play();
}
/**
* Fade out audio and pause
* @param {HTMLAudioElement} audio The audio track index in gameState
* @param {number} duration How long the fade should be in ms
* @returns {Promise} Resolves when fade out is complete
*/
function fadeOutAudio(audio, duration) {
return new Promise(resolve => {
const interval = 50;
const steps = duration / interval;
const volumeStep = audio.volume / (steps + 1);
let currentVolume = audio.volume;
const fadeInterval = setInterval(() => {
audio.volume = Math.max(0, audio.volume - volumeStep);
currentVolume = audio.volume;
if (audio.volume === 0) {
clearInterval(fadeInterval);
audio.pause();
audio.volume = 0.8;
resolve();
}
}, interval);
});
}
/**
* Creates button with four parameters and adds a click event
* @param {string} index The name of the button by corresponding index
* @param {string} id Setting the id for the button
* @param {Function} onClickNextFunction Sets the next function to be called
* @param {HTMLElement} container Sets which container to add the button to
*/
function createButton(index, id, onClickFunction, container) {
const button = document.createElement("button");
button.textContent = buttonNames[index];
button.id = id;
if (typeof onClickFunction === 'function') {
button.addEventListener("click", onClickFunction);
} else {
console.error("Provided onClickFunction is not a function!");
}
button.classList.add("btn");
container.appendChild(button);
}
/**
* Create page header element
*/
function createPageHeader() {
const pageHeader = document.getElementById("pageHeader");
pageHeader.innerHTML = "";
const pageParagraf = document.createElement("p");
pageParagraf.textContent = "A tale from the woods";
pageParagraf.className = "pageparagraf";
const pageTitle = document.createElement("h1");
pageTitle.textContent = "The Forest";
pageTitle.className = "pagetitle";
pageHeader.appendChild(pageParagraf);
pageHeader.appendChild(pageTitle);
}
/**
* Create page header with no animation
*/
function createPageHeaderNoAnimation() {
const pageHeader = document.getElementById("pageHeader");
pageHeader.innerHTML = "";
const pageParagraf = document.createElement("p");
pageParagraf.textContent = "A tale from the woods";
pageParagraf.className = "pageparagraf no-animation";
const pageTitle = document.createElement("h1");
pageTitle.textContent = "The Forest";
pageTitle.className = "pagetitle no-animation";
pageHeader.appendChild(pageParagraf);
pageHeader.appendChild(pageTitle);
}
/**
* Starting point of program
* @see createPageHeader
* @see createButton
* @see playLoopAudio
* @see fadeOutAudio
*/
function loadStartScene() {
createPageHeader();
const book = document.getElementById("storyBook");
book.style.display = "none";
// Handle audio transition
if (gameState.isMusicPlaying) {
// Fade track 1 if playing
fadeOutAudio(audioTracks[1], 1000).then(() => {
audioTracks[1].pause();
audioTracks[1].currentTime = 0;
gameState.currentTrack = 0;
// Start track 0
playLoopAudio(0);
});
}
// Create form
const form = document.createElement("form");
form.id = "formStoryName";
// Create label element
const label = document.createElement("label");
label.textContent = "Character name?";
label.className = "formlabel";
label.htmlFor = "storyName"; // Link label to input with htmlFor
form.appendChild(label);
// Create input text field
const inputField = document.createElement("input");
inputField.type = "text";
inputField.id = "storyName";
inputField.name = "storyName";
form.appendChild(inputField);
pageHeader.append(form);
createButton(9, "storyStart", saveUserInfo, form);
playLoopAudio(0);
fadeOutAudio(audioTracks[1], 2000);
updateDisplay();
}
/**
* Scene Main One
* @see createPageHeaderNoAnimation
* @see createButton
* @see setScene
* @see fadeOutAudio
* @see playLoopAudio
*/
function createSceneMain() {
createPageHeaderNoAnimation();
const book = document.getElementById("storyBook");
book.style.display = "grid";
const storyHeader = document.getElementById("storyHeader");
storyHeader.innerHTML = "";
// Get the characters name
const storyName = loadUserInfo();
// Create h2 element and add the characters name to the textContent
const title = document.createElement("h2");
title.id = "storyTitle";
title.className = "storytitle";
title.textContent = "Greetings " + storyName + " to The Forest's Edge";
// Create section for the paragraphs
const storySection = document.createElement("section");
storySection.className = "storyText";
// Text to be split
const text = 'You stand at the edge of an ancient forest, the sun dappling through the canopy. The air is thick with the scent of pine needles and damp earth, and the only sound is the gentle rustle of leaves. A sense of wonder and trepidation fills you as you look around.\nStrange, otherworldly sounds echoed through the undergrowth—the distant howl of a wolf, the eerie chirping of unseen insects. A surge of curiosity and a hint of trepidation fill your heart. You know that danger lurks in the shadows, but the allure of the unknown and treasures is too strong to resist.\nTo the west, a path winds down to an opening into the ancient forest. To the east, a narrow passage, barely wide enough for a single person, wound its way between the large rocks.';
text.id = "storyText";
// Using .split() and a for loop to create separate paragraphs
const sentences = text.split(/\n/);
for (let i = 0; i < sentences.length; i++) {
const paragraph = document.createElement("p");
paragraph.textContent = sentences[i];
paragraph.className = "storyParagraph";
storySection.appendChild(paragraph);
}
// Create element for question
const question = document.createElement("h3");
question.id = "storyQuestion";
question.className = "storyquestion";
question.textContent = "Which way should you go?"
// Create Button Container
const buttonContainer = document.createElement("div");
buttonContainer.id = "storyButtons";
buttonContainer.className = "buttoncontainer";
// Append to container storyHeader
storyHeader.append(title, storySection, question, buttonContainer);
// Change story image
const storyImage = document.getElementById("storyImage");
storyImage.src = "assets/image/hazy-sunlight-shines-through-a-forest-with-large-rocks.webp";
// Create text for figcaption
const figcaption = document.getElementById("storyCaption");
figcaption.className = "figcaption";
figcaption.textContent = "Rocky terrain meets towering trees, the fog adding a mystical touch. The land, a tapestry of stone and green, is shrouded in a veil of mist."
// Create the buttons
createButton(0, "west", createSceneForestOne, buttonContainer);
createButton(1, "east", createSceneCaveOne, buttonContainer);
// Save scene state
gameState.scene = "SceneMain";
setScene(gameState.scene);
// Audio fade out and play
fadeOutAudio(audioTracks[0], 2000);
gameState.currentTrack = 1;
playLoopAudio(1);
saveGameState();
// Display items
updateDisplay();
}
/**
* Scene Alt Main One
* @see createPageHeaderNoAnimation
* @see createButton
* @see setScene
*/
function createSceneAltMain() {
createPageHeaderNoAnimation();
const storyHeader = document.getElementById("storyHeader");
storyHeader.innerHTML = "";
// Get the characters name
const storyName = loadUserInfo();
// Create h2 element and add the char name to the textContent
const title = document.createElement("h2");
title.id = "storyTitle";
title.className = "storytitle";
title.textContent = "Welcome back " + storyName + " to The Forest's Edge";
// Create section for the paragraphs
const storySection = document.createElement("section");
storySection.className = "storyText";
// Text to be split
const text = 'You find yourself awakening to the sound of gentle rustle of leaves."Where am I?" A voice echoed in your mind.\nYou suddenly remember fearsome creatures and magic items, and a legend that speaks of a forgotten realm, hidden deep within these ancient forests, holding treasures beyond imagination.\n"Was it a dream, or a glimpse of something real?", "Have I been here before?" you wondered, your mind racing.\nA surge of curiosity and a hint of trepidation fill your heart. You know that danger lurks in the shadows, but the allure of the unknown and treasures is too strong to resist.\nTo the west, a path winds down to an opening into the ancient forest. To the east, a narrow passage, barely wide enough for a single person, wound its way between the large rocks.';
text.id = "storyText";
// The Split function using .split() and a for loop creating separate paragraphs
const sentences = text.split(/\n/);
for (let i = 0; i < sentences.length; i++) {
const paragraph = document.createElement("p");
paragraph.textContent = sentences[i];
paragraph.className = "storyParagraph";
storySection.appendChild(paragraph);
}
// Create element for question
const question = document.createElement("h3");
question.id = "storyQuestion";
question.className = "storyquestion";
question.textContent = "Which way should you go?"
// Create Button Container
const buttonContainer = document.createElement("div");
buttonContainer.id = "storyButtons";
buttonContainer.className = "buttoncontainer";
// Append to container storyHeader
storyHeader.append(title, storySection, question, buttonContainer);
// Change story image
const storyImage = document.getElementById("storyImage");
storyImage.src = "assets/image/hazy-sunlight-shines-through-a-forest-with-large-rocks.webp";
// Create text for figcaption
const figcaption = document.getElementById("storyCaption");
figcaption.className = "figcaption";
figcaption.textContent = "Rocky terrain meets towering trees, the fog adding a mystical touch. The land, a tapestry of stone and green, is shrouded in a veil of mist.";
// Create the buttons
createButton(0, "west", createSceneForestOne, buttonContainer);
createButton(1, "east", createSceneCaveOne, buttonContainer);
// Save scene state
gameState.scene = "SceneAltMain";
setScene(gameState.scene);
// Display items
updateDisplay();
}
/**
* Scene Alt Main Forest Edge
* @see createPageHeaderNoAnimation
* @see createButton
* @see setScene
*/
function createSceneAltMainForestEdge() {
createPageHeaderNoAnimation();
const storyHeader = document.getElementById("storyHeader");
storyHeader.innerHTML = "";
// Get the characters name
const storyName = loadUserInfo();
// Create h2 element and add the char name to the textContent
const title = document.createElement("h2");
title.id = "storyTitle";
title.className = "storytitle";
title.textContent = storyName + ", you find yourself back at The Forest's Edge";
// Create section for the paragraphs
const storySection = document.createElement("section");
storySection.className = "storyText";
// Text to be split
const text = 'Once again the familiar scent of pine needles and damp earth fills your nostrils, bringing back memories of your previous journey.\nThe towering trees seem to recognize you, their branches swaying gently as if in greeting. The same paths stretch before you - to the west, the winding trail into the depths of the forest, and to the east, the narrow passage between the weathered rocks.\nYou can\'t help but wonder if different choices might lead to different outcomes this time. The forest holds many secrets, and not all paths have been explored.\nThe distant howl of a wolf and the ethereal chirping of unseen creatures remind you of the dangers - and treasures - that await in these mystical woods.';
text.id = "storyText";
// The Split function using .split() and a for loop creating separate paragraphs
const sentences = text.split(/\n/);
for (let i = 0; i < sentences.length; i++) {
const paragraph = document.createElement("p");
paragraph.textContent = sentences[i];
paragraph.className = "storyParagraph";
storySection.appendChild(paragraph);
}
// Create element for question
const question = document.createElement("h3");
question.id = "storyQuestion";
question.className = "storyquestion";
question.textContent = "Which way should you go " + storyName + "?";
// Create Button Container
const buttonContainer = document.createElement("div");
buttonContainer.id = "storyButtons";
buttonContainer.className = "buttoncontainer";
// Append to container storyHeader
storyHeader.append(title, storySection, question, buttonContainer);
// Change story image
const storyImage = document.getElementById("storyImage");
storyImage.src = "assets/image/hazy-sunlight-shines-through-a-forest-with-large-rocks.webp";
// Create text for figcaption
const figcaption = document.getElementById("storyCaption");
figcaption.className = "figcaption";
figcaption.textContent = "Rocky terrain meets towering trees, the fog adding a mystical touch. The land, a tapestry of stone and green, is shrouded in a veil of mist.";
// Create the buttons
createButton(0, "west", createSceneForestOne, buttonContainer);
createButton(1, "east", createSceneCaveOne, buttonContainer);
// Save scene state
gameState.scene = "SceneAltMainForestEdge";
setScene(gameState.scene);
// Display items
updateDisplay();
}
/**
* Scene Forest One
* @see createPageHeaderNoAnimation
* @see createButton
* @see setScene
*/
function createSceneForestOne() {
createPageHeaderNoAnimation();
const storyHeader = document.getElementById("storyHeader");
storyHeader.innerHTML = "";
// Get the characters name
const storyName = loadUserInfo();
// Create h2 element and its content
const title = document.createElement("h2");
title.id = "storyTitle";
title.className = "storytitle";
title.textContent = "A figure in the shadows...";
// Create section for the paragraphs
const storySection = document.createElement("section");
storySection.className = "storyText";
// Text to be split
const text = `As you walked further into the forest, you couldn't shake the feeling that you were being watched. The trees seemed to lean in, their gnarled branches reaching out like skeletal fingers. The sunlight, once warm and inviting, now seemed to cast an eerie glow on the forest floor.\nAs you start to quickened your pace, hoping to escape the oppressive silence, you see a hooded figure standing in the shadows. The figure stepped into the light, revealing a merchant with a wide grin and a bag full of peculiar items.\n"What's your name?" murmured the merchant, while he showed you a variety of magical trinkets, potions, and weapons.\n"You can call me ` + storyName + `" you answered.\nThe merchant just nodded while speaking of ancient relics, lost treasures, and forbidden knowledge.\n"I'm looking for the Magic Orb, do you know the way?" you asked firmly.\n"For some gold coins, I sure will... " the merchant said silently, while stirring the camp fire. However, the merchant's appearance in such a remote and dangerous place was unsettling.`;
text.id = "storyText";
// The Split function using .split() and a for loop creating separate paragraphs
const sentences = text.split(/\n/);
for (let i = 0; i < sentences.length; i++) {
const paragraph = document.createElement("p");
paragraph.textContent = sentences[i];
paragraph.className = "storyParagraph";
storySection.appendChild(paragraph);
}
// Create element for question
const question = document.createElement("h3");
question.id = "storyQuestion";
question.className = "storyquestion";
question.textContent = "What's your next move " + storyName + "?";
// Create Button Container
const buttonContainer = document.createElement("div");
buttonContainer.id = "storyButtons";
buttonContainer.className = "buttoncontainer";
// Append to container storyHeader
storyHeader.append(title, storySection, question, buttonContainer);
// Change story image
const storyImage = document.getElementById("storyImage");
storyImage.src = "assets/image/an-old-merchant-by-the-campfire-surrounded-by-gnarly-trees.webp";
// Create text for figcaption
const figcaption = document.getElementById("storyCaption");
figcaption.className = "figcaption";
figcaption.textContent = "An old merchant sits by a campfire, surrounded by gnarly trees. Rings, trinkets and potions lays on a blanket beside him.";
// Create the buttons
createButton(1, "east", createSceneMain, buttonContainer);
createButton(2, "north", createSceneForestDeath, buttonContainer);
createInventoryButton(5, "decreaseMoneyOne", 5, buttonContainer);
// Save scene state
gameState.scene = "SceneForestOne";
setScene(gameState.scene);
// Display items
updateDisplay();
}
/**
* Scene Forest Two
* @see createPageHeaderNoAnimation
* @see createButton
* @see setScene
*/
function createSceneForestTwo() {
createPageHeaderNoAnimation();
const storyHeader = document.getElementById("storyHeader");
storyHeader.innerHTML = "";
// Get the characters name
const storyName = loadUserInfo();
// Create h2 element and add the char name to the textContent
const title = document.createElement("h2");
title.id = "storyTitle";
title.className = "storytitle";
title.textContent = "The trees are watching you, " + storyName + "";
// Create section for the paragraphs
const storySection = document.createElement("section");
storySection.className = "storyText";
// Text to be split
const text = `You continued your journey, deeper into the heart of the forest. The trees grew older and more twisted, their roots gnarled and exposed. Strange fungi, bioluminescent and otherworldly, clung to the decaying trunks.\n"Why not pick one of these mushrooms..." you heard yourself say.\nA sense of isolation crept over you as the forest seemed to close in around you. The only sound was the distant whisper of the wind and the occasional snap of a twig.\nYou could feel the ancient power of the woods, a force both awe-inspiring and terrifying.\nThe trees seemed to watch your every move, their gnarled branches reaching out like skeletal fingers. You knew that you were treading on sacred ground, and that the forest would not easily surrender its secrets.`;
text.id = "storyText";
// The Split function using .split() and a for loop creating separate paragraphs
const sentences = text.split(/\n/);
for (let i = 0; i < sentences.length; i++) {
const paragraph = document.createElement("p");
paragraph.textContent = sentences[i];
paragraph.className = "storyParagraph";
storySection.appendChild(paragraph);
}
// Create element for question
const question = document.createElement("h3");
question.id = "storyQuestion";
question.className = "storyquestion";
question.textContent = "Time to choose " + storyName + "";
// Create Button Container