A primeira coisa que um js jogo Cobra Nosso primeiro passo é usar abordagem orientada a objeto para o pensamento
Object-Oriented
Jogo de cobra todos sabemos, temos de olhar para objetos abstratos cobra.
Primeiro, cobra em si pode ser visto como um objeto único alimento aparecem aleatoriamente na tela, se é o maior aparece primitivos apenas uma comida ou uma versão mais alargada de alimentos aparece deve estar de acordo com certas regras. Assim, a comida aqui é também um objeto.
Primeiro, o item alimentar não está associada a outros objetos, primeiro determinar objetos alimentos js.
estabelecer food.js
/* 食物对象需要的属性,位置x,y,大小,颜色 */
function Food(options){
options=options||{};
this.x=options.x||0;
this.y=options.y||0;
this.width=options.width||20;
this.height=options.height||20;
this.color=options.color||'green';
}
var position="absolute";
/* Food的原型对象
render方法
动态创建div */
Food.prototype.render =function(map){
/* 创建div */
var div = document.createElement('div');
map.appendChild(div);
/* 设置div的样式 */
div.style.position=position;
div.style.left=this.x+'px';
div.style.top=this.y+'px';
div.style.width=this.width+'px';
div.style.height=this.height+'px';
div.style.backgroundColor=this.color;
}
/* test */
var map=document.getElementById('map');
var food=new Food();
food.render(map);
Sobre perfeito index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div id="map"></div>
<script src="js/food.js"></script>
</body>
</html>
Aqui notamos que, após a introdução de food.js a div indicado de outra forma, podem ocorrer ou limitada à seguinte pergunta.
报错: Uncaught TypeError: propriedade não pode ler 'appendChild' de indefinido
A razão para este problema não é encontrar as mapa div id módulo js antes do carregamento. Então, para lembrar de todos os js carregados na declaração volta div.
Estabelecer um css
#map {
width: 800px;
height: 600px;
background-color: red;
position: relative;/* 相对 */
}
ok, isso foi mostrado para ser vermelho com verde no navegador do Google, se nenhum problema
é tão quente o olho. alimentos ainda não foi completamente resolvido, como fazer comida aparecem aleatoriamente?
Random conjunto localização alimentos
Gerar um número aleatório para o valor máximo entre o mínimo
var Tools = {
getRandom: function (min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
}
ok apenas a nossa posição X e Y é o padrão, para definir sobre x e y no div, mas para o (aleatório).
Considere o problema de limite de números aleatórios : Somos essencialmente coordenadas aleatórias, 0:00 coordenadas aleatórias podem ser colocados alimentos em um mapa, isso é mais fácil para pensar. Max, na fronteira do mesmo, antes de tudo tem a sua própria largura mapa e altura do primeiro para vir até nós para obter a largura x (altura e y empatia) define alimentos em food.js 20px largura
na largura 800px mapa definido no css por quanto pode o primeiro é o mapa bloco discernir alimentos colocados horizontalmente visto, pode colocar 40
, mas pode ser igual a max 40 é? A resposta é não, porque igual a 40, porque estamos buscando as coordenadas, para expandir a comida, na verdade, não pertence ao âmbito do mapa.
Portanto max = 40-1 = 39
Assim, temos uma nova representação das coordenadas X e Y:
this.x=Tools.getRandom(0,map.offsetWidth/this.width-1)*this.width;
this.y=Tools.getRandom(0,map.offsetHeight/this.height-1)*this.height;
Tem sido aleatoriamente mostra, há uma importante regras do jogo: comer a comida.
Então, depois de comer para aleatoriamente exibição, antes do passo a passo exclusão de comida lá
alimentos de exclusão
var elements=[];//存储食物的元素
método aleatório geração:
var div = document.createElement('div');
map.appendChild(div);
/* 记录到数组中 */
elements.push(div);
function remove(){
for(var i=elements.length-1;i>=0;i--){
/* 删除div 调用父元素的removeChild方法删除*/
elements[i].parentsNode.removeChild(elements[i]);
/* 删除数组中的数据
第一个参数从哪个元素开始删除
第二个参数删除几个*/
elements.splice(i,1);
}
}
Desde que a função de chamada melhorada
Em primeiro lugar, uma vez que o objetivo é chamar a função para criar um escopo local, fazer chamadas de follow-up, etc. o mesmo nome não aparece
(function(){
})()
Antes de escrever o código para a função pode ser
notado aqui que um pequeno problema
método alimentar em função do âmbito local, chamadas de modo menos externos
/* window下的函数全局可访问,创建自调用函数之后,局部作用域使得外部的测试代码无法调用food方法 */
window.Food=Food;
Object-Oriented objeto em alimentos está quase completa
Construção dos objectos de cobra
Render ideias e objectos cobra alimentares Objectos Do mesmo modo, a orientação do objecto a ser fixado cobra e o corpo, o corpo com a matriz de armazenamento padrão, cada elemento representa o corpo de uma cobra uma secção de cobra.
(function(){
var position ='absolute';
function Snake(options){
options=options||{};
/* 蛇节大小和行进方向 */
this.width =options.width||20;
this.height=options.height||20;
this.derection=options.derection||'right';
/* 蛇身体 */
this.body=[
{x:3,y:2,color:'red'},
{x:2,y:2,color:'blue'},
{x:1,y:2,color:'blue'}
];
}
Snake.prototype.render=function(){
for(var i=0,len =this.body.length;i<len;i++){
var object =this.body[i];
var div=document.createElement('div');
map.appendChild(div);
/* 设置postion的目的是脱离文档流 在上面新建一个var postion*/
div.style.position=position;
/* 设置大小 */
div.style.width=this.width+'px';
div.style.height=this.height+'px';
/* 设置坐标,颜色 */
div.style.left=object.x*this.width+'px';
div.style.top=object.y*this.height+'px';
div.style.backgroundColor=object.color;
}
}
window.Snake=Snake;
})()
js Iniciar
Antes dos testes foram adicionados depois de um período de js códigos de teste, para iniciar um JS vez disso, criar um código de teste separado
(function(){
function Game(map){
/* 依赖于food和snake */
this.food=new Food();
this.snake=new Snake();
this.map=map;
}
Game.prototype.start=function(){
/* 把蛇和食物对象渲染到地图
开始游戏的逻辑 */
this.food.render(this.map);
this.snake.render(this.map);
}
window.Game=Game;
})();
var map=document.getElementById('map');
var game =new Game(map);
game.start();
papel Game.js é substituir o código de teste anterior, por isso, antes de tudo isso depende de alimentos e cobras os dois primeiros js, pode então ser processado de acordo com o seu método render. Como antes, o efeito de, e não os desenhos.
Movimento cobra controle
Snake.prototype.move =function(){
/* 控制蛇的身体移动 */
/* 蛇节 */
for(var i=this.body.length-1;i>0;i--){
this.body[i].x=this.body[i-1].x;
this.body[i].y=this.body[i-1].y;
}
/* 蛇头 */
var head =this.body[0];
switch(this.direction){
case'right':
head.x+=1;
break;
case'left':
head.x-=1;
break;
case'top':
head.y-=1;
break;
case'bottom':
head.y+=1;
break;
}
}
Cobra durante o movimento, precisa remover a seção de cobra antes de cobra em movimento.
Da mesma forma alimentos:
/* 私有成员函数 删除参照food*/
function remove(){
/* 从后往前删除 */
for(var i=elements.length-1;i>=0;i--){
/* 删除div */
elements[i].parentNode.removeChild(elements[i]);
elements.splice(i,1);
}
}
Deixe a cobra continua a se mover
// 私有的函数 让蛇移动
function runSnake() {
var timerId = setInterval(function () {
// 让蛇走一格
// 在定时器的function中this是指向window对象的
// this.snake
// 要获取游戏对象中的蛇属性
that.snake.move();
that.snake.render(that.map);
// 2.2 当蛇遇到边界游戏结束
// 获取蛇头的坐标
var maxX = that.map.offsetWidth / that.snake.width;
var maxY = that.map.offsetHeight / that.snake.height;
var headX = that.snake.body[0].x;
var headY = that.snake.body[0].y;
if (headX < 0 || headX >= maxX) {
alert('Game Over');
clearInterval(timerId);
}
if (headY < 0 || headY >= maxY) {
alert('Game Over');
clearInterval(timerId);
}
}, 150);
}
Aqui usado que, no var that; that = this;// 记录游戏对象
já definido anteriormente, para a obtenção deste.
Ao controlar a direção do movimento da cobra Teclado
// 通过键盘控制蛇移动的方向
function bindKey() {
// document.onkeydown = function () {};
document.addEventListener('keydown', function (e) {
// console.log(e.keyCode);
// 37 - left
// 38 - top
// 39 - right
// 40 - bottom
switch (e.keyCode) {
case 37:
that.snake.direction = 'left';
break;
case 38:
that.snake.direction = 'top';
break;
case 39:
that.snake.direction = 'right';
break;
case 40:
that.snake.direction = 'bottom';
break;
}
}, false);
}
coma alimentos
/* 判断蛇头是否和食物坐标重合 需要food 和map 在move方法中添加两个参数,同时game也需要添加两个参数*/
var headX=head.x*this.width;
var headY=head.y*this.height;
if(headX === food.x &&headY === food.y){
var last =this.body[this.body.length - 1];
this.body.push({
x:last.x,
y:last.y,
color:last.color
})
github Portal: https://github.com/qdjiangwenhao/snake