2013-10-24 4 views
0

У меня есть следующая проблема: я пытаюсь сделать простую игру в JavaScript. Идея игры состоит в том, чтобы иметь холст, шар, подпрыгивающий внутри, и маленькую площадку, идущую слева направо, чтобы попасть в мяч. Я сделал это так, и она отлично работает:JavaScript-игра не работает, зависает после инициализации

var canvasBg; 
var contextBg; 

var canvasBall; 
var contextBall; 


function Drawable() { 

    this.initialize = function(x,y) { 
     this.x = x; 
     this.y = y; 
    }; 

    this.draw = function() { 

    }; 
} 

function Ball() { 

    var dx = 2; 
    var dy = 2; 

    var radius = 5; 

    this.draw = function() { 

     contextBall.beginPath(); 
     contextBall.clearRect(0,0,canvasBall.width,canvasBall.height); 
     contextBall.closePath(); 

     contextBall.beginPath(); 
     contextBall.fillStyle = "#0000ff"; 
     contextBall.arc(this.x, this.y, radius, 0, Math.PI*2, true); 
     contextBall.closePath(); 
     contextBall.fill(); 

     // the code seems to stop here 
     if(this.x<0 || this.x>300) 
      dx = -dx; 
     if(this.y<0 || this.y>150) 
      dy = -dy; 

     if((this.x+radius)>pad.x && (this.x-radius)<(pad.x+50) && (this.y+radius)>pad.y && (this.y-radius)<(pad.y+10)) { 
      dy = -dy; 
     } 

     if(this.y>(pad.y-2) && this.y<(pad.y+12) && (this.x+radius)>pad.x && (this.x-radius)<(pad.x+50)) { 
      dx = -dx; 
     } 

     this.x += dx; 
     this.y += dy; 
    }; 

} 

Ball.prototype = new Drawable(); 

KEY_CODES = { 

    37: 'left', 
    39: 'right', 
}; 

KEY_STATUS = {}; 

for (code in KEY_CODES) { 

    KEY_STATUS[ KEY_CODES[ code ]] = false; 
} 

document.onkeydown = function(e) { 
    var keyCode = (e.keyCode) ? e.keyCode : e.charCode; 
    if (KEY_CODES[keyCode]) { 
     e.preventDefault(); 
     KEY_STATUS[KEY_CODES[keyCode]] = true; 
    } 
}; 

document.onkeyup = function(e) { 
    var keyCode = (e.keyCode) ? e.keyCode : e.charCode; 
     if (KEY_CODES[keyCode]) { 
     e.preventDefault(); 
     KEY_STATUS[KEY_CODES[keyCode]] = false; 
    } 
}; 

function Pad() { 

    var hSpeed = 5; 
    this.padWidth = 50; 
    this.padHeight = 10; 

    this.draw = function() { 

     contextBg.clearRect(0,0,canvasBg.width,canvasBg.height); 
     contextBg.fillStyle = "#ffffff"; 
     contextBg.fillRect(this.x,this.y,this.padWidth,this.padHeight); 

    }; 

    this.move = function() { 
     if(KEY_STATUS.left || KEY_STATUS.right) { 
      contextBg.clearRect(0,0,canvasBg.width,canvasBg.height); 

      if(KEY_STATUS.left) { 
       this.x -= hSpeed; 
      if (this.x <= 0) 
       this.x = 0; 
      } else if (KEY_STATUS.right) { 
       this.x += hSpeed; 
      if (this.x >= 300-this.padWidth) 
       this.x = 300 - this.padWidth; 
      } 
      this.draw(); 
     } 
    }; 
} 

Pad.prototype = new Drawable(); 


function init() { 

     canvasBg = document.getElementById('display'); 
     contextBg = this.canvasBg.getContext('2d'); 

     canvasBall = document.getElementById('ball'); 
     contextBall = this.canvasBall.getContext('2d'); 

     ball = new Ball(); 
     ball.initialize(10,10); 

     pad = new Pad(); 
     pad.initialize(120,80); 

     setInterval(function(){animate();},30); 

} 

function animate() { 
     ball.draw(); 
     pad.draw(); 
     pad.move(); 
}; 

Однако, я решил попытаться улучшить мой код немного, и я сделал класс Геймплей:

var game = new GamePlay(); 

function Drawable() { 

    this.initialize = function(x,y) { 
     this.x = x; 
     this.y = y; 
    }; 

    this.draw = function() { 

    }; 
} 

function Ball() { 

    var dx = 2; 
    var dy = 2; 

    var radius = 5; 

    this.draw = function() { 

     this.context.beginPath(); 
     this.context.clearRect(0,0,this.canvas.width,this.canvas.height); 
     this.context.closePath(); 

     this.context.beginPath(); 
     this.context.fillStyle = "#0000ff"; 
     this.context.arc(this.x, this.y, radius, 0, Math.PI*2, true); 
     this.context.closePath(); 
     this.context.fill(); 



     if(this.x<0 || this.x>300) 
      dx = -dx; 
     if(this.y<0 || this.y>150) 
      dy = -dy; 

     if((this.x+radius)>pad.x && (this.x-radius)<(pad.x+50) && (this.y+radius)>pad.y && (this.y-radius)<(pad.y+10)) { 
      dy = -dy; 
     } 

     if(this.y>(pad.y-2) && this.y<(pad.y+12) && (this.x+radius)>pad.x && (this.x-radius)<(pad.x+50)) { 
      dx = -dx; 
     } 


     this.x += dx; 
     this.y += dy; 
    }; 

} 

Ball.prototype = new Drawable(); 

KEY_CODES = { 

    37: 'left', 
    39: 'right', 
}; 

KEY_STATUS = {}; 

for (code in KEY_CODES) { 

    KEY_STATUS[ KEY_CODES[ code ]] = false; 
} 

document.onkeydown = function(e) { 
    var keyCode = (e.keyCode) ? e.keyCode : e.charCode; 
    if (KEY_CODES[keyCode]) { 
     e.preventDefault(); 
     KEY_STATUS[KEY_CODES[keyCode]] = true; 
    } 
}; 

document.onkeyup = function(e) { 
    var keyCode = (e.keyCode) ? e.keyCode : e.charCode; 
     if (KEY_CODES[keyCode]) { 
     e.preventDefault(); 
     KEY_STATUS[KEY_CODES[keyCode]] = false; 
    } 
}; 

function Pad() { 

    var hSpeed = 5; 
    this.padWidth = 50; 
    this.padHeight = 10; 

    this.draw = function() { 

     this.context.clearRect(0,0,this.canvas.width,this.canvas.height); 
     this.context.fillStyle = "#ffffff"; 
     this.context.fillRect(this.x,this.y,this.padWidth,this.padHeight); 

    }; 

    this.move = function() { 
     if(KEY_STATUS.left || KEY_STATUS.right) { 
      this.context.clearRect(0,0,this.canvas.width,this.canvas.height); 

      if(KEY_STATUS.left) { 
       this.x -= hSpeed; 
      if (this.x <= 0) 
       this.x = 0; 
      } else if (KEY_STATUS.right) { 
       this.x += hSpeed; 
      if (this.x >= 300-this.padWidth) 
       this.x = 300 - this.padWidth; 
      } 
      this.draw(); 
     } 
    }; 
} 

Pad.prototype = new Drawable(); 

function GamePlay() { 

    var ball; 
    var pad; 

    this.setUpGame = function() { 

     this.canvasBg = document.getElementById('display'); 
     this.contextBg = this.canvasBg.getContext('2d'); 

     this.canvasBall = document.getElementById('ball'); 
     this.contextBall = this.canvasBall.getContext('2d'); 

     Ball.prototype.canvas = this.canvasBall; 
     Ball.prototype.context = this.contextBall; 

     Pad.prototype.canvas = this.canvasBg; 
     Pad.prototype.context = this.contextBg; 

     ball = new Ball(); 
     ball.initialize(10,10); 

     pad = new Pad(); 
     pad.initialize(120,80); 

    }; 


    var animate = function() { 
     ball.draw(); 
     pad.draw(); 
     pad.move(); 
    }; 

    this.startGame = function() { 
     setInterval(function(){animate();},30); 
    }; 

} 

function init() { 
    game.setUpGame(); 
    game.startGame(); 
} 

НО, это только рисует шар по его инициализирующим координатам, а затем, кажется, останавливается там. Я попытался выполнить ручное тестирование, поставив alert() на определенные пункты кода, и я обнаружил, что он, кажется, останавливается в середине метода рисования шара и пропускает вызов pad.draw() и pad.move() в анимации (). Я не знаю, что случилось, я предполагаю, что это что-то с прототипами. Я новичок в JavaScript, и этот прототип OOP все еще немного запутан. Благодарю.

+0

Вы получаете какую-либо ошибку в консоли? – SLaks

+0

Я использую Aptana Studio, и консоль остается чистой. Но я не получаю желаемые результаты на моей странице html. – somi

ответ

1

Я пробовал код и обнаружил следующие проблемы:

  1. функция init - надеюсь, она вызывается после HTML полностью загружен
  2. Ball.draw функция относится объект pad, который не определен в контексте, использование game.pad
  3. var animate = function создает локальный "частный" переменную, изменить его this.animate = function
  4. в setInterval вызова собственно функции setInterval(function(){game.animate();},30);
  5. var game = new GamePlay(); вызывается перед GamePlay определяются, переместить эту строку ниже

после этих изменений он работает без ошибок в консоли

+0

Спасибо за ваш ответ. Я сделал эти исправления, но я все равно получаю тот же результат в html. Я использую между заголовками и . Это правильный способ загрузить скрипт. – somi

+0

@somi, тогда я действительно предлагаю вам использовать инструменты разработчика и код отладки, а также проверить 5-й элемент, который я добавил –

+0

. Я попробую. Спасибо – somi

0

Я считаю, что это из-за вашего промаха использования путей в вашем методе рисования.

Во-первых, вам не нужно обертывать .clearRect с .beginPath и .closePath.

Во-вторых, и что может привести к ошибке вашего сценария в том, что вы используете .fill после .closePath, когда вы рисуете круг. .fill следует использовать до .closePath и фактически после использования .fill вам не нужно использовать .closePath, поскольку он уже закроет ваш путь для вас.

+0

Спасибо за ваш ответ. Я сделал исправления, которые вы предложили, но я все равно получаю те же результаты. – somi

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