Всем добрый вечер. Я продолжаю писать змейку без использования canvas, игра почти готова, но осталось реализовать довольно сложный процесс - увеличение змейки при поедании яблока. Здесь же возник вопрос, как это реализовать, пока что вообще никаких идей по этому поводу нету. В коде по максимуму попытался объяснить что за что отвечает, заранее спасибо за подкинутые идеи, возможно готовые решения. Строго не судите, я еще не профи в Js) Вот и сам код: CodePen
var mainBlock = document.getElementById("mainBlock"), // Игровая область
snakeBlock = document.getElementById("snakeBlock"), // Змейка(белый квадрат)
appleBlock = document.getElementById("appleBlock"), // Яблоко(черный квадрат)
scoreBlock = document.getElementsByClassName("scoreBlock")[0], // Блок очков
score = document.getElementById("score"), // Набранные очки
scoreValue = Number(score.innerHTML), // Отображение набранных очков
playBtn = document.getElementById("playBtn"), // Кнопка PLAY
myConfirm = document.getElementById("myConfirm"), // Свое окно Confirm
okeyBtn = document.getElementById("agree"), // Кнопка OK(PLAY в confirm)
exitBtn = document.getElementById("desagree"), // Кнопка EXIT
snakeX = mainBlock.offsetWidth/2 - 10, // Начальные координаты змейки по X, центр
snakeY = mainBlock.offsetHeight/2 - 10, // Начальные координаты змейки по Y, центр
appleX, appleY, // Координаты яблока(зададим позже)
t, // Переменная для будущей установки/сброса setInterval
activeGame = false, // Игра не запущена по умолчанию
eatCost = 10, // Стоимость одного яблока
maxX = mainBlock.clientWidth - 20, // 20px - ширина головы змейки
maxY = mainBlock.clientHeight - 20; // 20px - высота головы змейки
function moveUp() {
if (snakeX > 0) {
snakeX -= 20;
snakeBlock.style.top = snakeX + "px";
eat();
} else {
myConfirmDisplay();
}
}
function moveDown() {
if (snakeX < maxY) {
snakeX += 20;
snakeBlock.style.top = snakeX + "px";
eat();
} else {
myConfirmDisplay();
}
}
function moveLeft() {
if (snakeY > 0) {
snakeY -= 20;
snakeBlock.style.left = snakeY + "px";
eat();
} else {
myConfirmDisplay();
}
}
function moveRight() {
if (snakeY < maxX) {
snakeY += 20;
snakeBlock.style.left = snakeY + "px";
eat();
} else {
myConfirmDisplay();
}
}
playBtn.addEventListener('click', startGame);
function startGame() {
activeGame = true;
createEat();
resetParams();
playBtn.style.display = 'none'; // Скрытие кнопки PLAY
snakeBlock.style.display = 'block'; // Отображение змейки
scoreBlock.style.display = 'block'; // Отображение очков
var activeArr; // Переменная для отслеживания направления и запрета двигатся в противоположную сторону, true - если кубик двигается вверх/вниз, false - если влево/вправо
window.addEventListener('keydown', function (e) {
if (e.keyCode == 37 && activeArr !== false) {
clearInterval(t);
t = setInterval(moveLeft, 50);
activeArr = false;
}
else if (e.keyCode == 38 && activeArr !== true) {
clearInterval(t);
t = setInterval(moveUp, 50);
activeArr = true;
}
else if (e.keyCode == 39 && activeArr !== false) {
clearInterval(t);
t = setInterval(moveRight, 50);
activeArr = false;
}
else if (e.keyCode == 40 && activeArr !== true) {
clearInterval(t);
t = setInterval(moveDown, 50);
activeArr = true;
}
});
}
function resetParams() {
snakeX = mainBlock.offsetWidth/2 - 10,
snakeY = mainBlock.offsetHeight/2 - 10,
snakeBlock.style.top = snakeX + 'px';
snakeBlock.style.left = snakeY + 'px';
if (t !== undefined){
clearInterval(t);
}
score.innerHTML = 0;
scoreValue = Number(score.innerHTML);
}
function myConfirmDisplay(){
activeGame = false;
myConfirm.style.display = 'flex';
snakeBlock.style.display = 'none'; // Скрытие змейки
appleBlock.style.display = 'none'; // Скрытие яблока
scoreBlock.style.display = 'none'; // Скрытие очков
okeyBtn.addEventListener('click', function(){
startGame();
myConfirm.style.display = 'none';
});
exitBtn.addEventListener('click', function(){
playBtn.style.display = 'block'; // Отображение кнопки PLAY
snakeBlock.style.display = 'none'; // Скрытие змейки
scoreBlock.style.display = 'none'; // Скрытие очков
myConfirm.style.display = 'none'; // Скрытие окна выбора
resetParams();
});
window.addEventListener('keydown', function (e) {
if (e.keyCode == 13 && activeGame == false) {
startGame();
myConfirm.style.display = 'none';
} else if (e.keyCode == 27 && activeGame == false) {
playBtn.style.display = 'block'; // Отображение кнопки PLAY
snakeBlock.style.display = 'none'; // Скрытие змейки
scoreBlock.style.display = 'none'; // Скрытие очков
myConfirm.style.display = 'none'; // Скрытие окна выбора
resetParams();
}
});
}
function createEat(){
appleBlock.style.display = 'block';
appleX = Math.floor(Math.floor(Math.random()*(500 + 1)) / 20) * 20;
appleY = Math.floor(Math.floor(Math.random()*(500 + 1)) / 20) * 20; // Координаты яблока(промежуток от 0 до 500(ширина и высота игровой области))
appleBlock.style.top = appleX + 'px';
appleBlock.style.left = appleY + 'px';
}
function eat() {
if(snakeX == appleX && snakeY == appleY){
scoreValue += eatCost;
score.innerHTML = scoreValue;
appleBlock.style.display = 'none';
createEat();
}
}
* {
overflow: hidden;
margin: 0;
padding: 0;
}
#mainBlock {
height: 500px;
width: 500px;
background: #fff;
outline: 2px solid #000;
box-shadow: 1px 3px 36px 5px rgba(0,0,0,0.3);
position: absolute;
top: 50%;
left: 50%;
margin-right: -50%;
transform: translate(-50%, -50%);
}
#playBtn {
position: absolute;
width: 200px;
height: 50px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-family: arial, sans-serif;
font-size: 16px;
font-weight: bold;
color: #333;
border: 1px solid #000;
border-radius: 3px;
background: #f7f7f7;
transition: all .3s ease 0s;
outline: none;
}
#playBtn:hover {
border: 1px solid #000;
background: #e9e9e9;
cursor: pointer;
}
#snakeBlock {
display: none;
height: 16px;
width: 16px;
background-color: #fff;
border: 2px solid #000;
position: absolute;
}
#appleBlock {
display: none;
height: 20px;
width: 20px;
background-color: #000;
position: absolute;
}
#myConfirm {
position: absolute;
display: none;
flex-direction: column;
justify-content: center;
align-items: center;
font-family: 'PT Sans', sans-serif;
color: #000;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
z-index: 9999;
}
.main {
position: absolute;
height: auto;
width: 350px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
align-items: center;
justify-content: center;
background: #e9e9e9;
padding: 50px 0 50px 0;
border-radius: 10px;
box-shadow: 0 0 30px rgba(0,0,0,0.3);
}
.main-text {
text-align: center;
}
.header {
font-size: 24px;
text-transform: uppercase;
margin-bottom: 20px;
}
#agree,
#desagree {
width: 100px;
height: 40px;
margin: 0 5px;
font-family: arial, sans-serif;
font-size: 16px;
font-weight: bold;
color: #333;
border: 1px solid #000;
border-radius: 3px;
background: #f7f7f7;
transition: all .3s ease 0s;
outline: none;
}
#agree:hover,
#desagree:hover {
border: 1px solid #000;
background: #e9e9e9;
cursor: pointer;
}
.scoreBlock {
display: none;
position: absolute;
top: 93%;
left: 20%;
font-family: arial, sans-serif;
font-size: 24px;
}
#score {
font-weight: bold;
}
<div id="myConfirm">
<div class="main">
<div class="main-text">
<div class="head-text">
<h4 class="header">Play again?</h4>
</div>
<div class="desc-text">
<input id="agree" type="button" value="PLAY">
<input id="desagree" type="button" value="EXIT">
</div>
</div>
</div>
</div>
<div id="mainBlock">
<input id="playBtn" type="button" value="PLAY">
<div id="snakeBlock"></div>
<div id="appleBlock"></div>
</div>
<div class="scoreBlock">
Score:
<span id="score">0</span>
</div>
Правильно перемещение змейки: - за 1 тик: убирается последний элемент змейки, добавляется впереди. - когда змейка сьедает что-то, последний элемент просто не убирается. Поэтому нужно реализовать правильный алгоритм перемещения для начала.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Как получить Json не логинясь на сайт? Если есть куки при переходе по ссылке сайт выплевывает JSON https://wwwfastgraphs
Как сделать так, чтобы таблица не рисовалась каждую секунду, а изменлись значения в ней?
Есть две таблицы, в обеих id_product - соответствует номеру товара
Использую слайдер lightSlider и одновременно magnific-popup(что бы картинка открывалась в модальном окне)И произошла такая проблема, добавил всего два...