Опытный
 
Профиль
Группа: Участник
Сообщений: 479
Регистрация: 31.12.2009
Репутация: нет Всего: 1
|
Ребята, помогите разобраться. Я решил написать канвасную (Canvas) змейку. Все шло довольно быстро, пока я не натолкнулся на следующую проблему. Змейка это объект. У змейки есть метод moveSnake, который и двигает ее. Двигает он ее следующим образом В этом же самом методе вшит таймер setTimeout, который этот метод вызывает (как бы рекурсивно). Пока мы играем первый раз - все замечательно. Но как только мы проиграли, хотим сделать перерисовку сцены, затираем Канвас, порождаем новую змейку, на экране их получается две! Наша старая змейка, в своих старых координатах, которая получает управление. И новая, которая видна на экране, но абсолютно мертва. Управление ведется клавишами со стрелками. | Код | var canvas; // Холст var context; // Контекст холста. var width = 20; // ширина сегмента var vector = {value:''}; //= 'right'; var ban = 'left'; var fruit; var free = true; //Свободен ли таймер. var mySnake; var message;
function elemBody(x, y) { this.x = x; this.y = y; }
function drawFruit(){ fruit.x = randomInteger(0, 39); fruit.y = randomInteger(0,39); paintSquare(fruit.x, fruit.y, '#800000'); }
function randomInteger(min, max) {// Функция случайного числа в звданном диапазоне. var rand = min + Math.random() * (max + 1 - min); rand = Math.floor(rand); return rand; }
function paintSquare (x, y, color) { //Функция отрисовки сегмента if (color != '') { context.fillStyle = color; context.fillRect(width * x + 1, width * y + 1, width - 2, width - 2); } else { context.clearRect(width * x + 1, width * y + 1, width - 2, width - 2); }
} // Конец функции.
function snake(length, tailColor, headColor) { //Cоздаем змейку. Конструктор. this.body = []; this.length = length; this.last = new elemBody(-1, -1); this.hit = 0; //Очки this.timer;
this.moveSnake = function(vector){ // Функция движения змейки Двигаем //alert(); if(vector.value == 'left' || vector.value == 'right' || vector.value == 'up' || vector.value == 'down') { this.last.x = this.body[this.body.length - 1].x; //Запоминаем последний элемент хвоста по х this.last.y = this.body[this.body.length - 1].y; //запоминаем последний элемент хвоста по у paintSquare(this.last.x, this.last.y, ''); //затираем хвост.
for (i = this.body.length-1; i >= 1; i--) { this.body[i].x = this.body[i - 1].x; this.body[i].y = this.body[i - 1].y; paintSquare(this.body[i].x, this.body[i].y, tailColor); } //Двигаем тело
switch (vector.value) { case 'right': this.body[0].x++; break; case 'left': this.body[0].x--; break; case 'up': this.body[0].y--; break; case 'down': this.body[0].y++; break; }
paintSquare(this.body[0].x, this.body[0].y, headColor);
if(this.body[0].x == fruit.x && this.body[0].y == fruit.y){ //Если ты столкнулся с фруктом. //alert(); this.body[this.body.length] = new elemBody(this.last.x, this.last.y); paintSquare(this.last.x, this.last.y, tailColor); drawFruit(); this.hit++; message.innerHTML = 'Счет: ' + this.hit; }
for(i=1; i < this.body.length-1; i++){ if(this.body[0].x == this.body[i].x && this.body[0].y == this.body[i].y){ message.innerHTML = 'GameOver'; //clearInterval(timer); alert('GameOver'); start(); break; } } } // var thiss = this;
// console.log(thiss); free = true; // thiss.moveSnake(vector); // console.log(vector);
// },100); // clearTimeout(timer); this.timer = setTimeout(() => this.moveSnake(vector), 100); }
var j = -1; for(i=this.length; i >=1; i--){ j++; this.body[i] = new elemBody(j, 0); paintSquare(this.body[i].x, this.body[i].y, tailColor); } j++; this.body[0] = new elemBody(j, 0); paintSquare(this.body[i].x, this.body[i].y, headColor); //создание змейки
}
window.onload = function () { //Событие загрузски страницы start(); // timer = setInterval(function(){ // clearTimeout(timer); mySnake.moveSnake(vector); free = true; // },100);
}
function loadScena() { //
canvas = document.getElementById("canvas"); context = canvas.getContext('2d'); context.clearRect(0, 0, canvas.width, canvas.height); for (y = 0; y < 800; y += width) { for (x = 0; x < 800; x += width) { context.strokeRect(x, y, width, width); } }
}
function start(){ //context.clearRect(0, 0, canvas.width, canvas.height); // alert(context); loadScena(); vector.value = ''; ban = 'left'; // delete(mySnake); mySnake = new snake(3, 'orange', 'red'); fruit = new elemBody(randomInteger(0,39), randomInteger(0,39)); paintSquare(fruit.x, fruit.y, '#800000'); message = document.getElementById('message'); message.innerHTML = 'Счет: ' + mySnake.hit; }
document.onkeydown = function (event) { //Обработчик событий клавиатуры
if(free == true) {
free = false;
switch (event.keyCode) { //Вправо case 39: if (ban != 'right') { ban = 'left'; vector.value = 'right'; // alert(); } break; case 40: // вниз if (ban != 'down') { ban = 'up'; vector.value = 'down'; } break; case 37://Влево if (ban != 'left') { ban = 'right'; vector.value = 'left'; } break; case 38: //Вверх if (ban != 'up') { ban = 'down'; vector.value = 'up'; } break; case 32: vector.value = ''; break;
}
}
}
|
Для тех кто захочет поиграть и увидеть проблему в действии, пожалуйста прилагаю полный набор. (html, css, js) Если вынести таймер из объекта во внешний мир (только он уже будет setInterval) Такой проблемы не возникает. Заранее спасибо тем, кто поможет разобраться! | Код | var canvas; // Холст var context; // Контекст холста. var width = 20; // ширина сегмента var vector; //= 'right'; var ban = 'left'; var timer; // Таймер var fruit; var free = true; //Свободен ли таймер. var mySnake; var message;
function elemBody(x, y) { this.x = x; this.y = y; }
function drawFruit(){ fruit.x = randomInteger(0, 39); fruit.y = randomInteger(0,39); paintSquare(fruit.x, fruit.y, '#800000'); }
function randomInteger(min, max) {// Функция случайного числа в звданном диапазоне. var rand = min + Math.random() * (max + 1 - min); rand = Math.floor(rand); return rand; }
function paintSquare (x, y, color) { //Функция отрисовки сегмента if (color != '') { context.fillStyle = color; context.fillRect(width * x + 1, width * y + 1, width - 2, width - 2); } else { context.clearRect(width * x + 1, width * y + 1, width - 2, width - 2); }
} // Конец функции.
function snake(length, tailColor, headColor) { //Cоздаем змейку. Конструктор. this.body = []; this.length = length; this.last = new elemBody(-1, -1); this.hit = 0; //Очки
this.moveSnake = function(vector){ //Двигаем //alert(); if(vector == 'left' || vector == 'right' || vector == 'up' || vector == 'down') { this.last.x = this.body[this.body.length - 1].x; //Запоминаем последний элемент хвоста по х this.last.y = this.body[this.body.length - 1].y; //запоминаем последний элемент хвоста по у paintSquare(this.last.x, this.last.y, ''); //затираем хвост.
for (i = this.body.length-1; i >= 1; i--) { this.body[i].x = this.body[i - 1].x; this.body[i].y = this.body[i - 1].y; paintSquare(this.body[i].x, this.body[i].y, tailColor); } //Двигаем тело
switch (vector) { case 'right': this.body[0].x++; break; case 'left': this.body[0].x--; break; case 'up': this.body[0].y--; break; case 'down': this.body[0].y++; break; }
paintSquare(this.body[0].x, this.body[0].y, headColor);
if(this.body[0].x == fruit.x && this.body[0].y == fruit.y){ //Если ты столкнулся с фруктом. //alert(); this.body[this.body.length] = new elemBody(this.last.x, this.last.y); paintSquare(this.last.x, this.last.y, tailColor); drawFruit(); this.hit++; message.innerHTML = 'Счет: ' + this.hit; }
for(i=1; i < this.body.length-1; i++){ if(this.body[0].x == this.body[i].x && this.body[0].y == this.body[i].y){ message.innerHTML = 'GameOver'; //clearInterval(timer); alert('GameOver'); start(); break; } } } // var thiss = this; //timer = setTimeout(function(){ // console.log(thiss); // thiss.moveSnake(vector); // console.log(vector);
//},100);
}
var j = -1; for(i=this.length; i >=1; i--){ j++; this.body[i] = new elemBody(j, 0); paintSquare(this.body[i].x, this.body[i].y, tailColor); } j++; this.body[0] = new elemBody(j, 0); paintSquare(this.body[i].x, this.body[i].y, headColor); //создание змейки
}
window.onload = function () { //Событие загрузски страницы start(); timer = setInterval(function(){ mySnake.moveSnake(vector); free = true; },100);
}
function loadScena() { //
canvas = document.getElementById("canvas"); context = canvas.getContext('2d'); context.clearRect(0, 0, canvas.width, canvas.height); for (y = 0; y < 800; y += width) { for (x = 0; x < 800; x += width) { context.strokeRect(x, y, width, width); } }
}
function start(){ //context.clearRect(0, 0, canvas.width, canvas.height); // alert(context); loadScena(); vector = ''; ban = 'left'; mySnake = new snake(3, 'green', 'red'); fruit = new elemBody(randomInteger(0,39), randomInteger(0,39)); paintSquare(fruit.x, fruit.y, '#800000'); message = document.getElementById('message'); message.innerHTML = 'Счет: ' + mySnake.hit; }
document.onkeydown = function (event) { //Обработчик событий клавиатуры
// if(free == true) {
// free = false;
switch (event.keyCode) { //Вправо case 39: if (ban != 'right') { ban = 'left'; vector = 'right'; // alert(); } break; case 40: // вниз if (ban != 'down') { ban = 'up'; vector = 'down'; } break; case 37://Влево if (ban != 'left') { ban = 'right'; vector = 'left'; } break; case 38: //Вверх if (ban != 'up') { ban = 'down'; vector = 'up'; } break; case 32: vector = ''; break;
}
// }
}
|
Присоединённый файл ( Кол-во скачиваний: 6 )
snakeproblems.rar 3,25 Kb
--------------------
"Арфы нет? Возьмите бубен!
Ребята, будем жить!"
(с) "В бой идут одни старики"
---
"ИЕ" - один из самых сумасшедших браузеров в нашей галактике.
|