2013-10-27 2 views
2

Я действительно новичок в Javascript, поэтому решил создать простую SnakeGame для встраивания в HTML. Тем не менее, мой код для изменения направления змеи замерзает после нескольких поворотов.Snake Game в Javascript

Примечание: Я использую это в HTML-холсте.

Источник:

var Canvas; 
var ctx; 

var fps = 60; 

var x = 0; 
var seconds = 0; 

var lastLoop; 
var thisLoop; 
var tempFPS = 0; 
var blockList = []; 
var DEFAULT_DIRECTION = "Right"; 

var pendingDirections = []; 

function update() { 
    x += 1; 

    thisLoop = new Date(); 
    tempFPS = 1000/(thisLoop - lastLoop); 
    lastLoop = thisLoop; 
    tempFPS = Math.round(tempFPS*10)/10; 

    if (x==10){ 
     document.getElementById("FPS").innerHTML = ("FPS: " + tempFPS); 
    } 

    //Rendering 
    for (var i = 0; i<blockList.length; i++){ 
     var block = blockList[i]; 
     draw(block.x, block.y); 
    } 

    if (x==5){ 
     x=0; 
     seconds+=1; 

     //Updates once per x frames 
     moveBlocks(); 
    } 
} 

function moveBlocks(){ 
    if(blockList.length === 0){ 
     return; 
    } 


    for (var j = 0; j<pendingDirections.length; j++){ 
     if (b >= blockList.length -1){ 
      pendingDirections.shift(); 

     }else { 
      //Iterates through each direction that is pending 
      var b = pendingDirections[j].block; 
      try{ 
       blockList[b].direction = pendingDirections[j].direction; 
      } catch(err){ 
       alert(err); 
      } 
      pendingDirections[j].block++; 
     } 
    } 

    for (var i = 0; i<blockList.length; i++){ 
     var block = blockList[i]; 
     clear(block.x, block.y); 
     if (block.direction == "Down"){ 
      block.y += BLOCK_SIZE; 
     } else if (block.direction == "Up"){ 
      block.y -= BLOCK_SIZE; 
     } else if (block.direction == "Left"){ 
      block.x -= BLOCK_SIZE; 
     } else if (block.direction == "Right"){ 
      block.x += BLOCK_SIZE; 
     } else { 
      alert(block.direction); 
     } 
     draw(block.x, block.y); 
    } 
} 

function init(){ 
    lastLoop = new Date(); 
    window.setInterval(update, 1000/fps); 
    Canvas = document.getElementById("Canvas"); 
    ctx = Canvas.getContext("2d"); 
} 

//The width/height of each block 
var BLOCK_SIZE = 30; 

//Draws a block 
function draw(x, y) { 

    ctx.fillStyle = "#000000"; 
    ctx.fillRect(x,y,BLOCK_SIZE,BLOCK_SIZE); 
} 

function clear(x,y){ 
    ctx.fillStyle = "#FFFFFF"; 
    ctx.fillRect(x,y,BLOCK_SIZE,BLOCK_SIZE); 
} 

function processInput(key){ 
    if (key == 110){ 
     //n (new) 
     newBlock(BLOCK_SIZE*4,0); 
     newBlock(BLOCK_SIZE*3,0); 
     newBlock(BLOCK_SIZE*2,0); 
     newBlock(BLOCK_SIZE*1,0); 
     newBlock(0,0); 

    } else if (key == 119){ 
     changeDirection("Up"); 
    } else if (key == 115){ 
     changeDirection("Down"); 
    } else if (key == 97){ 
     changeDirection("Left"); 
    } else if (key == 100){ 
     changeDirection("Right"); 
    } else if (key==122){ 
     var pDir = "Pending Directions: "; 
     for (var i = 0; i<pendingDirections.length; i++){ 
      pDir += pendingDirections[i].direction + ", "; 
     } 
     alert(pDir); 
    } else if (key == 120){ 
     var dir = "Directions: "; 
     for (var j = 0; j<blockList.length; j++){ 
      dir += blockList[j].direction + ", "; 
     } 
     alert(dir); 
    } else { 
     alert("KEY: " +key); 
    } 
} 

function changeDirection(d){ 
    var LD = blockList[0].direction; 
    var valid = false; 

    if (d == "Up"){ 
     if(LD != "Down"){ 
      valid = true; 
     } 
    } else if (d == "Down"){ 
     if(LD != "Up"){ 
      valid = true; 
     } 
    } else if (d == "Left"){ 
     if(LD != "Right"){ 
      valid = true; 
     } 
    } else if (d == "Right"){ 
     if(LD != "Left"){ 
      valid = true; 
     } 
    } 

    if (d == LD) { valid = false;} 

    if (valid){  
     var dir = {'direction' : d, 'block' : 0}; 
     pendingDirections.unshift(dir); 
    } 
} 
function newBlock(x, y){ 
    var block = {'x': x, 'y' : y, 'direction' : DEFAULT_DIRECTION}; 
    //This works: alert(block['x']); 
    draw(x,y); 
    blockList.push(block); 
} 

Благодаря

+0

Не могли бы вы переместить свой код в jsFiddle или JS Bin и предоставить ссылку? – Evan

+0

Здесь вы найдете: http://jsbin.com/iqAxonO/4/edit – michael99man

+0

Эта ссылка показывает только пустой холст для меня на последнем стабильном Chrome. – Evan

ответ

2

Как сказал Эван, главный вопрос заключается в том, как вы обращаетесь в ожидании направления.

Проблема возникает, когда вы поворачиваете дважды подряд, что приводит к добавлению двух отложенных направлений для одного и того же блока. Если они не обрабатываются в правильном порядке, тогда блоки могут перемещаться в неправильном направлении. При каждом обновлении требуется только одно отложенное направление для каждого блока, поэтому я переработал так, как это обрабатывается, чтобы избежать нескольких направлений на одном блоке во время одного обновления.

Вот ссылка на него: http://jsbin.com/EkOSOre/5/edit

Обратите внимание, когда изменение в направлении сделан, в ожидании направления на первом блоке обновляется, перезаписать существующие направления в ожидании.

if (valid) { 
    blockList[0].pendingDirection = direction; 
} 

Затем, когда происходит обновление, список блоков петельный через, а отложенное направление следующего блока устанавливается равным текущее направление текущего блока.

if(!!nextBlock) { 
    nextBlock.pendingDirection = block.direction; 
} 

Если текущий блок имеет отложенное направление, задайте направление в направлении ожидания.

if(block.pendingDirection !== null) { 
    block.direction = block.pendingDirection; 
} 

Затем обновите расположение блоков, как обычно.

У вас также были другие проблемы, такие как использование переменной (b) до ее инициализации и то, как вы поймали ошибку null/undefined (вы должны просто проверить эту ситуацию и обработать ее соответствующим образом), но это была основная проблема с вашим алгоритмом.

Вы также захотите удалить старые блоки, когда пользователь нажимает «n», потому что старый остается, увеличивая скорость и количество существующих блоков.

Удачи вам в остальной части игры и удачном изучении JavaScript.

+0

Большое спасибо! Работает отлично. – michael99man

Смежные вопросы