Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

Arduino Touch Breakout Game

Composants et fournitures

Arduino UNO
× 1
Az-Delivery 2.4 TFT LCD Touch Display Arduino Shield
× 1

Applications et services en ligne

Arduino IDE

À propos de ce projet

Il s'agit d'une petite version du jeu vidéo classique pour Arduino UNO et écran LCD TFT (240x320 pixels), pilote ILI9341 avec communication parallèle 8 bits.

Le jeu

Ce Breakout dispose de plusieurs écrans avec différentes rangées et colonnes de briques configurables, jusqu'à huit rangées, avec chacune deux rangées d'une couleur différente, qui peuvent être activées ou désactivées avec différents motifs. À l'aide d'une seule balle, à l'aide de l'écran tactile, le joueur doit abattre autant de briques que possible en utilisant les murs et/ou la pagaie en dessous pour faire ricocher la balle contre les briques et les éliminer. Si la raquette du joueur manque le rebond de la balle, il perdra un tour.

Chaque rangée de briques rapporte des points différents chacune.

uint8_t pointsForRow[] ={7, 7, 5, 5, 3, 3 , 1, 1} ; 

Chaque niveau peut configurer la taille de la raquette et la taille de la balle. La vitesse de la balle augmente à chaque coup, vous pouvez configurer la vitesse initiale pour chaque écran. Selon le point de la raquette qui frappe la balle, la vitesse horizontale change également

Vous pouvez définir de nouveaux écrans avec différents motifs muraux :

Comment jouer

Tenez l'appareil avec vos mains et utilisez vos pouces et vos doigts sur l'écran pour déplacer la palette vers la gauche ou vers la droite.

Définir un nouvel écran

Cette structure permet de définir un nouvel écran :

typedef struct game_type {
int ballsize;
int playerwidth;
int playerheight;
int exposant;
int top;
int lignes ;
int colonnes ;
int brickGap ;
int vies ;
int mur[GAMES_NUMBER] ;
int initVelx;
int initVely ;
} game_type;

et ajoutez le nouvel écran à l'ensemble :

game_type games[GAMES_NUMBER] =
// taille de la balle, largeur du joueur, hauteur du joueur, exposant, haut, rangées, colonnes, brickGap, vies, mur[8], initVelx, initVely
{
{ 10, 60, 8, 6, 40 , 8, 8, 3, 3, {0x18, 0x66, 0xFF, 0xDB, 0xFF, 0x7E, 0x24, 0x3C} , 28, -28},

Motif mural

Le motif de mur est défini comme un tableau de 8x8 bits

ej.

{0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA} 

qui correspond à ce tableau de bits

1,0,1,0,1,0,1,0
1,0,1,0,1,0,1,0
1,0,1, 0,1,0,1,0
1,0,1,0,1,0,1,0
1,0,1,0,1,0,1,0
1,0,1,0,1,0,1,0
1,0,1,0,1,0,1,0
1,0,1,0,1,0 ,1,0

Produira ce mur, notez qu'il est en miroir :

Matériel

Ce projet utilise un écran LCD TFT 2,4 pouces AZ-Delivery avec un écran tactile résistif à 4 fils et un lecteur de carte SD intégré. Écran LCD TFT 2,4 pouces AZ-Delivery.

Plus d'informations sur ce bouclier dans mon article "Tests routiers d'un écran tactile LCD AZ-Delivery 2, 4 TFT"

Assemblage du bouclier

Il vous suffit de brancher le blindage sur l'Aduino.

Bibliothèques

#include  // Bibliothèque graphique principale
#include
#include

Calibrage de l'écran tactile

Vous devez calibrer l'écran pour que les informations de position soient correctes lorsque vous touchez l'écran. La bibliothèque MCUFriend_kbv fournit un exemple avec le nom "TouchScreen_Calibr_native". L'exemple envoie les résultats au port série. Démarrez le moniteur série de l'IDE Arduino afin de pouvoir copier le code généré par l'exemple.

Suivez les instructions sur l'écran tactile, appuyez et maintenez les marqueurs de position affichés, qui sont surlignés en blanc. Une fois que vous avez fait tous les repères de position, le calibrage de l'écran vous est envoyé sur l'écran tactile et par le port série.

Pour ce projet, vous avez besoin des données pour le "calibrage du portrait".

Étalonnage GFX TouchScreen.h
Faire toutes les broches de contrôle et de bus INPUT_PULLUP
Le pullup analogique 30k typique avec la broche correspondante
serait faible lorsque numérique est écrit LOW
par ex. lit ~25 pour la direction 300R X
par ex. lit ~30 pour la direction Y 500R
Test :(A2, D8) =26
Test :(A3, D9) =28
ID =0x9341
cx=153 cy=103 cz=534 X, Y, Pression
cx=150 cy=475 cz=406 X, Y, Pression
cx=155 cy=868 cz=231 X, Y, Pression
cx=517 cy=103 cz=561 X, Y, Pression
cx=535 cy=855 cz=364 X, Y, Pression
cx=884 cy=88 cz=650 X, Y, Pression
cx=908 cy=478 cz=557 X, Y, pression
cx=902 cy=864 cz=488 X, Y, pression
*** COPIER-COLLER à partir du terminal série :
const entier XP=8,XM=A2,YP=A3,YM=9 ; //240x320 ID=0x9341
const int TS_LEFT=118,TS_RT=931,TS_TOP=72,TS_BOT=887;
CALIBRATION PORTRAIT 240 x 320
x =map(px, LEFT=118 , RT=931, 0, 240)
y =map(py, TOP=72, BOT=887, 0, 320)
CALIBRAGE DU PAYSAGE 320 x 240
x =map(py, LEFT=72, RT=887, 0, 320)
y =map(px, TOP=931, BOT=118, 0, 240)

Animation

Pour déplacer l'image sur l'écran au fil du temps, utilisez une vitesse statique et appliquez-la à la position d'une image à chaque pas de temps.

pos +=vel * dt;

Éviter l'arithmétique à virgule flottante

La résolution ILI9341 est de 240 x 320, nous avons donc besoin de deux entiers de 9 bits pour référencer un pixel à l'écran. En utilisant des entiers de 16 bits, cela laisse 6 bits libres pour représenter une partie décimale.

nnnn nnnn nndd jjjj

Nous appelons ce nombre, 6, l'exposant binaire. Et nous pouvons utiliser ces six bits pour avoir une partie décimale allant de 0,000 à 0,63. Nous pouvons donc utiliser des mathématiques entières en évitant l'arithmétique à virgule flottante.

Pour obtenir la partie entière du nombre, nous effectuons un décalage arithmétique à droite.

nombre>> exposant

state.ballx +=state.velx;
state.bally +=state.vely;

// vérifier les collisions de balles et quitter
checkBallCollisions(jeu , &state, state.ballx>> game->exponent, state.bally>> game->exponent);
checkBallExit(game, &state, state.ballx>> game->exposant, state.bally>> game ->exposant);

Mode démo

Décommentez la directive Define et la raquette suivra la balle comme on le voit dans les vidéos de démonstration :

#define DEMO_MODE 

Profitez-en !

Créez de nouveaux modèles et niveaux et partagez-les !

Code

  • Déploiement Arduino
Déploiement ArduinoArduino
/* Arduino Touch TFT Breakout Jeu d'évasion classique Pièces nécessaires :Ardunio UNO AZ-Delivery 2.4 TFT LCD Touch Display Arduino Shield ou compatible Cet exemple de code est dans le domaine public. Modifié le 11/07/2020 Par Enrique Albertos*/// #define DEMO_MODE#include // Bibliothèque graphique principale#include #include #define BLACK 0x0000#define BLUE 0x001F#define ROUGE 0xF800#define GREEN 0x07E0#define CYAN 0x07FF#define MAGENTA 0xF81F#define YELLOW 0xFFE0#define WHITE 0xFFFF#define PRIMARY_COLOR 0x4A11#define PRIMARY_LIGHT_COLOR 0x7A17#define 0 PRIMARY_COdef_D_Darn3 #define LCD_CD A2 // La commande/les données passe à Analog 2#define LCD_WR A1 // L'écriture LCD passe à Analog 1#define LCD_RD A0 // La lecture LCD passe à Analog 0#define LCD_RESET A4 // Peut alternativement se connecter à la réinitialisation d'Arduino pinAdafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);#define LOWFLASH (défini(__AVR_ATmega328P__) &&défini(MCUFRIEND_KBV_H_))// Seuil de pression de l'écran tactile#define MINPRESSURE 40#/define MAXPRESSURE 1000 8, XM =A2, YP =A3, YM =9 ; //240x320 ID=0x9341const int16_t TS_LEFT =122, TS_RT =929, TS_TOP =77, TS_BOT =884;const TouchScreen ts =TouchScreen(XP, YP, XM, YM, 300);#define SCORE_SIZE 30car scoreFormat[] =" 04d";typedef struct gameSize_type { int16_t x, y, width, height;} gameSize_type;gameSize_type gameSize;uint16_t backgroundColor =BLACK;int level;const uint8_t BIT_MASK[] ={0x01, 0x02, 0x04, 0x08, 0x10, 0x20 , 0x80};uint8_t pointsForRow[] ={7, 7, 5, 5, 3, 3 , 1, 1};#define GAMES_NUMBER 16typedef struct game_type { int ballsize; int playerwidth; int playerheight; exposant entier ; haut int; lignes entières ; colonnes entières ; int brickGap; vies int; mur int[GAMES_NUMBER] ; int initVelx; int initVely;} game_type;game_type games[GAMES_NUMBER] =// taille de la balle, largeur du joueur, hauteur du joueur, exposant, haut, rangées, colonnes, brickGap, vies, mur[8], initVelx, initVely{ { 10, 60, 8, 6, 40 , 8, 8, 3, 3, {0x18, 0x66, 0xFF, 0xDB, 0xFF, 0x7E, 0x24, 0x3C} , 28, -28}, { 10, 50, 8, 6, 40 , 8, 8, 3 , 3, {0xFF, 0x99, 0xFF, 0xE7, 0xBD, 0xDB, 0xE7, 0xFF} , 28, -28}, { 10, 50, 8, 6, 40 , 8, 8, 3, 3, {0xAA, 0x55 , 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55} , 28, -28}, { 8, 50, 8, 6, 40 , 8, 8, 3, 3, {0xFF, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF} , 34, -34}, { 10, 40, 8, 6, 40 , 8, 8, 3, 3, {0xFF, 0xAA, 0xAA, 0xFF, 0xFF, 0xAA, 0xAA, 0xFF} , 28, -28}, { 10, 40, 8, 6, 40 , 8, 8, 3, 3, {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA} , 28, -28}, { 12, 64, 8, 6, 60 , 4, 2, 3, 4, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} , 20, -20}, { 12, 60, 8, 6 , 60 , 5, 3, 3, 4, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} , 22, -22}, { 10, 56, 8, 6, 30 , 6, 4, 3, 4, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} , 24, -24}, { 10, 52, 8, 6, 30 , 7, 5, 3, 4, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} , 26, -26 }, { 8, 48, 8, 6, 30 , 8, 6, 3, 3, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} , 28, -28}, { 8, 44, 8, 6, 30 , 8, 7, 3, 3, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} , 30, -30}, { 8, 40, 8, 6, 30 , 8 , 8, 3, 3, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} , 32, -32}, { 8, 36, 8, 6, 40 , 8, 8, 3, 3, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} , 34, -34}, { 8, 36, 8, 6, 40 , 8, 8, 3, 3, {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA} , 34, -34}};game_type* jeu;typedef struct game_state_type { uint16_t ballx; uint16_t bally; uint16_t ballxold; uint16_t ballyold; int velx; int vely; int playerx; int playerxold; int wallState[8]; score entier ; int restantVies ; haut int; int bas; int walltop; int wallbottom; hauteur de brique int; int brickwidth;};game_state_type state;//////////////////////////////////////// ///////////////////// CONFIGURATION ARDUINO///////////////////////// ///////////////////////////////// void setup(){ initTft(tft); gameSize ={0, 0, tft.width(), tft.height()} ; newGame(&games[0], &state, tft);}//////////////////////////////////// ///////////////////////// BOUCLE ARDUINO//////////////////// //////////////////////////////////////int selection =-1;void loop( void){ selection =readUiSelection(jeu, &state, selection); drawPlayer(jeu, &état); // stocke l'ancienne position pour supprimer les anciens pixels state.playerxold =state.playerx; // calcule la nouvelle position de la balle x1 =x0 + vx * dt // vérifie la vitesse max if (abs( state.vely)> ((1 <exponent) - 1)) { state.vely =((1 <exposant) - 1) * ((state.vely> 0) - (state.vely <0)); } if (abs( state.velx)> ((1 <exposant) - 1)) { state.velx =((1 <exposant) - 1) * ((state.velx> 0 ) - (état.velx <0)); } état.ballx +=état.velx; état.bally +=état.vely; // vérifie les collisions de balles et quitte checkBallCollisions(game, &state, state.ballx>> game->exponent, state.bally>> game->exponent); checkBallExit (jeu, &état, état.ballx>> jeu-> exposant, état.bally>> jeu-> exposant); // dessine la balle dans une nouvelle position drawBall(state.ballx>> jeu-> exposant, état.bally>> jeu-> exposant, état.ballxold>> jeu-> exposant, état.ballyold>> jeu-> exposant, jeu ->ballsize ); // stocke l'ancienne position pour supprimer les anciens pixels state.ballxold =state.ballx; état.ballyold =état.bally; // incrémente la vitesse state.velx =(20 + (state.score>> 3 )) * ( (state.velx> 0) - (state.velx <0)); state.vely =(20 + (state.score>> 3 )) * ( (state.vely> 0) - (state.vely <0)); // si aucune brique passe au niveau suivant if (noBricks(game, &state) &&level vies, état->vies restantes); updateScore(état->score); setupWall(jeu, état); touchToStart(); clearDialog(gameSize); updateLives(jeu->vies, état->vies restantes); updateScore(état->score); setupWall(game, state);}void setupStateSizes(game_type* game, game_state_type * state, Adafruit_TFTLCD &tft) { state->bottom =tft.height() - 30; état->brickwidth =tft.width() / jeu->colonnes ; state->brickheight =tft.height() / 24;} void setupState(game_type* jeu, game_state_type * état, Adafruit_TFTLCD &tft) { setupStateSizes(jeu, état, tft); for (int i =0; i rows; i ++) { state->wallState[i] =0; } état->playerx =tft.width() / 2 - jeu->playerwidth / 2; état->remainingLives =jeu->vies ; état->bally =état->bas <exposant ; état->ballyold =état->bas <exposant ; état->velx =jeu->initVelx; state->vely =game->initVely;}void updateLives(int lives, int restantLives) { for (int i =0; i walltop =jeu->top + 40 ; état->wallbottom =état->walltop + jeu->lignes * état->brickheight ; for (int i =0; i rows; i++) { for (int j =0; j columns; j++) { if (isBrickIn(game->wall, j, i)) { setBrick (état->wallState, j, i); drawBrick(état, j, i, couleurs[i]); } } }}void drawBrick(game_state_type * state, int xBrick, int yBrickRow, uint16_t backgroundColor) { tft.fillRect((state->brickwidth * xBrick) + game->brickGap, state->walltop + (state->brickheight *) yBrickRow) + jeu->brickGap , état->brickwidth - jeu->brickGap * 2, état->brickheight - jeu->brickGap * 2, backgroundColor);}booléen noBricks(game_type * jeu, game_state_type * état) { pour ( int i =0 ; i rows ; i++) { if (state->wallState[i]) return false ; } return true;}void drawPlayer(game_type * game, game_state_type * state) { // paint tft.fillRect(state->playerx, state->bottom, game->playerwidth, game->playerheight, YELLOW); if (state->playerx !=state->playerxold) { // supprime les anciens pixels if (state->playerx playerxold) { tft.fillRect(state->playerx + game->playerwidth, state->bottom , abs(state->playerx - state->playerxold), game->playerheight, backgroundColor); } else { tft.fillRect(state->playerxold, state->bottom, abs(state->playerx - state->playerxold), game->playerheight, backgroundColor); } }}void drawBall(int x, int y, int xold, int yold, int ballsize) { // supprime les anciens pixels //if (xold !=x &&yold !=y) { if (xold <=x &&yold <=y) { tft.fillRect(xold , yold, ballsize, y - yold, BLACK); tft.fillRect(xold , yold, x - xold, ballsize, BLACK); } else if (xold>=x &&yold>=y) { tft.fillRect(x + ballsize , yold, xold - x, ballsize, BLACK); tft.fillRect(xold , y + ballsize, ballsize, yold - y, BLACK); } else if (xold <=x &&yold>=y) { tft.fillRect(xold , yold, x - xold, ballsize, BLACK); tft.fillRect(xold , y + ballsize, ballsize, yold - y, BLACK); } else if (xold>=x &&yold <=y) { tft.fillRect(xold , yold, ballsize, y - yold, BLACK); tft.fillRect(x + ballsize, yold, xold - x, ballsize, BLACK); } // peindre une nouvelle balle tft.fillRect(x , y, ballsize, ballsize, YELLOW); // }}void touchToStart() { drawBoxedString(0, 200, " BREAKOUT", 3, YELLOW, BLACK); drawBoxedString (0, 240, " TOUCHER POUR COMMENCER", 2, ROUGE, NOIR); while (waitForTouch() <0) {}}void gameOverTouchToStart() { drawBoxedString(0, 180, " GAME OVER", 3, YELLOW, BLACK); drawBoxedString (0, 220, " TOUCHER POUR COMMENCER", 2, ROUGE, NOIR); while (waitForTouch() <0) {}}void updateScore (int score) { char buffer[5]; snprintf(buffer, sizeof(buffer), scoreFormat, score); drawBoxedString(tft.width() - 50, 6, buffer, 2, YELLOW, PRIMARY_DARK_COLOR);}void checkBrickCollision(game_type* game, game_state_type * state, uint16_t x, uint16_t y) { int x1 =x + game->ballsize; int y1 =y + game->ballsize ; collisions int =0 ; collisions +=checkCornerCollision(jeu, état, x, y); collisions +=checkCornerCollision(jeu, état, x1, y1) ; collisions +=checkCornerCollision(jeu, état, x, y1) ; collisions +=checkCornerCollision(jeu, état, x1, y); if (collisions> 0 ) { état->vely =(-1 * état->vely); if ((((x % état->brickwidth) ==0) &&( état->velx <0 )) || ((((x + game->ballsize) % state->brickwidth) ==0) &&( état->velx> 0 )) ) { état->velx =(-1 * état->velx); } }}int checkCornerCollision(game_type * game, game_state_type * state, uint16_t x, uint16_t y) { if ((y> state->walltop) &&(y wallbottom)) { int yBrickRow =( y - state->walltop) / état->brickheight ; int xBrickColumn =(x / état->brickwidth); if (isBrickIn(state->wallState, xBrickColumn, yBrickRow) ) { hitBrick(state, xBrickColumn, yBrickRow); retour 1 ; } } return 0;}void hitBrick(game_state_type * state, int xBrick, int yBrickRow) { state->score +=pointsForRow[yBrickRow]; drawBrick(état, xBrick, yBrickRow, WHITE); retard(16); drawBrick(état, xBrick, yBrickRow, BLEU); délai(8) ; drawBrick(état, xBrick, yBrickRow, backgroundColor); unsetBrick(état->wallState, xBrick, yBrickRow); updateScore(state->score);}void checkBorderCollision(game_type * game, game_state_type * state, uint16_t x, uint16_t y) { // vérifier la collision du mur if (x + game->ballsize>=tft.width()) { state ->velx =-abs(état->velx); } if (x <=0 ) { état->velx =abs(état->velx); } if (y <=SCORE_SIZE ) { state->vely =abs(state->vely); } if (((y + game->ballsize)>=state->bottom) &&((y + game->ballsize) <=(state->bottom + game->playerheight)) &&(x>=state->playerx) &&(x <=(state->playerx + game->playerwidth))) { // changer le vel x près des frontières du joueur if (x> (state->playerx + game->playerwidth - 6)) { state ->velx =état->velx - 1 ; } else if (x <état->playerx + 6) { état->velx =état->velx + 1; } état->vely =-abs(état->vely); }} void checkBallCollisions(game_type * jeu, game_state_type * état, uint16_t x, uint16_t y) { checkBrickCollision(jeu, état, x, y); checkBorderCollision(game, state, x, y);}void checkBallExit(game_type * game, game_state_type * state, uint16_t x, uint16_t y) { if (((y + game->ballsize)>=tft.height())) { état->remainingLives--; updateLives(jeu->vies, état->vies restantes); retard (500); état->vely =-abs(état->vely); }}void setBrick(int wall[], uint8_t x, uint8_t y) { wall[y] =wall[y] | BIT_MASK[x];}void unsetBrick(int wall[], uint8_t x, uint8_t y) { wall[y] =wall[y] &~BIT_MASK[x];}boolean isBrickIn(int wall[], uint8_t x, uint8_t y) { mur de retour[y] &BIT_MASK[x];}////////////////////////////////// /////////////////////////// CONFIGURATION TFT////////////////// //////////////////////////////////////// void initTft(Adafruit_TFTLCD &tft) { tft.reset(); uint16_t ID =tft.readID(); tft.begin(ID); tft.setRotation(0);}//////////////////////////////////////// ///////////////////// Méthodes de Screen Painting //////////////////////// ////////////////////////////////////** Imprimer un texte en pré-couleur sur une case remplie avec Couleur de l'arrière plan. La taille du rectangle est calculée pour inclure tout le texte sans marges @param x coordonnée horizontale en points coin supérieur gauche @param y coordonnée verticale en points coin supérieur gauche @param fontsize taille de police du texte à imprimer @param foreColor forecolor du texte à imprimer @param backgroundColor couleur du rect rempli @return void*/void drawBoxedString(const uint16_t x, const uint16_t y, const char* string, const uint16_t fontsize, const uint16_t foreColor, const uint16_t backgroundColor) { tftsize.set);TextSize(fontsize int16_t x1, y1 ; uint16_t w, h; tft.getTextBounds(string, x, y, &x1, &y1, &w, &h); tft.fillRect(x, y, w, h, backgroundColor); tft.setCursor(x, y); tft.setTextColor(foreColor); tft.print(string);}/** Effacer l'écran aux arrière-plans par défaut @param void @return void*/void clearDialog(gameSize_type gameSize) { tft.fillRect(gameSize.x, gameSize.y, gameSize.width, gameSize .height, backgroundColor); tft.fillRect(gameSize.x, gameSize.y, gameSize.width, SCORE_SIZE, PRIMARY_DARK_COLOR);}/////////////////////////// ////////////////////////////////// LIRE LA SÉLECTION UI/////////// ////////////////////////////////////////////////////////////// //* Vérifie si l'utilisateur sélectionne l'un des éléments ui activés visibles Le rappel onTap de l'élément sélectionné est appelé et défini comme pressé @param lastSelected la dernière sélection @return la nouvelle sélection*/int readUiSelection(game_type * game, game_state_type * état, const int16_t lastSelected ) { int16_t xpos, ypos; //coordonnées de l'écran TSPoint tp =ts.getPoint(); //tp.x, tp.y sont des valeurs ADC // si vous partagez des broches, vous devrez corriger les directions des broches de l'écran tactile pinMode(XM, OUTPUT); pinMode(YP, SORTIE); // nous avons une pression minimale que nous considérons comme « valide » // une pression de 0 signifie qu'il n'y a pas de pression ! if (tp.z> MINPRESSURE &&tp.z tft.width() / 2) { état->playerx +=2; } else { état->playerx -=2; } if (state->playerx>=tft.width() - game->playerwidth) state->playerx =tft.width() - game->playerwidth ; if (état->playerx <0) état->playerx =0 ; retour 1 ; }#ifdef DEMO_MODE état->playerx =(état->ballx>> jeu->exposant) - jeu->playerwidth / 2 ; if (state->playerx>=tft.width() - game->playerwidth) state->playerx =tft.width() - game->playerwidth ; if (state->playerx <0) state->playerx =0;#endif return -1;}int waitForTouch() { int16_t xpos, ypos; //coordonnées d'écran TSPoint tp =ts.getPoint(); //tp.x, tp.y sont des valeurs ADC // si vous partagez des broches, vous devrez corriger les directions des broches de l'écran tactile pinMode(XM, OUTPUT); pinMode(YP, SORTIE); // nous avons une pression minimale que nous considérons comme « valide » // une pression de 0 signifie qu'il n'y a pas de pression ! if (tp.z> MINPRESSURE &&tp.z

Schémas


Processus de fabrication

  1. Jeu de gyroscope Arduino avec MPU-6050
  2. Jeu Arduino Pong - Écran OLED
  3. Piano tactile capacitif portable
  4. Contrôleur de jeu Arduino
  5. Jeu Arduino Pong sur matrice 24x16 avec MAX7219
  6. Giant Animatronics Lego Minfig Operation Game
  7. Adaptateurs MIDI sans fil USB-BLE
  8. Jeu Pixel Chaser
  9. Reconnaissance et synthèse vocales avec Arduino