gf2:javascript

Dies ist eine alte Version des Dokuments!


Anhand vom Snake game sollen Sie verstehen, wofür JavaScript beispielsweise verwendet werden kann und dies auch etwas „ausprobieren“.
Was ist JavaScript?
JavaScript ist eine Programmiersprache, die ursprünglich für die Entwicklung interaktiver Webseiten genutzt wurde.
Die json Programme werden direkt im Browser ausgeführt und ermöglichen, Webseiten dynamisch zu gestalten und auf Benutzeraktionen zu reagieren.
Heute wird JavaScript aber weit über den Browser hinaus eingesetzt und eine wichtige Programmiersprache für Webentwicklung, Server-Anwendungen, mobile Apps und sogar Desktop-Software geworden. Die Sprache ist dynamisch typisiert (Typ einer Variable wird erst zur Laufzeit bestimmt), relativ einfach zu erlernen und sehr vielseitig einsetzbar.

  1. Es ist nötig, dass Sie Visual Studio Code installiert haben. Falls dies noch nicht der Fall ist, sollten Sie mindestens zu zweit an einem Computer mit Visualstudiocode arbeiten können. Download https://code.visualstudio.com/download hier möglich.
  2. Laden Sie sich die Dateien des folgenden Ordners herunter: Link auf Onedrive von CMarro

Sie finden in diesem Ordner neben einer css-Datei (app.css) auch eine htm-Datei (index.html).

Auftrag 1

  • Verändern Sie die Hintergrundfarbe des html-Dokuments in Hellgrün.
  • Nennen Sie den Knopf „Manual Step“ um zu „Schritt für Schritt“.

Dabei Kann die Extension „Live Preview“ helfen, um das html immer direkt anzuschauen. Natürlich kann auch die html-Datei via Browser geöffnet werden und dann jeweils durch ein Refresh beobachtet werden,was passiert.

Studieren Sie das Programm, Ziel ist ein grobes Verständnis des Programms.

Javascript-Snake-Game

Hier werden die Variablen festgelegt. Es gibt hier Listen, Objekte oder einfache Wertvariablen. Alle sind leer oder auf 0 gesetzt.

'use strict';
 
var gameStart = {},
  gameSpeed = {},
  gameArea = {},
  manualStep = {},
  gameAreaContext = {},
  snake = [],
  gameAreaWidth = 0,
  gameAreaHeight = 0,
  cellWidth = 0,
  playerScore = 0,
  snakeFood = {},
  snakeDirection = '',
  speedSize = 0,
  timer = {};

Dies ist eine Funkion, welche die Startgeschwindigkeit oder auch den Startzeitpunkt etc initialisieren, darin enthalten ist auch das Spielfeld 400×600

function initElement() {
  gameStart = document.querySelector('#gameStart');
  gameSpeed = document.querySelector('#gameSpeed');
  gameArea = document.querySelector('#gameArea');
  manualStep = document.querySelector('#manualStep');
 
  gameAreaContext = gameArea.getContext('2d');
  gameAreaWidth = 400;
  gameAreaHeight = 600;
  cellWidth = 20;
  gameArea.width = gameAreaWidth;
  gameArea.height = gameAreaHeight;
}

Das Spielfeld wird erstellt mit dieser Funktion, wenn Sie dann aufgerufen wird. Spielfeldhiintergrund ist weiss (FFFFF).

function createGameArea() {
  gameAreaContext.fillStyle = '#FFFFFF';
  gameAreaContext.fillRect(0, 0, gameAreaWidth, gameAreaHeight);
  gameAreaContext.strokeStyle = '#000000';
  gameAreaContext.strokeRect(0, 0, gameAreaWidth, gameAreaHeight);
}

Hier wird das 'Essen' der Schlange erstellt, sobald dies aufgerufen wird, dabei wird es zufällig auf dem Spielfeld platziert.

function createFood() {
  snakeFood = {
    x: Math.round(Math.random() * (gameAreaWidth - cellWidth) / cellWidth),
    y: Math.round(Math.random() * (gameAreaHeight - cellWidth) / cellWidth),
  };
}

Hier wird überprüft, ob die Schlange sich selber trifft, was ja nicht sein darf, sonst ist das Spiel vorbei.

function snakeOnItself(x, y, array) {
  for (var index = 0, length = array.length; index < length; index++) {
    if (array[index].x == x && array[index].y == y) return true;
  }
  return false;
}

Hier wird der Score geschrieben, sobald fertig gespielt wurde.

function writeScore() {
  gameAreaContext.font = '50px sans-serif';
  gameAreaContext.fillStyle = '#FF0000';
  gameAreaContext.fillText('Score: ' + playerScore, (gameAreaWidth / 2) - 100, gameAreaHeight / 2);
}

Hier wird ein Quadrat für die Spielfläche generiert

function createSquare(x, y) {
  gameAreaContext.fillStyle = '#000000';
  gameAreaContext.fillRect(x * cellWidth, y * cellWidth, cellWidth, cellWidth);
}

Der folgnede Code ist die Steuerung der Schlange.

function checkDirectionUpdatePosition() {
  var snakeX = snake[0].x;
  var snakeY = snake[0].y;
  if (snakeDirection == 'right') {
    snakeX++;
  } else if (snakeDirection == 'left') {
    snakeX--;
  } else if (snakeDirection == 'down') {
    snakeY++;
  } else if (snakeDirection == 'up') {
    snakeY--;
  }
  return { snakeX, snakeY };
}

Hier wird überprüft, ob die Schlange das 'Essen' erwischt hat oder nicht.

function didSnakeEatTheFood(snakeX, snakeY) {
  if (snakeX == snakeFood.x && snakeY == snakeFood.y) {
    return true;
  } else {
    return false;
  }
}

Im Spiel ist immer wieder ein neues Update für das Spielfeld nötig.

function updateGameArea() {
 
  var snakeAteFootVar = false;
  var isSnakeOnItself = false
 
  createGameArea();
 
  var newPosition = checkDirectionUpdatePosition();
  var snakeX = newPosition.snakeX;
  var snakeY = newPosition.snakeY;
 
 
}

Es wird mit dieser Funktiongeschaut, dass die Schlange auf dem Spielfeld bleibt.

function checkSnakeOutOfBounds(snakeX, snakeY) {
  if ((snakeX == -1) || 
    (snakeX == gameAreaWidth / cellWidth) || 
    (snakeY == -1) || 
    (snakeY == gameAreaHeight / cellWidth)) {
      return true;
  }
  return false;
}

Mit der folgenden Methode wird das Spiel gestartet.

function startGame() {
 
  // initally create snake
  snake = [];
  snake.push({ x: 0, y: cellWidth });
 
  // create the food
  createFood();
 
  // make the snake move automatically
  clearInterval(timer);
  timer = setInterval(updateGameArea, 500 / speedSize);
}
 
function stepOnClick() {
  updateGameArea();
}
 
function onStartGame() {
  this.disabled = true;
 
  // reset score
  playerScore = 0;
 
  // reset direction to right
  snakeDirection = 'right';
 
  // reset speed the set value
  speedSize = parseInt(gameSpeed.value);
  if (speedSize > 9) {
    speedSize = 9;
  } else if (speedSize < 0) {
    speedSize = 1;
  }
 
  startGame();
}

Mit den Tasten 37 bis 40 sind die Pfeiltasten nummeriert. Es wird auch geschaut, dass man nicht rückwärts wandern kann.

function changeDirection(e) {
  var keys = e.which;
  if (keys == '40' && snakeDirection != 'up') snakeDirection = 'down';
  else if (keys == '39' && snakeDirection != 'left') snakeDirection = 'right';
  else if (keys == '38' && snakeDirection != 'down') snakeDirection = 'up';
  else if (keys == '37' && snakeDirection != 'right') snakeDirection = 'left';
}

Durch den Schitt für Schritt Button kann beim Programmieren viel ausprobiert werden.

function initEvent() {
  gameStart.addEventListener('click', onStartGame);
  manualStep.addEventListener('click', stepOnClick)
  window.addEventListener('keydown', changeDirection);
}
 
function init() {
  initElement();
  createGameArea()
  initEvent();
}
 
window.addEventListener('DOMContentLoaded', init);

Um etwas besser am Programm arbeiten zu können, hilft es eventuell, die folgenden Zeilen durch einen doppelten Backslash aus zu kommentieren:

// clearInterval(timer);
//timer = setInterval(updateGameArea, 500 / speedSize);

Auftrag 2

Verändern Sie die Farbe des Food-Quadrats.
Verändern Sie das Board, so das es Häuschen / ein Gitter hat.
Fügen Sie Buttons unten am Spielfeld an, um die Richtung dort zu ändern und nicht mehr mit den Pfeiltasten.
Zusätzlich kann auch die Geschwindigkeit nach jedem Essen der Schlange erhöht werden.

Sie dürfen sich auch Hilfe bei einer KI einem LLM holen, falls Sie möchten. </WRAP>

mögliche Lösungen

Um die Farbe des Essens zu verändern, könnte die Funktion createSquare verdoppelt werden und dann bei der kopierten Version der Funktion kann die Farbe anders eingestellt werden, beispielsweise

gameAreaContext.fillStyle = '#FF0000'

und weiter unten dann

  // create the food
  createSquare1(snakeFood.x, snakeFood.y);
 

Um ein Raster zu erhalten, muss die createGameArea() Funktion verändert werden, hier kann beispielsweise wie folgt vorgegangen werden:

function createGameArea() {
  gameAreaContext.fillStyle = '#FFFFFF';
  gameAreaContext.fillRect(0, 0, gameAreaWidth, gameAreaHeight);
  gameAreaContext.strokeStyle = '#000000';
  gameAreaContext.strokeRect(0, 0, gameAreaWidth, gameAreaHeight);
// Raster zeichnen
  const gridSize = 20; // Größe der Rasterzellen
  gameAreaContext.strokeStyle = '#CCCCCC'; // Hellgraue Rasterlinien
  gameAreaContext.lineWidth = 1;
 
// Vertikale Linien
  for (let ix = 0; ix <= gameAreaWidth; ix= gridSize+1) {
    gameAreaContext.beginPath();
    gameAreaContext.moveTo(ix, 0);
    gameAreaContext.lineTo(ix, gameAreaHeight);
    gameAreaContext.stroke();
  }
 
  // Horizontale Linien
  for (let iy = 0; iy <= gameAreaHeight; iy = gridSize+1) {
    gameAreaContext.beginPath();
    gameAreaContext.moveTo(0, iy);
    gameAreaContext.lineTo(gameAreaWidth, iy);
    gameAreaContext.stroke();
  }
 
  // Schwarzer Rahmen (wie vorher)
  gameAreaContext.strokeStyle = '#000000';
  gameAreaContext.strokeRect(0, 0, gameAreaWidth, gameAreaHeight);
}

Um die Steuerung auf der Website unterhalb des Spielfelds anzeigen zu lassen, muss in der html-Datei beispielsweise folgendes verändert werden:

<body>
  Speed: <input type="number" id="gameSpeed" value="5" min="1" max="9" step="1" />
  <input type="button" value="Start" id="gameStart" />
  <input type="button" value="Schritt für Schritt" id="manualStep" />
  <br> <br>
  <canvas id="gameArea"></canvas> 
  <br>
<script src="app.js"></script>
<button id="moveUp">Hoch</button>
<br>
<button id="moveLeft">links</button>
<button id="moveRight">rechts </button>
<br>
<button id="moveDown">runter</button>
 
</body>

und in der app.js Datei: Hier muss bei den Variablen noch für jede der vier Richtungen eine Variable dazugefügt werden.

...
  timer = {},
  moveDown = {},
  moveUp = {},
  moveLeft = {},
  moveRight= {};

Danach muss auch die funktion initElement() erweitert werden.

function initElement() {
  gameStart = document.querySelector('#gameStart');
  gameSpeed = document.querySelector('#gameSpeed');
  gameArea = document.querySelector('#gameArea');
  manualStep = document.querySelector('#manualStep');
  moveDown = document.querySelector('#moveDown');
  moveUp = document.querySelector('#moveUp');
  moveLeft = document.querySelector('#moveLeft');
  moveRight = document.querySelector('#moveRight');
 

zudem muss auch die Funktion initEvent() vervollständigt werden:

function initEvent() {
  gameStart.addEventListener('click', onStartGame);
  manualStep.addEventListener('click', stepOnClick)
  window.addEventListener('keydown', changeDirection);
  moveDown.addEventListener('click', function() { 
    if (snakeDirection != 'up') snakeDirection = 'down';
  });
  moveLeft.addEventListener('click', function() { 
    if (snakeDirection != 'right') snakeDirection = 'left';
  });
  moveRight.addEventListener('click', function() { 
    if (snakeDirection != 'left') snakeDirection = 'right';
  });
  moveUp.addEventListener('click', function() { 
    if (snakeDirection != 'down') snakeDirection = 'up';
  });
}
  • gf2/javascript.1749482514.txt.gz
  • Zuletzt geändert: 2025/06/09 17:21
  • von marroc