Balle rebondissante

Créations

Aurélien Rodot

il y a 2 ans

Cette fois ça prend vie, votre programme bouge tout seul ! Les prémices de votre jeu de raquettes sont là.

Boïng boïng, ça rebondit de partout

Durée 20 minutes (et plus si affinité)

Niveau débutant total

Prérequis

Dans l'atelier précédent vous avez fait un compteur d'invités. Vous stockiez sa valeur dans une variable de type int qu'on avait décidé d'appeler counter (logique !). On avait des conditions if pour changer la valeur du compteur quand on appuie sur les boutons. Et finalement, on affichait un rectangle dont la position dépendait de la valeur de notre variable.

Si on résume, vous faisiez bouger un rectangle à l'écran en appuyant sur les boutons. Donc on est pas loin d'avoir une raquette de pong ;) Mais un Pong sans balle c'est pas bien fun, c'est pourquoi on va maintenant faire une balle rebondissante.

Aller de l'avant

Dans le cas de notre balle rebondissante, il serait plus approprié d'appeler la variable positionX que counter, pour mieux refléter ce à quoi elle sert : stocker la position de la balle suivant l'axe horizontal X. On en profite pour ajouter une variable speedX qui va servir à stocker la vitesse horizontale de la balle.

Ensuite, la balle va avancer d'elle même, pas besoin de condition if avec les boutons. On aurait donc quelque chose comme ça.

#include <Gamebuino-Meta.h>

int positionX = 32;
int speedX = 1;

void setup() {
  gb.begin();

}

void loop() {
  while (!gb.update());
  gb.display.clear();

  positionX = positionX + speedX;

  gb.display.print("positionX: ");
  gb.display.print(positionX);
  gb.display.print("\nspeedX: ");
  gb.display.print(speedX);

  gb.display.fillRect(positionX, 32, 4, 4);
}

À propos de l'écran

Quand vous avez appris à utiliser un graphique, vous avez sûrement vu quelque chose comme ça, où le centre est là où X et Y sont nuls, et les X et Y grandissent quand on se déplace vers le haut et vers la droite. Mais pour les écrans, ça ne marche pas tout à fait comme ça.


Les coordonnées sur l'écran de la Gamebuino META, comme n'importe quel autre écran, commencent en haut à gauche. En plus, les valeurs selon l'axe Y augmentent quand on descend (selon l'axe X, les valeurs augmentent vers la droite, comme sur un graphique classique).

Donc le coin à l'opposé - en bas à droite - a pour coordonnées (gb.display.width() - 1, gb.display.height() - 1).

Mais pourquoi est ce qu'on a soustrait 1 pour obtenir le coin en bas à droite? C'est parce-que le premier pixel (en haut à gauche) est en position (0, 0), et non en position (1, 1). Pour mieux comprendre pourquoi ce fait change tout, imaginons que notre écran avait seulement 4 pixels et que le premier avait comme coordonnée 0. Dans ce cas, quel serait la coordonnée du 4ème (dernier) pixel?

Ici, on voit facilement que le dernier pixel a une coordonnée de 3, pas 4. Et bien la même chose ce passe avec l'écran de la Gamebuino! Les pixels de droite ont une coordonnée X égale à gb.display.width() - 1. De la même manière, les pixels du bas ont une coordonnée Y de gb.display.height() - 1.

Remarque: L'écran fait 80 pixels de large par 64 pixels de haut. Vous pouvez vérifier la largeur avec gb.display.print(gb.display.width());. Ou en comptant ;). Cependant, même si vous connaissez les dimensions de l'écran, il ne faut pas écrire 80 là où on peut mettre gb.display.width(), car c'est moins explicite et est une sorte d'offuscation légère.


Puisque nous parlons de l'écran de positionnement, j'en profite pour approfondir l'utilisation de gb.display.drawRect(). Voici sa structure (que l'on a déjà vu):

gb.display.drawRect(int x, int y, int largeur, int hauteur);

Tout comme l'écran, les X et y sont passés par paramètres. Ce sont les coordonnées du coin en haut à gauche de notre rectangle. Donc on peut calculer la position de l'angle en bas à droite, et on obtient (x + largeur - 1, y + hauteur - 1).

Maintenant que nous avons vu tout ça, essayez d'afficher la balle plus haut sur l'écran. Essayez aussi de l'afficher tout en bas de l'écran :)

Garder la balle en vue

Essayons notre petit jeu et voyons ce qu'il se passe...Hé, mais la balle ne s'arrête pas ! Normal, on n'a mis aucune condition, elle continue donc d'avancer, même en dehors de l'écran. Comment est-ce qu'on pourrait faire? Voilà la logique à avoir, en pseudo-code.

                                Si la balle atteint le bord droit
                                Alors aller à gauche

                                Si la balle atteint le bord gauche
                                Alors aller à droite

Deux questions se posent alors...

  • Comment faire pour que la balle aille à gauche ?
  • Comment savoir quand on a atteint le bord de l'écran ?

Je vais vous donner la solution, mais vous devriez essayer d'y réfléchir un peu avant de regarder. Quelques indices : essayez de jouer avec la valeur de speedX pour faire varier la vitesse. Qu'est ce qui se passe avec une vitesse de 2, de 3 ? Une vitesse négative ?

Maintenant que vous avez trouvé le truc pour faire aller la balle à gauche (n'est-ce pas ?), vous n'avez plus qu'à détecter quand positionX atteint le bord de l'écran. Les coordonnées horizontales en X peuvent varier de 0 à gb.display.width(). Une valeur de 0 correspond au bord gauche de l'écran et une valeur de gb.display.width() correspond au bord droit.

Vous avez maintenant tous les éléments pour faire rebondir la balle de gauche à droite :) Si vous bloquez, voilà un coup de pouce.

#include <Gamebuino-Meta.h>

int positionX = 32;
int speedX = 1;

void setup() {
  gb.begin();

}

void loop() {
  while (!gb.update());
  gb.display.clear();

  positionX = positionX + speedX;

  // Si la balle atteint ou dépasse le bord gauche
  if(positionX < 0){
    // On part à droite
    speedX = 1;
  }

  // Si la balle atteint ou dépasse le bord droit
  if(positionX > gb.display.width()){
    // On part à gauche
    speedX = -1;
  }

  gb.display.print("positionX: ");
  gb.display.print(positionX);
  gb.display.print("\nspeedX: ");
  gb.display.print(speedX);

  gb.display.fillRect(positionX, 32, 4, 4);
}

À vous de jouer!

Si la balle ne bouge qu'à l'horizontale, ça ne va pas être très excitant comme partie de Pong. Pourquoi ne pas créer de nouvelles variables positionY et speedY pour permettre à la balle de bouger verticalement ? Il faudra aussi des conditions pour détecter le bord de l'écran, cette fois avec gb.display.height() qui donne la hauteur de l'écran.

Faites nous rêver sur les réseaux sociaux avec #gamebuino #bouncingball , on vous suit de près ;)

Exemple de solution

Si vous êtes en panne d'inspiration, voilà ce qu'on a fait de notre côté :)

 

#include <Gamebuino-Meta.h> 

 




int positionX = 32;
int speedX = 2;
int positionY = 32;
int speedY = 1;
int ballSize = 8;




void setup() {
  gb.begin();




}




void loop() {
  while (!gb.update());
  gb.display.clear();




  // Mise à jour de la position horizontale
  positionX = positionX + speedX;




  // Si la balle atteint le bord gauche
  if(positionX < 0){
    // On part à droite
    speedX = 2;
  }




  // Si la balle atteint le bord droit
  if(positionX > gb.display.width() - ballSize){
    // On part à droite
    speedX = -2;
  }




  // Mise à jour de la position verticale
  positionY = positionY + speedY;




    // Si la balle atteint le bord haut
  if(positionY < 0){
    // On part en bas
    speedY = 1;
  }




  // Si la balle atteint le bord bas
  if(positionY > gb.display.height() - ballSize){
    // On part en haut
    speedY = -1;
  }




  gb.display.setColor(BROWN);
  gb.display.print("positionX: ");
  gb.display.print(positionX);
  gb.display.print("\nspeedX: ");
  gb.display.print(speedX);




  gb.display.print("\npositionY: ");
  gb.display.print(positionY);
  gb.display.print("\nspeedY: ");
  gb.display.print(speedY);




  gb.display.setColor(WHITE);
  gb.display.fillRect(positionX, positionY, ballSize, ballSize);
}




 





  Atelier suivant

Par Aurélien Rodot, modifié par Julien Giovinazzo

Voir la création

ripper121

NEW il y a 2 ans

Is this like a contest?

Aurélien Rodot

il y a 2 ans

Nah, this is a workshop to learn programming, they are all here, but only in French now : https://gamebuino.com/academy/workshops

Aurélien Rodot

NEW il y a 2 ans

ripper121 ripper121

Nah, this is a workshop to learn programming, they are all here, but only in French now : https://gamebuino.com/academy/workshops

soltk

il y a 2 ans

Where is the tutorial?  Your link just goes to the main page.  I have my Gamebuino and cannot program for it because I do not know how.

Nux

NEW il y a 2 ans

"Je vais vous donner la solution, mais vous devriez essayer d'y réfléchir un peu avant de regarder. Quelques indices : essayez de jouer avec la valeur de speedX pour faire varier la vitesse. Qu'est ce qui se passe avec une vitesse de 2, de 3 ? Un vitesse négative ?

Maintenant que vous avez trouvé le truc pour faire aller la balle à gauche (n'est-ce pas ?), vous n'avez plus qu'à détecter quand positionX atteint le bord de l'écran. Les coordonnée horizontales en X vont de 0 au bord gauche à gb.display.width() au bord droit."

J'ai été déçus de cette partie, tu commence à donner des indices avant de nous avoir donner tout les outils pour réussir l'exercice.


Quand j'ai commencer à lire le premier paragraphe j'avais quelque idée en tête mais je voulais savoir comment récupérée la valeur du bord droit. Quand j'ai lut "Quelques indices:" j’espérais que ce soit la et quand j'ai vus que c’était un indice sur la résolution de l'exercices je me suis senti spoiler.


J'aime bien le concepts dans sa globalité mais au niveau du plan, je pense que ça serais beaucoup plus sympa si ça respectais un shema comme:


1/ On apprend un ou des trucs

2/ On nous proposes un exercice pour utilisé ce (ou ces) nouveau truc

3/ On nous donne tout les outils pour pourvoir réalise cette exercice (ici la fonction gb.display.width() )


4/ on nous invite a la réflexion. avec un truc du genre "Voila vous savez tout ce qu'il vous faut pour faire ca si jamais vous bloquez je vous laisse un petit indice".


5/ un petit ou des petits indices qui aide mais pas trop (ici le "une valeur negative ?" c'est plus un indice c'est la solution)

exemple:

Indice 1#: Vous aurez besoin d'utilisé les conditions if que nous avons vus dans l'atelier d'avant

Indice 2#: gb.display.width() est une constant est peut donc être utilisé dans votre programme comme un nombre

Indice 3#: Vous pouvez faire changer la balle de direction en modifiant la valeur de speedX



6/ une phrase pour dire que la solution est la " bon la je pense que je vous ai assez aider reprennez le temps de réflechir est si vous n'y arrivé vraiment pas, aidez vous de la solution"


J'ai l'impression que tu fait plus ou moins tout mais pas dans le bonne ordre.

Aurélien Rodot

il y a 2 ans

Merci Nux pour ce retour super construit, je vais mettre l'atelier à jour en prenant des remarques très pertinentes en compte :)

Aurélien Rodot

NEW il y a 2 ans

Nux Nux

Merci Nux pour ce retour super construit, je vais mettre l'atelier à jour en prenant des remarques très pertinentes en compte :)

soltk

NEW il y a 2 ans

Aurélien Rodot Aurélien Rodot

Where is the tutorial?  Your link just goes to the main page.  I have my Gamebuino and cannot program for it because I do not know how.

Aurélien Rodot

il y a 2 ans

Workshops are only in French now, you can change the language in the footer. We'll translate them soon, sit tight :)

Nux

il y a 2 ans

Hello, you can join us on discord (link at the bottom right of the page).

We will help you and give you advice when you need.

Nux

il y a 2 ans


note: I am not sure if you are totaly new in programing or experienced but don't know how to do with Gamebuino if you are experienced you can go to step 2.

In my opinion, the best is to start to learn C++.


So here what i personally think is the best to start on gamebuino.

Step 1: Learn C++ stuff, the best site i have found for it is this one -> http://www.learncpp.com/

I am restarting to learn c++ on this website because i was feeling to have to much gab in my knowledge

Step 2: If this is not already done follow this tutorial to get your Arduino IDE and be able to upload your sofware on it.
-> https://gamebuino.com/creations/gamebuino-meta-setup

Step 2.A: To discover new gamebuino function or understand how to use them, use the library reference here
-> https://gamebuino.com/fr/academy/reference

You can find this reference link at the bottom of the page under "ACADEMY"
--------------------------------------------------

You can do stuff on Gamebuino super early when you are learning c++ a programe saying "Hello" if  you press A and "Good-bye" if you press B.
Ok this is not the game of the year but at this point you are able interect with a potential user (aka player) and you can already do some small fun game with some imagination.
And at this moment every new knowledge learn from Step 1 will open new door.

Edit: And once again if you have any issue at once of those step you can ask us on discord or on the website. I will be glad to help you if i can.
Edit2: Sorry for the long post

Aurélien Rodot

NEW il y a 2 ans

soltk soltk

Workshops are only in French now, you can change the language in the footer. We'll translate them soon, sit tight :)

Nux

NEW il y a 2 ans

soltk soltk

Hello, you can join us on discord (link at the bottom right of the page).

We will help you and give you advice when you need.

Nux

NEW il y a 2 ans

soltk soltk


note: I am not sure if you are totaly new in programing or experienced but don't know how to do with Gamebuino if you are experienced you can go to step 2.

In my opinion, the best is to start to learn C++.


So here what i personally think is the best to start on gamebuino.

Step 1: Learn C++ stuff, the best site i have found for it is this one -> http://www.learncpp.com/

I am restarting to learn c++ on this website because i was feeling to have to much gab in my knowledge

Step 2: If this is not already done follow this tutorial to get your Arduino IDE and be able to upload your sofware on it.
-> https://gamebuino.com/creations/gamebuino-meta-setup

Step 2.A: To discover new gamebuino function or understand how to use them, use the library reference here
-> https://gamebuino.com/fr/academy/reference

You can find this reference link at the bottom of the page under "ACADEMY"
--------------------------------------------------

You can do stuff on Gamebuino super early when you are learning c++ a programe saying "Hello" if  you press A and "Good-bye" if you press B.
Ok this is not the game of the year but at this point you are able interect with a potential user (aka player) and you can already do some small fun game with some imagination.
And at this moment every new knowledge learn from Step 1 will open new door.

Edit: And once again if you have any issue at once of those step you can ask us on discord or on the website. I will be glad to help you if i can.
Edit2: Sorry for the long post

Adamko

NEW il y a 2 ans

vos avez fais une faute dans l'exemple de solution.

Juice_Lizard

il y a 2 ans

Il y a une petite erreur dans les commentaires: c'est écrit deux fois "si la balle atteint le bord gauche" (le second concerne le bord droit donc).

qpd00z

NEW il y a 2 ans

@Adamko: You're right, but it would have been nice if you had concurrently given a solution. So, I do.

Fail: The ball is moving out of screen, when it reaches the right side of the the screen. 

Solution: We have to subtract the size of the ball. (like in case of bottom touch)

Bugfix: 

Change

// If the ball reaches the right side of the screen
if(positionX > gb.display.width()){

into

// If the ball reaches the right side of the screen
if(positionX > gb.display.width() - ballSize){

and everything works fine.

Greetz & have fun everybody 

qpd00z

Juice_Lizard

NEW il y a 2 ans

Adamko Adamko

Il y a une petite erreur dans les commentaires: c'est écrit deux fois "si la balle atteint le bord gauche" (le second concerne le bord droit donc).

Aurélien Rodot

il y a 2 ans

Merci, c'est corrigé !

Aurélien Rodot

NEW il y a 2 ans

Juice_Lizard Juice_Lizard

Merci, c'est corrigé !