JavaScript snake

0

Witam, wpadłem sobie na pomysł, żeby zrobić sobie grę snake w JS. Mam aktualnie problem z tym, gdy chce, żeby mój wąż (teraz to aktualnie jest tylko kwadracik), zmieniał kierunki ruchu, ale gdy wciskam klawisz to pojawia się znacznie za daleko i nie mogę tego ogarnąć. Proszę o pomoc bo nie daje sobie rady.

<!doctype html>
<html> <head> <meta charset="UTF-8" /> </head> <body> <canvas></canvas> <script> const canvas = document.querySelector('canvas'); const ctx = canvas.getContext('2d');
    canvas.width = 1000;
    canvas.height = 1000;

    const bw = canvas.width;
    const bh = canvas.height;

    const headSnake = 30;

    let snakeX = bw / 2
    let snakeY = bh / 2

    let snakeSpeed = 3;

    let key = '68';


    function board() {
        ctx.fillStyle = 'green';
        ctx.fillRect(0, 0, bw, bh);
    }

    function snake() {
        ctx.fillStyle = 'white';
        ctx.fillRect(snakeX, snakeY, headSnake, headSnake);

        if (key == '118') key = '68';
        if (key == '87') snakeY -= snakeSpeed; //w
        if (key == '83') snakeY += snakeSpeed; //s

        if (key == '65') snakeX -= snakeSpeed; //a
        if (key == '68') snakeX += snakeSpeed; //d
        document.addEventListener('keydown', snakeMove);

        function snakeMove(event) {
            key = event.keyCode;
            if (key == '118') key = '68';
            if (key == '87') snakeY -= snakeSpeed; //w
            if (key == '83') snakeY += snakeSpeed; //s
            if (key == '65') snakeX -= snakeSpeed; //a
            if (key == '68') snakeX += snakeSpeed; //d


        }



    }

    function game() {
        board();
        snake();

    }

    setInterval(game, 1000 / 60);
</script>
</body> </html>
0
<!doctype html>
<html>

<head>
    <meta charset="UTF-8" />
</head>

<body>
    <canvas></canvas>
    <script>
        const canvas = document.querySelector('canvas');
        const ctx = canvas.getContext('2d');

        canvas.width = 1000;
        canvas.height = 1000;

        const bw = canvas.width;
        const bh = canvas.height;

        const headSnake = 30;

        let snakeX = bw / 2
        let snakeY = bh / 2

        let snakeSpeed = 3;

        let key = '68';


        function board() {
            ctx.fillStyle = 'green';
            ctx.fillRect(0, 0, bw, bh);
        }

        function snake() {
            ctx.fillStyle = 'white';
            ctx.fillRect(snakeX, snakeY, headSnake, headSnake);

            if (key == '118') key = '68';
            if (key == '87') snakeY -= snakeSpeed; //w
            if (key == '83') snakeY += snakeSpeed; //s

            if (key == '65') snakeX -= snakeSpeed; //a
            if (key == '68') snakeX += snakeSpeed; //d
            document.addEventListener('keydown', snakeMove);

            function snakeMove(event) {
                key = event.keyCode;
                if (key == '118') key = '68';
                if (key == '87') snakeY -= snakeSpeed; //w
                if (key == '83') snakeY += snakeSpeed; //s
                if (key == '65') snakeX -= snakeSpeed; //a
                if (key == '68') snakeX += snakeSpeed; //d


            }



        }

        function game() {
            board();
            snake();

        }

        setInterval(game, 1000 / 60);
    </script>
</body>

</html> ```
0

Dodaj sobie w funkcji snakeMove instrukcję

console.log('wyskoczyl event');

i podejrzyj na konsoli developerskiej ile razy taki event jest odpalany. (Tzw. shotgun debugging, niestety dla JS nie potrafię inaczej.)
Następnie zastanów się, czy w tej funkcji jest zasadne ruszać wężem, skoro przecież już funkcja snake realizuje ruch na podstawie obranego kierunku.

0

Dzięki ::* masz rację, w funkcji snakeMove usunąłem, ruch węża, co usunęło błąd z przeskakiwaniem o kilka pól i wykorzystałem funkcję do ustawienia keyCodu w zmiennej. Jeszcze raz dzięki i pozdrawiam.

0

Już z wężem jest coraz lepiej, bo ogon porusza się za głową i teoretycznie jedzenie już połyka i powiększa ogon.
Teraz jest taki problem, że 2 jedoznka już nie chce zjeść, nie wiem dlaczego nie zgadzają się koordynaty jedzenia i głowy.
Ma ktoś może jakiś pomysł?

<!doctype html>
<html>

<head>
    <meta charset="UTF-8" />
</head>

<body>
    <canvas></canvas>
    <script>
        const canvas = document.querySelector('canvas');
        const ctx = canvas.getContext('2d');

        canvas.width = 1000;
        canvas.height = 1000;

        const bw = canvas.width;
        const bh = canvas.height;

        const headSnake = 30;

        let snakeX = bw / 2
        let snakeY = bh / 2

        let snakeSpeedX = 1;
        let snakeSpeedY = 0;

        let tailSpeedX = 1;
        let tailSpeedY = 0;

        let foodX = randomNumber();
        let foodY = randomNumber();

        let key = '68';

        let sizeSnake = 3;

        let toward = 68;

        let tail = [];

        let tailX = snakeY;
        let tailY = snakeX;

        let tailHelpX = 0;
        let tailHelpY = 0;



        function randomNumber() {
            return Math.floor((Math.random() * bw) + 1);
        }


        function board() {
            ctx.fillStyle = 'green';
            ctx.fillRect(0, 0, bw, bh);
        }

        function initSnake() {
            for (let i = 0; i < sizeSnake; i++) {
                tail.push({
                    x: i,
                    y: 0
                });
            }
        }

        function snake() {

            for (let i = 0; i < sizeSnake; i++) {
                ctx.fillStyle = 'white';
                ctx.fillRect(tail[i].x * sizeSnake, tail[i].y * sizeSnake, headSnake, headSnake);
            }

            moveSnake();

            //pojawienie sie jedzenia

        }

        function moveSnake() {
            if (key == '118') key = '68';
            let lastPartPositionX = tail[sizeSnake - 1].x;
            let lastPartPositionY = tail[sizeSnake - 1].y;
            let prevX = lastPartPositionX;
            let prevY = lastPartPositionY;


            //w
            if (key == '87') {
                snakeSpeedX = 0;
                snakeSpeedY = 2;
                tail[sizeSnake - 1].y -= snakeSpeedY;
                snakeSpeedX = 0;
                toward = 87;
                tailHelpX = snakeX;
                tailHelpY = snakeY;
            }

            //s
            if (key == '83') {
                snakeSpeedY = 2;
                snakeSpeedX = 0;
                tail[sizeSnake - 1].y += snakeSpeedY;
                toward = 83;
                tailHelpX = snakeX;
                tailHelpY = snakeY;
            }

            //a
            if (key == '65') {
                snakeSpeedY = 0;
                snakeSpeedX = 2;
                tail[sizeSnake - 1].x -= snakeSpeedX;
                toward = 65;
                tailHelpX = snakeX;
                tailHelpY = snakeY;
            }

            //d
            if (key == '68') {
                snakeSpeedX = 2;
                snakeSpeedY = 0;
                tail[sizeSnake - 1].x += snakeSpeedX;
                toward = 68;
                tailHelpX = snakeX;
                tailHelpY = snakeY;

            }

            for (let i = sizeSnake - 2; i >= 0; i--) {
                lastPartPositionX = tail[i].x;
                lastPartPositionY = tail[i].y;
                tail[i].x = prevX;
                tail[i].y = prevY;
                prevX = lastPartPositionX;
                prevY = lastPartPositionY;
            }

            document.addEventListener('keydown', snakeMove);

            function snakeMove(event) {
                key = event.keyCode;

            }


        }

        function food() {
            ctx.fillStyle = 'white';
            ctx.fillRect(foodX, foodY, headSnake, headSnake);

            if (tail[sizeSnake - 1].x * 3 >= foodX && tail[sizeSnake - 1].x * 3 <= foodX + headSnake &&
                tail[sizeSnake - 1].y * 3 >= foodY && tail[sizeSnake - 1].y * 3 <= foodY + headSnake ||
                tail[sizeSnake - 1].x * 3 + headSnake <= foodX + headSnake &&
                tail[sizeSnake - 1].x * 3 + headSnake >= foodX &&
                tail[sizeSnake - 1].y * 3 + headSnake <= foodY + headSnake &&
                tail[sizeSnake - 1].y * 3 + headSnake >= foodY) {

                foodX = randomNumber();
                foodY = randomNumber();

                sizeSnake++;
                tail.unshift({
                    x: -sizeSnake,
                    y: -sizeSnake
                })
            }


        }
        initSnake();

        function game() {
            board();
            snake();
            food();

        }

        setInterval(game, 1000 / 60);
    </script>
</body>

</html>'''
0
Chory Szczur napisał(a):

Już z wężem jest coraz lepiej, bo ogon porusza się za głową i teoretycznie jedzenie już połyka i powiększa ogon.
Teraz jest taki problem, że 2 jedoznka już nie chce zjeść, nie wiem dlaczego nie zgadzają się koordynaty jedzenia i głowy.
Ma ktoś może jakiś pomysł?

Niepotrzebnie komplikujesz sobie problem, mieszając 3 aspekty: logikę gry, input (klawiatura), oraz renderowanie grafiki.
Sensowne podejście do tematu to rozgrywanie gry na planszy dyskretnej, bez związku z rozmiarem pikseli renderowanej grafiki.
Wtedy masz np. sprawdzanie, czy głowa węża weszła na jedzenie

 if(sX === fX && sY === fY) //s - snake head, f - food

Jeżeli chcesz brnąć dalej w pomieszane z poplątanym, to polecam zatrzymać sobie grę, tak by kolejny krok gry toczył się na żądanie, i debugowanie zawartości zmiennych.

let keyPr = true;
//......
        function game() {
			if(keyPr === false){
				return;
			}
            board();
            snake();
            food();
			keyPr = false;

        }
		
		function cont(event) {
                keyPr = true;

		}

        setInterval(game, 1000 / 60);
		document.addEventListener('keydown', cont);

a następnie na konsoli developerskiej (F12) możesz sobie podejrzeć zmienne.
U mnie wygląda, że coś się mocno nie zgadza, np. w momencie kolizji mam

>> tail[sizeSnake - 1].x * 3
546
>> foodX
706

jednakowoż mogłem coś źle zrozumieć, najlepiej jakbyś samodzielnie pooglądał swoje zmienne.

1 użytkowników online, w tym zalogowanych: 0, gości: 1