Snake

Snake Spil Grøn Niveau

Forklaring af, hvordan vi får en værdi til at “flytte sig” i et Array

Forestil dig, at vi vil gemme de seneste 50 positioner for musen, så vi kan tegne en sti, der følger efter den. For at gøre dette, skal vi bruge to arrays: ét til X-positioner og ét til Y-positioner. På den måde kan vi holde styr på, hvor musen har været, og opdatere positionerne over tid.

Først opretter vi to arrays:

int[] xpos = new int[50];
int[] ypos = new int[50];

Her kan xpos gemme 50 værdier for musens X-positioner, og ypos gemmer 50 værdier for musens Y-positioner.

Da musen ikke har bevæget sig, når vi starter programmet, fylder vi arrays med 0'er:

for (int i = 0; i < xpos.length; i++) {
  xpos[i] = 0;
  ypos[i] = 0;
}

Det betyder, at når vi starter, står alle værdier i xpos og ypos på 0, så stien begynder samlet ét sted.

I draw() opdaterer vi arrays med musens aktuelle position, men for kun at gemme de sidste 50 positioner, skal vi flytte alle værdierne ét skridt fremad i arrays først. For at få hvert element til at “bevæge sig frem” i arrayet, gør vi sådan:

for (int i = 0; i < xpos.length - 1; i++) {
  xpos[i] = xpos[i + 1];
  ypos[i] = ypos[i + 1];
}

Dette betyder, at værdien på plads 0 bliver den samme som på plads 1, plads 1 bliver lig plads 2, osv., så alle værdier “skubbes” ét trin frem.

Når alle værdier er flyttet en plads frem, sætter vi musens nuværende position som den sidste værdi i arrays:

xpos[xpos.length - 1] = mouseX;
ypos[ypos.length - 1] = mouseY;

Nu har vi musens aktuelle position i slutningen af arrays, og resten af værdierne viser, hvor musen har været.

For at visualisere stien, tegner vi en cirkel for hver værdi i arrays. På den måde viser hvert punkt musens tidligere position:

for (int i = 0; i < xpos.length; i++) {
  ellipse(xpos[i], ypos[i], 10, 10);
}

Resultatet er, at vi får en serie af cirkler, der følger musens bevægelse og viser de sidste 50 positioner, den har været på.

Samlet kode:

int[] xpos = new int[50];
int[] ypos = new int[50];

void setup() {
  size(400, 400);
  // Startværdier
  for (int i = 0; i < xpos.length; i++) {
    xpos[i] = 0;
    ypos[i] = 0;
  }
}

void draw() {
  background(255);

  // Flyt værdierne fremad i arrays
  for (int i = 0; i < xpos.length - 1; i++) {
    xpos[i] = xpos[i + 1];
    ypos[i] = ypos[i + 1];
  }

  // Opdater den sidste plads med musens position
  xpos[xpos.length - 1] = mouseX;
  ypos[ypos.length - 1] = mouseY;

  // Tegn en sti af cirkler
  for (int i = 0; i < xpos.length; i++) {
    ellipse(xpos[i], ypos[i], 10, 10);
  }
}

Opgave 1: Ændr retningen med piletasterne

Mål: Ændr koden, så slangen bevæger sig i retninger styret af piletasterne.

  1. Opret retning for slangen: Definér to variabler retningX og retningY, som angiver slangens retning. Start f.eks. med at lade retningX være 1 (højre) og retningY være 0.
  2. Tilføj retning med piletasterne: Tilføj en funktion, keyPressed(), hvor retningX og retningY ændres, når man trykker på piletasterne.
  3. Opdater slangens hoved med retning: I draw() skal slangens hoved bevæge sig i retning af retningX og retningY. Udskift linjen, der bruger musens position, med en linje, der tilføjer retningX * størrelse til X-positionen og retningY * størrelse til Y-positionen for slangens hoved.

Nedenunder kan du se pseudokoden for hvordan man løser punkt 1 og 2.

hvis op-pilen trykkes:
    sæt retningX til 0
    sæt retningY til -1
hvis ned-pilen trykkes:
    sæt retningX til 0
    sæt retningY til 1
hvis venstre-pilen trykkes:
    sæt retningX til -1
    sæt retningY til 0
hvis højre-pilen trykkes:
    sæt retningX til 1
    sæt retningY til 0

TIP: Kig her for hjælp til funktionen keyPressed() med piletasterne UP, DOWN, LEFT, RIGHT.

Til punkt 3 er der følgende eksempel på kode du kan bruge.

xpos[xpos.length - 1] += retningX * størrelse;
ypos[ypos.length - 1] += retningY * størrelse;
Opgave 2: Begræns slangens bevægelse til skærmen

Mål: Forhindre slangen i at bevæge sig udenfor skærmens grænser.

  • Tilføj grænsekontrol: Indsæt en betingelse, der stopper slangen, hvis den når kanten af skærmen.

Du kan bruge følgende pseudokode som inspiration til at løse opgaven. Kig også på dit tidligere pong projekt.

hvis slangens X-position er mindre end 0 eller større end skærmens bredde
    stop spillet
hvis slangens Y-position er mindre end 0 eller større end skærmens højde
    stop spillet
Opgave 3: Tilføj mad til slangen og gør den i stand til at vokse

Mål: Lav en mad-position på skærmen, som slangen kan “spise” for at vokse.

  1. Opret mad-variabler: Definér to variabler madX og madY for madens position. Tilføj initialiseringen af disse i setup()-funktionen, så maden får en tilfældig placering på skærmen.
  2. Tjek om slangen spiser maden: I draw() skal du tjekke, om slangens hoved rammer madens position. Hvis dette sker:
  • Øg slangens længde.
  • Flyt maden til en ny, tilfældig placering.

Følgende kode bruges til punkt 2.

if (xpos[xpos.length - 1] == madX && ypos[ypos.length - 1] == madY) {
  slangeLængde++; // Øger slangens længde
  madX = int(random(width / størrelse)) * størrelse;
  madY = int(random(height / størrelse)) * størrelse;
}
Ekstra opgave: Tjek for kollision med slangen selv

Mål: Sørg for, at slangen ikke kan bevæge sig ind i sig selv.

  1. Tjek kollision med egen krop: I draw() skal du lave et loop, der tjekker, om slangens hoved rammer et af slangens øvrige segmenter. Hvis dette sker, stopper spillet.

Følgende kode kan hjælpe dig med at lave denne funktion.

for (int i = 0; i < slangeLængde - 1; i++) {
  if (xpos[i] == xpos[xpos.length - 1] && ypos[i] == ypos[ypos.length - 1]) {
    println("Game Over");
    noLoop();
  }
}
Task Runner