Jeu rétro arduino avec un écran oled
Jamais demandé combien le travail qu`il faut pour écrire vos propres jeux rétro? Comment est facile Pong à coder pour l`Arduino? Joignez-vous à moi comme je vous montre comment construire une console mini-jeux rétro alimenté Arduino, et comment le code Pong à partir de zéro. Voici le résultat final:
Contenu
plan de construction
Ceci est un circuit assez simple. UNE potentiomètre (Pot) va contrôler le jeu, et un écran OLED sera entraîné par l`Arduino. Ce sera produit sur une planche à pain, mais vous pouvez faire un circuit permanent et l`installer dans un cas. Nous avons écrit à propos de recréant Pong Mais avant aujourd`hui, je vais vous montrer comment écrire le code à partir de zéro, et à faire tomber toutes les parties.Comment faire pour Recréer le jeu classique Pong utilisant ArduinoComment faire pour Recréer le jeu classique Pong utilisant ArduinoPong a été le premier jeu vidéo qui a atteint le marché de masse. Pour la première fois dans l`histoire, le concept de "jeu vidéo" a été amené dans la maison familiale, grâce à l`Atari 2600 -...Lire la suite
De quoi as-tu besoin
Voici ce que vous avez besoin:
- 1 x Arduino (tout modèle)
- 1 x 10k Potentiomètre
- 1 x 0,96 "écran OLED I2C
- 1 x Breadboard
- mâle assorties gt; mâle fil de montage
Tout Arduino devrait fonctionner, alors regardez notre Guide d`achat si vous n`êtes pas sûr de ce modèle à acheter.
Ces écrans OLED sont très cool. Ils peuvent généralement être achetés en blanc, bleu, jaune, ou un mélange des trois. Ils existent en couleur, mais ceux-ci ajoutent un tout autre niveau à la complexité et le coût de ce projet.
Le circuit
Ceci est tout à fait un circuit simple. Si vous n`avez pas beaucoup d`expérience avec Arduino, consultez ces projets débutants premier.10 Grands projets Arduino pour les débutants10 Grands projets Arduino pour les débutantsRemplir un projet Arduino vous donne un sentiment de satisfaction comme aucun autre. La plupart des débutants ne sont pas sûrs où commencer cependant, et même les projets débutants peuvent sembler assez intimidant.Lire la suite
C`est ici:
En regardant la face avant du pot, connecter la broche de gauche à +5 V et la broche droit de sol. Connectez la broche du milieu à analogique broche 0 (A0).
L`écran OLED est connecté en utilisant le protocole I2C. Relier CCV et GND à l`Arduino +5 V et sol. Relier SCL à analogique cinq (A5). Relier SDA à analogique 4 (A4). La raison pour laquelle cela est relié aux broches analogiques est simple- ces broches contiennent les circuits requis pour le protocole I2C. Assurez-vous qu`ils sont connectés correctement et ne se croisent pas. Les broches exactes varient selon le modèle, mais A4 et A5 sont utilisés sur le Nano et Uno. Consultez la documentation de la bibliothèque de fil pour votre modèle si vous n`êtes pas en utilisant un Arduino ou Nano.
pot test
Téléchargez ce code de test (assurez-vous de sélectionner la carte et le port de la Outils gt; Planche et Outils gt; Port menus):
vide installer() {// mettre votre code d`installation ici, pour exécuter une fois:En série.commencer(9600)- // série d`installation}vide boucle() {// mettre votre code principal ici, pour exécuter de façon répétitive:En série.println(analogRead(A0))- // imprimer la valeur du potretard(500)-}
Maintenant, ouvrez le moniteur série (En haut à droite gt; Serial Monitor) Et tourner le pot. Vous devriez voir la valeur affichée sur le moniteur de série. Entièrement anti-horaire devrait être zéro, et dans le sens horaire devrait être 1023:
Vous ajusterez plus tard, mais pour l`instant il est très bien. Si rien ne se passe, ou les changements de valeur sans vous rien faire, débrancher et vérifiez le circuit.
test OLED
L`écran OLED est un peu plus complexe à configurer. Vous devez installer deux bibliothèques pour commander l`affichage en premier. Télécharger les bibliothèques Adafruit_SSD1306 et Adafruit-GFX de Github. Copiez les fichiers dans le dossier des bibliothèques. Cela varie en fonction de votre système d`exploitation:
- Mac OS: / Utilisateurs / Nom d`utilisateur / Documents / Arduino / bibliothèques
- Linux: / Home / Nom d`utilisateur / Sketchbook
- Les fenêtres: / Utilisateurs / Arduino / bibliothèques
Maintenant télécharger une esquisse de test. Aller à Fichier gt; Exemples gt; Adafruit SSD1306 gt; ssd1306_128x64_i2c. Cela devrait vous donner une grande esquisse contenant beaucoup de graphiques:
Si rien ne se passe après le téléchargement, débranchez et vérifiez vos connexions. Si les exemples ne sont pas dans les menus, vous devrez peut-être redémarrer votre Arduino IDE.
Le code
Maintenant il est temps pour le code. Je serai expliquer toutes les étapes, donc passer à la fin si vous voulez juste pour le faire fonctionner. Ceci est une bonne quantité de code, donc si vous ne vous sentez pas à l`aise, consultez ces 10 ressources gratuites, et ces 5 grandes ressources apprendre à code.Apprenez à code: 10 gratuit et fantastiques ressources en ligne pour affûter vos compétencesApprenez à code: 10 gratuit et fantastiques ressources en ligne pour affûter vos compétencesCodage. Un sujet qui est évité par beaucoup. Il y a une abondance de ressources et d`outils gratuits, qui sont tous disponibles en ligne. Bien sûr, vous pouvez prendre des cours sur le sujet à proximité ...Lire la suite
Commencez par y compris les bibliothèques nécessaires:
#comprendre #comprendre #comprendre #comprendre
SPI et CÂBLE sont deux bibliothèques Arduino pour gérer la communication I2C. Adafruit_GFX et Adafruit_SSD1306 sont les bibliothèques installées précédemment.
Ensuite, configurer l`affichage:
Adafruit_SSD1306 afficher(4)-
Ensuite, configurer toutes les variables nécessaires pour exécuter le jeu:
int résolution[2] = {128, 64}, ballon[2] = {20, (résolution[1] / 2)}-const int PIXEL_SIZE = 8, WALL_WIDTH = 4, PADDLE_WIDTH = 4, BALL_SIZE = 4, LA VITESSE = 3-int playerScore = 0, aiScore = 0, playerpos = 0, aiPos = 0-carboniser ballDirectionHori = `R`, ballDirectionVerti = `S`-booléen InProgress = vrai-
Ces stocker toutes les données nécessaires pour exécuter le jeu. Certains de ces magasins l`emplacement de la balle, la taille de l`écran, l`emplacement du joueur et ainsi de suite. Remarquez comment certains d`entre eux sont const ce qui signifie qu`ils sont constants, et ne changera jamais. Cela permet le bit d`accélérer les choses du compilateur Arduino vers le haut.
La résolution de l`écran et l`emplacement de la balle sont stockés dans tableaux. Les tableaux sont des collections de choses semblables, et la balle, stocker les coordonnées (X et Y). L`accès aux éléments dans des tableaux est facile (ne pas inclure ce code dans votre fichier):
résolution[1]-
Sous forme de tableaux à partir de zéro, cela renvoie le deuxième élément dans la matrice de résolution (64). Mise à jour des éléments est encore plus facile (encore une fois, ne comprennent pas ce code):
ballon[1] = 15-
À l`intérieur void setup(), configurer l`affichage:
vide installer() {afficher.commencer(SSD1306_SWITCHCAPVCC, 0x3C)-afficher.afficher()-}
La première ligne indique la bibliothèque Adafruit ce protocole dimensions et les communications de votre affichage utilise (dans ce cas, 128 X 64 et I2C). La seconde ligne (display.display ()) Indique à l`écran pour montrer tout ce qui est stocké dans la mémoire tampon (qui est rien).
Créer deux méthodes appelées drawBall et eraseBall:
vide drawBall(int X, int y) {afficher.drawCircle(X, y, BALL_SIZE, BLANC)-}vide eraseBall(int X, int y) {afficher.drawCircle(X, y, BALL_SIZE, NOIR)-}
Celles-ci prennent la X et y les coordonnées de la balle et dessiner sur l`écran en utilisant le drawCircle Procédé de bibliothèques d`affichage. Celui-ci utilise la constante BALL_SIZE défini précédemment. Essayez de changer cela et de voir ce qui se passe. Cette méthode de drawCircle accepte une couleur de pixel - NOIR ou BLANC. Comme ceci est un affichage monochromatique (une couleur), blanc correspond à un pixel se trouvant sur, et se transforme en noir du pixel éteint.
Maintenant, créez une méthode appelée moveAi:
vide moveAi() {eraseAiPaddle(aiPos)-si (ballon[1] gt; aiPos) {++aiPos-}autre si (ballon[1] lt; aiPos) {--aiPos-}drawAiPaddle(aiPos)-}
Cette méthode gère le déplacement de la Intelligence artificielle ou AI joueur. Ceci est tout à fait un adversaire simple ordinateur - Si la balle est au-dessus de la palette, déplacer vers le haut. Il est en dessous de la palette, déplacer vers le bas. Très simple, mais il fonctionne bien. Les symboles d`incrémentation et de décrémentation sont utilisés (++aiPos et -aiPos) Pour ajouter ou soustraire un de la aiPosition. Vous pouvez ajouter ou soustraire un plus grand nombre de faire l`AI se déplacer plus rapidement, et donc plus difficile à battre. Voici comment vous le faire:
aiPos += 2-
Et:
aiPos -= 2-
le en plus Equals et moins Equals les signes sont des abréviations pour additionner ou soustraire deux de / à la valeur courante de aiPos. Voici une autre façon de le faire:
Video: Jeu video sur shield écran LCD 16*2 Arduino
aiPos = aiPos + 2-
et
aiPos = aiPos - 1-
Remarquez comment cette méthode permet d`effacer d`abord la palette, puis dessine à nouveau. Cela doit être fait comme ça. Si la nouvelle position de la palette a été établi, il y aurait deux palettes qui se chevauchent sur l`écran.
le DrawNet procédé utilise deux boucles pour dessiner le but:
vide DrawNet() {pour (int je = 0- je lt; (résolution[1] / WALL_WIDTH)- ++je) {drawPixel(((résolution[0] / 2) - 1), je * (WALL_WIDTH) + (WALL_WIDTH * je), WALL_WIDTH)-}}
Celui-ci utilise la WALL_WIDTH variables à définir sa taille.
Video: simulation ARDUINO + AFFICHEUR LCD sur ISIS PROTEUS
Créer des méthodes appelées drawPixels et erasePixels. Tout comme les méthodes de balle, la seule différence entre ces deux est la couleur des pixels:
vide drawPixel(int posX, int posY, int dimensions) {pour (int X = 0- X lt; dimensions- ++X) {pour (int y = 0- y lt; dimensions- ++y) {afficher.drawPixel((posX + X), (posY + y), BLANC)-}}}vide erasePixel(int posX, int posY, int dimensions) {pour (int X = 0- X lt; dimensions- ++X) {pour (int y = 0- y lt; dimensions- ++y) {afficher.drawPixel((posX + X), (posY + y), NOIR)-}}}
Encore une fois, ces deux méthodes utilisent deux pour boucles pour dessiner un groupe de pixels. Plutôt que d`avoir à dessiner chaque pixel en utilisant les bibliothèques drawPixel procédé, les boucles dessiner un groupe de pixels sur la base des dimensions données.
le drawScore méthode utilise les caractéristiques du texte de la bibliothèque pour écrire le joueur et le score AI à l`écran. Ceux-ci sont stockés dans playerScore et aiScore:
vide drawScore() {afficher.SetTextSize(2)-afficher.SetTextColor(BLANC)-afficher.setCursor(45, 0)-afficher.println(playerScore)-afficher.setCursor(75, 0)-afficher.println(aiScore)-}
Cette méthode a également eraseScore homologue, qui définit les pixels de noir ou hors tension.
Les quatre dernières méthodes sont très similaires. Ils dessinent et effacent le joueur et palettes AI:
vide erasePlayerPaddle(int rangée) {erasePixel(0, rangée - (PADDLE_WIDTH * 2), PADDLE_WIDTH)-erasePixel(0, rangée - PADDLE_WIDTH, PADDLE_WIDTH)-erasePixel(0, rangée, PADDLE_WIDTH)-erasePixel(0, rangée + PADDLE_WIDTH, PADDLE_WIDTH)-erasePixel(0, rangée + (PADDLE_WIDTH + 2), PADDLE_WIDTH)-}
Remarquez comment ils appellent la erasePixel méthode créer plus tôt. Ces méthodes dessinent et effacent la palette appropriée.
Il y a un peu plus de logique dans la boucle principale. Voici le code complet:
#comprendre #comprendre #comprendre #comprendre Adafruit_SSD1306 afficher(4)-int résolution[2] = {128, 64}, ballon[2] = {20, (résolution[1] / 2)}-const int PIXEL_SIZE = 8, WALL_WIDTH = 4, PADDLE_WIDTH = 4, BALL_SIZE = 4, LA VITESSE = 3-int playerScore = 0, aiScore = 0, playerpos = 0, aiPos = 0-carboniser ballDirectionHori = `R`, ballDirectionVerti = `S`-booléen InProgress = vrai-vide installer() {afficher.commencer(SSD1306_SWITCHCAPVCC, 0x3C)-afficher.afficher()-}vide boucle() {si (aiScore gt; 9 || playerScore gt; 9) {// vérifier l`état du jeuen cours = faux-}si (en cours) {eraseScore()-eraseBall(ballon[0], ballon[1])-si (ballDirectionVerti == `U`) {// déplacer la balle en diagonaleballon[1] = ballon[1] - LA VITESSE-}si (ballDirectionVerti == `RÉ`) {// déplacer la balle en diagonaleballon[1] = ballon[1] + LA VITESSE-}si (ballon[1] lt; = 0) { // rebondir la balle sur le dessus ballDirectionVerti = « D`-} if (balle [1] gt; = résolution [1]) {// rebondir la balle sur le fondballDirectionVerti = `U`-}si (ballDirectionHori == `R`) {ballon[0] = ballon[0] + LA VITESSE- // déplacer une ballesi (ballon[0] gt; = (résolution[0] - 6)) {// balle est au bord de l`écran AIsi ((aiPos + 12) gt; = ballon[1] && (aiPos - 12) lt; = ballon[1]) { // frappe paddleball AI si (balle [1] gt; (AiPos + 4)) {// dévier vers le bas balleballDirectionVerti = `RÉ`-}autre si (ballon[1] lt; (aiPos - 4)) {// dévier la balle en placeballDirectionVerti = `U`-}autre {// dévier la balle droiteballDirectionVerti = `S`-}// changement de direction balleballDirectionHori = `L`-}autre {// OBJECTIF!ballon[0] = 6- // déplacer la balle de l`autre côté de l`écranballDirectionVerti = `S`- // remettre la balle à Voyage droiteballon[1] = résolution[1] / 2- // déplacer la balle au milieu de l`écran++playerScore- // augmentation score joueur}}}si (ballDirectionHori == `L`) {ballon[0] = ballon[0] - LA VITESSE- // déplacer une ballesi (ballon[0] lt; = 6) { // balle est à l`avant du lecteur de l`écran if ((playerpos + 12) gt; = bille [1] && (12) - playerpos lt; = boule [1]) {// balle frappe paddle joueur si (balle [1] gt; (Playerpos + 4)) {// dévier vers le bas balleballDirectionVerti = `RÉ`-}autre si (ballon[1] lt; (playerpos - 4)) { // dévier la balle en ballDirectionVerti = `U`-} else {// dévier la balle droite ballDirectionVerti =` S`-} // changer la direction du ballon ballDirectionHori = « R`-} else {ball [0] = résolution [0] - 6- // déplacer la balle de l`autre côté de l`écran ballDirectionVerti = « S`- // réinitialiser balle balle de Voyage droite [1] = résolution [1] / 2- // déplacer balle au milieu de l`écran ++ // aiScore- augmenter partition AI}}} drawBall (bille [0], boule [1]) - erasePlayerPaddle (playerpos) - playerpos = analogRead (A2) - // lu potentiomètre joueur playerpos = carte (playerpos, 0, 1023, 8, 54) - // valeur de conversion 0-1023 8 - 54 drawPlayerPaddle (playerpos) - moveAi () - DrawNet () - drawScore () -} else {// quelqu`un a gagné display.clearDisplay () - display.setTextSize (4) - display.setTextColor (BLANC) - display.setCursor (0, 0) - // savoir qui si (aiScore gt; playerScore) {afficher.println("TU AS PERDU!")-}autre si (playerScore gt; aiScore) {afficher.println("VOUS GAGNEZ!")-}}afficher.afficher()-}vide moveAi() {// déplacer la palette AIeraseAiPaddle(aiPos)-si (ballon[1] gt; aiPos) {++aiPos-}autre si (ballon[1] lt; aiPos) {--aiPos-}drawAiPaddle(aiPos)-}vide drawScore() {// Dessine scores AI et les joueursafficher.SetTextSize(2)-afficher.SetTextColor(BLANC)-afficher.setCursor(45, 0)-afficher.println(playerScore)-afficher.setCursor(75, 0)-afficher.println(aiScore)-}vide eraseScore() {// effacer les scores AI et les joueursafficher.SetTextSize(2)-afficher.SetTextColor(NOIR)-afficher.setCursor(45, 0)-afficher.println(playerScore)-afficher.setCursor(75, 0)-afficher.println(aiScore)-}vide DrawNet() {pour (int je = 0- je lt; (résolution[1] / WALL_WIDTH)- ++je) {drawPixel(((résolution[0] / 2) - 1), je * (WALL_WIDTH) + (WALL_WIDTH * je), WALL_WIDTH)-}}vide drawPixel(int posX, int posY, int dimensions) {// tirer groupe de pixelspour (int X = 0- X lt; dimensions- ++X) {pour (int y = 0- y lt; dimensions- ++y) {afficher.drawPixel((posX + X), (posY + y), BLANC)-}}}vide erasePixel(int posX, int posY, int dimensions) {// effacement groupe de pixelspour (int X = 0- X lt; dimensions- ++X) {pour (int y = 0- y lt; dimensions- ++y) {affic