簡體   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