Breakout -- By JulienGio

Breakout

Author :  JulienGio

This workshop is still going through changes, therefore we only provide it in French. Come back soon :)

Author :  jicehel

Très bien Julien  ;)  J'ai trouvé des astuces que j'aurais pu appliquer dans mon casse-briques. Si j'y retouche, je pense que j'utiliserais le collide par exemple.

Sinon quelques petites fautes à corriger:  au début: tu met une fois casse brique (mieux vaut ajouter le s car tu le mets avant et après. Plus bas "en estiment" à corriger en "en estimant". Dans la section "Les briques", il est écrit: "Mais mieux les discerner", je pense qu'un pour a disparu et que tu voulais écrire "Mais pour mieux les discerner". Plus loin: " l'intérieur de deux accolades, n'existe pas à l'extérieur" => " l'intérieur de deux accolades, n'existent pas à l'extérieur". Avant Arc en ciel "vous devrez" => "vous devriez".

Après ce joli tuto j'espère que plein de lecteur auront des idées pour améliorer mon Breakout (casse-briques en anglais).  :D  

Author :  Juice_Lizard

"Un seul point-virgule vous manque et rien n'est compilé." (Lamartine à la plage)

Il faut enlever l'espace en trop dans #include <Gamebuino-Meta.h >

Et corriger les collide.rectRect en collideRectRect

Et là ça marche. Merci pour ce tuto.

Author :  Aurélien Rodot

Et corriger les collide.rectRect en collideRectRect

collideRectRect est obsolète, tu devrais mettre ta library à jour et utiliser gb.collide.rectRect :)

Author :  Juice_Lizard

Ma bibliothèque est déjà à jour, version 1.1.0, je ne vois pas de version plus récente. Dans votre article "Référence", c'est toujours écrit "collideRectRect".

Author :  Aurélien Rodot

La nouvelle 1.2.0 est maintenant en ligne ! https://github.com/Gamebuino/Gamebuino-META/releases/tag/1.2.0

Il faudra attendre quelques heures pour qu'elle apparaisse directement dans Arduino.

Author :  Grungy

Bonjour je débute et suis les tuto 1 par un et pour celui-ci je sèche mon casse brique reste tout blanc aucune couleurs arc en ciel, meme en faisant un copié/collé du code...


Author :  Codnpix

Bonjour, merci pour ce tuto ! Je suis arrivé au bout mais je crois que j'ai trouvé une petite erreur, ou alors je n'ai pas saisi quelque chose.. : 

Dans la condition pour vérifier s'il reste des briques  :

for (int x = 0; x < GRILLE_TAILLE; x += 1) {
          for (int y = 0; y < GRILLE_TAILLE; y += 1) {
            if (briques[y][x] == 0) {  // On a trouvé une brique!
              plusDeBriques = false;  // ne pas reinitialiser
            }
          }

est-ce que √ßa ne serait pas plut√īt :" if (briques[y][x] == 1) " au lieu de if (briques[y][x] == 0) ? (Elles existent quand elles sont √©gales √† 1, donc si on en trouve une √©gale √† 1 c'est qu'elle existe encore...

___

Sinon, j'ai fait un essai de calcul pour la vitesse ajout√©e en x √† la balle pour pouvoir contr√īler un peu l'angle avec lequel on la fait rebondir. Le rendu n'est pas tr√®s tr√®s propre mais √ßa fonctionne quand m√™me √† peu pr√®s comme j'imaginais. Je partage mon extrait de code, si vous avez des conseils :).

L'idée est que l'angle avec lequel la balle est renvoyée varie en fonction de la distance entre la balle et le bord de la palette au moment du rebond. Si on tape au centre de la palette la balle rebondit verticalement, si on tape plus ou moins proche du bord gauche, on rebondit plus ou moins vers la gauche, pareil pour la droite...

void update() {
//...
//collisions
    if (gb.collide.rectRect(ballX, ballY, BALL_SIZE, BALL_SIZE, padX, padY, PAD_W, PAD_H) || ballY <= 0) {
      if (gb.collide.rectRect(ballX, ballY, BALL_SIZE, BALL_SIZE, padX, padY, PAD_W, PAD_H)) {
    float dist_edgePad_left = (ballX + BALL_SIZE /2) - padX;//distance balle/c&ocirc;t&eacute; gauche pad
    float dist_edgePad_right = (padX + PAD_W) - (ballX + BALL_SIZE /2);//distance ball/c&ocirc;t&eacute; droit pad

    if (dist_edgePad_right &gt; dist_edgePad_left) {
      speedX = min(-1 / dist_edgePad_left, -1);//si la balle est du cot&eacute; gauche du pad, partir vers la gauche(speeX max = -1)
    }
    else if (dist_edgePad_left &gt; dist_edgePad_right) {
      speedX = min(1 / dist_edgePad_right, 1);//si la balle est du c&ocirc;t&eacute; droit, partir vers la droite(speeX max = 1)
    } 
    else {
      speedX = 0;
    }
  }

  speedY *= -1;
}

//…
}

Author :  jicehel

Tu as raison pour le test avec if (briques[y][x] == 1) pour vérifier qu'il y a encore des briques.

Sinon tu t'embêtes à calculer la distance par rapport à la gauche ou à la droite... Est ce vraiment nécessaire ? Tu as déjà le signe si tu calcules par apport au milieu de la raquette... Par contre comme ta raquette est plate, ton rebond devrait se faire juste en inversant la vitesse en y. Pour ton genre de rebond, la raquette devrait être courbe si je ne m'abuse.

Sinon, si tu veux que ta vitesse soit plus réalise, change les vx et vy. Tant qu'ils seront en entier, tu auras des choses bizarre avec les formules que tu appliques.

Bonne chance pour tes dev et n'hésites pas à partager ton résultat. 

PS pou l'√©quipe et Sylvain: Pour les tutos avec des sujets communs pour que tout le monde puisse partager sa cr√©ation sans cr√©er des centaines de cr√©ations sur le m√™me sujet. Sur une cr√©ation ou un tuto, l'id√©e serait de pouvoir cr√©er une cr√©ation rattach√©e √† ce sujet (qui n'appara√ģtrait pas dans les listes de cr√©ations).





Author :  Codnpix

Merci de ta réponse.

Par contre comme ta raquette est plate, ton rebond devrait se faire juste en inversant la vitesse en y. Pour ton genre de rebond, la raquette devrait être courbe si je ne m'abuse.

L'idée était justement un peu "d'émuler" une surface de raquette un peu courbe. Même si dans la réalité elle reste plate effectivement...

Sinon, si tu veux que ta vitesse soit plus réalise, change les vx et vy. Tant qu'ils seront en entier, tu auras des choses bizarre avec les formules que tu appliques.

J'avais bien passé ballX et speedX en float pour pouvoir y mettre la valeur que je récupère avec "+ ou - 1 / distance_bord_droit_ou_gauche".  Pour speedY je n'y pas touché, c'est toujours 1 ou -1.

J'essaierai de chercher un calcul plus efficace en me basant sur le milieu plut√īt que sur les bords.

Voici la totalité de mon code, ce sera plus concret (et plus simple pour tester le résultat peut-être ^^) !

#include <Gamebuino-Meta.h>

bool launched;

//balle
float ballX;
int ballY;
float speedX;
int speedY;
const int BALL_SIZE = 4;

//palette
int padX;
int padY;
const int PAD_W = 14;
const int PAD_H = 3;

//briques
const int GRID_SIZE = 8;
int briques[GRID_SIZE][GRID_SIZE];
const int BRICK_W = gb.display.width() / GRID_SIZE - 2;
const int BRICK_H = 3;

void setup() {
gb.begin();
initGame();
}

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

input();
if (launched) {
updates();
}
draw();
}


void input() {
    //ENTREES//
    if (gb.buttons.pressed(BUTTON_A)) {
      launched = true;
    }
    if (gb.buttons.repeat(BUTTON_LEFT,0)) {
      movePad("left");
    }
    if (gb.buttons.repeat(BUTTON_RIGHT,0)) {
      movePad("right");
    }
}


void updates() {
    //UPDATES//
//collisions
if (gb.collide.rectRect(ballX, ballY, BALL_SIZE, BALL_SIZE, padX, padY, PAD_W, PAD_H) || ballY &lt;= 0) {
  if (gb.collide.rectRect(ballX, ballY, BALL_SIZE, BALL_SIZE, padX, padY, PAD_W, PAD_H)) {

    float dist_edgePad_left = (ballX + BALL_SIZE /2) - padX;//distance balle/c&ocirc;t&eacute; gauche pad
    float dist_edgePad_right = (padX + PAD_W) - (ballX + BALL_SIZE /2);//distance balle/c&ocirc;t&eacute; droit pad

    if (dist_edgePad_right &gt; dist_edgePad_left) {
      speedX = min(-1 / dist_edgePad_left, -1);//si la balle est du cot&eacute; gauche du pad, partir vers la gauche(speeX max = -1)
    }
    else if (dist_edgePad_left &gt; dist_edgePad_right) {
      speedX = min(1 / dist_edgePad_right, 1);//si la balle est du c&ocirc;t&eacute; droit, partir vers la droite(speeX max = 1)
    } 
    else {
      speedX = 0;
    }
  }

  speedY *= -1;
}

else if (ballX + BALL_SIZE &gt;= gb.display.width() || ballX &lt;= 0) {
  speedX *= -1;
}

else if (ballY + BALL_SIZE &gt;= gb.display.height()) {
  initGame();
}

//collisions briques

for (int rangee = 0; rangee &lt; GRID_SIZE; rangee++) {
  for (int colonne = 0; colonne &lt; GRID_SIZE; colonne++) {
    if (briques[rangee][colonne] == 0) {
      continue;
    }
    int briqueX =  colonne * (BRICK_W +2) +1;
    int briqueY = rangee * (BRICK_H +2) +1;
    if (gb.collide.rectRect(ballX, ballY, BALL_SIZE, BALL_SIZE, briqueX, briqueY, BRICK_W, BRICK_H)) {
      speedY *= -1;
      briques[rangee][colonne] = 0;//detruire la brique en cas de collision
      //verifier briques restantes
      bool zeroBriques = true;//passera &agrave; false si il reste au moins une brique
      for (int x = 0; x &lt; GRID_SIZE; x++) {
        for (int y = 0; y &lt; GRID_SIZE; y++) {
          if (briques[y][x] == 1) {
            zeroBriques = false;
          }
        }
      }
      if (zeroBriques) {
        initGame();
      }
    }
  }
}
ballX += speedX;
ballY += speedY;

}

void initGame() {
padX = gb.display.width() /2 - 5;
padY = gb.display.height() -3;
ballX = padX + PAD_W /2 - BALL_SIZE /2;
ballY = padY - BALL_SIZE;
speedX = 0;
speedY = -1;
launched = false;

for (int rangee = 0; rangee < GRID_SIZE; rangee++) {
for (int colonne = 0; colonne < GRID_SIZE; colonne++) {
briques[rangee][colonne] = 0;
}
}

for (int rangee = 0; rangee < GRID_SIZE; rangee++) {
for (int colonne = 0; colonne < GRID_SIZE; colonne++) {
briques[rangee][colonne] = rangee + 1;
}
}
}

void movePad(char dir[6]) {
if (dir == "left") {
if (padX <=0) {
padX = 0;
} else {
padX -= 1;
}
}
else if (dir == "right") {
if (padX + PAD_W >= gb.display.width()) {
padX = gb.display.width() - PAD_W;
} else {
padX += 1;
}
} else {
padX = padX;
}
}


void draw() {
    //DISPLAY//
  gb.display.clear();
  //paddle 
  gb.display.fillRect(padX, padY, PAD_W, PAD_H);
  //ball
  gb.display.fillRect(ballX, ballY, BALL_SIZE, BALL_SIZE);
  //briques
  const Color rainbow[8] = {WHITE, PURPLE, RED, YELLOW, LIGHTGREEN, GREEN, DARKBLUE, BLUE};
  for (int rangee = 0; rangee < GRID_SIZE; rangee ++) {
    for (int colonne = 0; colonne < GRID_SIZE; colonne++) {
      if(briques[rangee][colonne] == 0) {
        continue;
      }
      gb.display.setColor(rainbow[briques[rangee][colonne] - 1]);
      int briqueX = colonne * (BRICK_W + 2) + 1;
      int briqueY = rangee * (BRICK_H +2) +1;
      gb.display.fillRect(briqueX, briqueY, BRICK_W, BRICK_H);
    }
  }
}
Author :  Max_NN

Bonjour tout le monde ! J'ai un problème, je veux faire un programme qui dessine un cercle avec une taille aléatoire, mais pour le moment la taille est toujours la même. Voici mon programme. Merci !

#include <Gamebuino-Meta.h>

int ballSize = random(1, 15);

void setup() {
  gb.begin();
}

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

 
  gb.display.print(ballSize);
  gb.display.setColor(WHITE);
  gb.display.drawCircle(39, 31, ballSize);
}

Author :  deeph

Tu devrais créer ta propre discussion parce que là c'est un peu hors sujet.

En regardant rapidement ton code, le probl√®me c'est que ton calcul al√©atoire est en dehors de la boucle, donc qu'il ne s‚Äôex√©cute qu'une fois. Essaie plut√īt √ßa :

#include <Gamebuino-Meta.h>

void setup() {
gb.begin();
}

void loop() {
gb.display.clear();
gb.display.setColor(WHITE);
int ballSize = random(1, 15);
gb.display.print(ballSize);
gb.display.drawCircle(39, 31, ballSize);
while (!gb.update());
}