Мазмұны:

Джойстик пен инфрақызыл қабылдағышпен Arduino басқарылатын платформалық ойын: 3 қадам (суреттермен)
Джойстик пен инфрақызыл қабылдағышпен Arduino басқарылатын платформалық ойын: 3 қадам (суреттермен)
Anonim
Джойстик пен инфрақызыл қабылдағышпен Arduino басқарылатын платформалық ойын
Джойстик пен инфрақызыл қабылдағышпен Arduino басқарылатын платформалық ойын

Бүгін біз Arduino микроконтроллерін қолданып, C#негізіндегі қарапайым платформерлік ойынды басқарамыз. Мен Arduino -ді джойстик модулінен енгізу үшін қолданамын және бұл кірісті сериялық қосылым арқылы тыңдайтын және декодтайтын C# қосымшасына жіберемін. Жобаны аяқтау үшін сізге бейне ойындар құруда бұрынғы тәжірибе қажет болмаса да, «ойын циклінде» болып жатқан кейбір нәрселерді сіңіру үшін біраз уақыт қажет болуы мүмкін, оны біз кейінірек талқылаймыз.

Бұл жобаны аяқтау үшін сізге қажет:

  • Visual Studio қауымдастығы
  • Arduino Uno (немесе ұқсас)
  • Джойстик контроллері модулі
  • Шыдамдылық

Егер сіз бастауға дайын болсаңыз, жалғастырыңыз!

1 -қадам: джойстик пен IR светодиодын қосыңыз

Джойстик пен IR светодиодын қосыңыз
Джойстик пен IR светодиодын қосыңыз
Джойстик пен IR светодиодын жалғаңыз
Джойстик пен IR светодиодын жалғаңыз

Мұнда қосылу өте қарапайым. Мен тек джойстик қосылған схемаларды, сондай -ақ мен қолданатын қондырғыны енгіздім, оған джойстик пен ойынға қашықтан басқару пультімен басқаруға арналған инфрақызыл жарық диоды кіреді, ол көптеген Arduino жиынтықтарымен бірге келеді. Бұл міндетті емес, бірақ сымсыз ойынмен айналысу керемет идея болып көрінді.

Орнату кезінде түйреуіштер қолданылады:

  • A0 (аналогты) <- Көлденең немесе X осі
  • A1 (аналогты) <- Тік немесе Y осі
  • 2 түйреуіш <- джойстик қосқышының кірісі
  • Pin 2 <- инфрақызыл жарықдиодты кіріс
  • ВК <- 5В
  • Жер
  • №2 жер

2 -қадам: Жаңа эскиз жасаңыз

Жаңа эскиз жасаңыз
Жаңа эскиз жасаңыз

Біз Arduino эскиз файлын құрудан бастаймыз. Бұл өзгерістер үшін джойстикті сұрайды және бұл өзгерістерді бірнеше миллисекунд сайын C# бағдарламасына жібереді. Нақты бейне ойынында біз кіру үшін ойын цикліндегі сериялық портты тексеретін едік, бірақ мен ойынды эксперимент ретінде бастадым, сондықтан кадр жиілігі сериялық порттағы оқиғалар санына негізделген. Мен жобаны Arduino әпкесі өңдеуде бастадым, бірақ ол әлдеқайда баяу болды және экрандағы қораптардың санын өңдей алмады.

Сонымен, алдымен Arduino код редакторында жаңа эскиз жасаңыз. Мен кодты көрсетемін, содан кейін ол не істейтінін түсіндіремін:

#«IRremote.h» қосыңыз

// IR қабылдағыштары int қабылдағыш = 3; // IR қабылдағышының IR түйрегішінің сигнал түйіні IRrecv irrecv (қабылдағыш); // decode_results нәтижелерінің «irrecv» данасын құру; // «decode_results» данасын құру // джойстик/ойын айнымалы int xPos = 507; int yPos = 507; байт joyXPin = A0; байт қуанышYPin = A1; байт joySwitch = 2; тұрақсыз байт clickCounter = -1; int minMoveHigh = 530; int minMoveLow = 490; int currentSpeed = 550; // Әдепкі = int speedIncrement = 25 орташа жылдамдығы; // Y кіруімен жылдамдықты жоғарылату/төмендету сомасы белгісіз ұзақ ток = 0; // ағымдағы уақыт белгісін ұстайды int wait = 40; хабарлар арасында күту үшін // ms [Ескертпе: күтудің төмендеуі = жылдамдықтың жиілігі] тұрақсыз бол түймесі Pressed = false; // Өлшеу, егер түйме басылса, void setup () {Serial.begin (9600); pinMode (joySwitch, INPUT_PULLUP); attachInterrupt (0, секіру, FALLING); ағымдағы = миллис (); // Ағымдағы уақытты орнату // Инфрақызыл қабылдағышты орнату: irrecv.enableIRIn (); // Ресиверді іске қосыңыз} // void loop орнату () {int xMovement = analogRead (joyXPin); int yPos = analogRead (joyYPin); // Joystick X қозғалысын уақытқа қарамай өңдеңіз: if (xMovement> minMoveHigh || xMovement ағымдағы + күту) {currentSpeed = yPos> minMoveLow && yPos <minMoveHigh // Егер сәл ғана қозғалсаңыз…? currentSpeed //… тек ағымдағы жылдамдықты қайтарыңыз: getSpeed (yPos); // Тек джойстик айтарлықтай қозғалғанда yPos өзгертіңіз // int қашықтық =; Serial.print ((String) xPos + «,» + (String) yPos + ',' + (String) currentSpeed + '\ n'); ағымдағы = миллис (); }} // loop int getSpeed (int yPos) {// Теріс мәндер Джойстиктің жоғары жылжытылғанын көрсетеді, егер (yPos 1023? 1023: currentSpeed + speedIncrement;} if else (yPos> minMoveHigh) // «Төмен» деп түсіндіріледі {// Қорғау 0 қайтару ағымдағы Жылдамдық - жылдамдық өсуі <0? 0: currentSpeed - speedIncrement;}} // getSpeed void jump () {buttonPressed = true; // Көрсету батырмасы басылды.} // секіру // Түйме басылғанда қашықтан басқару, дұрыс жауап void translateIR (decode_results нәтижелері) // алынған IR коды негізінде әрекет етеді {switch (results.value) {case 0xFF18E7: //Serial.println("2 «); currentSpeed += speedIncrement * 2; үзіліс; жағдай 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 (» басқа түйме «); үзіліс;} // Аяқтау қосқышы} // Аударуды аяқтауIRIR

Мен кодты өздігінен түсінікті етіп жасауға тырыстым, бірақ айта кету керек бірнеше нәрсе бар. Мен есептеуге тырысқан бір нәрсе келесі жолдарда болды:

int minYMoveUp = 520;

int minYMoveDown = 500;

Бағдарлама жұмыс істеп тұрған кезде джойстиктен аналогтық кіріс секіруге бейім, әдетте 507 шамасында қалады. Бұны түзету үшін енгізу minYMoveUp -ден үлкен немесе minYMoveDown -дан кіші болмаса өзгермейді.

pinMode (joySwitch, INPUT_PULLUP);

attachInterrupt (0, секіру, FALLING);

AttachInterrupt () әдісі кез келген уақытта қалыпты циклды үзуге мүмкіндік береді, осылайша біз джойстик батырмасы басылған кезде батырманы басу сияқты кірісті аламыз. Мұнда біз pinMode () әдісін қолдана отырып, үзілісті алдыңғы жолға тіркедік. Бұл жерде маңызды ескерту - Arduino Uno -да үзіліс орнату үшін сізге 2 немесе 3 -ші түйреуіштерді қолдану қажет. Басқа модельдерде әр түрлі үзу түйреуіштері қолданылады, сондықтан сіздің модель Arduino веб -сайтында қандай түйреуіштерді қолданатынын тексеру қажет болуы мүмкін. Екінші параметр кері байланыс әдісіне арналған, бұл жерде ISR немесе «Үзіліс қызметі» деп аталады. Ол ешқандай параметрлерді қабылдамауы немесе ештеңені қайтармауы керек.

Serial.print (…)

Бұл біздің деректерді C# ойынына жіберетін желі. Мұнда біз X осінің оқуын, Y осінің оқуын және жылдамдық айнымалысын ойынға жібереміз. Бұл оқылымды ойынның қызықты болуы үшін басқа кірістер мен оқуларды қосу үшін кеңейтуге болады, бірақ мұнда біз тек жұпты қолданамыз.

Егер сіз кодты тексеруге дайын болсаңыз, оны Arduino -ға жүктеп, [Shift] + [Ctrl] + [M] пернелерін басып, сериялық мониторды ашыңыз және сізде қандай да бір нәтиже бар -жоғын білу үшін. Егер сіз Arduino -дан деректер алсаңыз, біз кодтың C# бөлігіне өтуге дайынбыз …

3 -қадам: C# жобасын жасаңыз

Біздің графиканы көрсету үшін мен бастапқыда Процессингте жобаны бастадым, бірақ кейін біз көрсетуге қажет барлық объектілерді көрсету тым баяу болады деп шештім. Сонымен, мен C#-ді қолдануды таңдадым, ол біздің кірісті өңдеу кезінде әлдеқайда тегіс және тезірек болды.

Жобаның C# бөлігі үшін.zip файлын жүктеп алып, оны өз қалтасына шығарып алғаннан кейін оны өзгерткен дұрыс. ZIP файлында екі қалта бар. Жобаны Visual Studio -да ашу үшін Windows Explorer -де RunnerGame_CSharp қалтасын енгізіңіз. Мұнда.sln (шешім) файлын екі рет шертіңіз, сонда VS жобаны жүктейді.

Мен ойын үшін бірнеше түрлі сыныптар құрдым. Мен әр сынып туралы егжей -тегжейлі айтпай -ақ қояйын, бірақ мен негізгі сыныптар не үшін арналғанын шоламын.

Қорап класы

Мен терезе түрінде экранда салуға болатын қарапайым тіктөртбұрышты объектілерді жасауға мүмкіндік беру үшін қорап класын құрдым. Идея - графиканың қандай да бір түрін салғысы келетін басқа сыныптардың көмегімен кеңейтілетін сынып құру. «Виртуалды» кілт сөзі басқа сыныптар оларды алмастыруы үшін қолданылады («ауыстыру» кілт сөзі арқылы). Осылайша, біз қажет болған жағдайда Player класы мен Платформа класы үшін бірдей мінез -құлықты ала аламыз, сонымен қатар объектілерді қажет болған жағдайда өзгерте аламыз.

Барлық мүлік туралы көп уайымдамаңыз және қоңыраулар жасаңыз. Мен бұл сабақты болашақта жасағым келетін кез келген ойынға немесе графикалық бағдарламаға кеңейту үшін жаздым. Егер сізге бірден тіктөртбұрыш салу керек болса, онда мұндай үлкен сыныпты жазудың қажеті жоқ. C# құжаттамасында мұны қалай жасауға болатыны туралы жақсы мысалдар бар.

Дегенмен, мен «Box» сыныбының логикасын түсіндіремін:

жалпыға ортақ виртуалды бол IsCollidedX (Box otherObject) {…}

Мұнда біз X-бағыттағы объектілермен соқтығысуды тексереміз, себебі ойыншы тек экранда қатарға қойылған жағдайда Y бағытында (жоғары және төмен) соқтығысуды тексеруі қажет.

жалпыға ортақ виртуалды бол IsCollidedY (Box otherObject) {…}

Біз басқа ойын объектісінің үстінде немесе астында болған кезде, біз Y соқтығысуын тексереміз.

жалпыға ортақ виртуалды бол IsCollided (Box otherObject) {…}

Бұл X және Y соқтығысуын біріктіріп, кез келген объектінің соқтығысқанын қайтарады.

OnPaint жалпыға ортақ виртуалды жарамсыздығы (Графикалық графика) {…}

Жоғарыда көрсетілген әдісті қолдана отырып, біз кез келген графикалық объектіні жібереміз және оны бағдарлама жұмыс істеп тұрған кезде қолданамыз. Біз салу қажет болуы мүмкін кез келген тіктөртбұрышты жасаймыз. Бұл әр түрлі анимация үшін қолданылуы мүмкін. Біздің мақсатымыз үшін тіктөртбұрыш платформалар үшін де, ойнатқыш үшін де жақсы болады.

Таңбалар класы

Character класы менің Box сыныбымды кеңейтеді, сондықтан бізде белгілі бір физика бар. Мен соқтығысу үшін жасаған барлық платформаларды жылдам тексеру үшін «CheckForCollisions» әдісін жасадым. «Jump» әдісі ойыншының жоғары жылдамдығын JumpSpeed айнымалы мәніне қояды, содан кейін MainWindow класында кадрлық түрде өзгертіледі.

Бұл жерде қақтығыстар Box класына қарағанда сәл басқаша өңделеді. Мен бұл ойында мен жоғары секіретін болсақ, біз платформа арқылы секіре аламыз деп шештім, бірақ егер ол соқтығысса, біздің ойыншыны төмен түсетін жолда ұстайды.

Платформа класы

Бұл ойында мен тек X координатын енгізу ретінде осы сыныптың конструкторын қолданамын, MainWindow класындағы барлық платформалардың X орындарын есептеймін. Әрбір платформа кездейсоқ Y координатында экранның 1/2-ден 3/4 экран биіктігіне дейін орнатылады. Биіктігі, ені мен түсі де кездейсоқ түрде жасалады.

MainWindow класы

Бұл жерде біз ойын жүріп жатқан кезде қолданылатын барлық логиканы қоямыз. Біріншіден, конструкторда біз бағдарламада бар барлық COM портын басып шығарамыз.

foreach (SerialPort. GetPortNames ішіндегі жол порты))

Console. WriteLine («AVAILABLE PORTS:» + порт);

Біз коммуникацияларды қайсысы қабылдайтынын таңдаймыз, сіздің портқа сәйкес сіздің Arduino қазірдің өзінде қолданады:

SerialPort = жаңа SerialPort (SerialPort. GetPortNames () [2], 9600, Parity. None, 8, StopBits. One);

Пәрменге мұқият назар аударыңыз: SerialPort. GetPortNames () [2]. [2] қай сериялық портты қолдану керектігін білдіреді. Мысалы, егер бағдарлама «COM1, COM2, COM3» басып шығарса, біз COM3 тыңдайтын боламыз, себебі нөмірлеу массивте 0 -ден басталады.

Сонымен қатар конструкторда біз барлық платформаларды жартылай кездейсоқ интервалмен және экранда Y бағытында орналастырумен жасаймыз. Барлық платформалар List объектісіне қосылады, ол C# тілінде массивке ұқсас деректер құрылымын басқарудың өте ыңғайлы және тиімді әдісі болып табылады. Содан кейін біз кейіпкер объектісі болып табылатын Ойыншыны құрамыз, есепті 0 -ге орнатамыз және GameOver -ді жалғанға қоямыз.

жеке статикалық жарамсыз DataReceived (объект жіберуші, SerialDataReceivedEventArgs e)

Бұл сериялық портта деректер алынған кезде шақырылатын әдіс. Бұл жерде біз өзіміздің барлық физикамызды қолданамыз, ойынды көрсетуді, платформаларды жылжытуды және т.б. шешеміз. Егер сіз бұрын ойын ойнаған болсаңыз, әдетте сізде «ойын циклы» деп аталатын нәрсе бар, ол кадр сайын аталады. сергітеді. Бұл ойында DataReceived әдісі ойын циклы ретінде әрекет етеді, тек контроллерден деректер алынған кезде физиканы басқарады. Негізгі терезеде Таймерді орнатып, алынған деректерге негізделген объектілерді жаңарту жақсы жұмыс істеген болар еді, бірақ бұл Arduino жобасы болғандықтан, мен одан келіп түсетін деректерге сүйене отырып жұмыс істейтін ойын жасағым келді..

Қорытындылай келе, бұл орнату ойынды қолдануға болатын нәрсеге кеңейтуге жақсы негіз береді. Физика өте жетілмеген болса да, ол біздің мақсатымыз үшін жақсы жұмыс істейді, яғни Arduino -ны бәріне ұнайтын нәрсеге пайдалану: ойын ойнау!

Ұсынылған: