2017-02-02 8 views
2

私はヘビのゲームを作りました。ヘビが壁や自分自身を打つと、まだ動きは止まらなくなりました。私はclearTimeout()を使用すれば、それが助けになるとわかりました。しかしそれはしませんでした。 ループを停止する方法はありますか?それとも別の問題ですか? スネークゲームでsetTimeoutループを停止しますか?

jQuery(document).ready(function($) { 
 
    init(); 
 
}); 
 

 
var move; 
 
function init() { 
 
    board.initBoard(); 
 
    drawSnake(); 
 
    food.createFood(); 
 
} 
 

 
function play() { 
 
    $('.newGame').css('visibility', 'hidden'); 
 
    $('.playgame').css('visibility', 'hidden'); 
 
    moveSnake(); 
 
    getSnakeDir(); 
 
} 
 

 
function gameover() { 
 
    clearTimeout(move); 
 
    $('.newGame').css('visibility', 'visible'); 
 
} 
 

 
function playGame() { 
 
    $('#gameboard').empty(); 
 
    $('.newGame').hide(); 
 
    init(); 
 
    play(); 
 
} 
 

 
var board = { 
 
    DIM: 20, 
 
    initBoard: function() { 
 
     for (var i = 0; i < board.DIM; i++) { 
 
      var row = $('<div class="row-' + i + '"></div>'); 
 
      
 
      for (var j = 0; j < board.DIM; j++) { 
 
       var col = ('<div class="col-' + j + '-' + i + '"></div>'); 
 
       $(row).append(col); 
 
      } 
 
      $("#gameboard").append(row); 
 
     } 
 
    } 
 
} 
 

 
var snake = { 
 
    position: ['10-10', '10-11', '10-12'], 
 
    direction: 'r', 
 
    speed: 200, 
 
}; 
 

 
function drawSnake() { 
 
    $('.col-10-10').addClass('snake'); 
 
    $('.col-11-10').addClass('snake'); 
 
} 
 

 
function getSnakeDir() { 
 
    $(document).keydown(function(event) { 
 
     //event.preventDefault(); 
 
     if (event.which == 38) { 
 
      snake.direction = 'u'; 
 
     } else if (event.which == 39) { 
 
      snake.direction = 'r'; 
 
     } else if (event.which == 40) { 
 
      snake.direction = 'd'; 
 
     } else if (event.which == 37) { 
 
      snake.direction = 'l'; 
 
     } 
 
    }); 
 
} 
 

 
function moveSnake() { 
 
    var tail = snake.position.pop(); 
 
    $('.col-' + tail).removeClass('snake'); 
 

 
    var coords = snake.position[0].split('-'); 
 
    var x = parseInt(coords[0]); 
 
    var y = parseInt(coords[1]); 
 

 
    if (snake.direction == 'r') { 
 
     x = x + 1; 
 
    } else if (snake.direction == 'd') { 
 
     y = y + 1; 
 
    } else if (snake.direction == 'l') { 
 
     x = x - 1; 
 
    } else if (snake.direction == 'u') { 
 
     y = y - 1; 
 
    } 
 
    
 
    var currentcoords = x + '-' + y; 
 
    snake.position.unshift(currentcoords); 
 

 
    $('.col-' + currentcoords).addClass('snake'); 
 

 
    //when snake eats food 
 
    if (currentcoords == food.coords) { 
 
     console.log('true'); 
 
     $('.col-' + food.coords).removeClass('food'); 
 
     snake.position.push(tail); 
 
     food.createFood(); 
 
    } 
 

 
    //game over 
 
    if (x < 0 || y < 0 || x > board.DIM || y > board.DIM) { 
 
     gameover(); 
 
    
 
    } 
 

 
    //if snake touch itself 
 
    if (hitItself(snake.position) == true) { 
 
     gameover(); 
 
    } 
 
    
 
    move=setTimeout(moveSnake, 200); 
 
} 
 

 
var food = { 
 
    coords: "", 
 

 
    createFood: function() { 
 
     var x = Math.floor(Math.random() * (board.DIM-1)) + 1; 
 
     var y = Math.floor(Math.random() * (board.DIM-1)) + 1; 
 
     var fruitCoords = x + '-' + y; 
 
     $('.col-' + fruitCoords).addClass('food'); 
 
     food.coords = fruitCoords; 
 
    }, 
 
} 
 

 
function hitItself(array) { 
 
    var valuesSoFar = Object.create(null); 
 
    for (var i = 0; i < array.length; ++i) { 
 
     var value = array[i]; 
 
     if (value in valuesSoFar) { 
 
      return true; 
 
     } 
 
     valuesSoFar[value] = true; 
 
    } 
 
    return false; 
 
}
.buttonnewgame { 
 
    position: relative; 
 
} 
 

 
.newGame { 
 
    position: absolute; 
 
    top: 45%; 
 
    left: 25%; 
 
    padding: 15px; 
 
    font-size: 1em; 
 
    font-family: arial; 
 
    visibility: hidden; 
 
} 
 

 
.gameContainer{ 
 
    width: 100%; 
 
} 
 

 
#gameboard { 
 
    background-color:#eee; 
 
    padding:3px; 
 
} 
 

 
.playgame { 
 
    position: absolute; 
 
    top: 45%; 
 
    left: 20%; 
 
    padding: 15px; 
 
    font-size: 1em; 
 
    font-family: arial;  
 
} 
 

 
/* styling the board */ 
 
div[class^='row'] { 
 
    height: 15px; 
 
    text-align: center; 
 
} 
 

 
div[class*='col']{ 
 
    display: inline-block; 
 
    border: 1px solid grey; 
 
    width: 15px; 
 
    height: 15px; 
 
} 
 

 
/*display the snake*/ 
 
.snake { 
 

 
    background-color: blue; 
 
    z-index: 99; 
 
} 
 

 
.food { 
 
    background: red; 
 
    z-index: 99; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div class="game"> 
 
    <div class="buttonnewgame"> 
 
     <input type="button" name="new game" value="new game" class="newGame" onclick="playGame()" /> 
 
     <button class="playgame" onclick="play()">Play Game</button> 
 
     <div class="gameContainer"> 
 
      <div id="gameboard"> 
 
       <!-- snake game in here --> 
 
      </div> 
 
     </div> 
 
    </div> 
 
</div>

答えて

1

んが、は '作業バージョン'(より多くのバグがある)であります。

1)drawSnakeからcreateSnakeに名前を変更しました。 init()に電話したとき、あなたは完全にヘビを再初期化していませんでした。以前のdrawSnakeメソッドでスネークの位置がリセットされていないため、ゲームが再生できないように見えます。

その後、さらに2つのバグがありました。

2)gameOverに電話した後に戻る必要がありますか、ゲームが実際に終了することはありませんか? gameoverでタイムアウトをクリアすると、ゲームが終了しても戻ってこなかったので、すぐにmoveSnake()の最後の行にタイムアウトを設定します。それがゲームのように思われるような奇妙な結果につながり、反応しなくなりました。

3)visibilitynoneまたはvisible$.hide()の組み合わせを使用していました。 $.hide()display: noneを使用していますので、visibilityのスタイルが変更されたときに再度表示しようとしたときには、まだdisplay: noneと表示されますので、新しいゲームボタンが表示されなくなります。

ゲームコーダーには、ゲームの仕組み(ゲームの論理、時計の動き、ゲームの状態の初期化など)を処理するコードと、どのように表示されるかを知ることができます。 htmlとcss)。きれいに書かれたシステムの後にゲームロジックをモデル化することは、読み込みとデバッグが容易です。このコードは、表示コードがゲームロジックと混在していると、理解して変更するのが難しくなります。理論的には、私たちのゲームはどんな種類のレンダリングもせずに完璧に動作するはずです。次に、HTMLキャンバス、html DOM、コマンドラインのテキスト、またはOpenGLを生成するレンダラーを記述することができます。

私はこれまでに完成したことのない古いプロジェクトに、モデルとビューの分離を示す必要があります。

http://tando.us/ganix/ganix.htm

jQuery(document).ready(function($) { 
 
    init(); 
 
}); 
 

 
var move; 
 
function init() { 
 
    board.initBoard(); 
 
    createSnake(); 
 
    food.createFood(); 
 
} 
 

 
function play() { 
 
    $('.newGame').hide(); 
 
    $('.playgame').hide(); 
 
    moveSnake(); 
 
    getSnakeDir(); 
 
} 
 

 
function gameover() { 
 
    clearTimeout(move); 
 
    $('.newGame').show(); 
 
} 
 

 
function playGame() { 
 
    $('#gameboard').empty(); 
 
    $('.newGame').hide(); 
 
    init(); 
 
    play(); 
 
} 
 

 
var board = { 
 
    DIM: 20, 
 
    initBoard: function() { 
 
     for (var i = 0; i < board.DIM; i++) { 
 
      var row = $('<div class="row-' + i + '"></div>'); 
 
      
 
      for (var j = 0; j < board.DIM; j++) { 
 
       var col = ('<div class="col-' + j + '-' + i + '"></div>'); 
 
       $(row).append(col); 
 
      } 
 
      $("#gameboard").append(row); 
 
     } 
 
    } 
 
} 
 

 
var snake = { 
 
    position: ['10-10', '10-11', '10-12'], 
 
    direction: 'r', 
 
    speed: 200, 
 
}; 
 

 
function createSnake() { 
 
    $('.col-10-10').addClass('snake'); 
 
    $('.col-11-10').addClass('snake'); 
 
    snake.position = ['10-10', '10-11', '10-12']; 
 
} 
 

 
function getSnakeDir() { 
 
    $(document).keydown(function(event) { 
 
     //event.preventDefault(); 
 
     if (event.which == 38) { 
 
      snake.direction = 'u'; 
 
     } else if (event.which == 39) { 
 
      snake.direction = 'r'; 
 
     } else if (event.which == 40) { 
 
      snake.direction = 'd'; 
 
     } else if (event.which == 37) { 
 
      snake.direction = 'l'; 
 
     } 
 
    }); 
 
} 
 

 
function moveSnake() { 
 
    var tail = snake.position.pop(); 
 
    $('.col-' + tail).removeClass('snake'); 
 

 
    var coords = snake.position[0].split('-'); 
 
    var x = parseInt(coords[0]); 
 
    var y = parseInt(coords[1]); 
 

 
    if (snake.direction == 'r') { 
 
     x = x + 1; 
 
    } else if (snake.direction == 'd') { 
 
     y = y + 1; 
 
    } else if (snake.direction == 'l') { 
 
     x = x - 1; 
 
    } else if (snake.direction == 'u') { 
 
     y = y - 1; 
 
    } 
 
    
 
    var currentcoords = x + '-' + y; 
 
    snake.position.unshift(currentcoords); 
 

 
    $('.col-' + currentcoords).addClass('snake'); 
 

 
    //when snake eats food 
 
    if (currentcoords == food.coords) { 
 
     console.log('true'); 
 
     $('.col-' + food.coords).removeClass('food'); 
 
     snake.position.push(tail); 
 
     food.createFood(); 
 
    } 
 

 
    //game over 
 
    if (x < 0 || y < 0 || x > board.DIM || y > board.DIM) { 
 
     gameover(); 
 
     return; 
 
    
 
    } 
 

 
    //if snake touch itself 
 
    if (hitItself(snake.position) == true) { 
 
     gameover(); 
 
     return; 
 
    } 
 
    
 
    move=setTimeout(moveSnake, 200); 
 
} 
 

 
var food = { 
 
    coords: "", 
 

 
    createFood: function() { 
 
     var x = Math.floor(Math.random() * (board.DIM-1)) + 1; 
 
     var y = Math.floor(Math.random() * (board.DIM-1)) + 1; 
 
     var fruitCoords = x + '-' + y; 
 
     $('.col-' + fruitCoords).addClass('food'); 
 
     food.coords = fruitCoords; 
 
    }, 
 
} 
 

 
function hitItself(array) { 
 
    var valuesSoFar = Object.create(null); 
 
    for (var i = 0; i < array.length; ++i) { 
 
     var value = array[i]; 
 
     if (value in valuesSoFar) { 
 
      return true; 
 
     } 
 
     valuesSoFar[value] = true; 
 
    } 
 
    return false; 
 
}
.buttonnewgame { 
 
    position: relative; 
 
} 
 

 
.newGame { 
 
    position: absolute; 
 
    top: 45%; 
 
    left: 25%; 
 
    padding: 15px; 
 
    font-size: 1em; 
 
    font-family: arial; 
 
} 
 

 
.gameContainer{ 
 
    width: 100%; 
 
} 
 

 
#gameboard { 
 
    background-color:#eee; 
 
    padding:3px; 
 
} 
 

 
.playgame { 
 
    position: absolute; 
 
    top: 45%; 
 
    left: 20%; 
 
    padding: 15px; 
 
    font-size: 1em; 
 
    font-family: arial;  
 
} 
 

 
/* styling the board */ 
 
div[class^='row'] { 
 
    height: 15px; 
 
    text-align: center; 
 
} 
 

 
div[class*='col']{ 
 
    display: inline-block; 
 
    border: 1px solid grey; 
 
    width: 15px; 
 
    height: 15px; 
 
} 
 

 
/*display the snake*/ 
 
.snake { 
 

 
    background-color: blue; 
 
    z-index: 99; 
 
} 
 

 
.food { 
 
    background: red; 
 
    z-index: 99; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div class="game"> 
 
    <div class="buttonnewgame"> 
 
     <input type="button" name="new game" value="new game" class="newGame" style="display:none;" onclick="playGame()" /> 
 
     <button class="playgame" onclick="play()">Play Game</button> 
 
     <div class="gameContainer"> 
 
      <div id="gameboard"> 
 
       <!-- snake game in here --> 
 
      </div> 
 
     </div> 
 
    </div>

+0

詳細な説明ありがとうございます。そしてそれは働いた!注記すると、MVCについて知る前に、私はこのゲームを約5ヶ月前に作ったのです。あなたは正しい。そのコードの混乱。しかし、私はポートフォリオが欠陥と進歩を示すためにそれを含めるようにしています。もう一度、ありがとう:) – Ndx

+0

作業が面倒なコードは、壊れたコードよりも望ましいです。あなたは正しい道にいる。 – GantTheWanderer

1

あなたは時とmoveSnake機能の新しいsetTimeout通話を開始しないようにしようが、代わりに使用することができます。

function play() { 
    $('.newGame').css('visibility', 'hidden'); 
    $('.playgame').css('visibility', 'hidden'); 
    move = setInterval(moveSnake, 200); 
    getSnakeDir(); 

} 

、ここmoveSnake機能から

move = setTimeout(moveSnake, 200) 

を削除して、いくつかの問題がありました

function gameover() { 
    clearInterval(move); 
    $('.newGame').css('visibility', 'visible'); 
} 
+0

私はそれをやった、それが働きました。しかし、新しいゲームをクリックすると、ヘビは移動しません。 – Ndx

+0

@ Nordaxの場合、ボタンをクリックしてsetTimeout関数をもう一度実行すると、ゲームをリセットする必要があります – Ibu

+0

playGame()関数で何をしたのですか?なぜそれは働かない? – Ndx

関連する問題