Мазмуну:

Ардуино - фортепиано плиткалары: 16 кадам (сүрөттөр менен)
Ардуино - фортепиано плиткалары: 16 кадам (сүрөттөр менен)

Video: Ардуино - фортепиано плиткалары: 16 кадам (сүрөттөр менен)

Video: Ардуино - фортепиано плиткалары: 16 кадам (сүрөттөр менен)
Video: ОГУРЕЧНОЕ ПИАНИНО | огуркофон? | электроогурцы? | собрал на arduino 2024, Июль
Anonim
Ардуино - фортепиано плиткалары
Ардуино - фортепиано плиткалары

Саламатсыздарбы интернет элдери, бул arduino uno r3төгү мобилдик оюнду СӨЗСҮЗ бузбоо керектиги жөнүндө болмокчу.

Ошентип, баштоо үчүн сизге төмөнкүдөй болгон бардык бөлүктөр керек! 1x Arduino Uno r3 ($ 42)

2x LCD баскыч калканы (ар бири 19 доллар)

5x баскычтар

5х 220Ω резисторлор

28x зымдар

Жарайт, бардык бөлүктөрдү алгандан кийин баштоого убакыт келди!

1 -кадам: Кабелдөө

Электр өткөргүчтөрү
Электр өткөргүчтөрү
Электр өткөргүчтөрү
Электр өткөргүчтөрү
Электр өткөргүчтөрү
Электр өткөргүчтөрү

Диаграммада көрсөтүлгөндөй ардуиноңузду жана досторуңузду туташтыруудан баштаңыз, Кнопкалардын туура жол менен байланыштырылгандыгын текшериңиз, баскычтын рельсинин астындагы A0-4 уячалары бар, же arduino анын ордуна баскычтар пресстин ордуна дайыма басылып турат деп ойлойт.

2 -кадам: Декларациялык билдирүүлөр

Бул жердеги бардык коддор боштук орнотууңузга жана боштук циклине чейин кетиши керек, анткени бул өзгөрмөлөрдүн жана объекттердин бардыгы биз орното турган бир нече функцияларда колдонулат.

Баштоо менен коюу:

#кошуу

кодуңуздун жогору жагында, бул arduinoго "LiquidCrystal.h" китепканасын жана анын бир бөлүгү болгон функцияларды колдонууну билдирет.

Кийинки кадам - бул кодду биздин #include астына коюу менен биз баскычтарыбыз үчүн колдонуп жаткан казыктарды аныктоо:

#аныктоо btnEnter A0 #аныктоо btn1 15 #аныктоо btn2 16 #аныктоо btn3 17 #аныктоо btn4 18

Биз кодду окуубузду жеңилдетүү үчүн btnEnter жана btn1ден btn 4кө чейинки терминдерди аныктайбыз же керек болсо өзгөртөбүз. Бул btn1 тергенде, ардуино чындыгында 15 баскычын билдирерин билебиз дегенди билдирет, биз 15, 16, 17 жана 18 портторун чакырып жатканыбызга карабастан, алар ардуинодо A1 A2 A3 жана A4 деп белгиленген, мунун себеби алар аналогдук кирүүлөр үчүн атайын колдонулган порттор, бирок биз аларды санариптик киргизүү үчүн гана колдонуп жатабыз.

Андан кийин биз Суюк Кристалл Дисплейлерди башкара турган объекттерди түзөбүз. Бул үчүн бул кодду биздин аныктамалардын астына коюңуз

LiquidCrystal lcdLeft (8, 9, 12, 10, 11, 13); LiquidCrystal lcdRight (2, 3, 4, 5, 6, 7);

Мунун эмне кылганы ардуиного lcdLeft же lcdRightке чалганда биз LiquidCrystal объектиси жөнүндө айтып жатканыбызды айтат. Тиркелген кашаанын ичиндеги сандар arduinoго биз алардын функцияларын колдонуп жатканда ЖКга билдирүүлөрдү жөнөтүү үчүн кайсы портторду колдонуу керектигин айтат.

Эми биз объектинин декларациясынын астына коддун кийинки битин коюп, өзгөрмөлөрдү жарыялашыбыз керек:

// бул өзгөрмөлөр сиз өзгөртө турган варианттар - жогорку сандар = оюндун ылдамдыгы intGameSpeedEasy = 10; int intGameSpeedMedium = 25; int intGameSpeedHard = 80;

// gameboolean bolPlay үчүн өзгөрмөлөрдү орнотуу; // тректер, эгерде оюнчу int intScore; // оюнчунун упайын көзөмөлдөйт int intiff; // жөн гана эстетикалык нерсе, оюндун кандай кыйынчылыкта экенин // int intEnter киргизүү үчүн өзгөрмөлөрдү орнотуу; // колдонуучу int intInput кирүү баскычын басса, көз салат; // колдонуучу логикалык bolTilePressed баскычтарын баскан тректер; // оюнчу кокусунан 5x кнопкасын басып кетпесин камсыз кылуу // int intTickти буруш үчүн өзгөрмөлөрдү орнотуу; // intDelay int intDelay чейин миллиге чейин эсептейт (циклге); // программанын кийинки кезекке чейин күткөн убактысы int intGameSpeed; // мүчүлүштүктөрдү оңдоо параметрлери логикалык bolSerialBoard; // качан true тактаны сериялык мониторго басып чыгарат

Биз маалыматтын түрүн, андан кийин өзгөрмөнүн атын билдирүү менен өзгөрмөнү жарыялайбыз, мис. int thisIsAnInteger

BolSerialBoard жана bolPlay сыяктуу логикалык өзгөрмөлөр чыныгы же жалган деген эки маанинин бирине гана ээ болушу мүмкүн.

IntScore жана intInput сыяктуу бүтүн өзгөрмө (int) бүтүн сандарды 1, 5 же 100 сыяктуу баалуулук катары кабыл алат.

Биз колдонбогон кээ бир башка көрүнүктүү маалымат түрлөрү - бул тексттин бир бөлүгү болгон сап жана ондук сан болгон калкыма.

Бул жердеги өзгөрмөлөрдүн ар бири программа тарабынан бир нече жерде колдонулат, бул жерде алардын ар бири эмне кылаары жөнүндө кыскача маалымат бар

bolPlay программага менюну көрсөтүү керекпи же чыныгы оюн иштеп жаткандыгын айтат.

intScore плиткаларды сүзгөндө оюнчунун упайын көзөмөлдөйт, intDiff негизги менюда ЖКга кайсы текстти басып чыгаруу керек экенин программага айтуу үчүн колдонулат, intEnter программага кирүү баскычы (эң сол жакта) басылганда айтуу үчүн колдонулат, intInput башка 4 баскычтын кайсынысы басылганын программага айтуу үчүн колдонулат.

bolTilePressed программасы баскыч басылганда гана окула тургандыгын текшерүү үчүн колдонулат, ал кармалып турганда эмес.

intGameSpeed, intGameSpeedEasy, intGameSpeedMedium жана intGameSpeedHard оюндун ылдамдыгын ылдамдатууну көзөмөлдөө үчүн колдонулат.

intTick жана intDelay программанын айланган сайын тактанын жылышын токтотуу үчүн колдонулат.

bolSerialBoard программаны тестирлөө үчүн ардуинонун сериялык мониторуна бир катар сандар катары жөнөтүүгө мүмкүнчүлүк берүү үчүн колдонулат.

Акыр -аягы, биздин кодду бул кодду колдонуп массив катары жарыялоонун убактысы келди:

// arrayint arrGame [16] [4] = {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}};

Массив - бул матрица, аны каалаган чекитти математикага чакырууга же өзгөртүүгө болот.

Сиздин кодуңуз ушул сыяктуу көрүнүшү керек;

// китепканаларды камтыйт#камтыйт

// бул өзгөрмөлөр сиз өзгөртө турган варианттар - жогорку сандар = оюндун ылдамдыгы

int intGameSpeedEasy = 10; int intGameSpeedMedium = 25; int intGameSpeedHard = 80;

// Пиндерди аныктоо

#define btnEnter A0 #define btn1 15 #define btn2 16 #define btn3 17 #define btn4 18

// LCD объектилерин түзүү (n, ~, n, ~, ~, n)

LiquidCrystal lcdLeft (8, 9, 12, 10, 11, 13); LiquidCrystal lcdRight (2, 3, 4, 5, 6, 7);

// оюн массивин орнотуу

int arrGame [16] [4] = {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}};

// оюн үчүн өзгөрмөлөрдү орнотуу

логикалык bolPlay; // tracks if player if intScore; // оюнчунун упайын көзөмөлдөйт int intiff; // жөн гана эстетикалык нерсе, оюндун кандай кыйынчылыкта экенин

// киргизүү үчүн өзгөрмөлөрдү орнотуу

int intEnter; // колдонуучу int intInput кирүү баскычын басса, көз салат; // колдонуучу логикалык bolTilePressed баскычтарын баскан тректер; // оюнчу кокусунан 5x кнопкасын басып койбосун камсыз кылыңыз

// бурулуш үчүн өзгөрмөлөрдү коюу

int intTick; // intDelay int intDelay чейин миллиге чейин эсептейт (циклге); // программанын кийинки кезекке чейин күткөн убактысы int intGameSpeed;

// мүчүлүштүктөрдү оңдоо мүмкүнчүлүктөрү

логикалык bolSerialBoard; // качан true тактаны сериялык мониторго басып чыгарат

3 -кадам: Орнотуу функциясы

Орнотуу цикли - бул ардуино башында баштаганда бир гана жолу окуган функция.

Орнотуу циклинде биз бир нече өзгөрмөлөрүбүздүн маанилерин жөн эле коюп жатабыз, анткени аларды жарыялоодо маанини коюунун ордуна биз муну бул жерде жасайбыз.

Бул кодду Void Setupка коюу менен баштаңыз.

bolPlay = false; intScore = 0; intTick = 0; intDelay = 1000; intDiff = 1; intGameSpeed = intGameSpeedMedium;

Ар бир сап жөн гана өзгөрмөнү мааниге коюп жатат.

bolPlay оюну ойноп баштабашы үчүн false деп коюлган.

intScore 0 коюлган, анткени табигый түрдө сиздин балл 0дөн башталат.

intTick 0ден башталат, анткени программа учурда эч нерсени эсептебейт.

intDelay 1000ге коюлган, анткени бул плиткалар баштала турган ылдамдык.

intDiff - бул жөн гана аскетикалык нерсе, ошондуктан программа оюндун татаалдыгы үчүн эмне жазууну билет.

intGameSpeed intGameSpeedMedium кандай гана болбосун коюлган, башкача айтканда ал орто кыйынчылыкта коюлган.

Андан кийин бул кодду сиз киргизген коддун астындагы Void Setupка коюңуз.

lcdLeft.begin (16, 2); lcdRight.begin (16, 2);

Serial.begin (9600);

Бул arduinoго компьютер менен сериялык монитор аркылуу байланышты баштоону айтат (arduino IDEдин жогорку оң жагындагы баскычты басуу менен көрүнөт).

Сиздин боштук орнотууңуз азыр ушундай көрүнүшү керек!

void setup () {Serial.begin (9600); // сериялык мониторду баштоо // өзгөрмөлөрдү коюу bolPlay = false; intScore = 0; intTick = 0; intDelay = 1000; intDiff = 1; intGameSpeed = intGameSpeedMedium; // begin lcd's lcdLeft.begin (16, 2); lcdRight.begin (16, 2); }

4 -кадам: Loop Function

Цикл функциясы ардуинонун ар бир итерациясын ардуино башкарат.

Төмөнкү кодду Void Loopко көчүрүңүз.

void loop () {input (); // if (bolPlay == true) if if (bolPlay == true) {if (intTick> = intDelay) {// оюндун бурулушу керекпи же жокпу Serial.println ("~~~~~~~ ~~ "); // басып чыгаруу, тактаны жылдырууну билдирүү үчүн // writeSerial (); // эгерде параметр иштетилген болсо, тактаны катарлык түймөлөргө жазгылаGame (); // оюнчу киргизүүлөрүн текшерүү playBoard (); // тактаны жылдыруу жана жаңы плитканы кошуу clearLcd (); // drawBoard () тартуудан мурун ЖКны тазалаңыз; // тактаны lcd түбүнө тартууCheck (); intTick = 0; // баштапкы абалга келтирүү intTick} башка {buttonGame (); // оюнчу киргизүүлөрүн текшерүү clearLcd (); // drawBoard () тартуудан мурун ЖКны тазалаңыз; // тактаны lcd's intTick = intTick + intGameSpeedге тартыңыз; // белгиге кошуу}} башка {clearLcd (); // аталышын тартуудан мурун ЖКны тазалаңыз (); // дисплейдин аталышы жана упай маалыматы баскычтарыMenu (); // оюнчу киргизүүнү окуу clearBoard (); // бүт коллегияны камсыз кылуу = 0} кечигүү (10); // ардуинону бир азга кечиктирүү}

качан bolPlay чындыкка барабар болсо, бул оюн ойноп жаткандыгын билдирет жана оюн качан ойногондугу үчүн бардык коддор иштетилиши керек, бирок биз intTick биздин intDelayден чоңураак болгондо тактанын жаңы плитканы кошуп, ылдый жылышын каалайбыз, антпесе, биз дагы эле колдонуучуга плитканы басуу үчүн баскычты басууга жана intTickтин ылдамдыгын жогорулатууга уруксат бергибиз келет.

Бул коддун көпчүлүгү биз жасай элек функцияларды колдонот жана биз аларды кийинки кадамдарда жасайбыз. Бул функциялардын максаты төмөндөгүдөй.

Кирүү колдонуучу кайсы баскычтарды басканын окуйт.

buttonGame баскычтар менюда эмес, оюнда эмне кылаарын көзөмөлдөйт

playBoard доскага жаңы плитканы кошот, андан кийин тактадагы бардыгын бир боштукка ылдый жылдырат

clearLCD плиткалардын артында эч кандай элестер калбашы үчүн ЖКны тазалайт

drawBoard arrGame аркылуу өтүп, аны ЖКга басып чыгарат

clearBoard оюн ойнобогондо arrGame бүт тазалайт

bottomCheck, arrGameдин астынкы катасын текшерет

аталышы менюда оюндун аталышын жана упай маалыматын көрсөтөт

баскычтар менюсу колдонуучунун киргизүүлөрү менюда эмне кылаарын көзөмөлдөйт.

gameOver - бул башка функция, бирок бул жерде чакырылбайт, бирок анын ордуна түбүндө текшерилет жана түймелери Оюн функциялары.

5 -кадам: ClearLCD функциясы

функцияны түзүү үчүн муну кодго кошуу менен баштайбыз

void functionName () {

}

"functionName" эч нерсе болушу мүмкүн, эгер ал жок болсо.

Бул кодду программаңызга көчүрүңүз:

void clearLcd () {for (int i = 0; i <= 15; i ++) {for (int ii = 0; ii <= 1; ii ++) {lcdLeft.setCursor (i, ii); lcdLeft.write (""); lcdRight.setCursor (i, ii); lcdRight.write (""); }}}

бул ЖКнын ар бир чекитинен өтүп, боштук жазуу үчүн 2 эсептелген циклди колдонуу менен бүт массивди аралап өтөт.

Эч нерсеге кайтарылбастан, ЖК мурда жазылган нерселерди сактап калат

6 -кадам: DrawBoard Функциясы

бул кодду программаңызга көчүрүңүз

void drawBoard () {for (int i = 1; i <= 15; i ++) {// сол LCDдеги 1 жана 2 колумдарды тарткыла // эгер плитка = 0 эч нерсе жазбаса, = 1 "#", = 2 деп жаз "@" lcdLeft.setCursor жаз (i, 1); // биринчи колумнга коюлган (эң алыскы сол) if (arrGame [0] == 1) {lcdLeft.write ("#");} if (arrGame [0] == 2) {lcdLeft.write ("@");} lcdLeft.setCursor (i, 0); // экинчи колумнга коюлган (борбордун сол жагында) if (arrGame [1] == 1) {lcdLeft.write ("#");} if (arrGame [1] == 2) {lcdLeft.write ("@");} lcdRight.setCursor (i, 1); // үчүнчү колумнга коюңуз (борбордун оң жагында) if (arrGame [2] == 1) {lcdRight.write ("#");} if (arrGame [2] == 2) {lcdRight.write ("@");} lcdRight.setCursor (i, 0); // төртүнчү колумнга коюлган (эң алыскы оңго) if (arrGame [3] == 1) {lcdRight.write ("#");} if (arrGame [3] == 2) {lcdRight.write ("@");}}}

Бул тактанын ар бир сабынан өтүү үчүн циклди колдонот, андан кийин катардагы кандайдыр бир мамыча 1 же 2ге барабар экенин текшерет, ошонун негизинде ал LCDге хэштег басып чыгарат хит, же хит плиткасы үчүн @.

7 -кадам: PlayBoard функциясы

бул кодду программаңызга көчүрүңүз.

void playBoard () {for (int i = 0; i <= 3; i ++) {arrGame [0] = 0;} // arrGame жогорку катарын тазалоо [0] [random (0, 4)] = 1; // жогорку катардагы туш келди чекитти коюңуз (int i = 15; i> = 1; i-) {// үчүн тактанын түбүнөн өйдө карай иштөө (int ii = 0; ii <= 3; ii ++) {// ар бир колум үчүн arrGame [ii] = arrGame [i - 1] [ii]; }}}

Бул код жогорку саптын баарын 0го чейин тазалоо менен башталат, же плиткасыз, андан кийин бир туш келди плитканы 1ге жана көрүнбөгөн плиткага коет.

Андан кийин 15тен 1ге чейин тескери эсептелген укуруктан өтөт, катарды үстүндөгү катар кандай болсо, ошого барабар кылып, такта ЖКнын ылдый жылышына шарт түзөт.

8 -кадам: ClearBoard Функциясы

бул кодду программаңызга көчүрүңүз.

void clearBoard () {// кенени баштапкы абалга келтирүү жана маанилерин кечиктирүү intTick = 0; intDelay = 1000; // доска аркылуу өтүп, баарын 0 үчүн коюңуз (int i = 0; i <= 15; i ++) {for (int ii = 0; ii <= 3; ii ++) {arrGame [ii] = 0; }}}

Бул код, arrGame толугу менен 0 коюлганына же плиткалары жок экенине ынануу үчүн, оюн ойнобогондо, массив аркылуу өтүү үчүн эсептелген циклдерди колдонуу менен иштейт.

Код ошондой эле intDelay жана intTick маанилерин баштапкы абалга келтирет.

9 -кадам: Аталыш функциясы

төмөнкү кодду программаңызга көчүрүңүз

void title () {// титулун LCDге жазуу жана lcdRight.setCursor упайы үчүн боштук (0, 0); lcdRight.write ("Фортепиано плиткалары"); lcdRight.setCursor (0, 1); lcdRight.write ("Упай:"); // упайды string strScoreга айландыруу [3]; sprintf (strScore, "%d", intScore); // баллды LCD lcdRight.writeге көрсөтүү (strScore); // diffictuly lcdRight.setCursor кошуу (10, 1); if (intDiff == 0) {lcdRight.write ("Оңой"); } if (intDiff == 1) {lcdRight.write ("Medium"); } if (intDiff == 2) {lcdRight.write ("Hard"); } // lcdLeft.setCursor көрсөтмөсүн бир аз басыңыз (0, 0); lcdLeft.write ("Enter" баскычын басыңыз); lcdLeft.setCursor (0, 1); lcdLeft.write ("баштоо үчүн!"); }

Бул код оюндун аталышын жана баллды ЖКга жазат, муну ЖКга LCD.setCursor аркылуу терүүнү кайдан баштоо керектигин айтып, андан кийин LCD.writeдеги сапты жазуу аркылуу жасайт.

Бул жерде жаңы өзгөрмө түзүлөт, strScore, ал sprintf функциясын колдонуу менен intScoreны сапка же char маалымат түрүнө айландыруу үчүн колдонулат.

intDiff бул жерде дагы колдонулат, анын баалуулуктарына таянып, ал ар кандай кыйынчылыктардын варианттарын басып чыгарат.

10 -кадам: ButtonsMenu Функциясы

программаңызга төмөнкү кодду киргизиңиз

void buttonMenu () {// enter басылганда оюнду баштаңыз жана эгерде (intEnter == 1) {bolPlay = true; intScore = 0; playBoard (); drawBoard (); } // 3 -баскыч басылганда, тактаны катарынан басып чыгаруунун оңдоо параметрин күйгүзүңүз, эгерде (intInput == 3) {if (bolSerialBoard == false) {Serial.println ("Serial Board Active"); bolSerialBoard = true; } else {Serial.println ("Сериялык такта өчүрүлгөн"); bolSerialBoard = false; }} // оюн ылдамдыгын оңой кыйынчылыкка кой, эгерде (intInput == 0) {Serial.print ("Оюн оңойго коюлган" ()); Serial.print (intGameSpeedEasy); Serial.println ("мс ылдамдатуу)"); intDiff = 0; intGameSpeed = intGameSpeedEasy; } // оюн ылдамдыгын орто кыйынчылыкка кой, эгерде (intInput == 1) {Serial.print ("Оюн орточо ("); Serial.print (intGameSpeedMedium); Serial.println ("мс ылдамдатуу)"); intDiff = 1; intGameSpeed = intGameSpeedMedium; } // оюндун ылдамдыгын кыйын кыйынчылыкка кой, эгерде (intInput == 2) {Serial.print ("Оюн катуу коюлган ("); Serial.print (intGameSpeedHard); Serial.println ("мс ылдамдатуу)"); intDiff = 2; intGameSpeed = intGameSpeedHard; }}

бул код bolPlay боштук Циклда жалганга барабар болгондо гана иштейт

Эгерде intEnter 1 деп коюлса, анда кирүү баскычы басылганын билдирет, эгерде ал басылып жатса, программа bolPlayди чындыкка коюп, оюн башталат.

Андан кийин программа intInput эмнеге барабар экенин окуйт. эгер ал 0го барабар болсо, сол жактагы биринчи баскыч басылып жатат, оңго карай 3кө чейин барат. Эгерде intInput 4кө барабар болсо, эч кандай баскыч басылбайт.

эгер 0-2 баскычтары басылса, оюн кыйынчылыкты өзгөртөт, ошондой эле оюндун ылдамдыгынын маанисин жөнгө салат, башкача айтканда, ал тезирээк ылдамдайт.

эгер 3 -баскыч басылса, оюн мүчүлүштүктөрдү оңдоо режимин жандандырат же өчүрөт, мында программанын көйгөйлөрүн табууга жардам берүү үчүн такта сериялык монитордо басылып чыгат.

11 -кадам: ButtonsGame Функциясы

төмөнкү кодду программаңызга көчүрүңүз

void keysGame () {if (intInput! = 4) {// if a button is pressed if if (bolTilePressed == false) {// if bolTilePressed жалган болсо, баскычты текшерүү үчүн bolTilePressed = true басыңыз; // анда bolTilePressed'ди true кылып коюңуз, ал кокусунан кайра иштетилбейт int intLowestTile = 0; // эң төмөнкү плиткасы бар плиткага коюу int intCheckedTile = 15; // кайсы плиталар текшерилгенин көзөмөлдөп туруу үчүн (intLowestTile == 0) {// эч нерсе коюлбаса, плиткаларды текшерүү (int i = 0; i 100) {// int кечигүү 100дөн төмөн эмес intDelay = intDelay - 20; // андан маанини алыңыз}} башка {Serial.println ("Туура эмес баскыч басылды"); оюн бүттү(); // болбосо оюн бүттү}}}}}

Код bolPlay боштук Циклда чындыкка барабар болгондо гана иштейт.

IntInput маанисине негизделген buttonMenu сыяктуу, оюнчу плитканы уруп же өткөрүп жибергенин текшерет.

Бул муну arrGame аркылуу төмөндөн өйдө карай өтүү менен, бир аз циклди колдонуп, кайсы катар эң начар экенин изделбейт. Андан кийин басылган баскычка дал келген саптын такталбаган плитка экенин же жок экендигин текшерет, эгерде ал жок болсо, аны 1 эмес, 2ге теңейт, башкача айтканда ал @катары көрсөтүлөт, антпесе gameOver биз жасай элек функция.

Бул функция ошондой эле bolTilePressed өзгөрмөсүн колдонуп, аны кнопка басылганда чындыкка, ал эми баскыч басылбаса жалганга орнотот. Бул колдонуучунун оюнду кокусунан жоготуп албашын камсыз кылуу үчүн, анткени программа алар баскычты басып турганда бир нече жолу басат деп ойлошкон.

12 -кадам: GameOver Функциясы

Төмөнкү кодду программаңызга көчүрүңүз

void gameOver () {Serial.println ("Оюн бүттү!"); Serial.print ("Сиздин упайыңыз:"); Serial.println (intScore); Serial.print ("Сиздин ылдамдыгыңыз:"); Serial.println (intDelay); bolPlay = жалган; }

Бул checkBottom же buttonGame функциялары менен ишке ашат жана bolPlay'ди жалган деп коюп, оюндун аягына чыгарат.

Ал ошондой эле колдонуучулардын упайлары үчүн сериялык мониторго билдирүү басып чыгарат жана ылдамдык плиткалары миллисекундтарда кошулган.

13 -кадам: Киргизүү функциясы

Төмөнкү кодду программаңызга көчүрүңүз.

void input () {intEnter = digitalRead (btnEnter); // окуу киргизиңиз // башка киргизүүлөрдүн кайсынысын окуйсуз, же эч ким 4кө коюлбаса (digitalRead (btn1) == HIGH) {intInput = 0;} else {if (digitalRead (btn2) == HIGH) {intInput = 1;} else {if (digitalRead (btn3) == HIGH) {intInput = 2;} else {if (digitalRead (btn4) == HIGH) {intInput = 3;} else {intInput = 4; }}}} // сериялык кириштерди if (intEnter == 1) {Serial.println ("Enter Pressed!");} if (intInput! = 4) {Serial.print ("Button Press:"); Serial.println (intInput); } else {// эгер эч кандай кнопка басылбаса reset bolTilePressed bolTilePressed = false; }}

Бул код buttonGame жана buttonMenu функциялары менен колдонулат. колдонуучу баскан баскычтардын негизинде intInput маанисин коет, же баскыч басылбаса intInput 4кө теңдейт.

Эгерде эч кандай баскыч басылбаса, бул жерде bolTilePressed түймөлөрү Оюн функциясы үчүн баштапкы абалга келтирилет.

Ошондой эле ал баскыч басылган сериялык мониторго билдирүү басып чыгарат.

14 -кадам: BottomCheck Функциясы

төмөнкү кодду программаңызга көчүрүңүз.

void bottomCheck () {for (int i = 0; i <= 3; i ++) {// 4 collumns үчүн if (arrGame [15] == 1) {// эгер кафель ылдыйкы серияда болсо.println ("Төмөндөгү плитка"); arrGame [15] = 2; drawBoard (); кечигүү (400); arrGame [15] = 1; drawBoard (); кечигүү (400); arrGame [15] = 2; drawBoard (); кечигүү (400); arrGame [15] = 1; drawBoard (); кечигүү (400); оюн бүттү(); }}}

циклди колдонуп, бул код arrGameдин астыңкы катарын ар кандай көрүнбөгөн плиткалар үчүн текшерет (плиткалар 1ге барабар), эгерде экрандын ылдый жагында жараксыз плитка болсо, ал плитканы жаркылдатып, андан кийин оюндун функциясын иштетет.

15 -кадам: WriteSerial Функциясы

төмөнкү кодду программаңызга көчүрүңүз

Void WriteSerial () {if (bolSerialBoard == true) {for (int i = 0; i <= 15; i ++) {for (int ii = 0; ii <= 3; ii ++) {Serial.print (arrGame [ii]); Serial.print (","); } Serial.println (""); }}}

Бул buttonMenu функциясында иштетиле турган мүчүлүштүктөрдү оңдоо функциясы. Эгерде bolSerialBoard бул функцияда true деп коюлса, ал arrGame аркылуу өтөт жана массивди колдонуу менен тестти сериялык мониторго басып чыгарат.

16 -кадам: Аяктоо

Аяктоо!
Аяктоо!

Сиздин коддун баары толук болбошу керек жана ушул сыяктуу көрүнүшү керек!

/ * * Аты - Пианино плиткалары; Arduino * By - Domenic Marulli * Date - 11/ *

/ китепканаларды камтыйт

#кошуу

// бул өзгөрмөлөр сиз өзгөртө турган варианттар - жогорку сандар = оюндун ылдамдыгы

int intGameSpeedEasy = 10; int intGameSpeedMedium = 25; int intGameSpeedHard = 80;

// Пиндерди аныктоо

#define btnEnter A0 #define btn1 15 #define btn2 16 #define btn3 17 #define btn4 18

// LCD объектилерин түзүү (n, ~, n, ~, ~, n)

LiquidCrystal lcdLeft (8, 9, 12, 10, 11, 13); LiquidCrystal lcdRight (2, 3, 4, 5, 6, 7);

// оюн массивин орнотуу

int arrGame [16] [4] = {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}};

// оюн үчүн өзгөрмөлөрдү орнотуу

логикалык bolPlay; // tracks if player if intScore; // оюнчунун упайын көзөмөлдөйт int intiff; // жөн гана эстетикалык нерсе, оюндун кандай кыйынчылыкта экенин

// киргизүү үчүн өзгөрмөлөрдү орнотуу

int intEnter; // колдонуучу int intInput кирүү баскычын басса, көз салат; // колдонуучу логикалык bolTilePressed баскычтарын баскан тректер; // оюнчу кокусунан 5x кнопкасын басып койбосун камсыз кылыңыз

// бурулуш үчүн өзгөрмөлөрдү коюу

int intTick; // intDelay int intDelay чейин миллиге чейин эсептейт (циклге); // программанын кийинки кезекке чейин күткөн убактысы int intGameSpeed;

// мүчүлүштүктөрдү оңдоо мүмкүнчүлүктөрү

логикалык bolSerialBoard; // качан true тактаны сериялык мониторго басып чыгарат

// бир жолу иштетиле турган орнотуу

void setup () {Serial.begin (9600); // сериялык мониторду баштоо // өзгөрмөлөрдү коюу bolPlay = false; intScore = 0; intTick = 0; intDelay = 1000; intDiff = 1; intGameSpeed = intGameSpeedMedium; // begin lcd's lcdLeft.begin (16, 2); lcdRight.begin (16, 2); }

// ар бир 10 миллисекундада иштей турган цикл

void loop () {input (); // if (bolPlay == true) if if (bolPlay == true) {if (intTick> = intDelay) {// оюндун бурулушу керекпи же жокпу Serial.println ("~~~~~~~ ~~ "); // басып чыгаруу, тактаны жылдырууну билдирүү үчүн // writeSerial (); // эгерде параметр иштетилген болсо, тактаны катарлык түймөлөргө жазгылаGame (); // оюнчу киргизүүлөрүн текшерүү playBoard (); // тактаны жылдыруу жана жаңы плитканы кошуу clearLcd (); // drawBoard () тартуудан мурун ЖКны тазалаңыз; // тактаны lcd түбүнө тартууCheck (); intTick = 0; // баштапкы абалга келтирүү intTick} башка {buttonGame (); // оюнчу киргизүүлөрүн текшерүү clearLcd (); // drawBoard () тартуудан мурун ЖКны тазалаңыз; // тактаны lcd's intTick = intTick + intGameSpeedге тартыңыз; // белгиге кошуу}} башка {clearLcd (); // аталышын тартуудан мурун ЖКны тазалаңыз (); // дисплейдин аталышы жана упай маалыматы баскычтарыMenu (); // оюнчу киргизүүнү окуу clearBoard (); // бүт коллегияны камсыз кылуу = 0} кечигүү (10); // ардуинону бир азга кечиктирүү}

// лкди тазалайт, андыктан киргизилбеген клеткалар ошол жерде калбайт

void clearLcd () {for (int i = 0; i <= 15; i ++) {for (int ii = 0; ii <= 1; ii ++) {lcdLeft.setCursor (i, ii); lcdLeft.write (""); lcdRight.setCursor (i, ii); lcdRight.write (""); }}}

// тактаны lcd'лерге тартат

void drawBoard () {for (int i = 1; i <= 15; i ++) {// сол LCDдеги 1 жана 2 колумдарды тарткыла // эгер плитка = 0 эч нерсе жазбаса, = 1 "#", = 2 деп жаз "@" lcdLeft.setCursor жаз (i, 1); // биринчи колумнга коюлган (эң алыскы сол) if (arrGame [0] == 1) {lcdLeft.write ("#");} if (arrGame [0] == 2) {lcdLeft.write ("@");} lcdLeft.setCursor (i, 0); // экинчи колумнга коюлган (борбордун сол жагында) if (arrGame [1] == 1) {lcdLeft.write ("#");} if (arrGame [1] == 2) {lcdLeft.write ("@");} lcdRight.setCursor (i, 1); // үчүнчү колумнга коюңуз (борбордун оң жагында) if (arrGame [2] == 1) {lcdRight.write ("#");} if (arrGame [2] == 2) {lcdRight.write ("@");} lcdRight.setCursor (i, 0); // төртүнчү колумнга коюлган (эң алыскы оңго) if (arrGame [3] == 1) {lcdRight.write ("#");} if (arrGame [3] == 2) {lcdRight.write ("@");}}}

// тактаны ылдый жылдырат жана плитка болуу үчүн туш келди маанини коёт

void playBoard () {for (int i = 0; i <= 3; i ++) {arrGame [0] = 0;} // arrGame жогорку катарын тазалоо [0] [random (0, 4)] = 1; // жогорку катардагы туш келди чекитти коюңуз (int i = 15; i> = 1; i-) {// үчүн тактанын түбүнөн өйдө карай иштөө (int ii = 0; ii <= 3; ii ++) {// ар бир колум үчүн arrGame [ii] = arrGame [i - 1] [ii]; }}}

// бүт коллегияны 0ге коюп, өзгөрмөлөрдү баштапкы оюнга кайтарат

void clearBoard () {// кенени баштапкы абалга келтирүү жана маанилерин кечиктирүү intTick = 0; intDelay = 1000; // доска аркылуу өтүп, баарын 0 үчүн коюңуз (int i = 0; i <= 15; i ++) {for (int ii = 0; ii <= 3; ii ++) {arrGame [ii] = 0; }}}

// ЖКнын Негизги Менюсун көрсөтөт

void title () {// титулун LCDге жазуу жана lcdRight.setCursor упайы үчүн боштук (0, 0); lcdRight.write ("Фортепиано плиткалары"); lcdRight.setCursor (0, 1); lcdRight.write ("Упай:"); // упайды string strScoreга айландыруу [3]; sprintf (strScore, "%d", intScore); // баллды LCD lcdRight.writeге көрсөтүү (strScore); // diffictuly lcdRight.setCursor кошуу (10, 1); if (intDiff == 0) {lcdRight.write ("Оңой"); } if (intDiff == 1) {lcdRight.write ("Medium"); } if (intDiff == 2) {lcdRight.write ("Hard"); } // lcdLeft.setCursor көрсөтмөсүн бир аз басыңыз (0, 0); lcdLeft.write ("Enter" баскычын басыңыз); lcdLeft.setCursor (0, 1); lcdLeft.write ("баштоо үчүн!"); }

// баскычтарды текшерет жана оюндан тышында алар үчүн эмне кылуу керек

void buttonMenu () {// enter басылганда оюнду баштаңыз жана эгерде (intEnter == 1) {bolPlay = true; intScore = 0; playBoard (); drawBoard (); } // 3 -баскыч басылганда, тактаны катарынан басып чыгаруунун оңдоо параметрин күйгүзүңүз, эгерде (intInput == 3) {if (bolSerialBoard == false) {Serial.println ("Serial Board Active"); bolSerialBoard = true; } else {Serial.println ("Сериялык такта өчүрүлгөн"); bolSerialBoard = false; }} // оюн ылдамдыгын оңой кыйынчылыкка кой, эгерде (intInput == 0) {Serial.print ("Оюн оңойго коюлган" ()); Serial.print (intGameSpeedEasy); Serial.println ("мс ылдамдатуу)"); intDiff = 0; intGameSpeed = intGameSpeedEasy; } // оюн ылдамдыгын орто кыйынчылыкка кой, эгерде (intInput == 1) {Serial.print ("Оюн орточо ("); Serial.print (intGameSpeedMedium); Serial.println ("мс ылдамдатуу)"); intDiff = 1; intGameSpeed = intGameSpeedMedium; } // оюндун ылдамдыгын кыйын кыйынчылыкка кой, эгерде (intInput == 2) {Serial.print ("Оюн катуу коюлган ("); Serial.print (intGameSpeedHard); Serial.println ("мс ылдамдатуу)"); intDiff = 2; intGameSpeed = intGameSpeedHard; }}

// баскычтарды текшерет жана оюнда алар үчүн эмне кылуу керек

void keysGame () {if (intInput! = 4) {// if a button is pressed if if (bolTilePressed == false) {// if bolTilePressed жалган болсо, баскычты текшерүү үчүн bolTilePressed = true басыңыз; // анда bolTilePressed'ди true кылып коюңуз, ал кокусунан кайра иштетилбейт int intLowestTile = 0; // эң төмөнкү плиткасы бар плиткага коюу int intCheckedTile = 15; // кайсы плиталар текшерилгенин көзөмөлдөп туруу үчүн (intLowestTile == 0) {// эч нерсе орнотулбаса (int i = 0; i 100) {// int кечигүү 100дөн төмөн эмес intDelay = intDelay - 20; // андан маанини алыңыз}} башка {Serial.println ("Туура эмес баскыч басылды"); оюн бүттү(); // болбосо оюн бүттү}}}}}

void gameOver () {

Serial.println ("Оюн бүттү!"); Serial.print ("Сиздин упайыңыз:"); Serial.println (intScore); Serial.print ("Сиздин ылдамдыгыңыз:"); Serial.println (intDelay); bolPlay = жалган; }

// оюнчу киргизилгенин текшерет

void input () {intEnter = digitalRead (btnEnter); // окуу киргизиңиз // башка киргизүүлөрдүн кайсынысын окуйсуз, же эч ким 4кө коюлбаса (digitalRead (btn1) == HIGH) {intInput = 0;} else {if (digitalRead (btn2) == HIGH) {intInput = 1;} else {if (digitalRead (btn3) == HIGH) {intInput = 2;} else {if (digitalRead (btn4) == HIGH) {intInput = 3;} else {intInput = 4; }}}} // сериялык кириштерди if (intEnter == 1) {Serial.println ("Enter Pressed!");} if (intInput! = 4) {Serial.print ("Button Press:"); Serial.println (intInput); } else {// эгер эч кандай кнопка басылбаса reset bolTilePressed bolTilePressed = false; }}

// тактанын ылдый жагын текшерет

void bottomCheck () {for (int i = 0; i <= 3; i ++) {// for 4 collumns if if (arrGame [15] == 1) {// if a tile is the bottom Serial.println ("Төмөндөгү плитка"); arrGame [15] = 2; drawBoard (); кечигүү (400); arrGame [15] = 1; drawBoard (); кечигүү (400); arrGame [15] = 2; drawBoard (); кечигүү (400); arrGame [15] = 1; drawBoard (); кечигүү (400); оюн бүттү(); }}}

// bolSerialBoard чын болсо, тактаны сериялык мониторго басып чыгарат

Void WriteSerial () {if (bolSerialBoard == true) {for (int i = 0; i <= 15; i ++) {for (int ii = 0; ii <= 3; ii ++) {Serial.print (arrGame [ii]); Serial.print (","); } Serial.println (""); }}}

Бардык код киргизилгенден кийин, ардуиного жүктөп, ырахат алыңыз!

Сунушталууда: