Casse brique - évolution

Créations

Codnpix

il y a 5 ans

This is a little breakout game, based on a customisation of the one from this tutorial https://gamebuino.com/fr/creations/breakout .

Evolutions :

- Multiple levels (6, maybe more one day :))

- Bounce angle control on paddle

- Various types of bricks (1, 2, 3 shots destroyed, moving bricks...)

- custom FX

- user menu (level choose, see locked and unlocked levels)

- music (to get the version with the musics download the .wav files in that repository : https://github.com/Codnpix/casse_brique_evolution and just add them inside the folder you downloaded here.)


Thank you for giving me feedbacks of any kind :) !


Petit essai de jeu de casse-brique en évolution de celui proposé par le tutoriel https://gamebuino.com/fr/creations/breakout .

Évolutions :

- Plusieurs niveaux (6, peut-être d'autres un jour :))

- Contrôle de l'angle de rebond sur la palette

- briques variées, briques en mouvement...

- menu utilisateur (choisir le niveau, voir les niveaux bloqués et débloqués)

- custom FX

- musique (Pour télécharger le jeu avec les musiques, rendez-vous ici : https://github.com/Codnpix/casse_brique_evolution , vous pouvez juste télécharger tous les .wav et les ajouter dans le dossier téléchargé ici).


Merci pour vos retours :) !

Voir la création

geed

NEW il y a 5 ans

ça fonctionne très bien :)
c'est simple mais niveau gameplay, à part peut-être des bonus et/ou une accélération de la balle, je vois pas quoi ajouter de plus !

Un "vrai" menu, une page de scores, et hop, ça fera un excellent casse-brique à laisser sur la carte :)


Codnpix

il y a 5 ans

Merci :) !

Disons que je me sers de développer ce petit jeu pour apprendre et prendre en main l'environnement Gamebuino, c'est parti du tutoriel et j'essaye d'y ajouter les idées qui viennent, ça fait des petits challenges de programmation, c'est formateur... Par exemple je suis en train d'ajouter des niveaux ou les briques bougent, et là je bloque totalement pour arriver à les faire bouger ensemble autour d'un cercle, mon niveau en math me fait un peu défaut ^^. Mais quand je verrai le bout de mes petites idées de customisation j'essaierai de soigner un peu plus la présentation !

jicehel

NEW il y a 5 ans

Pas eu le temps de vraiment tester mais je vais y remédier  ;)

Codnpix

NEW il y a 5 ans

geed geed

Merci :) !

Disons que je me sers de développer ce petit jeu pour apprendre et prendre en main l'environnement Gamebuino, c'est parti du tutoriel et j'essaye d'y ajouter les idées qui viennent, ça fait des petits challenges de programmation, c'est formateur... Par exemple je suis en train d'ajouter des niveaux ou les briques bougent, et là je bloque totalement pour arriver à les faire bouger ensemble autour d'un cercle, mon niveau en math me fait un peu défaut ^^. Mais quand je verrai le bout de mes petites idées de customisation j'essaierai de soigner un peu plus la présentation !

geed

il y a 5 ans

Regarde mon jeu DTC, pour la partie menu et score, tu auras un truc "clef en main" à adapter à ton usage. J'ai moi même piqué/adapté le code à Rodot sur UFO-Race pour cette partie là, des fois, ça ne sert à rien de réinventer l'eau chaude :D

Pour tes histoires de mouvements en cercle, pourquoi ne pas faire un petit tableau qui contiendrait les "modificateurs" de position en X/Y de ta brique. A chaque itération tu "avances" d'un cran dans le tableau et modifie la positions de ta briques avec le modificateur sur les coordonnées.
Tu peux même imaginer plusieurs "pattern" du coup, avec plusieurs tableaux (en rond, en rectangle, etc. etc.). Pis comme ça, pas de calcul compliqué avec des maths (sin/cos etc.) qui ralentiront ton programme.

geed

NEW il y a 5 ans

Codnpix Codnpix

Regarde mon jeu DTC, pour la partie menu et score, tu auras un truc "clef en main" à adapter à ton usage. J'ai moi même piqué/adapté le code à Rodot sur UFO-Race pour cette partie là, des fois, ça ne sert à rien de réinventer l'eau chaude :D

Pour tes histoires de mouvements en cercle, pourquoi ne pas faire un petit tableau qui contiendrait les "modificateurs" de position en X/Y de ta brique. A chaque itération tu "avances" d'un cran dans le tableau et modifie la positions de ta briques avec le modificateur sur les coordonnées.
Tu peux même imaginer plusieurs "pattern" du coup, avec plusieurs tableaux (en rond, en rectangle, etc. etc.). Pis comme ça, pas de calcul compliqué avec des maths (sin/cos etc.) qui ralentiront ton programme.

Codnpix

il y a 5 ans

Ok j'irai voir ! 

Pour les patterns stockés dans un tableau j'ai un peu essayé, je ne m'en suis pas vraiment sorti mais il faut peut être que je creuse encore un peu.

Codnpix

NEW il y a 5 ans

geed geed

Ok j'irai voir ! 

Pour les patterns stockés dans un tableau j'ai un peu essayé, je ne m'en suis pas vraiment sorti mais il faut peut être que je creuse encore un peu.

Codnpix

NEW il y a 5 ans

Bonjour à tous, 

je suis en train d'essayer de mettre en place le menu pour pouvoir sélectionner manuellement un niveau dans mon casse brique, et ça m'a fait mettre le doigt sur un problème que je n'arriver pas à solutionner : 

Les images des briques leurs sont assignées en fonction d'un tableau d'entiers de ce style :

 {
    {0,1,1,1,1,1,1,0},
    {0,2,0,2,1,0,2,0},
    {0,1,0,1,2,0,1,0},
    {0,2,2,3,3,2,2,0},
    {0,1,0,1,2,0,1,0},
    {0,2,0,2,1,0,2,0},
    {0,1,1,1,1,1,1,0},
    {0,0,0,0,0,0,0,0}
  }

Chaque nombre correspond à un type de brique, donc quand j'initialise le niveau je parcours le tableau qui correspond au niveau pour assigner la bonne image à chaque brique. Les zéro ne corresponde à rien donc ça donnc un emplacement vide. Sauf que...

Ça se passe bien tant que je charge mon niveau sur une matrice vierge (par exemple quand j'allume la console ou que j'ai détruit toute les briques et que je passe au niveau suivant). Mais si je charge un niveau via le menu et que le précédent niveau chargé affichait encore des briques, les zéro de la matrices n'ont en fait aucun effet ! Certes ils ne chargent pas une nouvelle image mais ils ne remplacent pas non plus l'ancienne par du vide. Du coup je me retrouve avec les briques du niveau sélectionné et les briques du dernier niveau affiché là ou il devrait y avoir du vide....

Donc en gros j'aimerais trouver un moyen de réinitialiser vraiment ces emplacements sur du vide mais je ne sais pas comment m'y prendre.

Voici la fonction qui charge le niveau selon ce tableau : 

void loadLevel(int myLevel) {

  for (int rangee = 0; rangee < NB_RANGEES; rangee++) {
      for (int colonne = 0; colonne < NB_COLONNES; colonne++) {
        types_set[rangee][colonne] = levels[myLevel][rangee][colonne];
      }
    }
}

et voici un extrait de comment la fonction "initGame" attribue les images à chaque brique selon son type (du coup je me contente d'ignorer les zéros mais visiblement c'est un peu léger :D !) :

void initGame() {
//...

  //initialiser les briques
  for (int rangee = 0; rangee < NB_RANGEES; rangee ++) {
    for (int colonne = 0; colonne < NB_COLONNES; colonne++) {
      briques[rangee][colonne].type = types_set[rangee][colonne];
      briques[rangee][colonne].x = colonne * (BRICK_W + 1) + 1;
      briques[rangee][colonne].y = rangee * (BRICK_H + 1) + 1;
      if (briques[rangee][colonne].type == 1) {
        briques[rangee][colonne].state = 1;
        briques[rangee][colonne].img = brick1;
      } else if (briques[rangee][colonne].type == 2) {
        briques[rangee][colonne].state = 2;
        briques[rangee][colonne].img = brick2;
      } else if (briques[rangee][colonne].type == 3) {
        briques[rangee][colonne].state = -2;
        briques[rangee][colonne].img = brick3;
//...

Et voici la structure d'un brique :

struct Brique {
  int x;
  int y;
  int _w;//largeur
  int _h;//hauteur
  int type;
  int state;
  Image img;
  int speedX;
  int speedY;
  unsigned long deathTime;
};


Est-il possible de "nullifier" l'objet image d'une brique ? J'ai essayé de me débrouiller avec des pointeurs pour que l'objet image de la struct Brique soit en fait un pointeur vers l'adresse d'une image dans un tableau ou bien vers une valeur NULL si le type==0. Mais je ne m'en suis pas sorti (même pas réussi à juste remplacer l'image réelle de la brique par un pointeur vers une image..).


Voilà en gros où j'en suis, merci d'avance si quelqu'un a un conseil à me donner !


EDIT : J'ai trouvé un solution un peu en "trichant", je fait en sorte que les briques dont le type est zéro soient détruites d'entrée de jeu et à partir de là plus de problème. Mais je suis pas sûr que ce soit très propre comme solution, donc je reste ouvert aux suggestions !



clement

NEW il y a 5 ans

Salut,

pour optimiser un peux tout ca et enlever ce probleme de brique fantôme tu peux changer la structure de stockage des briques 

si au lieux de les stocker dans un tableau a 2 dimensions  tu les stock dans un tableau a une dimension tu ne stoque que les brique a afficher

int nombreDeBriqueCourent = 0;
for (int rangee = 0; rangee < NB_RANGEES; rangee ++) {
    for (int colonne = 0; colonne < NB_COLONNES; colonne++) {
      if (types_set[rangee][colonne] > 0) {
         briques[nombreDeBriqueCourent].type = types_set[rangee][colonne];
         // evidement tout le reste de l initialisation
         nombreDeBriqueCourent++;
     }
  }
}

Dans ton tableau tu aura uniquement des briques a afficher (entre l index 0 et  nombreDeBriqueCourent - 1)

Dans les boucles d'affichage et mise a jour tu tournera evidement uniquement sur le nombreDeBriqueCourent.


++




Codnpix

NEW il y a 5 ans

Hi, 

I added some musics for each level of the game and I wonder if it's possible to include the wav files in my creation right from this page and then to be presents directly in the download zip.

Is there a way to upload other files but the binary file and the title screen in the creation ?

Otherwise, everything can be downloaded on my github repo but it's less convenient... 


Bonjour, 

j'ai ajouté des musiques pour chaque niveau du jeu, je voudrais savoir s'il était possible que j'inclue mes fichiers wav dans la création ici même pour qu'ils soient bien présents dans le dossier de téléchargement. 

Il y a un moyen d'uplader d'autre fichiers que le fichier binaire pour une création ? (à part les images)

Sinon tout est sur mon repo Github mais c'est moins pratique...

makerSquirrel

NEW il y a 5 ans

Hiho,

I tried it a little longer and I really like it (graphics escecially ;).
As constructive feedback I have collected some points:

  • maybe you could add more angles, so that the paddle-position when hit by the ball changes the direction of flight more. I had one case where I was not able to leave an endless ball bouncing because ohter paddle positions didn't help
  • Alternatively (or additionally) one could try to "catch" the ball again by clicking A when the ball hits the paddle. This would allow chaning positions before starting again.
  • Highscore please ;)

Codnpix

il y a 5 ans

Thank you for feedback makerSquirrel !

maybe you could add more angles, so that the paddle-position when hit by the ball changes the direction of flight more. I had one case where I was not able to leave an endless ball bouncing because ohter paddle positions didn't help

That's right, I have seen that case sometimes. I'm not really sure how I could "add" angles : this is the calculation I do when the ball bounce on the paddle : 

  int8_t int_ballX = floor(ballX);
  int8_t int_ballY = floor(ballY);
  int8_t ballTop = int_ballY;
  int8_t ballBottom = int_ballY + BALL_SIZE;
  int8_t ballLeft = int_ballX;
  int8_t ballRight = int_ballX + BALL_SIZE;

  //collision balle/palette
  if (int_ballX + BALL_SIZE > padX
  && int_ballX - BALL_SIZE < padX + PAD_W
  && ballBottom > PAD_Y) {
    float dist = (ballX + BALL_SIZE / 2) - (padX + PAD_W / 2);
    if (dist != 0) {//éviter la division par 0
      speedX = 1 / (1/ dist);
    } else {
      speedX = 0;
    }
    speedY *= -1;
    gb.sound.fx(bouncePaddle);
}

I really don't know how I could make it more accurate without slowing down the game.

Alternatively (or additionally) one could try to "catch" the ball again by clicking A when the ball hits the paddle. This would allow chaning positions before starting again.

Indeed that could be another solution :).


Codnpix

NEW il y a 5 ans

makerSquirrel makerSquirrel

Thank you for feedback makerSquirrel !

maybe you could add more angles, so that the paddle-position when hit by the ball changes the direction of flight more. I had one case where I was not able to leave an endless ball bouncing because ohter paddle positions didn't help

That's right, I have seen that case sometimes. I'm not really sure how I could "add" angles : this is the calculation I do when the ball bounce on the paddle : 

  int8_t int_ballX = floor(ballX);
  int8_t int_ballY = floor(ballY);
  int8_t ballTop = int_ballY;
  int8_t ballBottom = int_ballY + BALL_SIZE;
  int8_t ballLeft = int_ballX;
  int8_t ballRight = int_ballX + BALL_SIZE;

  //collision balle/palette
  if (int_ballX + BALL_SIZE > padX
  && int_ballX - BALL_SIZE < padX + PAD_W
  && ballBottom > PAD_Y) {
    float dist = (ballX + BALL_SIZE / 2) - (padX + PAD_W / 2);
    if (dist != 0) {//éviter la division par 0
      speedX = 1 / (1/ dist);
    } else {
      speedX = 0;
    }
    speedY *= -1;
    gb.sound.fx(bouncePaddle);
}

I really don't know how I could make it more accurate without slowing down the game.

Alternatively (or additionally) one could try to "catch" the ball again by clicking A when the ball hits the paddle. This would allow chaning positions before starting again.

Indeed that could be another solution :).


Steph

il y a 5 ans

To spice up your game a little bit and imitate a curved paddle, you can make sure that the rebound is linearly correlated to the distance of the impact from the center of the paddle (which we will note Xp).

For example, you can consider that the position limit corresponding to the far left of the paddle returns the ball back to where it came from. In this case the speed of the ball is simply reversed. And when the impact takes place exactly at the center of the upper edge of the paddle, the rebound is normal: only the vertical speed is reversed. You can then deduce a simple correlation to determine the velocity after impact as follows:

Of course, if the ball comes from the left and you hit it with the right edge of the paddle (i.e. when Xp > 0), its horizontal speed will increase! It'll make things harder for the player :-)

It's just a suggestion. Test it and you'll see if you're happy with this behavior!

makerSquirrel

NEW il y a 5 ans

Then probably the easiest approach ich catching the ball. Simply check if a is currently pressed when doing the collision check. Then you could put the ball into the paddle again

Steph

NEW il y a 5 ans

Codnpix Codnpix

To spice up your game a little bit and imitate a curved paddle, you can make sure that the rebound is linearly correlated to the distance of the impact from the center of the paddle (which we will note Xp).

For example, you can consider that the position limit corresponding to the far left of the paddle returns the ball back to where it came from. In this case the speed of the ball is simply reversed. And when the impact takes place exactly at the center of the upper edge of the paddle, the rebound is normal: only the vertical speed is reversed. You can then deduce a simple correlation to determine the velocity after impact as follows:

Of course, if the ball comes from the left and you hit it with the right edge of the paddle (i.e. when Xp > 0), its horizontal speed will increase! It'll make things harder for the player :-)

It's just a suggestion. Test it and you'll see if you're happy with this behavior!

Codnpix

il y a 5 ans

Thank you for advice Steph !

Indeed I don't know if my current calculation is really linear (I tried to so but...). Also I wanted to remain a controlled max-speed for the ball, so the "speedX" value added to the lateral ball position is recalculated at the output of the function to remain it below a maximum. (and the speedY value can only be 1 or -1). 

Maybe that's why I cannot have all the possible bounce angles, but it prevents to fall into "infinite speed increase" cases and some other little problems...

Anyway I will try something with your equation, it looks quite better than mine :) !

Codnpix

NEW il y a 5 ans

Steph Steph

Thank you for advice Steph !

Indeed I don't know if my current calculation is really linear (I tried to so but...). Also I wanted to remain a controlled max-speed for the ball, so the "speedX" value added to the lateral ball position is recalculated at the output of the function to remain it below a maximum. (and the speedY value can only be 1 or -1). 

Maybe that's why I cannot have all the possible bounce angles, but it prevents to fall into "infinite speed increase" cases and some other little problems...

Anyway I will try something with your equation, it looks quite better than mine :) !

Steph

il y a 5 ans

Yes, of course, you can limit the horizontal speed with a maximum absolute value (let's call it vmax). In this case, it is enough to do:

vx = vx < 0 ? max(vx, -vmax) : min(vx, vmax);

Just after the calculation I developed above...

jicehel

NEW il y a 5 ans

yes your speedY have to be real to let you have more possibilities and have movement more fluent

Steph

NEW il y a 5 ans

Codnpix Codnpix

Yes, of course, you can limit the horizontal speed with a maximum absolute value (let's call it vmax). In this case, it is enough to do:

vx = vx < 0 ? max(vx, -vmax) : min(vx, vmax);

Just after the calculation I developed above...