我正在尝试制作一个老式的文字冒险游戏。到目前为止它一直很顺利,但是当我到达操作对象的更复杂部分并使它们与其他人交互时,我遇到了问题。主要考虑一次添加多个命令,并将库存对象与房间对象一起使用。
我感觉我完全以错误的方式解决了这个问题,并就如何更好地构建代码寻求建议。我尝试将所有游戏对象变成实际的编码对象,但事实证明这更像是一种障碍 - 也许我只是以错误的方式处理事情。正如你从我所做的那样看,我试图使游戏变得流畅,因此它不需要精确的命令。
You can see a working version here。目前有很多错误 - 比如在房间之间移动太快会搞砸所显示的信息。但我对如何简化和更好地构建我的游戏更感兴趣。
任何建议都将不胜感激。请温柔,我是一个完全的业余爱好者。这是代码,我已经把我放弃尝试“使用对象”包含在内,以便了解到目前为止我尝试过的内容。
var db = { // ROOMS
rooms:
[{ // Room 0 - North room
description: "You find yourself in a dank smelling old room, plaster and smashed glass litters the floor. To the North is a broken window, beyond which you can only see a thick grey mist. There is one door by which to exit, to the South.",
roomImg: "images/room_0.jpg",
exits:
{
north: false,
south: 1,
east: false,
west: false,
up: false,
down: false
},
roomInvent: ["a box of matches", "a glass shard", "soap"],
roomInventPerma: ["window", "wall"]
},
{ // Room 1 - Corridor
description: "You are in a short, dark corridor, a single tungsten bulb hangs stiffly from the ceiling. There is a light switch on the wall.",
roomImg: "images/room_1.jpg",
exits:
{
north: 0,
south: 4,
east: 3,
west: false,
up: 5,
down: false
},
roomInvent: ["a rotten apple"],
roomInventPerma: ["light switch"]
},
{ // Room 2 - West Room - Locked room
description: "",
roomImg: "images/room_2.jpg",
exits:
{
north: false,
south: false,
east: false,
west: false,
up: false,
down: false
},
roomInvent: ["broken toy"],
roomInventPerma: []
},
{ // Room 3 - East room - Bedroom
description: "You are in the Bedroom",
roomImg: "images/room_3.jpg",
exits:
{
north: false,
south: false,
east: false,
west: 1,
up: false,
down: false
},
roomInvent: ["a rusty ring"],
roomInventPerma: []
},
{ // Room 4 - South room - kitchen
description: "You are in a small kitchen. There is an old log fire on the East wall, and a door leading outside to the South.",
roomImg: "images/room_4.jpg",
exits:
{
north: 1,
south: false,
east: false,
west: false,
up: false,
down: false
},
roomInvent: ["a kitchen knife"],
roomInventPerma: []
},
{ // Room 5 - Attic
description: "You are in the Attic.",
roomImg: "images/room_5.jpg",
exits:
{
north: false,
south: false,
east: false,
west: false,
up: false,
down: 1
},
roomInvent: [],
roomInventPerma: []
}]
}; //End db
var inventory = [];
var inputTextBox = document.getElementById("inputTextBox");
var diologueBox = document.getElementById("diologueBox");
var roomLoc = 0;
function displayOut() {
// images
document.getElementById("imgBox").style.backgroundImage = "url(" + db.rooms[roomLoc].roomImg + ")";
// Diologue box
diologueBox.innerHTML = ""; // Clear Box
teleTyperDiologue(db.rooms[roomLoc].description +
(function() { // Check if room has items in inventory, if so, list them.
if (db.rooms[roomLoc].roomInvent != "") {
return " The room contains " +
(function() {
let items = "";
for (let i = 0; i < db.rooms[roomLoc].roomInvent.length; i++) {
items += db.rooms[roomLoc].roomInvent[i] + ", ";
};
items = items.slice(0, items.length - 2);
return items + ".";
})();
} else {
return " The room is empty.";
};
})());
};
// Function for changing room location
function navigateTo(direction) {
if (db.rooms[roomLoc].exits[direction] === false) {
teleTyperOutBox("You cannot go " + direction + " from here.");
} else {
roomLoc = db.rooms[roomLoc].exits[direction];
teleTyperOutBox("You go " + direction)
displayOut();
}
}
// Inventory check
function inventCheck() {
if (inventory.length == 0) {
teleTyperOutBox("You have nothing in your Inventory");
} else {
teleTyperOutBox("You are holding the following items: " +
(function() {
let x = "";
for (let i = 0; i < inventory.length; i++) {
x += inventory[i] + ", ";
// console.log(x);
}
x = x.slice(0, -2);
return x + ".";
})());
}
}
// Inventory changes
///////Getting items////////////
// Check string
function getItem(inString) {
// console.log(inString + " has got to 'get item' function");
switch (true) {
case inString.includes("box"):
case inString.includes("matches"):
case inString.includes("box of matches"):
checkRoomForItem("a box of matches");
break;
case "match":
checkroomforitem("match");
break;
case inString.includes("soap"):
checkRoomForItem("soap");
break;
case inString.includes("glass"):
case inString.includes("shard"):
case inString.includes("glass shard"):
checkRoomForItem("a glass shard");
break;
case inString.includes("apple"):
case inString.includes("rotten apple"):
checkRoomForItem("a rotten apple");
break;
case inString.includes("knife"):
case inString.includes("kitchen knife"):
checkRoomForItem("a kitchen knife");
break;
case inString.includes("rotten apple"):
checkRoomForItem("a rotten apple");
break;
case inString.includes("ring"):
case inString.includes("rusty"):
checkRoomForItem("a rusty ring");
break;
case inString.includes("window"):
checkRoomForItem("window");
break;
default:
inString = inString.slice(4);
teleTyperOutBox("You cannot see " + inString + " here.");
}
}
////////take item from room inventory and output result
function checkRoomForItem(string1) {
let x = false;
let z = false;
let inventConcat = inventory.concat(db.rooms[roomLoc].roomInvent, db.rooms[roomLoc].roomInventPerma);
// console.log(string1 + " has got to checkroomforitem function");
for (let i = 0; i < inventConcat.length; i++){
if (db.rooms[roomLoc].roomInvent[i] === string1) {
// console.log("room inventory is " + db.rooms[roomLoc].roomInvent);
inventory.push(string1); // Add item to inventory
db.rooms[roomLoc].roomInvent.splice(db.rooms[roomLoc].roomInvent.indexOf(string1), 1); // Remove item from room Inventory
x = true;
}
if (db.rooms[roomLoc].roomInventPerma[i] === string1) {
z = true;
}
// console.log("x equals --- " + x)
};
if (x === true) {
teleTyperOutBox("You get " + string1);
}
if (x === false && z === false) {
teleTyperOutBox("You cannot see " + string1 + " here");
}
if (x === false && z === true) {
teleTyperOutBox("You cannot get " + string1)
}
displayOut();
}
/////// Examine Items ////////////////
// Check String
function examItem(inString) {
// console.log("examItem has " + inString);
switch (true) {
case inString.includes("box"):
case inString.includes("matches"):
examineOut("a box of matches", "You find a match inside!");
inventory.push("match");
break;
case inString.includes("soap"):
examineOut("soap", "a petrified bar of soap");
break;
case inString.includes("glass"):
case inString.includes("shard"):
examineOut("a glass shard", "It looks dangerously sharp.");
break;
case inString.includes("apple"):
examineOut("a rotten apple", "It's old and mouldy.");
break;
case inString.includes("knife"):
examineOut("a kitchen knife", "It is blunt, old, and extremely rusty.");
break;
case inString.includes("ring"):
examineOut("a rusty ring", "It is a ring, 'tis rusty.");
break;
case inString.includes("wall"):
console.log("instring contains wall: " + inString.includes("wall"));
examineOut("wall", "There are some words scratched into the wall: \"I have been trapped here in this strange dwelling for three days. I do not know how I came to be here, but I cannot survive much longer. I will take myself into the mist in the hope that salvation lies beyond. May God guide me on my journey. Reuben C. Thomas. Jan 8th 1912\"");
break;
case inString.includes("window"):
examineOut("window", "The window is smashed, although it is not clear what broke it. Through the hole you see a thick grey mist, in the distance you momentarily glipse an uncanny form that fills you with a sense of dread");
break;
case inString.includes("light switch"):
case inString.includes("switch"):
examineOut("light switch", "It is an ordinary light switch.");
break;
default:
inString = inString.slice(8);
teleTyperOutBox("You see nothing special");
}
}
// Examine and description
function examineOut(item, description) {
console.log("Item equals " + item);
console.log("Description equals " + description);
let x = false;
let z = false;
let inventConcat = inventory.concat(db.rooms[roomLoc].roomInvent, db.rooms[roomLoc].roomInventPerma);
console.log("Inv concat equals " +inventConcat);
for (let i = 0; i < inventConcat.length; i++) {
if (item === inventConcat[i]) {
x = true;
} else if (item === db.rooms[roomLoc].roomInvent[i]) {
x = true;
} else if (item === db.rooms[roomLoc].roomInventPerma[i]) {
z === true;
}
}
console.log("z equals" + z)
if (x === true) {
teleTyperOutBox(description);
}
if (x === false && z === false) {
teleTyperOutBox("You cannot see " + item + " here.");
}
if (x === false && z === true) {
teleTyperOutBox("You see nothing special");
}
}
// Dropping Items
function dropItem(item, item2) {
let x = false;
for (let i = 0; i < inventory.length; i++) {
if (inventory[i].includes(item) || inventory[i].includes(item2)) {
db.rooms[roomLoc].roomInvent.push(inventory[i]);
inventory.splice(i);
x = true;
} /* else if (inventory[i] !== item && inventory[i] !== item2) {
x = false;
} //Else if statement not needed?
*/ }
if (x === true) {
teleTyperOutBox("You drop " + item);
} else if (x === false ) {
teleTyperOutBox("You do not posess " + item);
}
displayOut();
}
/*
// Using items
function useItem(stringArray) {
console.log(stringArray + " is in use function");
let x = false;
let arrayConcat = inventory.concat(db.rooms.roomInventPerma, db.rooms.roomInvent);
for (let i = 0; i < arrayConcat.length; i++) {
if (stringArray[i] === arrayConcat[i]) {
x = true;
}
}
console.log("Use function x equals " + x)
if (x === false) {
teleTyperOutBox("Use " + stringArray[1] + " with what?")
}
}
*/
/*
// Using items
function useItem(stringArray) {
let x = false;
switch (true) {
case (stringArray.includes("soap") && stringArray.includes("armpits") && inventory.indexOf("soap") > -1):
teleTyperOutBox("You wash yourself with the petrified bar of soap and seem unsurprised that you don't feel any clearner");
break;
case (stringArray.includes("soap") && stringArray.includes("armpits") && inventory.indexOf("soap") === -1):
teleTyperOutBox("You don't possess soap");
break;
// Doesn't exist
case (inventory.index)
}
}
*/
// Teletyper for Output Box
function teleTyperOutBox(string) {
let textTrans = document.createTextNode(outputBox.innerText);
let newPara = document.createElement("p");
outputBox.innerHTML = "";
// console.log(textTrans)
newPara.appendChild(textTrans);
outputBoxOld.appendChild(newPara, outputBoxOld.firstChild);
string = "> " + string;
for (let i = 0; i < string.length; i++) {
setTimeout(function() {
outputBox.innerHTML += string.slice(i, i + 1);
}, 10 * i);
}
//Max paragraph limiter for Output box
let maxPara = outputBoxOld.getElementsByTagName("P");
console.log("max para equals " + maxPara.length)
if (maxPara.length >= 5) {
outputBoxOld.removeChild(maxPara[0]);
} // End paragraph limiter
}
// Teletyper for Diologue Box
function teleTyperDiologue(string) {
for (let i = 0; i < string.length; i++) {
setTimeout(function() {
diologueBox.innerHTML += string.slice(i, i + 1);
}, 10 * i);
}
}
// Input interpritation
inputTextBox.addEventListener("keypress", function(event) {
let stringArray = [];
let x = event.which || event.keyCode;
let inString = inputTextBox.value.toLowerCase();
stringArray = inString.split(" ");
if (x === 13) { // 13 is the Return key
// console.log(stringArray[0] + " " + stringArray[1]);
switch (stringArray[0]) { ////////// This is assuming command word will be first, I could check with includes, but that gets complicated.
//Actions
case "":
// Nothing happens
break;
case "north":
case "n":
navigateTo("north");
break;
case "south":
case "s":
navigateTo("south");
break;
case "east":
case "e":
navigateTo("east");
break;
case "west":
case "w":
navigateTo("west");
break;
case "up":
case "u":
navigateTo("up");
break;
case "down":
case "d":
navigateTo("down");
break;
case "throw":
teleTyperOutBox("Throwing " + (stringArray[1] || "nothing") + " would appear to be a waste of energy");
break;
case "attack":
teleTyperOutBox("Attacking " + (stringArray[1] || "nothing") + " would appear to be a waste of energy");
break;
case "cry":
case "sob":
teleTyperOutBox("You sit down a wail uncontrollably");
break;
// Inventory
case "inventory":
case "inv":
case "i":
inventCheck();
break;
case "get":
case "take":
case "grab":
getItem(inString);
break;
case "examine":
examItem(inString);
break;
case "drop":
dropItem(stringArray[1], stringArray[2]);
break;
case "use":
useItem(stringArray)
break;
//Diologue Help
case "help":
teleTyperOutBox("Here is a list of useful commands: North, South, East, West, Up, Down, Look, Examine, Inventory, Take, Use");
break;
// Comedy
case "elisa":;
teleTyperOutBox("Hello my love :)");
break;
case "fuck":
teleTyperOutBox("Something wonderful has happened to your computer.");
break;
case "wank":
case "masturbate":
teleTyperOutBox("You find the situation difficult to masturbate to...");
break;
case "shit":
case "crap":
teleTyperOutBox("On reflection, you decide leaving a massive steamer on the floor will not help your situation.");
break;
case "piss":
case "pee":
teleTyperOutBox("The situation urine is already bad enough!");
break;
case "fart":
teleTyperOutBox("The putrid stench is overwhelming!");
break;
case "ug":
teleTyperOutBox("Urrghghhg, urrruh, ug");
break;
//
default:
teleTyperOutBox(" I have no idea what \u2018" + inputTextBox.value + "'" + " means...");
} // End switch
//Clear InputTextBox
inputTextBox.value = "";
inputTextBox.setAttribute("placeholder", "Enter commands here");
} // End KeyPress
}); // End Event listener
displayOut();
@charset "utf-8";
@font-face {
font-family: 'Terminal'; /*a name to be used later*/
src: url(lcd_solid.ttf); /*URL to font*/
}
* {
font-family: Terminal;
font-size: 18px;
margin: 0;
border: 0;
}
body, html {
font-family: helvetica;
font-size: 12px;
background: #282828;
}
#imgBox {
margin: 0px auto 0px auto;
background-image: url("../images/room_0.jpg");
background-repeat: no-repeat;
height: 600px;
width: 1024px;
}
#conBox {
margin: 0px auto 0px auto;
position: relative;
width: 1024px;
height: 300px;
}
#diologueBox {
background: #CCC;
height: 100px;
clear: both;
padding: 1px 0px 1px 3px;
overflow: none;
position: relative;
}
#diologueBox p {
margin: 5px;
left: 0px;
bottom: 0px;
}
#outputBox {
background: #CCC;
height: 70px;
clear: both;
padding: 1px 0px 1px 3px;
overflow: none;
position: relative;
}
#outputBox p {
display: block;
margin-left: 10px;
}
#outputBoxOld {
background: #CCC;
height: 140px;
clear: both;
padding: 1px 0px 1px 3px;
overflow: none;
position: relative;
}
#inputBox {
position: relative;
height: 20px;
background: #C1C1C1;
}
#inputTextBox {
height: 18px;
padding: 1px;
float: right;
width: 1004px;
background: #C1C1C1;
}
::-webkit-input-placeholder {
color: red;
}
:-moz-placeholder { /* Firefox 18- */
color: red;
}
::-moz-placeholder { /* Firefox 19+ */
color: red;
}
:-ms-input-placeholder {
color: red;
}
#inputTextBox.focus, input:focus {
outline: none;
}
#bullet {
width: 15px;
float: left;
padding: 4px 0px 1px 3px;
}
#divider {
background-color: #CCC;
padding: 10px;
}
.hrBlack {
float: center;
background-color: black;
height: 2px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="styles/style.css">
<meta charset="utf-8">
<title>House in the Grey Mist</title>
</head>
<body>
<div id="imgBox"></div>
<div id="conBox">
<div id="diologueBox"></div>
<div id ="divider"><hr class="hrBlack"></div>
<div id="outputBoxOld">
</div>
<div id="outputBox"></div>
<div id="inputBox">
<div id="bullet">></div>
<input id="inputTextBox" type="text" maxlength="60" placeholder="Type commands here, type 'Help' at any time for list of commands" autofocus></input>
</div>
</div>
<script src="script3.js"></script>
</body>
</html>
提前感谢您的帮助,非常感谢。