簡體   English   中英

JavaScript 游戲中的 if 語句無法正常工作以允許碰撞檢測

[英]if statement in JavaScript game not working as desired to allow for collision detection

我正在完成 HTML、CSS 和 JScript 游戲中的一些基本步驟,以便在角色和敵人之間進行非常簡單的碰撞檢測

我正在尋找足夠簡單的東西來向 8 - 11 歲的孩子解釋。

如果角色和敵人發生碰撞,則“游戲結束”。 我嘗試了各種方法,但需要一些代碼幫助和 getComputedStyle 方法的解釋以及它獲得的屬性,以便我有效地創建主 if 語句。

如果 function,這是相關的:

if(
        characterTop==enemyLeft //have tried characterRight==enemyLeft didn't work
    )
    {
        enemy.style.animation="none"; //remove the animation
        enemy.style.display="none";
        alert("Game Over");
        
    } 
},10);

這是聲明變量的setInterval function (我在 if 函數中使用)。 我已經基於 varcharacterTop 變量和enemyLeft 創建了 var CharacterRight 變量,但它似乎不起作用,或者我不確定我是否以正確的方式進行操作。

在當前設置中發生了一些奇怪的事情。 如果我離開角色並且不移動它,則(敵人)彈跳 5 次后游戲結束,即使按照 if function,characterTop 根本沒有改變。 那么那里發生了什么?

請在回答中:

a)根據我現有的代碼提出碰撞檢測的建議解決方案

b) GetComputedStyle 和 getProperties 的說明及其文檔。 例如,如果 characterTop 沒有改變(如果我不移動角色)它怎么會突然輸出“游戲結束”,這表明 characterTop 是 ==enemyLeft。

c) 簡單碰撞檢測的最佳實踐(對於絕對初學者的學習概念,並根據現有代碼提出最簡單的解決方案)

var checkDead =setInterval(function(){
    var characterTop = parseInt(window.getComputedStyle(character).getPropertyValue("top"));
    var enemyLeft = parseInt(window.getComputedStyle(enemy).getPropertyValue("left"));
    //ADD VARIABLE TO FIND CHARACTER RIGHT -if it collides with enemy left, you are out
    //remove the condition that the enemy has to be in the first 30 pixels of the game (left side)
    var characterRight =parseInt(window.getComputedStyle(character).getPropertyValue("right"));

為了完整起見,這里是整個代碼:

HTML

<!DOCTYPE html>

<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" href="style.css">
    
</head>
<body>
  <h1>Game</h1>
 
   
   
   <div id="game">
        <div id="sky"></div>
       <div id="ground"></div>
        <div id="enemy"></div>
       <div id="character"></div>
   </div>
   
<script src="script.js"></script>
</body>

</html>

CSS

*{
    padding:0;
    margin:22;
}

#game{
    width:500px;
    height:500px;
    border:4px solid #171918;
}

#character{
    width:30px;
    height:120px;
    background-color:green;
    position:relative;
    top:320px;
    border-radius:20px;
    /*animation: jump 300ms */
    
}

/* new class called animate */
.animate{
    animation: jump 500ms;
}


#enemy{
    width:60px;
    height:60px;
    background-color:red;
    border-radius:14px;
    position:relative;
    top:320px;
    left:440px;
    animation: moveenemy 1s infinite linear;
    
}

@keyframes moveenemy{
    0%{left:440px;}
    50%{top:58px;}
    100%{left:0px; top:320x;}
}

@keyframes jump{
    0%{top:380px;}
    30%{top:50px;}
    50%{top:40px;}
    100%{top:380px;}
}





/* adding sky*/
#sky{
    width:500px;
    height:340px;
    background-color:skyblue;
    position:absolute;
    top:118px;
}

/* adding ground */
#ground{
    width:500px;
    height:170px;
    background-color:bisque;
    position:absolute;
    top:450px;
}

JavaScript

var character = document.getElementById("character");
var enemy = document.getElementById("enemy");    
function jump(){
    if(character.classlist!="animate"){
    character.classList.add("animate");
    }
    setTimeout(function(){
        character.classList.remove("animate");
    },500);
    
}

//right movement

function right() {
  var leftVal =  parseInt(window.getComputedStyle(character).getPropertyValue("left"))
  character.style.left = (leftVal + 30) + "px";

}

//left movement
function left() {

  var leftVal =  parseInt(window.getComputedStyle(character).getPropertyValue("left"))
  character.style.left = (leftVal - 30) + "px";

}

var checkDead =setInterval(function(){
    var characterTop = parseInt(window.getComputedStyle(character).getPropertyValue("top"));
    var enemyLeft = parseInt(window.getComputedStyle(enemy).getPropertyValue("left"));
    //ADD VARIABLE TO FIND CHARACTER RIGHT -if it collides with enemy left, you are out
    //remove the condition that the enemy has to be in the first 30 pixels of the game (left side)
    var characterRight =parseInt(window.getComputedStyle(character).getPropertyValue("right"));
    
    console.log(characterRight);
    console.log(enemyLeft)
  
    if(
        characterTop==enemyLeft //have tried characterRight==enemyLeft didn't work
    )
    {
        enemy.style.animation="none"; //remove the animation
        enemy.style.display="none";
        alert("Game Over");
        
    } 
},10);


//left
addEventListener("keydown", function(e) {
    if(e.keyCode == 37) left()
})

//jump (up)
addEventListener("keydown", function(e) {
  if (e.keyCode === 38) {
    jump()
  }
})

//right
addEventListener("keydown", function(e) {
  if (e.keyCode === 39) {
    right()
  }
})

我看過這個文檔,但它似乎沒有引用對象。 https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle

按順序列出提出的要點:

a)根據我現有的代碼提出碰撞檢測的建議解決方案

您不能在此處使用 getComputedStyle(參見 b 點)。 下面是使用帶有碰撞檢測的 getBoundingClientRect 的代碼(即當敵人和角色完全重疊時)

b) GetComputedStyle 和 getProperties 的說明及其文檔。 例如,如果 characterTop 沒有改變(如果我不移動角色)它怎么會突然輸出“游戲結束”,這表明 characterTop 是 ==enemyLeft。

getComputedStyle 就是這樣做的,它遍歷所有樣式設置並將它們合並,以便您獲得元素的當前樣式。 參見例如https://developer.mozilla.org/en-US/docs/Web/API/Window/getComputedStyle

Window.getComputedStyle() 方法返回一個 object 包含所有 CSS 元素的屬性的值,在應用活動樣式表並解析任何基本計算之后。

The problem we have in this case is that it's not the computed styles we are after, it is the actual, of this moment, position of an element which is being flown around the window by a CSS animation. 因此使用 getBoundingClientRect 來獲取元素的實際當前 x 和 ys。

原作中角色頂部對敵人左側的測試並沒有告訴你任何事情。 但有時它們可能會匹配,所以你會得到一個游戲結束。

c) 簡單碰撞檢測的最佳實踐(針對初學者的學習概念)

老實說,我不認為我可以對此發表看法,因為我不知道學生已經掌握了多少幾何/代數等。 下面使用的代碼檢測敵人是否完全在角色上方,反之亦然,如果不是,則一個人是否完全在另一個人的左側。 否則它們會重疊。

這是完整的代碼。 不幸的是,SO 的代碼片段系統似乎沒有響應 keydown 事件,所以我無法在此處將其呈現為可運行的代碼片段。

<!DOCTYPE html>

<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
    *{
    padding:0;
    margin:22;
}

#game{
    width:500px;
    height:500px;
    border:4px solid #171918;
}

#character{
    width:30px;
    height:120px;
    background-color:green;
    position:relative;
    top:320px;
    border-radius:20px;
    /*animation: jump 300ms */
    
}

/* new class called animate */
.animate{
    animation: jump 500ms;
}


#enemy{
    width:60px;
    height:60px;
    background-color:red;
    border-radius:14px;
    position:relative;
    top:320px;
    left:440px;
    animation: moveenemy 1s infinite linear;    
}

@keyframes moveenemy{
    0%{left:440px;}
    50%{top:58px;}
    100%{left:0px; top:320x;}
}

@keyframes jump{
    0%{top:380px;}
    30%{top:50px;}
    50%{top:40px;}
    100%{top:380px;}
}





/* adding sky*/
#sky{
    width:500px;
    height:340px;
    background-color:skyblue;
    position:absolute;
    top:118px;
}

/* adding ground */
#ground{
    width:500px;
    height:170px;
    background-color:bisque;
    position:absolute;
    top:450px;
}
</style>    
</head>
<body>
  <h1>Game</h1>
 
   
   
   <div id="game">
        <div id="sky"></div>
       <div id="ground"></div>
        <div id="enemy"></div>
       <div id="character"></div>
   </div>
   
<script>
var character = document.getElementById("character");
var enemy = document.getElementById("enemy");    
function jump(){
    if(character.classlist!="animate"){
    character.classList.add("animate");
    }
    setTimeout(function(){
        character.classList.remove("animate");
    },500);
    
}

//right movement

function right() {
  var leftVal =  parseInt(window.getComputedStyle(character).getPropertyValue("left"))
  character.style.left = (leftVal + 30) + "px";

}

//left movement
function left() {

  var leftVal =  parseInt(window.getComputedStyle(character).getPropertyValue("left"))
  character.style.left = (leftVal - 30) + "px";

}

var checkDead = setInterval(function(){
       
    // Get the positions of the top, left and bottom, right of the enemy and the character    
    let enemyPos = enemy.getBoundingClientRect() // this will give us the left, right, top and bottom positions of the enemy
    let characterPos = character.getBoundingClientRect() // this will give us the left, right, top and bottom positions of the character

    // now let's see if there is any overlap between the enemy and the character

   // we are going to check whether one of them is to the left of the other.
   // For example if the left side of the enemy is bigger than the right side of the character then the enemy is to the right of the character
    if (enemyPos.left >= characterPos.right || characterPos.left >= enemyPos.right) {
       // Now we know they don't overlap as either the enemy is to the right of the character or vice versa so do nothing
    }
    
       // if we still don't know, we see whether the character is above the enemy or vice versa
    else if (enemyPos.bottom <= characterPos.top || characterPos.bottom <= enemyPos.top) {
       // Now we know they don't overlap as either the enemy is above the character or vice versa so do nothing
    }
      
      // neither of them is totally to the left or totally above the other so they must overlap somewhere- GOTCHA!
    else {
        enemy.style.animation="none"; //remove the animation
        enemy.style.display="none";
        alert("Game Over");
        clearInterval(checkDead); //I've added this but you may want to start again completely or....
    }        
  },10 );


//left
addEventListener("keydown", function(e) {
    if(e.keyCode == 37) left()
})

//jump (up)
addEventListener("keydown", function(e) {
  if (e.keyCode === 38) {
    jump()
  }
})

//right
addEventListener("keydown", function(e) {
  if (e.keyCode === 39) {
    right()
  }
})
</script>

</body>

</html>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM