Lasergame Arcade Target Practice Met Arduino (Nederlands/Dutch)

by mapaya in Circuits > Arduino

74 Views, 1 Favorites, 0 Comments

Lasergame Arcade Target Practice Met Arduino (Nederlands/Dutch)

Lasergame Arcade Showcase
IMG_3968.jpeg
IMG_3948.jpeg

[Deze instructable is gemaakt voor een project bij de HKU, door Maya Kooi]

Met deze instructable kan je je eigen lasergame arcade maken met verplaatsbare targets, random volgorde van actieve targets en een dynamische tijdsintervalregeling voor spel op jouw niveau!

Voor deze opdracht wou ik een spelletje maken waarbij je je schietprecisie kan oefenen. Oorspronkelijk wilde ik dit doen voor pijl en boog, maar dat leek mij iets te gevaarlijk. Lasergamen is the next best thing!

De meeste lasergames maken gebruik van infrarood licht, maar dit project functioneert met algemeen licht. Hier heb ik voor gekozen omdat er al lichtsensoren in mijn arduino-kit zaten. Als je graag wil kan je ook de lichtsensoren vervangen met infrarood sensoren, en schieten met een infrarood zender als een echt lasergame pistool, of een afstandsbediening.

Supplies

  • Arduino Uno + USB-kabel
  • 3 LEDjes geel
  • 1 LEDje rood
  • 1 LEDje groen
  • 3 x LDR lichtgevoelige weerstand
  • 3x 10kOhm weerstanden
  • 5x 330Ohm-weerstanden
  • 1x piezo buzzer
  • 1x breadboard + draadjes
  • 40x50 3mm MDF
  • Laserlampje
  • een hele hoop draad

Bouw Een Proefversie Op Het Breadboard

Schermafbeelding 2024-03-30 165754.png
IMG_3857.jpeg

Voordat je direct de behuizing gaan maken en solderen, is het handig om met de componenten die je hebt te kijken wat mogelijk is. Zo kan je een beter beeld krijgen van wat je wil gebruiken, en hoe je dit op elkaar wilt aansluiten.

Omdat het nog een proefversie is hoef je nog niet te veel na te denken over het ontwerp. Nu kan je beter de focus leggen op het werkend krijgen van alles.

Hier heb ik een kleine arcade gebouwd met 2 targets van lichtsensoren. Deze staan links op het breadboard op het schema. Boven de targets staan de desbetreffende LEDjes die zullen oplichten bij het actieve target. In het midden heb ik een piezo buzzer aangesloten die geluidsfeedback geeft nadat je een target geraakt of gemist hebt. Rechts staat een groene en een rood LEDje. De groene zal branden als je een target raakt, en de rode als je mist.

De Complete Code

Lasergame Arcade test op breadboard

Nu is het tijd voor de code! In de comments staat uitleg over welk deel wat doet.

Als je meer targets wilt toevoegen, moet je een paar dingen doen. Het is niet heel ingewikkelt, je moet vooral stukjes code knippen en plakken.

Bovenin de code moet je een nieuwe bool maken voor de hit per target. In de loop knip en plak je een nieuw blokje die kijkt of er genoeg licht valt in de nieuwe sensor, met een nieuwe value variabele en de analogRead op de juiste pin van de nieuwe lichtsensor.

Daarna moet je de Targetselect verhogen met het aantal nieuwe targets wat je toevoegt.

Ten slotte moet je in de TimerRunning functie nog twee dingen aanpassen. Je moet een stukje van de targetnum remap knippen en plakken met de juiste info, evenals bij "statement om te kijken of je de juiste target raakt als die actief is".

bool hit1 = false;  //bool of de target geraakt is voor individuele target
bool hit2 = false;
bool hit3 = false;


int TargetNum;
unsigned long previousMillis = 0;  // variabele voor de vergane tijd
int interval = 4000;               // interval voor de timer (3 secondes)
int score;                         //om de geraakte targets bij te houden
int rounds;                        //aantal keer dat de targets zijn opgelicht


void setup() {
  Serial.begin(9600);
  pinMode(A0, INPUT);   //lichtsensor 1
  pinMode(A1, INPUT);   //lichtsensor 2
  pinMode(A2, INPUT);   //lichtsensor 3
  pinMode(10, OUTPUT);  //ledje 1
  pinMode(5, OUTPUT);   //ledje 2
  pinMode(3, OUTPUT);   //ledje 3
  pinMode(11, OUTPUT);  //groene led
  pinMode(6, OUTPUT);   //rode led
  TargetSelect();       //roept functie de random target selecteert
}


void loop() {


  //kijkt of er licht in sensor zit, sensor 1
  int value1 = analogRead(A0);
  //Serial.println(value1); //voor afstellen van de juiste grenswaarde
  if (value1 <= 95) {  //als licht gelijk is aan of kleiner is dan 95 raak je de target (kleinere waarde is feller licht)
    hit1 = true;
  } else {
    hit1 = false;
  }


  // kijkt of er licht in sensor zit, sensor 2
  int value2 = analogRead(A1);
  //Serial.println(value2);
  if (value2 <= 95) {
    hit2 = true;
  } else {
    hit2 = false;
  }


  // kijkt of er licht in sensor zit, sensor 3
  int value3 = analogRead(A2);
  //Serial.println(value3);
  if (value3 <= 95) {
    hit3 = true;
  } else {
    hit3 = false;
  }


  TimerRunning(TargetNum);  //roept functie aan die desbetreffende LEDjes laat branden voor de juiste target
}


//RANDOM TARGET SELECT
void TargetSelect() {  //functie voor random geselecteerde target
  TargetNum = int(random(1, 4));
  //Serial.println(TargetNum); //om in de console te zien welk target actief is
  rounds++;  //er wordt een ronde bij op geteld
}


void TargetHit(int LEDNum) {  //functie die code van target raken uitvoert
  tone(8, 900, 20);           //geluidje buzzer: pin van buzzer in arduino, frequentie, lengte
  digitalWrite(11, HIGH);     //groene LED brandt
  delay(1000);                //pauze zodat je de LED ziet branden
  interval -= 100;            //kortere tijdsinterval tussen rondes
  if (interval <= 1999) {     //minimale tijdslimiet: het tijdsinterval wordt omhooggebracht naar 2000 ms als die eronder kwam
    interval = 2000;          //minimum tijd
  }
  digitalWrite(11, LOW);      //groene LED uit
  digitalWrite(LEDNum, LOW);  //target LED uit
  score++;                    //score omhoog met 1 punt
  PrintScore();               //roept functie aan om de score in de console weer te geven
  delay(500);
  TargetSelect();  //nieuwe target wordt uitgekozen
}


void PrintScore() {  //functie om de score in console weer te geven "score: score / rondes" en "interval: tijdsinterval tussen rondes"
  Serial.print("score: ");
  Serial.print(score);
  Serial.print(" / ");
  Serial.println(rounds);
  Serial.print("interval: ");
  Serial.println(interval);
}


void TimerRunning(int target) {
  //remap zodat de target int gelijk staat aan het nummer van het ledje
  int targetLed;              //variabele van opslaan van juiste LEDje voor een target
  if (target == 1) {          //als de random target de 1e target is:
    targetLed = 10;           //dan hoort LEDje 10 erbij
    //Serial.println("LED 10");
  } else if (target == 2) {  //als de random target de 2e target is:
    targetLed = 5;           //dan hoort LEDje 5 erbij
    //Serial.println("LED 5");
  } else if (target == 3) {  //als de random target de eerste target is:
    targetLed = 3;           //dan hoort LEDje 3 erbij
    //Serial.println("LED 3");
  }


  //statement om te kijken of je de juiste target raakt als die actief is
  bool hitTarget = false;             //geeft door of de code van het daadwerkelijke raken uitgevoerd mag worden
  if (target == 1 && hit1 == true) {  //als target 1 actief is en geraakt is:
    hitTarget = true;
  } else if (target == 2 && hit2 == true) {
    hitTarget = true;
  } else if (target == 3 && hit3 == true) {
    hitTarget = true;
  }


  unsigned long currentMillis = millis();  //krijg de huidige tijd sinds het opstarten van het programma in milliseconden


  digitalWrite(6, LOW);  //rode led uit, zodat deze alleen brandt wanneer het moet


  if ((currentMillis - previousMillis) >= interval) {  //wanneer de huidige tijd groter is dan het interval (tijd is voorbij):
    if (hitTarget == false) {                          //target is niet op tijd geraakt
      tone(8, 240, 80);                                //lage toon
      digitalWrite(targetLed, LOW);                    //LEDje van target gaat uit
      digitalWrite(6, HIGH);                           //rode led aan
      interval += 100;                                 //langere tijdsinterval voor betere kansen in de volgende ronde
      PrintScore();                                    //laat score zien in console
      delay(1500);                                     //pauze van 1,5 seconde
      TargetSelect();                                  //nieuwe target selecteren
    }
    previousMillis = currentMillis;    // Reset de timer
  } else {                             //als de timer nog niet voorbij is:
    digitalWrite(targetLed, HIGH);     //target LED van nieuwe random target staat aan
    if (hitTarget == true) {           //als de target geraakt wordt:
      TargetHit(targetLed);            //roept functie die code van het geraakte target uitvoert
      previousMillis = currentMillis;  //reset de timer
    }
  }
}


Behuizing Ontwerpen

target schetsen moveable.png
target schetsen rond als blazoen.png
target schetsen big plank decals.png
target schetsen big plank.png

Verzin en schets wat leuke ideeen voor je behuizing. Misschien wil je het op een groot bord doen, waarbij je op figuurtjes moet schieten. Misschien kan je bewegende targets maken, of targets die je kan ophangen of verplaatsen.

Ik heb wat van mijn schetsen toegevoegd, en heb de eerste gekozen. Dat zijn targets die met lange draden vastzitten aan de centrale behuizing, waar de arduino in komt. Door de targets los te houden kan je ze neerzetten waar je wil, wat meer vrijheid en speelvariatie geeft.

Behuizing Lasersnijden

IMG_3862.jpeg
IMG_3859.jpeg
Schermafbeelding 2024-03-30 193247.png
Schermafbeelding 2024-03-30 194345.png

Als je de behuizing net als mij gaat lasersnijden, moet je eerst een bestand daarvoor maken. Ik heb dat gedaan door gegenereerde doosjes als basis te gebruiken en in Adobe Illustrator details toe te voegen.

De website die ik heb gebruikt voor de basis: Boxes.py

De behuizing van mijn targets zijn 10x10x4 cm, en de behuizing van de arduino en aanhang is 17x15x10 cm. In de bijlage staan van beide de DXF en de SVG bestanden. Ik heb zwart MDF gebruikt van 3mm dik.

Zorg er wel voor dat al je lampjes en sensoren in de gaatjes kunnen passen, stem dit af op jouw onderdelen.

Soldeertijd!

Schermafbeelding 2024-03-30 230015.png
Schermafbeelding 2024-03-30 230225.png
IMG_3887.JPG
IMG_3907.JPG
IMG_3928.jpeg
IMG_3933.jpeg
IMG_3934.jpeg

Nu je de behuizing voor je hebt liggen, kunnen we alles gaan solderen! Maak van tevoren een overzichtje van hoe je alles wilt verbinden op het printplaatje, ter verduidelijking voor jezelf. Het is beter om van tevoren zeker te weten hoe je het wil solderen dan halverwege erachter komen dat je iets belangrijks bent vergeten.

BELANGRIJK: zorg dat je de draden van de LEDjes en lichtsensoren die naar de targets gaan gelijk door de behuizing doet voordat je het vast gaat solderen. Anders moet je ze doorknippen en opnieuw solderen!

Nog een tip: organiseer de draden met tape. Alle draden die naar hetzelfde target lopen kan je samenvoegen voor overzichtelijkheid.

Testen En Afwerken

IMG_3938.jpeg
IMG_3939.jpeg
IMG_3947.jpeg
IMG_3948.jpeg
IMG_3956.PNG

Als je alles gesoldeerd hebt, is het goed om te testen of het werkt. Check of je alle draadjes aangesloten hebt op de juiste pinnen, dat er niks tegen elkaar aan zit en dat de stroomcircuits helemaal rond gaan. Test vervolgens of alle lampjes branden en sensoren werken. Hopelijk doet ie het in 1 keer!

Nu kan je gaan afwerken.

Zet alles extra vast met wat lijm, en tape de draden dichter bij elkaar voor een afgewerkte look. Zorg ervoor dat alles stevig genoeg is, zodat je het zonder zorgen kan oppakken en verplaatsen. Het is handig om ook een tierap om de draden heen te doen waar ze naar buiten gaan en dit te verzekeren met lijm. Mocht er druk op komen te staan, kunnen ze net iets meer aan.

Playtesting En Code Aanpassen Voor Betere Flow

Lasergame Arcade Showcase
IMG_3965.jpeg
IMG_3956.PNG

Alles werkt en zit goed vast! Nu kan je het leukste doen: je spel spelen! En de code aanpassen zodat het zo fijn mogelijk speelt. Probeer wat met de tijdsintervallen, of maak bijvoorbeeld een systeem waarbij je levens hebt als je wil!

Nu heb je je eigen lasergame arcade! Veel speelplezier!