Warum funktioniert dieser JavaScript-Code nicht?

AlexX184  18.08.2023, 15:40

Was ist die Fehlermeldung?

MCStar975 
Fragesteller
 18.08.2023, 15:44

Es gibt keine. Es ist ja nichts falsch. Der Code Editor denkt das soll so.

3 Antworten

Der Code funktioniert nicht, weil in der Bedingung

if (foodCollected = true)

eine Zuweisung anstelle eines Gleichheitsoperators verwendet wird. Dadurch wird die Bedingung immer als wahr ausgewertet, unabhängig davon, ob Nahrung gesammelt wurde oder nicht. Verwenden Sie stattdessen den Gleichheitsoperator

===

oder noch besser, verwenden Sie einfach

if (foodCollected)

für die Bedingung, um sicherzustellen, dass der Score nur dann erhöht wird, wenn tatsächlich Nahrung gesammelt wurde.


MCStar975 
Fragesteller
 18.08.2023, 15:52
Es funktioniert immer noch nicht hier der ganze Code.




<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">       MCStarschlange
    <title>http://MCStar.schlange.de</title>
</head>
<body>
 
  <canvas id="canvas" width="480" height="480"></canvas>
  <p>Score: <span id="score">0</span></p>
  <script>
    let canvas = document.getElementById('canvas');
    let ctx = canvas.getContext('2d');   //Variablen
    let rows = 20;
    let cols = 20;
    let snake = [
    {x: 9, y: 3}
    ];
        
    let cellWidth = canvas.width / cols;
    let cellHeight = canvas.height / rows;
    let direction = 'LEFT';
    let foodCollected = false;
    var scoreElement = document.getElementById("score");
    var score = 0;
    
    placeFood();



    
    setInterval(gameLoop, 200);
    document.addEventListener('keydown', keyDown);     //Funktionen
 
    draw();
    


    



    
    
    function updateScore() {
         scoreElement.textContent = score; 
        
    }
    
    function increaseScore() {
        if (foodCollected == true); {
            score++;
            updateScore();


            foodCollected = false;
        }
    }




    function draw(){
        ctx.fillStyle = 'black';
        ctx.fillRect(0, 0, canvas.width, canvas.height);    //canvas
        ctx.fillStyle = 'white';



        snake.forEach(part => add(part.x, part.y));


        
 


        ctx.fillStyle = 'yellow';
        add(food.x, food.y);    //Essen


        requestAnimationFrame(draw);
    }





    function testGameOver() {


        let firstPart = snake[0];
        let otherParts = snake.slice(1);
        let duplicatePart = otherParts.find(part => part.x == firstPart.x && part.y == firstPart.y);


        // 1. Schlange läuft gegen die Wand
        if (snake[0].x < 0 ||
        snake[0].x > cols - 1 ||
        snake[0].y < 0 ||
        snake[0].y > rows -1 ||                   //Spielneustart
        duplicatePart
        ) {
            placeFood();
            snake = [{
                x: 19,
                y: 3
            }];
            direction = 'LEFT';
        }
    }


    
    function placeFood() {
        let randomX = Math.floor(Math.random() * cols);
        let randomY = Math.floor(Math.random() * rows);


        food = {x: randomX, y: randomY};
    }
    





    function add(x, y){ 
        ctx.fillRect(x * cellWidth, y * cellHeight, cellWidth - 1, cellHeight - 1); // Kordinaten übersichtlicher machen
    
    }
    function shiftSnake() {
        for (let i = snake.length - 1; i > 0; i--) {
            const part = snake[i];
            const lastPart = snake[i - 1];
            part.x = lastPart.x;
            part.y = lastPart.y;
    }
    }


       


    function gameLoop(){
        testGameOver();
        if(foodCollected) {
            snake = [{x: snake[0].x, y: snake[0].y}, ...snake];


            foodCollected = false;
        }




        increaseScore();


        shiftSnake();


        if(direction == 'LEFT') {
            snake[0].x--;
        }
        if(direction == 'RIGHT') {
            snake[0].x++;
        }                             //Schlange bewegen usw.
        if(direction == 'UP') {
            snake[0].y--;
        }
        if(direction == 'DOWN') {
            snake[0].y++;
        }


        if(snake[0].x == food.x 
        && snake[0].y == food.y) {
            foodCollected = true;
            
            placeFood();
        }
        
    }


    function keyDown(e) {
        if(e.keyCode == 37){
            direction = 'LEFT';
        }
        if(e.keyCode == 38){            //Tasten zuweisung
            direction = 'UP';                          
        }
        if(e.keyCode == 39){
            direction = 'RIGHT';
        }
        if(e.keyCode == 40){
            direction = 'DOWN';
        }
    }
   </script>
   
</body>
</html>
0
MCStar975 
Fragesteller
 18.08.2023, 15:56
@MCStar975

Ich benutze VSCode und führe ihn in Chrome aus

0
butterkipfel  18.08.2023, 16:00
@MCStar975

es sind noch ein paar kleinere fehler versteckt.

In der Zeile

<meta name="viewport" content="width=device-width, initial-scale=1.0"> MCStarschlange

gibt es anscheinend einen zusätzlichen Text "MCStarschlange" außerhalb des Meta-Tags . Du solltest diesen entfernen, damit nur die Meta-Tag-Zeile übrig bleibt.

In der Funktion

placeFood()

wird die Variable "food" nicht deklariert, bevor sie zugewiesen wird. Du musst die Variable "food" außerhalb der Funktion definieren, damit sie im gesamten Code verwendet werden kann. Du könntest sie am Anfang des Skripts hinzufügen:

let food;

In der Funktion

increaseScore()

ist ein Semikolon nach der "if"-Bedingung, was dazu führt, dass der darin befindliche Block unabhängig von der Bedingung ausgeführt wird. Du solltest das Semikolon entfernen, damit die Bedingung korrekt funktioniert.

Die Funktion

draw()

wird mit

requestAnimationFrame(draw);

am Ende aufgerufen, jedoch wird diese Funktion wiederum von sich selbst aufgerufen, ohne eine Ausstiegsbedingung. Dadurch wird der Browser in eine Endlosschleife geraten. Du könntest stattdessen

setInterval(draw, 200);

verwenden, um die Funktion in regelmäßigen Abständen aufzurufen.

Die Funktion

add()

verwendet den

ctx.fillRect()

-Befehl, aber sie versucht, die

add()

-Funktion innerhalb der

draw()

-Funktion aufzurufen. Dadurch wird die

add()

-Funktion in einer Schleife immer wieder aufgerufen und führt zu einem unerwünschten Verhalten. Stattdessen solltest du den

ctx.fillRect()

-Befehl direkt in der

draw()

-Funktion verwenden.

2
MCStar975 
Fragesteller
 18.08.2023, 19:35
@butterkipfel
Ich habe wieder irgentwas falsch gemacht. Jetzt sieht man keine Schlange und kein Essen mehr. Ich bin noch Anfänger deswegen mach ich noch viel falsch.




<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>http://MCStar.schlange.de</title>
</head>
<body>
 
  <canvas id="canvas" width="480" height="480"></canvas>
  <p>Score: <span id="score">0</span></p>
  <script>
    let food;
    let canvas = document.getElementById('canvas');
    let ctx = canvas.getContext('2d');   //Variablen
    let rows = 20;
    let cols = 20;
    let snake = [
    {x: 9, y: 3}
    ];
        
    let cellWidth = canvas.width / cols;
    let cellHeight = canvas.height / rows;
    let direction = 'LEFT';
    let foodCollected = false;
    var scoreElement = document.getElementById("score");
    var score = 0;
    
    placeFood();



    
    setInterval(gameLoop, 200);
    document.addEventListener('keydown', keyDown);     //Funktionen
 
    draw();
    


    



    
    
    function updateScore() {
         scoreElement.textContent = score; 
        
    }
    
    function increaseScore() {
        if (foodCollected == true) {
            score++;
            updateScore();


            foodCollected = false;
        }
    }




    function draw(){
        setInterval(draw, 200);
        ctx.fillStyle = 'black';
        ctx.fillRect(0, 0, canvas.width, canvas.height);    //canvas
        ctx.fillStyle = 'white';



        snake.forEach(part => add(part.x, part.y));


    
 


        ctx.fillStyle = 'yellow';
        add(food.x, food.y);    //Essen


    }





    function testGameOver() {


        let firstPart = snake[0];
        let otherParts = snake.slice(1);
        let duplicatePart = otherParts.find(part => part.x == firstPart.x && part.y == firstPart.y);


        // 1. Schlange läuft gegen die Wand
        if (snake[0].x < 0 ||
        snake[0].x > cols - 1 ||
        snake[0].y < 0 ||
        snake[0].y > rows -1 ||                   //Spielneustart
        duplicatePart
        ) {
            placeFood();
            snake = [{
                x: 19,
                y: 3
            }];
            direction = 'LEFT';
        }
    }


    
    function placeFood() {
        let randomX = Math.floor(Math.random() * cols);
        let randomY = Math.floor(Math.random() * rows);


        food = {x: randomX, y: randomY};
    }
    






    function shiftSnake() {
        for (let i = snake.length - 1; i > 0; i--) {
            const part = snake[i];
            const lastPart = snake[i - 1];
            part.x = lastPart.x;
            part.y = lastPart.y;
    }
    }


       


    function gameLoop(){
        testGameOver();
        if(foodCollected) {
            snake = [{x: snake[0].x, y: snake[0].y}, ...snake];


            foodCollected = false;
        }




        increaseScore();


        shiftSnake();


        if(direction == 'LEFT') {
            snake[0].x--;
        }
        if(direction == 'RIGHT') {
            snake[0].x++;
        }                             //Schlange bewegen usw.
        if(direction == 'UP') {
            snake[0].y--;
        }
        if(direction == 'DOWN') {
            snake[0].y++;
        }


        if(snake[0].x == food.x 
        && snake[0].y == food.y) {
            foodCollected = true;
            
            placeFood();
        }
        
    }


    function keyDown(e) {
        if(e.keyCode == 37){
            direction = 'LEFT';
        }
        if(e.keyCode == 38){            //Tasten zuweisung
            direction = 'UP';                          
        }
        if(e.keyCode == 39){
            direction = 'RIGHT';
        }
        if(e.keyCode == 40){
            direction = 'DOWN';
        }
    }
   </script>
   
</body>
</html>
1

Javascript erlaubt, leider, Zuweisungen in if Bedingungen.

Das heißt "foodCollected = true" setzt foodCollected auf true(und hat dem Wert von true, wie das meiste bei Javascript).

Viele andere Programmiersprachen würden dir zumindest eine Warnung geben, wenn nicht sogar einen Fehler.


jo135  18.08.2023, 19:27
Javascript erlaubt, leider, Zuweisungen in if Bedingungen.

Strenggenommen ist das nicht das Problem. In JavaScript sind Zuweisungen aber Ausdrücke und haben somit einen Wert. So wie in C, aber nicht in diversen anderen Sprachen.

Ein vernünftiger JS-Editor sollte hier aber warnen.

0

= ist eine Zuweisung.

== ist ein Vergleich.

Überleg dir, was du wo brauchst.