Опытный
Профиль
Группа: Участник
Сообщений: 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
--------------------
"Арфы нет? Возьмите бубен!
Ребята, будем жить!"
(с) "В бой идут одни старики"
---
"ИЕ" - один из самых сумасшедших браузеров в нашей галактике.
|