【发布时间】:2018-02-07 22:04:47
【问题描述】:
我的意图:使用对象制作 CYOA
我是 Javascript 的新手,一直在尝试制作一个简单的 CYOA 游戏,使用来自 this Reddit comment 的 this code 作为模板。但是,我想使用对象(其值应该是常量)来存储消息的各种字符串值和每个选择指向的对象,而不是将所有对象都放在数组中并且必须使用 using 指向它们他们在数组中的索引。我的理由是(理论上)我使用“msg_001”或“story5_28”之类的字符串组织起来会更简单,而不是在我在中间插入一些新消息时更改一堆数字数组。
我的问题:第一条消息不再显示
基本上,我想循环回到第一条消息及其答案集,但它不会。
初始printCurrentMsg() 起作用(将“消息”div 的内容更改为msgText 的值,并循环遍历对象的choices 数组以设置“选择”div 中的按钮,基于currentMsg) 中指定的对象和按钮各自的 onlick 属性似乎可以工作,直到它们被设置为显示 msg_000。
似乎无论currentMsg 的值是什么,printCurrentMsg 都不会显示字符串所指的对象,除非它最初显示。此外,在脚本中的各个点使用console.log 之后,我注意到currentMsg 没有改变,并且对currentMsg 和window[currentMsg] 都使用console.log(typeof) 表明前者是一个字符串,而后者是一个东西。我是否无意中创建了两个单独的变量?
我试过了……
- ...使用
printCurrentMessage中的参数。 - ...在函数中使用
currentMsg而不是window[currentMsg]。 - ...使用点表示法而不是括号表示法。
- ...使用
this[]而不是window[]。
我不确定这是否与asynchronicity 有关,我是accessing object properties 不正确,我对scope 的理解有缺陷,或者我是否错误地使用了全局变量。我应该使用某种回调吗?
使用“虚拟”msg_000——制作另一个名称不同但属性相同的对象——作为权宜之计,但我仍然不明白问题出在哪里。将所有msg_*** 对象放在一个数组中并通过索引号而不是字符串来引用它们也可以,但我很犹豫是否要依赖它来解决上述乏味和我仍然不明白为什么currentMsg 的值保持不变。
为了更好地表达我的问题,here is a jsfiddle with my code,我也将其发布在下面。
//messages
var msg_000 = { //Starts with this one, I want to be able to go back to it
msgName: "msg_000",
msgText: "Sup! Choose an option!",
choices: [
ans_000 = {
ansText: "Climb a hill!",
ansGoto: "msg_001" //this works
},
ans_001 = {
ansText: "Skin a cat!",
ansGoto: "msg_002" //this works
},
ans_002 = {
ansText: "Build a birdhouse!",
ansGoto: "msg_003" //this works
}
]
};
var msg_001 = {
msgName: "msg_001",
msgText: "You summit the great snowy peaks!",
choices: [
ans_000 = {
ansText: "Talk to the Recursion Guru!",
ansGoto: "msg_000" //this doesn't work
}
]
};
var msg_002 = {
msgName: "msg_002",
msgText: "You suffer severe lacerations to the face!",
choices: [
ans_000 = {
ansText: "Start Over",
ansGoto: "msg_000" //this doesn't work
}
]
};
var msg_003 = {
msgText: "You build a pretty average looking birdhouse. Some grackles have moved in nonetheless, placing their various knicknacks, bedding materials, and chrono-gateways within their new abode.",
choices: [
ans_000 = {
ansText: "Step through the chrono-gateway!",
ansGoto: "msg_000" //this doesn't work
},
ans_001 = {
ansText: "I think I wanna climb that mountain over there.",
ansGoto: "msg_001" //this works
}
]
}
var currentMsg = "msg_000"; //the first message is "msg_000"
printCurrentMsg = function() {
document.getElementById("message").innerHTML =
window[currentMsg].msgText;
//sets the message (the div with the id of "message")
//based on the "currentMsg" variable. "currentMsg.msgText"
//doesn't seem to work.
var choices = "";
for (var i = 0, l = window[currentMsg].choices.length; i < l; i++) {
choices += "<p><button onclick='setMessage(" +
window[currentMsg].choices[i].ansGoto + ")'>" +
window[currentMsg].choices[i].ansText + "<br>Goto " +
window[currentMsg].choices[i].ansGoto + "</button></p>";
//make the buttons, sets the button's onclick
//"setMessage" function's parameter to the the value of
//the "ansGoto" property -> in the answers object at the
//i/th index of the choices property array -> in the
//"msg_(number)" object."
};
document.getElementById("choices").innerHTML = choices;
//takes the value of the "choices" [local?] variable and puts
//it in the "choices" div.
};
setMessage = function(msg) {
window[currentMsg] = msg; //I think this is the source of all
//my problems, it's supposed to set "currentMsg" to the value
//of the "msg" parameter, but when I check it with
//console.log(currentMsg) it hasn't been changed (i.e., still
//it's initial value of "msg_000") and when I use
//console.log(window[currentMsg]) it returns "[Object
//object]"; using typeof shows me that "currentMsg" is a
//string and "window[currentMsg]" is an object. I thought
//they both were the same object, am I unintentionally
//creating two different objects?
printCurrentMsg(); //runs that function, seems to display the
//messages except the ones from object "msg_000".
};
printCurrentMsg(); //Displays the initial message and choices
//from "msg_000", but after a new message is chosen it won't
//display "msg_000" if it's pointed to from an "ansGoto"
//property.
<!DOCTYPE html>
<html>
<body>
<div id="message"></div>
<!-- "msgText" goes here -->
<div id="choices"></div>
<!-- "choices" go here -->
</body>
</html>
感谢您的宝贵时间。
【问题讨论】:
-
我希望我的问题标题不要太含糊;我不确定如何简洁地表达我的问题这一事实可能说明了我的问题的性质。
-
不要使用动态变量名,使用对象来保存所有消息。
标签: javascript html object scope global-variables