Innholdsfortegnelse:
Video: Arduino-kontrollert plattformspill med joystick og IR-mottaker: 3 trinn (med bilder)
2024 Forfatter: John Day | [email protected]. Sist endret: 2024-01-30 11:25
I dag skal vi bruke en Arduino mikrokontroller for å kontrollere et enkelt C#-basert plattformspill. Jeg bruker Arduino til å ta inngang fra en joystick -modul, og sende denne inngangen til C# -programmet som lytter og dekoder input over en seriell tilkobling. Selv om du ikke trenger noen tidligere erfaring med å bygge videospill for å fullføre prosjektet, kan det ta litt tid å absorbere noen av tingene som skjer i "spillløkken", som vi vil diskutere senere.
For å fullføre dette prosjektet trenger du:
- Visual Studio Community
- En Arduino Uno (eller lignende)
- En styrespakskontrollmodul
- Tålmodighet
Hvis du er klar til å begynne, fortsett!
Trinn 1: Koble til styrespaken og IR -LED
Her er tilkoblingen ganske enkel. Jeg har inkludert diagrammer som viser bare styrespaken koblet til, samt oppsettet jeg bruker, som inkluderer joysticken pluss en infrarød LED for å kontrollere spillet med en fjernkontroll, som følger med mange Arduino -sett. Dette er valgfritt, men det virket som en kul idé å kunne spille trådløst.
Pinnene som ble brukt i oppsettet er:
- A0 (analog) <- Horisontal eller X-akse
- A1 (analog) <- Vertikal eller Y-akse
- Pin 2 <- Joystick Switch inngang
- Pin 2 <- Infrarød LED-inngang
- VCC <- 5V
- Bakke
- Bakken #2
Trinn 2: Lag en ny skisse
Vi starter med å lage vår Arduino skissefil. Dette undersøker styrespaken for endringer, og sender endringene til C# -programmet hvert flere millisekund. I et faktisk videospill ville vi sjekke seriell port i en spillløkke for input, men jeg begynte spillet som et eksperiment, så frameraten er faktisk basert på antall hendelser på serieporten. Jeg hadde faktisk startet prosjektet i Arduino søsterprosjektet, Processing, men det viser seg at det var mye, mye tregere og ikke kunne håndtere antall bokser på skjermen.
Så, opprett først en ny skisse i Arduino -koderedigeringsprogrammet. Jeg vil vise koden min og deretter forklare hva den gjør:
#include "IRremote.h"
// IR -variabler int mottaker = 3; // Signalpinne av IR -mottaker IRrecv irrecv (mottaker); // lage forekomst av 'irrecv' decode_results resultater; // opprett forekomst av 'decode_results' // Joystick/game variables int xPos = 507; int yPos = 507; byte joyXPin = A0; byte joyYPin = A1; byte joySwitch = 2; flyktig byte clickCounter = -1; int minMoveHigh = 530; int minMoveLow = 490; int currentSpeed = 550; // Standard = gjennomsnittlig hastighet int speedIncrement = 25; // Mengde for å øke/redusere hastigheten med Y -inngang usignert langstrøm = 0; // Holder gjeldende tidsstempel int wait = 40; // ms for å vente mellom meldingene [Merk: lavere ventetid = raskere framerate] volatile bool buttonPressed = false; // Måler hvis du trykker på knappen void setup () {Serial.begin (9600); pinMode (joySwitch, INPUT_PULLUP); attachInterrupt (0, hopp, FALLING); nåværende = millis (); // Konfigurer gjeldende tid // Konfigurer infrarød mottaker: irrecv.enableIRIn (); // Start mottakeren} // setup void loop () {int xMovement = analogRead (joyXPin); int yPos = analogRead (joyYPin); // Håndter joystick X -bevegelsen uavhengig av timing: hvis (xMovement> minMoveHigh || xMovement current + wait) {currentSpeed = yPos> minMoveLow && yPos <minMoveHigh // Hvis bare flyttet litt …? currentSpeed // … bare returner gjeldende hastighet: getSpeed (yPos); // Endre bare yPos hvis joysticken flyttes betydelig // int distance =; Serial.print ((String) xPos + "," + (String) yPos + ',' + (String) currentSpeed + '\ n'); nåværende = millis (); }} // loop int getSpeed (int yPos) {// Negative verdier indikerer joysticken flyttet opp hvis (yPos 1023? 1023: currentSpeed + speedIncrement;} annet hvis (yPos> minMoveHigh) // Tolkes "ned" {// Beskytt mot går under 0 return currentSpeed - speedIncrement <0? 0: currentSpeed - speedIncrement;}} // getSpeed void jump () {buttonPressed = true; // Angi at knappen ble trykket.} // hopp // Når en knapp trykkes på fjernkontroll, håndter riktig svar void translateIR (decode_results results) // tar handling basert på mottatt IR -kode {switch (results.value) {case 0xFF18E7: //Serial.println("2 "); currentSpeed += speedIncrement * 2; break; case 0xFF10EF: //Serial.println("4 "); xPos = -900; break; case 0xFF38C7: //Serial.println("5"); jump (); break; case 0xFF5AA5: // Serial. println ("6"); xPos = 900; break; case 0xFF4AB5: //Serial.println("8 "); currentSpeed -= speedIncrement * 2; break; default: //Serial.println (" annen knapp "); pause;} // Sluttbryter} // SLUTT translateIR
Jeg prøvde å lage koden for å være mest selvforklarende, men det er noen ting som er verdt å nevne. En ting jeg prøvde å gjøre rede for var i følgende linjer:
int minYMoveUp = 520;
int minYMoveDown = 500;
Når programmet kjører, har den analoge inngangen fra styrespaken en tendens til å hoppe rundt, vanligvis på rundt 507. For å korrigere dette endres ikke inngangen med mindre den er større enn minYMoveUp, eller mindre enn minYMoveDown.
pinMode (joySwitch, INPUT_PULLUP);
attachInterrupt (0, hopp, FALLING);
Ved hjelp av attachInterrupt () -metoden kan vi når som helst avbryte den normale sløyfen, slik at vi kan ta innspill, for eksempel trykk på knappen når du klikker på styrespaken. Her har vi festet avbruddet i linjen før det, ved hjelp av pinMode () -metoden. En viktig merknad her er at for å feste en avbrudd på Arduino Uno, må du bruke enten pin 2 eller 3. Andre modeller bruker forskjellige interrupt pins, så du må kanskje sjekke hvilke pins din modell bruker på Arduino nettstedet. Den andre parameteren er for tilbakeringingsmetoden, her kalt en ISR eller en "Interrupt Service Routine". Det skal ikke ta noen parametere eller returnere noe.
Serial.print (…)
Dette er linjen som sender dataene våre til C# -spillet. Her sender vi avlesning av X-aksen, avlesning av Y-aksen og en hastighetsvariabel til spillet. Disse avlesningene kan utvides til å inkludere andre innganger og avlesninger for å gjøre spillet mer interessant, men her vil vi bare bruke et par.
Hvis du er klar til å teste koden, laster du den opp til Arduino og trykker på [Shift] + [Ctrl] + [M] for å åpne den serielle skjermen og se om du får utgang. Hvis du mottar data fra Arduino, er vi klare til å gå videre til C# -delen av koden …
Trinn 3: Opprett C# -prosjektet
For å vise grafikken vår startet jeg først et prosessprosjekt, men bestemte meg senere for at det ville være for sakte å vise alle objektene vi må vise. Så jeg valgte å bruke C#, som viste seg å være mye jevnere og mer lydhør når vi håndterte innspillene våre.
For C# -delen av prosjektet er det best å bare laste ned.zip -filen og pakke den ut til sin egen mappe, og deretter endre den. Det er to mapper i zip -filen. For å åpne prosjektet i Visual Studio, skriv inn mappen RunnerGame_CSharp i Windows Utforsker. Dobbeltklikk på.sln-filen (løsning), og VS vil laste inn prosjektet.
Det er noen forskjellige klasser jeg laget for spillet. Jeg vil ikke gå inn på alle detaljene om hver klasse, men jeg vil gi en oversikt over hva hovedklassene er for.
Boksklassen
Jeg opprettet bokseklassen slik at du kan lage enkle rektangelobjekter som kan tegnes på skjermen i et Windows-skjema. Ideen er å lage en klasse som kan utvides ved hjelp av andre klasser som kanskje vil tegne en slags grafikk. Det "virtuelle" søkeordet brukes slik at andre klasser kan overstyre dem (ved å bruke søkeordet "overstyr"). På den måten kan vi få samme oppførsel for Player -klassen og Platform -klassen når vi trenger det, og også endre objektene slik vi trenger det.
Ikke bekymre deg for mye om alle egenskapene og trekk samtaler. Jeg skrev denne klassen slik at jeg kunne utvide den til alle spill eller grafikkprogrammer jeg kanskje vil lage i fremtiden. Hvis du bare trenger å tegne et rektangel i farten, trenger du ikke å skrive ut en stor klasse som denne. C# -dokumentasjonen har gode eksempler på hvordan du gjør dette.
Imidlertid vil jeg legge ut noen av logikken i min "Box" -klasse:
offentlig virtuell bool IsCollidedX (Box otherObject) {…}
Her sjekker vi kollisjoner med objekter i X-retningen, fordi spilleren bare trenger å se etter kollisjoner i Y-retningen (opp og ned) hvis han er stilt opp med den på skjermen.
offentlig virtuell bool IsCollidedY (Box otherObject) {…}
Når vi er over eller under et annet spillobjekt, ser vi etter Y -kollisjoner.
offentlig virtuell bool IsCollided (Box otherObject) {…}
Dette kombinerer X- og Y -kollisjoner, og returnerer om et objekt blir kollidert med dette.
offentlig virtuelt tomrom OnPaint (grafikkgrafikk) {…}
Ved å bruke metoden ovenfor, sender vi ethvert grafikkobjekt inn og bruker det mens programmet kjører. Vi lager alle rektangler som må trekkes. Dette kan imidlertid brukes til en rekke animasjoner. For våre formål vil rektangler gjøre det bra for både plattformene og spilleren.
Karakterklassen
Character -klassen utvider Box -klassen min, så vi har viss fysikk ut av esken. Jeg opprettet "CheckForCollisions" -metoden for å raskt kontrollere alle plattformene vi har opprettet for en kollisjon. "Jump" -metoden setter spillerens hastighet oppover til JumpSpeed-variabelen, som deretter blir endret bilde for bilde i MainWindow-klassen.
Kollisjoner håndteres litt annerledes her enn i Box -klassen. Jeg bestemte meg i dette spillet at hvis vi hopper oppover, kan vi hoppe gjennom en plattform, men det vil fange spilleren vår på vei ned hvis den kolliderer med den.
Plattformklassen
I dette spillet bruker jeg bare konstruktøren av denne klassen som tar en X-koordinat som inngang, som beregner alle plattformenes X-steder i MainWindow-klassen. Hver plattform er satt opp med en tilfeldig Y-koordinat fra 1/2 skjermen til 3/4 av skjermens høyde. Høyden, bredden og fargen genereres også tilfeldig.
MainWindow -klassen
Det er her vi legger all logikken som skal brukes mens spillet er i gang. Først, i konstruktøren, skriver vi ut alle COM -portene som er tilgjengelige for programmet.
foreach (strengport i SerialPort. GetPortNames ())
Console. WriteLine ("TILGJENGELIGE PORTER:" + port);
Vi velger hvilken vi vil godta kommunikasjon på, i henhold til hvilken port din Arduino allerede bruker:
SerialPort = ny SerialPort (SerialPort. GetPortNames () [2], 9600, Parity. None, 8, StopBits. One);
Vær nøye med kommandoen: SerialPort. GetPortNames () [2]. [2] angir hvilken serieport som skal brukes. For eksempel, hvis programmet skrev ut "COM1, COM2, COM3", ville vi lytte på COM3 fordi nummereringen begynner med 0 i matrisen.
Også i konstruktøren lager vi alle plattformene med semi-tilfeldig avstand og plassering i Y-retningen på skjermen. Alle plattformene legges til i et listeobjekt, som i C# ganske enkelt er en veldig brukervennlig og effektiv måte å administrere en matriselignende datastruktur. Vi oppretter deretter spilleren, som er vårt karakterobjekt, setter poengsummen til 0 og setter GameOver til false.
private static void DataReceived (objektavsender, SerialDataReceivedEventArgs e)
Dette er metoden som kalles når data mottas på serieporten. Det er her vi bruker all vår fysikk, bestemmer om vi skal vise spillet over, flytte plattformene osv. Hvis du noen gang har bygget et spill, har du vanligvis det som kalles en "game loop", som kalles hver gang rammen oppdateres. I dette spillet fungerer DataReceived -metoden som spillsløyfen, og manipulerer bare fysikken ettersom data mottas fra kontrolleren. Det kunne ha fungert bedre å sette opp en timer i hovedvinduet og oppdatere objektene basert på mottatte data, men siden dette er et Arduino -prosjekt, ønsket jeg å lage et spill som faktisk kjørte basert på dataene som kom inn fra det.
Avslutningsvis gir dette oppsettet et godt grunnlag for å utvide spillet til noe brukbart. Selv om fysikken ikke er helt perfekt, fungerer den godt nok til våre formål, det vil si å bruke Arduino til noe alle liker: å spille spill!
Anbefalt:
Kontrollere 2 servoer ved hjelp av analog joystick .: 5 trinn (med bilder)
Kontrollere 2 servoer ved hjelp av analog joystick .: Hei folkens, dette er min første instruks, og i dette innlegget deler jeg hvordan du bruker Analog Joystick til å kontrollere servoer ved hjelp av Arduino UNO. Jeg skal prøve å forklare det så enkelt som mulig håper du liker den
Plattformspill med uendelige nivåer på GameGo med Makecode Arcade: 5 trinn (med bilder)
Plattformspill med uendelige nivåer på GameGo med Makecode Arcade: GameGo er en Microsoft Makecode -kompatibel retro spillkonsoll utviklet av TinkerGen STEM education. Den er basert på STM32F401RET6 ARM Cortex M4 -brikken og laget for STEM -lærere eller bare folk som liker å ha det gøy med å lage retro videospill
Slik demonterer du en datamaskin med enkle trinn og bilder: 13 trinn (med bilder)
Slik demonterer du en datamaskin med enkle trinn og bilder: Dette er en instruksjon om hvordan du demonterer en PC. De fleste grunnkomponentene er modulære og fjernes lett. Det er imidlertid viktig at du er organisert om det. Dette vil bidra til å hindre deg i å miste deler, og også i å gjøre monteringen igjen
Bruke PSP som datamaskin joystick og deretter kontrollere datamaskinen med PSP: 5 trinn (med bilder)
Bruke PSP som datamaskin joystick og deretter kontrollere datamaskinen din med PSP: Du kan gjøre mange kule ting med PSP homebrew, og i denne instruksen vil jeg lære deg hvordan du bruker PSP som en joystick for å spille spill, men det er også et program som lar deg bruke joysticken som musen. Her er materien
Mini joystick med brannknapp: 9 trinn (med bilder)
Mini joystick med brannknapp: Dette er en miniatyr joystick laget av noen få brytere og en kulepenn. En valgfri brannknapp kan legges til hvis pennen din er klikkertype. Handlingen er veldig jevn og lydhør. En liten bakhistorie følger så hoppe over den og få