13.10.2020, 09:05
|
Аспирант
|
|
Регистрация: 06.09.2020
Сообщений: 57
|
|
Скорость змейки
Всем привет, нужно увеличивать скорость змейки при поедании еды и замедлять, когда она натыкается на препятствия. Как реализовать, можете дописать код? Буду благодарна,никак не пойму, как реализовать.
const canvas = document.getElementById("game");
const ctx = canvas.getContext("2d");
const ground = new Image();
ground.src = "img/ground.png";
const foodImg = new Image();
foodImg.src = "img/food.png";
const barImg = new Image();
barImg.src = "img/bar.png";
const tireImg = new Image();
tireImg.src = "img/tire.png";
const pizzaImg = new Image();
pizzaImg.src = "img/pizza.png";
let box = 32;
let score = 0;
var food = {
x: Math.floor((Math.random() * 17 + 1)) * box,
y: Math.floor((Math.random() * 15 + 3)) * box,
};
var snake = [];
snake[0] = {
x: 9 * box,
y: 10 * box
};
var bar = {
x: Math.floor((Math.random() * 17 + 1)) * box,
y: Math.floor((Math.random() * 15 + 3)) * box,
};
var tire = {
x: Math.floor((Math.random() * 17 + 1)) * box,
y: Math.floor((Math.random() * 15 + 3)) * box,
};
var pizza = {
x: Math.floor((Math.random() * 17 + 1)) * box,
y: Math.floor((Math.random() * 15 + 3)) * box,
};
document.addEventListener("keydown", direction);
let dir;
function direction(event) {
if(event.keyCode == 37 && dir != "right")
dir = "left";
else if(event.keyCode == 38 && dir != "down")
dir = "up";
else if(event.keyCode == 39 && dir != "left")
dir = "right";
else if(event.keyCode == 40 && dir != "up")
dir = "down";
}
function eatTail(head, arr) {
for(let i = 0; i < arr.length; i++) {
if(head.x == arr[i].x && head.y == arr[i].y)
clearInterval(game); // очищаем интервал
}
}
function drawGame() {
ctx.drawImage(ground, 0, 0);
ctx.drawImage(foodImg, food.x, food.y);
ctx.drawImage(barImg, bar.x, bar.y);
ctx.drawImage(tireImg, tire.x, tire.y);
ctx.drawImage(pizzaImg, pizza.x, pizza.y);
if (bar.x == food.x && bar.y == food.y) {
food = {
x: Math.floor((Math.random() * 17 + 1)) * box,
y: Math.floor((Math.random() * 15 + 3)) * box,
};
bar = {
x: Math.floor((Math.random() * 17 + 1)) * box,
y: Math.floor((Math.random() * 15 + 3)) * box,
};
}
for(let i = 0; i < snake.length; i++) {
ctx.fillStyle = i == 0 ? "green" : "red";
ctx.fillRect(snake[i].x, snake[i].y, box, box);
}
if (food.x == bar.x && food.y == bar.y || food.x == tire.x && food.y == tire.y || bar.x == tire.x && bar.y == tire.y) {
food = {
x: Math.floor((Math.random() * 17 + 1)) * box,
y: Math.floor((Math.random() * 15 + 3)) * box,
};
bar = {
x: Math.floor((Math.random() * 17 + 1)) * box,
y: Math.floor((Math.random() * 15 + 3)) * box,
};
tire = {
x: Math.floor((Math.random() * 17 + 1)) * box,
y: Math.floor((Math.random() * 15 + 3)) * box,
};
}
if (pizza.x == food.x && pizza.y == food.y || pizza.x == bar.x && pizza.y == bar.y || pizza.x == tire.x && pizza.y == tire.y) {
food = {
x: Math.floor((Math.random() * 17 + 1)) * box,
y: Math.floor((Math.random() * 15 + 3)) * box,
};
bar = {
x: Math.floor((Math.random() * 17 + 1)) * box,
y: Math.floor((Math.random() * 15 + 3)) * box,
};
tire = {
x: Math.floor((Math.random() * 17 + 1)) * box,
y: Math.floor((Math.random() * 15 + 3)) * box,
};
pizza = {
x: Math.floor((Math.random() * 17 + 1)) * box,
y: Math.floor((Math.random() * 15 + 3)) * box,
};
}
ctx.fillStyle = "white";
ctx.font = "50px Arial";
ctx.fillText(score, box * 2.5, box * 1.7);
let snakeX = snake[0].x;
let snakeY = snake[0].y;
if(snakeX == food.x && snakeY == food.y) {
score++;
food = {
x: Math.floor((Math.random() * 17 + 1)) * box, // по x
y: Math.floor((Math.random() * 15 + 3)) * box, // по y
};
} else if(snakeX == pizza.x && snakeY == pizza.y) {
score += 2;
pizza = {
x: Math.floor((Math.random() * 17 + 1)) * box, // по x
y: Math.floor((Math.random() * 15 + 3)) * box, // по y
};
} else {
snake.pop();
}
if(snakeX == bar.x && snakeY == bar.y) {
score -= 3;
snake.pop();
bar = { // ставим еду в новом месте
x: Math.floor((Math.random() * 17 + 1)) * box, // по x
y: Math.floor((Math.random() * 15 + 3)) * box, // по y
};
}
if(snakeX == tire.x && snakeY == tire.y) {
score--;
snake.pop();
tire = {
x: Math.floor((Math.random() * 17 + 1)) * box, // по x
y: Math.floor((Math.random() * 15 + 3)) * box, // по y
};
}
if (score >= 50) {
clearInterval(game);
alert('Вы выиграли!');
document.location.reload();
}
if(score <= -1) {
clearInterval(game);
alert('Вы проиграли!');
document.location.reload();
}
if(snakeX < box || snakeX > box * 17
|| snakeY < 3 * box || snakeY > box * 17) {
clearInterval(game);
alert('Вы проиграли!');
document.location.reload();
}
if(dir == "left") snakeX -= box;
if(dir == "right") snakeX += box;
if(dir == "up") snakeY -= box;
if(dir == "down") snakeY += box;
let newHead = {
x: snakeX,
y: snakeY
};
eatTail(newHead, snake);
snake.unshift(newHead);
}
let game = setInterval(drawGame, 100);
|
|
13.10.2020, 10:48
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,743
|
|
Использовать setTimeout вместо setInterval.
Если съела еду уменьшить время задаваемое в setTimeout, если наткнулась - увеличить.
|
|
13.10.2020, 12:48
|
|
Профессор
|
|
Регистрация: 07.03.2011
Сообщений: 1,138
|
|
|
|
14.10.2020, 09:49
|
Аспирант
|
|
Регистрация: 06.09.2020
Сообщений: 57
|
|
voraa,
MallSerg,
исправила, но теперь не двигается ничего, а если через интервалы, то получается, но не выполняется условие
let game = setTimeout(drawGame, 150); // Вызов функции из вне,
// каждые 100 миллисекунд вызывается
if (snakeX == food.x && snakeY == food.y) {
game = setTimeout(drawGame, 50);
} else if (snakeX == pizza.x && snakeY == pizza.y) {
game = setTimeout(drawGame, 50);
}
if (snakeX == bar.x && snakeY == bar.y) {
game = setTimeout(drawGame, 300);
} else if (snakeX == tire.x && snakeY == tire.y) {
game = setTimeout(drawGame, 300);
}
|
|
14.10.2020, 10:20
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,743
|
|
Нет, не так
const canvas = document.getElementById("game");
const ctx = canvas.getContext("2d");
const ground = new Image();
ground.src = "img/ground.png";
const foodImg = new Image();
foodImg.src = "img/food.png";
const barImg = new Image();
barImg.src = "img/bar.png";
const tireImg = new Image();
tireImg.src = "img/tire.png";
const pizzaImg = new Image();
pizzaImg.src = "img/pizza.png";
let box = 32;
let score = 0;
let timed = 100 // Интервал между вызовами
var food = {
x: Math.floor((Math.random() * 17 + 1)) * box,
y: Math.floor((Math.random() * 15 + 3)) * box,
};
var snake = [];
snake[0] = {
x: 9 * box,
y: 10 * box
};
var bar = {
x: Math.floor((Math.random() * 17 + 1)) * box,
y: Math.floor((Math.random() * 15 + 3)) * box,
};
var tire = {
x: Math.floor((Math.random() * 17 + 1)) * box,
y: Math.floor((Math.random() * 15 + 3)) * box,
};
var pizza = {
x: Math.floor((Math.random() * 17 + 1)) * box,
y: Math.floor((Math.random() * 15 + 3)) * box,
};
document.addEventListener("keydown", direction);
let dir;
function direction(event) {
if(event.keyCode == 37 && dir != "right")
dir = "left";
else if(event.keyCode == 38 && dir != "down")
dir = "up";
else if(event.keyCode == 39 && dir != "left")
dir = "right";
else if(event.keyCode == 40 && dir != "up")
dir = "down";
}
function eatTail(head, arr) {
for(let i = 0; i < arr.length; i++) {
if(head.x == arr[i].x && head.y == arr[i].y)
// clearInterval(game); // очищаем интервал
return true;
}
reurn false;
}
function drawGame() {
ctx.drawImage(ground, 0, 0);
ctx.drawImage(foodImg, food.x, food.y);
ctx.drawImage(barImg, bar.x, bar.y);
ctx.drawImage(tireImg, tire.x, tire.y);
ctx.drawImage(pizzaImg, pizza.x, pizza.y);
if (bar.x == food.x && bar.y == food.y) {
food = {
x: Math.floor((Math.random() * 17 + 1)) * box,
y: Math.floor((Math.random() * 15 + 3)) * box,
};
bar = {
x: Math.floor((Math.random() * 17 + 1)) * box,
y: Math.floor((Math.random() * 15 + 3)) * box,
};
}
for(let i = 0; i < snake.length; i++) {
ctx.fillStyle = i == 0 ? "green" : "red";
ctx.fillRect(snake[i].x, snake[i].y, box, box);
}
if (food.x == bar.x && food.y == bar.y || food.x == tire.x && food.y == tire.y || bar.x == tire.x && bar.y == tire.y) {
food = {
x: Math.floor((Math.random() * 17 + 1)) * box,
y: Math.floor((Math.random() * 15 + 3)) * box,
};
bar = {
x: Math.floor((Math.random() * 17 + 1)) * box,
y: Math.floor((Math.random() * 15 + 3)) * box,
};
tire = {
x: Math.floor((Math.random() * 17 + 1)) * box,
y: Math.floor((Math.random() * 15 + 3)) * box,
};
}
if (pizza.x == food.x && pizza.y == food.y || pizza.x == bar.x && pizza.y == bar.y || pizza.x == tire.x && pizza.y == tire.y) {
food = {
x: Math.floor((Math.random() * 17 + 1)) * box,
y: Math.floor((Math.random() * 15 + 3)) * box,
};
bar = {
x: Math.floor((Math.random() * 17 + 1)) * box,
y: Math.floor((Math.random() * 15 + 3)) * box,
};
tire = {
x: Math.floor((Math.random() * 17 + 1)) * box,
y: Math.floor((Math.random() * 15 + 3)) * box,
};
pizza = {
x: Math.floor((Math.random() * 17 + 1)) * box,
y: Math.floor((Math.random() * 15 + 3)) * box,
};
}
ctx.fillStyle = "white";
ctx.font = "50px Arial";
ctx.fillText(score, box * 2.5, box * 1.7);
let snakeX = snake[0].x;
let snakeY = snake[0].y;
if(snakeX == food.x && snakeY == food.y) {
score++;
timed -= 20 // Увеличиваем скорость
if (timed < 25) timed = 25 // Но не бесконечно
food = {
x: Math.floor((Math.random() * 17 + 1)) * box, // по x
y: Math.floor((Math.random() * 15 + 3)) * box, // по y
};
} else if(snakeX == pizza.x && snakeY == pizza.y) {
score += 2;
timed -= 30 // Увеличиваем скорость
if (timed < 25) timed = 25 // Но не бесконечно
pizza = {
x: Math.floor((Math.random() * 17 + 1)) * box, // по x
y: Math.floor((Math.random() * 15 + 3)) * box, // по y
};
} else {
snake.pop();
}
if(snakeX == bar.x && snakeY == bar.y) {
score -= 3;
timed += 50 // Уменьшаем скорость
if (timed > 250) timed = 250 // Но не бесконечно
snake.pop();
bar = { // ставим еду в новом месте
x: Math.floor((Math.random() * 17 + 1)) * box, // по x
y: Math.floor((Math.random() * 15 + 3)) * box, // по y
};
}
if(snakeX == tire.x && snakeY == tire.y) {
score--;
timed += 25 // Уменьшаем скорость
if (timed > 250) timed = 250 // Но не бесконечно
snake.pop();
tire = {
x: Math.floor((Math.random() * 17 + 1)) * box, // по x
y: Math.floor((Math.random() * 15 + 3)) * box, // по y
};
}
if (score >= 50) {
// clearInterval(game);
alert('Вы выиграли!');
document.location.reload();
}
if(score <= -1) {
// clearInterval(game);
alert('Вы проиграли!');
document.location.reload();
}
if(snakeX < box || snakeX > box * 17
|| snakeY < 3 * box || snakeY > box * 17) {
// clearInterval(game);
alert('Вы проиграли!');
document.location.reload();
}
if(dir == "left") snakeX -= box;
if(dir == "right") snakeX += box;
if(dir == "up") snakeY -= box;
if(dir == "down") snakeY += box;
let newHead = {
x: snakeX,
y: snakeY
};
if (! eatTail(newHead, snake) ) setTimeout (drawGame, timed) // Вызывает снова через установленный интервал, если не съела хвост;
snake.unshift(newHead);
}
drawGame ();
Последний раз редактировалось voraa, 14.10.2020 в 10:25.
|
|
14.10.2020, 16:50
|
Аспирант
|
|
Регистрация: 06.09.2020
Сообщений: 57
|
|
voraa,
спасибо, но теперь возникла новая проблема, не срабатывает функция поедания хвоста, просто стопается отрисовка, пробовала через
alert('Вы проиграли!');
document.location.reload();
после return, но ничего так и не получилось, либо обновляет страницу сразу же при попытке съесть еду, либо же просто не даёт нажать кнопки на клаве... не понимаю причину и как исправить,уже часа 2 сижу, думаю, всё перепробовала, можете помочь?
|
|
14.10.2020, 17:32
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,743
|
|
А что должно происходить при поедании хвоста?
|
|
14.10.2020, 19:43
|
Аспирант
|
|
Регистрация: 06.09.2020
Сообщений: 57
|
|
voraa, алертом вывод, что игра окончена и при нажатии на ок обновление страницы и обнуление всего
|
|
14.10.2020, 20:06
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,743
|
|
Замените строку 221 в моем коде на
if (eatTail(newHead, snake) ) {
alert('Вы проиграли!');
document.location.reload();
}
setTimeout (drawGame, timed)
|
|
14.10.2020, 20:11
|
Аспирант
|
|
Регистрация: 06.09.2020
Сообщений: 57
|
|
voraa, благодарочка, всё получилось
|
|
|
|