为了账号安全,请及时绑定邮箱和手机立即绑定

用 Javascript 制作游戏,有点像视觉小说

用 Javascript 制作游戏,有点像视觉小说

牧羊人nacy 2023-03-18 17:09:14
我是 JS 初学者。我想制作一款视觉小说类型的游戏。当你在法庭上时,有点像 Ace Attorney 游戏。在这个游戏中,你会遇到人,而不是打架,而是与他们交谈。在遭遇中,顶部是一个图像。此图像将根据您的反应而改变。它下方有一个文本框,显示当前文本。下面有 2 个(或可能更多)选项框。你有一个有 100 点的耐心计(就像健康计)。根据您选择的选项,您将失去或获得耐心。你用完了你就输了。目标是使用正确的响应并在不失去所有耐心的情况下到达对话的结尾。根据您所做的选择,将出现不同的对话框。所以我正在准备一个对话树。关于如何编码的任何想法?我真的很难弄清楚在哪里存储所有文本和选项。以及如何访问文本和选项。这是文本和选项的示例。起初我尝试将文本放在对象中。sales1 是介绍文字。如果您选择 opt1,sales2 文本将显示在屏幕上。如果您选择 opt2,sales3 文本将显示在屏幕上。const sales1 = { action: "Salesman Chad wants to talk!", opt1: "告诉他你不感兴趣", opt2: "听他说完" };const sales2 = { action: "他对此进行了反驳!"先生,像你这样有品位的人需要这辆车!", opt1: ""我们甚至不在经销店!", opt2: ""Ooo一辆新车”” };const sales3 = { action: ""Ssssooooooooo, 你有什么样的电视服务?", 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>
查看完整描述

2 回答

?
慕码人2483693

TA贡献1860条经验 获得超9个赞

您可以将您的数据结构从简单的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(),我们从故事的当前点移动到故事的新点。控制这两个选项的按钮是 jQuery 语法,$('#option-1').click(function(e) {...})同样适用于#option-2.

定义完所有这些后,我通过以下方式简单地从初始起点开始游戏/小说: applyPoint(1);


查看完整回答
反对 回复 2023-03-18
?
慕桂英3389331

TA贡献2036条经验 获得超8个赞

这个解决方案包括几个概念(除了数据存储),这些概念可以使开发更复杂的游戏更容易推理。


<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 中通常是个好主意。您可以想象添加patience、一个score值、一个timer、inventory、npcs或任何其他可能代表游戏的东西。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 元素,这不是必需的。


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


查看完整回答
反对 回复 2023-03-18
  • 2 回答
  • 0 关注
  • 82 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信