Warum funktioniert dieser JavaScript-Code nicht?
function updateScore() {
scoreElement.textContent = score;
}
function increaseScore() {
if (foodCollected = true) {
score++;
updateScore();
foodCollected = false;
}
}
Der Score wird jede halbe Sekunde immer größer und nicht nur dann, wenn sie etwas gefressen hat!
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.
Ich benutze VSCode und führe ihn in Chrome aus
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.
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>
= ist eine Zuweisung.
== ist ein Vergleich.
Überleg dir, was du wo brauchst.
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.
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.