【问题标题】:Making a game with Javascript, kinda like a visual novel用Javascript做游戏,有点像视觉小说
【发布时间】:2020-09-22 03:25:19
【问题描述】:

我是 JS 初学者。我想做一个视觉小说类型的游戏。当你在法庭上时,有点像游戏王牌律师。在这个游戏中,你会遇到人,而不是打架,而是和他们交谈。在相遇中,顶部是图像。此图像将根据您的反应而改变。它下面有一个文本框,显示当前文本。以及下面的 2 个(或可能更多)选项框。你有一个有 100 分的耐心表(就像一个健康表)。根据您选择的选项,您将失去或获得耐心。你跑了你就输了。目标是使用正确的响应并在不失去所有耐心的情况下完成对话。根据您所做的选择,会有不同的对话框。所以我正在准备一个对话树。

关于如何编码的任何想法?我很难弄清楚在哪里存储所有文本和选项。以及如何访问文本和选项。

这里是文本和选项的示例。起初我尝试将文本放入对象中。 sales1 是介绍文本。如果您选择 opt1,sales2 文本将显示在屏幕上。如果您选择 opt2,则 sales3 文本将显示在屏幕上。

常量销售额1 = { action: "推销员 Chad 想说话!", opt1: "告诉他你不感兴趣", opt2:“听他说完” };

常量销售额2 = { 行动:“他对此有一个反驳!”先生,像您这样的优雅男人需要这辆车!“”, opt1: ""我们甚至不在经销商处!"", opt2: ""一辆新车"" };

常量销售额3 = { action: ""Ssssoooooooo,你有什么样的电视服务?"", opt1:“告诉他你的房东付钱了”, opt2:“告诉他你不怎么看电视” };

@font-face {
    font-family: "Game Over Cre";
    src: url(fonts/gameovercre1.ttf);
    font-style: normal;
    font-weight: 300;
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: "Game Over Cre", sans-serif;
    font-size: 40px;
}

body {
    background: black;
    color: white;
}

#image-box {
    border: 4px solid white;
    height: 500px;
    width: 60%;
    margin: 10px auto;
    align-items: center;
    display: flex;
    justify-content: center;
}

#opponent {
    height: 400px;
}

#text-box {
    border: 4px solid white;
    height: 150px;
    width: 60%;
    margin: 10px auto;
    padding: 20px;
}

#options {
    display: flex;
    width: 60%;
    /* background: gray; */
    margin: auto;
    flex-wrap: wrap;
    justify-content: space-between;
}

#option-1, #option-2, #option-3, #option-4 {
    height: 100px;
    width: 49.5%;
    border: 4px solid white;
    margin-bottom: 10px;
    font-size: 35px;
    padding: 10px;
}

#option-1:hover, #option-2:hover, #option-3:hover, #option-4:hover {
    background: white;
    color: black;
}
<body>
    <section class="main-hub">
        <div id="image-box">
            <img id="opponent" src="img/salesman-chad.png">
        </div>
        <div id="text-box">
            <h1 id="action-text">Salesman Chad wants to talk!</h1>
        </div>
        <div id="options">
            <div id="option-1">Tell him you're not interested</div>
            <div id="option-2">Hear him out</div>
            <!-- <div id="option-3"></div>
            <div id="option-4"></div> -->
        </div>
    </section>

    <script src="main.js"></script>
</body>

【问题讨论】:

  • 听起来你在编写决策树(有点像 Black Mirror - Bandersnatch,在 JavaScript 中)。
  • 问:[我可以在哪里] 存储所有文本和选项。以及如何访问文本和选项? A:为什么不把你的数据保存在一个Json文件中,直接把Json读入一个JS对象呢?这是一个很好的例子:stackoverflow.com/a/24378510/421195 这个链接也可能有帮助:gamedesigning.org/learn/javascript
  • 嘿,tneilson08:如果我的回答有帮助,请告诉我!看起来很有用,恕我直言。我猜有人不喜欢它,以至于浏览了我所有的答案并对每个答案都投了反对票。人啊!无论如何,希望我的回答有所帮助。
  • 太棒了!我确实更喜欢您的原始答案,因为使用数组时,当有 50 多个对话部分时,知道我所在的数字会让人感到困惑!

标签: javascript


【解决方案1】:

您可以将您的数据结构从简单的opt1:sometext扩展为opt1:{text:sometext, nextpoint:2},这样您就可以以相对简单的方式展示和遍历您的小说游戏。您只需要能够执行 JSON 即可从此处继续。

使用代码示例,尝试玩下面的迷你版游戏!

const sales = [
    {
        action: "Salesman Chad wants to talk!",
        opt1: {
            text: "Tell him you're not interested",
            nextpoint: 1,
        },
        opt2:  {
            text: "Hear him out",
            nextpoint: 2,
        },
    },
    {
        action: "He has a rebuttal for that! 'Sir, a classy man like you needs this car!'",
        opt1: {
            text: "We're not even at a dealership!",
            nextpoint: 0,
        },
        opt2: {
            text: "Ooo a new car",
            nextpoint: 2,
        }
    },
    {
        action: "Ssssoooooooo, what kind of TV service do you have?",
        opt1: {
            text: "Tell him your landlord pays for it",
            nextpoint: 1,
        },
        opt2: {
            text: "Tell him you don't watch much TV",
            nextpoint: 0,
        }
    }
];

function applyPoint(next) {
    const point = sales[next];
    $('#action-text').text(point.action);
    $('#option-1').text(point.opt1.text);
    $('#option-2').text(point.opt2.text);
    $('#option-1').attr('data-nextpoint', point.opt1.nextpoint);
    $('#option-2').attr('data-nextpoint', point.opt2.nextpoint);
}

$('#option-1').click(function(e) {
    applyPoint($(this).attr('data-nextpoint'));
});

$('#option-2').click(function(e) {
    applyPoint($(this).attr('data-nextpoint'));
});

applyPoint(0);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
    <section class="main-hub">
        <div id="image-box">
            <img id="opponent" src="img/salesman-chad.png">
        </div>
        <div id="text-box">
            <h1 id="action-text"></h1>
        </div>
        <div id="options">
            <div id="option-1"></div>
            <div id="option-2"></div>
        </div>
    </section>
</body>

如您所见,小说本身存储在const sales 中,作为一个简单的 JSON 对象数组。在函数applyPoint() 中,我们从故事的当前点移动到故事的新点。控制这两个选项的按钮是 $('#option-1').click(function(e) {...}) 的 jQuery 语法,#option-2 也是如此。

定义完所有这些后,我以初始、起点开始游戏/小说,方法很简单:applyPoint(1);

【讨论】:

  • 您的数据结构建议使用数组而不是对象。
  • 好点,在这种情况下,数组也可以工作。但是带有nextpoint 的对象很容易成为日期时间组合或其他基于故事情节的键。
  • 这是使用 jQuery,根本没有问过。
  • 嗨,NVRM:感谢您指出这一点。 jQuery 是一个 JavaScript 框架,上面的代码旨在解决 OP 的问题: 我很难弄清楚在哪里存储所有文本和选项。以及如何访问文本和选项。
  • 严格来说这不是 JSON 对象,因为键不是字符串。
【解决方案2】:

这是对 @HoldOfHugers 答案的扩展,包括几个概念(数据存储之外),可以使开发更复杂的游戏更容易推理。

<body>
    <section class="main-hub">
        <div id="image-box">
            <img id="opponent" src="img/salesman-chad.png">
        </div>
        <div id="text-box">
            <h1 id="action-text"></h1>
        </div>
        <div id="options">
            <div id="option-1"></div>
            <div id="option-2"></div>
        </div>
    </section>
</body>
const sales = [
    {
        action: "Salesman Chad wants to talk!",
        opt1: {
            text: "Tell him you're not interested",
            nextpoint: 1,
        },
        opt2:  {
            text: "Hear him out",
            nextpoint: 2,
        },
    },
    {
        action: "He has a rebuttal for that! 'Sir, a classy man like you needs this car!'",
        opt1: {
            text: "We're not even at a dealership!",
            nextpoint: 0,
        },
        opt2: {
            text: "Ooo a new car",
            nextpoint: 2,
        }
    },
    {
        action: "Ssssoooooooo, what kind of TV service do you have?",
        opt1: {
            text: "Tell him your landlord pays for it",
            nextpoint: 1,
        },
        opt2: {
            text: "Tell him you don't watch much TV",
            nextpoint: 0,
        }
    }
];

const state = {
  index: 0,
  data: sales,
  get current() {
    return this.data[this.index]
  }
};

const ui = {
  action: document.querySelector('#action-text'),
  left: document.querySelector('#option-1'),
  right: document.querySelector('#option-2')
};

const update = (nextpoint) => {
  state.index = nextpoint;
  render();
};

const render = () => {
  ui.action.innerText = state.current.action;
  ui.left.innerText = state.current.opt1.text;
  ui.right.innerText = state.current.opt2.text;
};

ui.left.addEventListener('click', () => update(state.current.opt1.nextpoint));
ui.right.addEventListener('click', () => update(state.current.opt2.nextpoint));

render();

我添加的第一件事是游戏状态对象。这实际上可以是任何东西,但将游戏状态保存在可访问区域(例如变量或变量集)而不是 DOM 中通常是个好主意。您可以想象添加patiencescore 值、timerinventorynpcs 或任何其他可能代表游戏的内容。对于我们的例子,我们可能只想要对话框中的当前index,也许是所有dialog 信息,然后是当前派生的对话框值,因此查找起来更容易。它可以让您的生活变得更简单。

const state = {
  index: 0,
  data: sales,
  get current() {
    return this.data[this.index]
  }
};

接下来是更新方法。这可以被认为是我们游戏中的一个步骤。它负责获取我们当前的游戏状态和一些输入以及integrating 或导出下一个状态。更新函数通常以固定的时间间隔调用,比如每秒 60 次,但对于这个游戏,我们真的只需要响应用户。在更复杂的游戏中,更新函数调用会处理许多子系统,例如物理、动画、游戏逻辑等。出于我们的目的,当我们收到用户的新决定时,我们的游戏“步骤”。

const update = (nextpoint) => {
  state.index = nextpoint;
  render();
};

代码的最后一部分只是渲染当前的游戏状态。渲染函数从字面上查看当前状态并确保 UI 反映这些值。 ui 对象仅允许我以语义方式组织 UI 元素,这不是必需的。

如果您过去做过任何 Web 编程,您可能会发现这与 MVC 或反应式 ui 框架非常相似。数据单向流动。

【讨论】:

  • 感谢您扩展它!看到这些解决方案让我意识到我仍然需要学习更多的 JS 基础知识。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-18
相关资源
最近更新 更多