Всем добрый вечер. Я продолжаю писать змейку без использования 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 тик: убирается последний элемент змейки, добавляется впереди. - когда змейка сьедает что-то, последний элемент просто не убирается. Поэтому нужно реализовать правильный алгоритм перемещения для начала.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Как получить Json не логинясь на сайт? Если есть куки при переходе по ссылке сайт выплевывает JSON https://wwwfastgraphs
Как сделать так, чтобы таблица не рисовалась каждую секунду, а изменлись значения в ней?
Есть две таблицы, в обеих id_product - соответствует номеру товара
Использую слайдер lightSlider и одновременно magnific-popup(что бы картинка открывалась в модальном окне)И произошла такая проблема, добавил всего два...