繁体   English   中英

第一次在无法正常运作的Clicker游戏中使用JavaScript

[英]First time using javascript for a clicker game that doesn't work

这是我第一次使用javascript。 我基本上想创建一个“点击器”游戏。 游戏的目标是单击图像以取得积分。 我已经尝试过自己修复它并在互联网上查找,但没有发现任何问题。 解决问题的原因是什么?

基本上,每次我打开页面时,分数已经设置为1,但是当我单击图像时分数不会增加。

<div id="bgk">
<div class="layer">
        <div class="row p-2">
            <div class="col-lg-6 col-xl-6 text-left"><p>Score: <span class="score"><script>document.write(scorecounter());</script></span></p></div>
            <div class="col-lg-6 col-xl-6 text-right"><p>Time: <span class="time">2</span></p></div>

            <div class="p-2">
                <img src="png.png" id="image" onclick="scorecounter()">
            </div>
        </div>
    </div>
</div>

虽然这是增加分数的脚本

<script>
var score = 0;
function scorecounter() 
{
    score ++;
    return score;
}
</script>

您的score最初是1,因为您在使用时会调用函数

document.write(scorecounter());

这将增加score的值,然后将其返回,从而显示数字1。

您的点击没有增加score的原因是因为您没有再次显示score 目前,您只是在页面加载时显示分数。 然后,当您单击图像时, score的值会增加,但不会再次显示在DOM(即页面)上。 要在页面上显示分数的值,可以在要显示分数的元素上使用.innerHTML

请参见下面的工作示例:

 var score = 0; function scorecounter() { score++; document.getElementById('score').innerHTML = score; // Set the element with the id 'score' to have the value 'score' inside of it. Also note that .innerHTML can be replaced with .textContent to help resolve XSS vulnrabilities. } 
 /* css - ignore this */ .red { background-color: red; height: 50px; width: 100%; color: white; text-align: center; cursor: pointer; } 
 <p>Score: <span id="score">0</span></p> <div class='red' onclick="scorecounter()"> Click me (imagine this as your image) </div> 

编辑:正如@BrandonBuck指出的那样, .innerHTML倾向于跨站点脚本(XSS)。 为了避免这种情况,请使用.textContent而不是.innerHTML来避免这种情况。

这是它的一个JSFiddle。

因此,您正在做很多事情,您可能不应该做。 这不一定是你的错。 JavaScript很旧,并且在线上有很多资源,其中某些资源注定是不好的。 更不用说,我不知道您从哪里开始,所以您可能会得到一些非常古老的例子或您拥有什么。

那么从哪里开始,让我们看看...我们不再使用document.write了。 事实上,大约17年前我开始使用JS时,它并不是那么普遍。 document.write的问题在于它没有按照您认为的那样做。 最初解析页面时,将执行该页面,并将编写您告诉它的内容,就是这样。 它已经完成工作,并且结束了。 在重新加载页面之前,它将永远不会再写入。

正如@NickParsons在他的评论中指出的那样,您的分数“始于” 1因为您在写语句中调用了scorecounter ,因此您要增加分数并同时写入新的值

接下来,您将使用HTML属性来关联JavaScript操作。 由于我们倾向于将JS和HTML保持非常独立,因此在现代Web开发中通常对此并不满意。 我将向您展示一些示例。

好的,另一件事是全局值。 当然,在您的示例中,这不一定是可以避免的,但是我们可以为此进行一些清理。 所以,让我们去吧。 首先,让我们清理HTML。 除了JS之外,大多数都还不错。

这是我第一次使用javascript。 我基本上想创建一个“点击器”游戏。 游戏的目标是单击图像以取得积分。 我已经尝试过自己修复它并在互联网上查找,但没有发现任何问题。 是什么引起了问题?

基本上,每次我打开页面时,分数已经设置为1,但是当我单击图像时分数不会增加。

<div id="bgk">
  <div class="layer">
    <div class="row p-2">
      <div class="col-lg-6 col-xl-6 text-left">
        <p>
          Score: <span class="score-value"></span>
        </p>
      </div>
      <div class="col-lg-6 col-xl-6 text-right">
        <p>
          Time: <span class="time-value">2</span>
        </p>
      </div>
      <div class="p-2">
        <img src="png.png" id="image">
      </div>
    </div>
  </div>
</div>

因此,除了格式化之外,我要做的最大事情是删除所有JS代码,并将值范围内的类更改为<name>-value ,所以score是一个很好的类名,请不要误解我-但是score-value对于我们要放置的内容更加清楚

接下来,我们需要清理JavaScript。 作为基础,这还不错。 但这不是我们想要去的地方。 让我们逐步进行。 我将在这里从头开始,因为我们将对其进行很多更改。 首先,我们有一个Game ,我们的游戏将获得一个与之相关的score 因此,让我们创建一个类(类语法是新的,但是大多数使用的主要浏览器都本身支持)。

class Game {
  constructor() {
    this.score = 0;
  }
}

am 上了我们的课。 我们还需要什么? 好吧-我们需要增加分数。 因此,让我们这样做。

class Game {
  constructor() {
    this.score = 0;
  }

  incrementScore() {
    this.score += 1;
  }
}

很简单。 接下来,我们需要呈现分数,或将其添加到DOM(浏览器处理后的HTML变成“ DOM”或文档对象模型,这是一个API,可让我们通过编程方式与页面进行交互)。

现在,渲染此分数可能是我们游戏的一部分,但事实并非如此-我们的游戏应该仅仅是游戏本身。 它实际上不应该包含其他逻辑。 否则,我们将获得超类,并且我们可能还没有尝试这样做。 但是我们可以创建一个新的类...称之为UserInterface ,因为您知道这是我们的UserInterface 大多数JavaScript库会将应用程序的HTML / DOM方面称为“视图”或“组件”。我使用的是“用户界面”,因为我们是在谈论“游戏”,而通用术语是UI。

class UserInterface {}

好的,所以我们需要渲染text 为此,我们需要获取要存储分数的DOM节点 ,然后将其文本设置为当前score UserInterface不知道得分是多少,游戏知道,所以我们需要传递一些数据。

class UserInterface {
  renderScore(score) {
    const el = document.querySelector('.score-value');
    el.textContent = score;
  }
}

你看我用过const 在大多数情况下,您可以想象const就像var一样-它声明了一个变量。 在下面,它们的工作方式完全不同。 在不深入讨论JavaScript变量作用域的情况下,我只想说var是老派,而const是新派。 const不仅定义了像var这样的变量,而且还对其进行了定义,以使其无法重新分配。 由于我们从未在renderScore主体中重新分配el ,因此将其设置为const 现在, var就像我说的那样是老派,而新的替代是let ,它和const (就作用域而言),但允许您重新分配值。 我鼓励您更多地研究为什么添加letconst ,但这超出了这个答案。

这里有一个优化-您看到我每次渲染时都在搜索.score-value元素。 这不好。 我可以在这里采取几种方法,但是为了简单起见,让我们最简单地进行一下准备。

class UserInterface {
  constructor() {
    this.scoreValueEl = document.querySelector('.score-value');
  }

  renderScore(score) {
    this.scoreValueEl.textContent = score;
  }
}

顺便说一句,您可能不知道document.querySelector做什么,但是您可以将其视为在DOM(同样,在浏览器处理HTML页面之后,HTML页面变成什么)中寻找与您传递给它的文本匹配的元素。 selector一词来自CSS,您可以在其中通过“选择”元素来定义规则。 您可以按标签, h3div等进行选择。也可以按类名进行选择(只需在类名前面附加一个. ,例如class="score-value"元素的.score-value )即可通过ID选择(只需在类名后附加一个类似于.# )即可。 您可能会变得更加复杂,但现在就不要说了。 因此document.querySelector('.score-value')说,“嘿DOM,您能找到上面带有“ score-value”类的元素并将其还给我吗?”

好的,现在我有了Game来跟踪得分(以及其他将来的游戏元素),然后有了User Interface来将这些内容呈现给用户。 接下来,我们需要进行一些交互。 这部分可能是传递许多函数等的主题。因此,我将使其保持相对简单。 准备好Game和UserInterface类后,我们将点击绑定到我们的图像上并增加分数并进行渲染。 因此,让我们放手一搏。 首先,让我们创建新的值:

const game = new Game();
const ui = new UserInterface();

// we want to show the score on load, so let's do that
ui.renderScore(game.score);

好吧,所以第一部分下来。 现在让我们处理点击。 再次使用document.querySelector来获取图像:

// see here, we only have one img tag on the page, so I use the tag
// as the selector to find it
const img = document.querySelector('img');

img.addEventListener('click', () => {
  game.incrementScore();
  ui.renderScore(game.score);
});

好的,这里有两个新内容。 addEventListener是JS表示“嘿元素,当用户执行X做Y时”的方式,在这种情况下,我们说“当用户单击此图像时,运行此功能”。 因此,我们传递给addEventListener的第一个值是我们要处理的事件的名称,第二个值是我们要在触发事件时执行的函数。 现在,该函数是作为“箭头函数”编写的,它是简写形式,与function() {}含义相同。 因此, () => {}function() {} () => {}是相同的东西function() {}同样,我掩盖了一些差异,因为它超出了此答案的范围,您肯定应该查找这些差异)。 因此,不要被其中的箭头功能惊慌,它是我们传递给调用的简单JS函数。 请注意,在此函数内部,我们增加了分数,然后进行渲染。

所以最终的JS应该是这样的:

class Game {
  constructor() {
    this.score = 0;
  }

  incrementScore() {
    this.score += 1;
  }
}

class UserInterface {
  constructor() {
    this.scoreValueEl = document.querySelector('.score-value');
  }

  renderScore(score) {
    this.scoreValueEl.textContent = score;
  }
}

const game = new Game();
const ui = new UserInterface();

ui.renderScore(game.score);

const img = document.querySelector('img');
img.addEventListener('click', () => {
  game.incrementScore();
  ui.renderScore(game.score);
});

这是它的一个JSFiddle。

添加在

(是的,我还有更多话要说)

综上所述,学习JS很容易且容易上手。 如果您想复习或学习新知识,可以前往CodeAcademy,或者如果您不介意一些自费技能,SkillShare,PluralSight,CodeSchool等提供JavaScript课程。

除了学习更多有关JavaScript的知识外,大多数现实世界中的JavaScript都是以某种框架为起点编写的。 提到了Vue,因此当您觉得自己有了JS的知识和舒适度时,就应该研究Vue。 很棒是因为它具有最少的样板(“入门”所需的代码量),并且从本质上讲,与其他流行的解决方案具有同等的功能。 其他解决方案包括React,Angular,也许Ember仍然存在,Meteor(用于完整堆栈的东西)等等。 同样,尽管随着越来越多的人离开它,jQuery正在“走出困境”,但jQuery仍然存在,并且仍然提供了大量便利,而不是直接与DOM一起使用。 因此,总会有这条路线。

JavaScript的世界太大了 ,并且还在增长。 因此,您可以真正找到满足其目的的任何产品。 有成百上千的MVC框架,组件框架,DOM包装器,其他基本utils,游戏引擎等。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM