Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Gioco Breakout --- rimbalzo palla(direzione) OpenGL
Forum - C/C++ - Gioco Breakout --- rimbalzo palla(direzione) OpenGL

Avatar
Gemini (Normal User)
Rookie


Messaggi: 33
Iscritto: 04/10/2021

Segnala al moderatore
Postato alle 8:50
Domenica, 22/01/2023
Buongiorno e buona domenica a tutti.... non so se il titolo si capisce in ogni caso lo modifico se non va bene....
Ho un problema con un gioco che sto facendo... in pratica sto facendo il gioco Breakout in OpenGL...preso spunto da LearnOpenGL....
Allora non voglio copiare quello che fa vedere nel tutorial ma voglio capire bene come fa la palla a rimbalzare nella direzione opposta del paddle....
ho visto un pò il tutorial ma non ho capito tanto bene....qualcuno può spiegarmi come posso fare cioè se la palla colpisce il paddle nel lato sinistro ovviamente avra una spinta verso sinistra e non centrale non capisco come posso calcolare questa spinta.... ripeto non voglio copiare quello che fa nel tutorial di learnopengl ma voglio capire bene come calcola questa collisione e la spinta..

https://files.fm/u/6wgs4znbc <--- video per chi non abbia capito quale sia il gioco :D


Ultima modifica effettuata da Gemini il 22/01/2023 alle 9:53
PM Quote
Avatar
Thejuster (Admin)
Guru^2


Messaggi: 2298
Iscritto: 04/05/2008

Segnala al moderatore
Postato alle 9:19
Lunedì, 23/01/2023
Eccome.
Dopo al commodore, l'atari e stata la mia prima console.

Il trucco c'è ma non si vede :yup:
Svelo l'arcano.

Il pad e diviso in 3 aree o meglio 3 Sprite collegate.

Punto sinistro,centrale,punto destro.

In base all'andamento della pallina, la traiettoria cambia.

Immagina che la pallina stia scendendo da sinistra esempio.

Toccando il pad sinistro,  cambia la traiettoria da sinistra giù, a sinistra su.
Sul centrale fa un rimbalzo normale, mentre su quello destro ne amplifica la direzione.
Tipo abbassando Y.

Come fare ciò?
Un semplicissimo random di max 2f. (Su Y)
Qualcosa di non estremamente forte.
Ma giusto per dare una spinta diversa ad ogni tocco altrimenti i rimbalzi rimangono statici e sembra di giocare in loop.


Ti crei un metodo ad ogni area toccata e da lì ti gestisci al meglio l'algoritmo.
Se è troppo forte, riduci la spinta su Y o viceversa.





https://mire.forumfree.it/ - Mire Engine
C# UI Designer
PM Quote
Avatar
Gemini (Normal User)
Rookie


Messaggi: 33
Iscritto: 04/10/2021

Segnala al moderatore
Postato alle 10:22
Lunedì, 23/01/2023
ah ok quindi devo dividere il paddle in piu sezioni e ogni sezione ha una sua collisione a se....giusto? o avendo un solo quad come paddle posso calcolare la collisione del lato sinistro/centrale/destro... avevo pensato anche io una cosa del genere ma non volevo scriverla per dire cavolate XD

PM Quote
Avatar
Thejuster (Admin)
Guru^2


Messaggi: 2298
Iscritto: 04/05/2008

Segnala al moderatore
Postato alle 11:40
Lunedì, 23/01/2023
Testo quotato

Postato originariamente da Gemini:

ah ok quindi devo dividere il paddle in piu sezioni e ogni sezione ha una sua collisione a se....giusto? o avendo un solo quad come paddle posso calcolare la collisione del lato sinistro/centrale/destro... avevo pensato anche io una cosa del genere ma non volevo scriverla per dire cavolate XD



Non esistono cavolate :rotfl: ma diversi metodi di implementazione, che siano corretti o scorretti.
Avvolte ho visto utilizzare dei metodi assurdi per ottenere più o meno la medesima cosa.

Io preferisco usare questo sistema.
Non sono esperto di C++ quanto col C#, In c++ me la cavicchio ma non posso paragonarlo alla mia esperienza con il C#.
Ma in c# realizzo proprio degli eventi a determinate istruzioni.
Non mi piace incasinare il sorgente, preferisco avere funzioni pulite che facciano esattamente quello che servono.

potresti sperimentare l'uso dei delegati ed eventi in c++

https://tongtunggiang.com/2017/cpp-event-delegate/

una volta appreso l'uso dei delegati ed eventi non ne potrai fare più a meno.
Sono veramente una manna dal cielo. Sopratutto in progetti del genere.

Questa è una screen di un progetto che sto sviluppando.
https://i.ibb.co/XVJ0kXg/image.png

Immagina senza l'uso di delegati o eventi. è praticamente impossibile stabilire in che parte, punto, determinata situazione o condizione viene eseguita una determinata operazione.


Ultima modifica effettuata da Thejuster il 23/01/2023 alle 11:46


https://mire.forumfree.it/ - Mire Engine
C# UI Designer
PM Quote
Avatar
Gemini (Normal User)
Rookie


Messaggi: 33
Iscritto: 04/10/2021

Segnala al moderatore
Postato alle 0:26
Mercoledì, 25/01/2023
Codice sorgente - presumibilmente Plain Text

  1. Non esistono cavolate :rotfl: ma diversi metodi di implementazione, che siano corretti o scorretti.
  2. Avvolte ho visto utilizzare dei metodi assurdi per ottenere più o meno la medesima cosa.



*_*

dio qualcuno che mi capisce!!! e non mi dice ma NOOOO si deve fare cosi!!!! anche io penso che la programmazione alla fine sia come un qualcosa che uno scrive di personale... uno lo scrive in una maniera un'altro nelll'altra comei libri... xD xo alla fine i libri sempre libri sono e anche questo penso che sia lo stesso...ovviamente scrivere codice buono e in maniere corretta si ha dei vantaggi..XO qui nessuno è perfetto e specialmente nella programmazione noi non siamo e non saremo mai perfertti.... cmq just ho implementato in a metà le collisioni e la spinta...xò mi sembra ancora troppo meccanica...ora non sono a casa appena torno posto il codice x far capire un pò!!!!

PM Quote
Avatar
Thejuster (Admin)
Guru^2


Messaggi: 2298
Iscritto: 04/05/2008

Segnala al moderatore
Postato alle 21:56
Giovedì, 26/01/2023
:rotfl: si ritengo la programmazione come una calligrafia.
Nessuno scrive allo stesso modo.

Cmq ti ho fatto un piccolo esempio molto veloce anche se non ottimizzato la massimo.
ma spero di rendere l'idea


https://youtu.be/Tgr83m5tUI4


Te lo mostro in C#, penso che sia comprensibile anche da chi scrive in c++
Non è proprio perfetto!! ma penso fatto in una ventina di minuti possa andare


Ho creato due classi, Una per la palla e una per il pad.
Entrambe fanno riferimento alla risorsa delle immagini, ed entrambe le classi hanno valori come
Posizione e Grandezza della risorsa.

Classe del Pads

Codice sorgente - presumibilmente VB.NET

  1. public class Pad
  2.     {
  3.         //Campi privati
  4.         Rectangle source;
  5.         Texture2D pads;
  6.         MouseState ms;
  7.         Vector2 position;
  8.         Vector2 size = new Vector2(128, 30);
  9.  
  10.  
  11.  
  12.         //Campi Pubblici
  13.         public Vector2 Posizione { get => position; set => position = value; }
  14.         public Vector2 Size { get => size; set => size = value; }
  15.  
  16.         public Pad(Texture2D Atlas)
  17.         {
  18.             source = new Rectangle(148, 302,(int)Size.X,(int)Size.Y);
  19.             pads = Atlas;
  20.             position = new Vector2(800 / 2, 600 - 50); //Posizione di partenza, prendo in rif la risoluzione di gioco
  21.         }
  22.  
  23.  
  24.         public void Update(GameTime gameTime)
  25.         {
  26.             ms = Mouse.GetState();
  27.             position = new Vector2(ms.X, 600 - 50);
  28.         }
  29.  
  30.         public void Draw(SpriteBatch spriteBatch)
  31.         {
  32.             spriteBatch.Draw(pads, position, source, Color.White);
  33.         }
  34. }




Classe della pallina

Codice sorgente - presumibilmente VB.NET

  1. public class Ball
  2.     {
  3.         //Campi privati
  4.         private Vector2 posizione;
  5.         private Rectangle source;
  6.         private Texture2D palla;
  7.         private float forza = 150f;
  8.         private Vector2 velocità;
  9.         private Vector2 size = new Vector2(32, 32);
  10.  
  11.  
  12.         //Campi pubblici
  13.         public float Forza { get => forza; set => forza = value; }
  14.         public Vector2 Posizione { get => posizione; set => posizione = value; }
  15.         public Vector2 Velocita { get => velocità; set => velocità = value; }
  16.         public Vector2 Size { get => size; set => size = value; }
  17.  
  18.         //Delegati
  19.         delegate void LeftBorderTouch();
  20.         delegate void RightBorderTouch();
  21.         delegate void TopBorderTouch();
  22.         delegate void BottomBorderTouch();
  23.  
  24.         //Eventi
  25.         event LeftBorderTouch OnLeftBorderTouch;
  26.         event RightBorderTouch OnRightBorderTouch;
  27.         event TopBorderTouch OnTopBorderTouch;
  28.         event BottomBorderTouch OnBottomBorderTouch;
  29.  
  30.  
  31.         /// <summary>
  32.         /// Costruttore della palla
  33.         /// </summary>
  34.         /// <param name="sheet">Richiede Atlas</param>
  35.         public Ball(Texture2D sheet)
  36.         {
  37.             //Posizione sorgente della palla
  38.             source = new Rectangle(96, 160, 32, 32);
  39.             palla = sheet;
  40.             posizione = new Vector2(100, 100);
  41.             velocità = new Vector2(forza, forza);
  42.  
  43.             //Sub Moduli
  44.             OnBottomBorderTouch += () => { velocità = new Vector2(velocità.X, -forza); };
  45.             OnTopBorderTouch += () => { velocità = new Vector2(velocità.X, forza); };
  46.             OnRightBorderTouch += () => { velocità = new Vector2(-forza, velocità.Y); };
  47.             OnLeftBorderTouch += () => { velocità = new Vector2(forza, velocità.Y); };
  48.         }
  49.  
  50.  
  51.  
  52.         /// <summary>
  53.         /// Metodo di Aggiornamento
  54.         /// </summary>
  55.         /// <param name="gameTime">Temp di Gioco</param>
  56.         public void Update(GameTime gameTime)
  57.         {
  58.  
  59.             posizione += velocità * (float)gameTime.ElapsedGameTime.TotalSeconds;
  60.             CheckBounds();
  61.         }
  62.  
  63.  
  64.         /// <summary>
  65.         /// Metodo Draw
  66.         /// </summary>
  67.         /// <param name="spriteBatch">Device del Disegno</param>
  68.         public void Draw(SpriteBatch spriteBatch)
  69.         {
  70.             spriteBatch.Draw(palla, posizione, source, Color.White);
  71.         }
  72.  
  73.  
  74.  
  75.         /// <summary>
  76.         /// Controlla se vengono toccati i bordi esterni
  77.         /// </summary>
  78.         void CheckBounds()
  79.         {
  80.             if (posizione.Y >= (600 - source.Height))
  81.                 OnBottomBorderTouch();
  82.  
  83.             if (posizione.Y <= 0)
  84.                 OnTopBorderTouch();
  85.  
  86.             if (posizione.X >= (800 - source.Width))
  87.                 OnRightBorderTouch();
  88.  
  89.             if (posizione.X <= 0)
  90.                 OnLeftBorderTouch();
  91.  
  92.         }
  93.     }




Mentre nel main verifico la collisione passando al void come argomento sia la palla che il pad

Codice sorgente - presumibilmente C++

  1. void CollisionePad(Ball ball,Pad pad)
  2.         {
  3.             Rectangle br = new Rectangle((int)ball.Posizione.X,(int)ball.Posizione.Y,(int)ball.Size.X,(int)ball.Size.Y);
  4.             Rectangle pr = new Rectangle((int)pad.Posizione.X, (int)pad.Posizione.Y, (int)pad.Size.X, (int)pad.Size.Y);
  5.  
  6.             if(br.Intersects(pr))
  7.             {
  8.                 float relativo = (pad.Posizione.X + pad.Size.X / 2) - (ball.Posizione.X + ball.Size.X / 2);
  9.                 float normalizzato = relativo / (pad.Size.X / 2);
  10.                 float angolo = normalizzato * 30; //Oppure (float)(Math.PI/3)  dipende da come vuoi settare il gioco.
  11.  
  12.                 ball.Velocita = new Vector2((float)Math.Sin(angolo), -1) * ball.Velocita.Length();
  13.             }
  14.          }



il gioco del rimbalzo sul pad in questo caso lo fà l'angolo cercando di ottenere la differenza del resto della collisione tra la palla e il pad.
Gioca su quei valori per trovare il modo corretto o che più ti aggarba
Del tipo Se la pallina tocca quasi all'estremità del pad,  Posizione del pad + larghezza prendi il centro e fai uguale per la pallina.
Poni esempio che il pad misura 128 px e si trova a 200 dal bordo
200 + 128 = 328 / 2 (Centro) = 164
la pallina si trova a esempio 220 dal bordo e misura 32 px

220 + 32 = 252 / 2 (centro)  = 126

164 - 126 = 38

Hai una differenza di 38 pixel dal bordo iniziale del pad alla posizione relativa della pallina.
e da li fai partire un calcolo o algoritmo per dare una direzione alla palla.
in questo esempio ho usato la variabile forza per dare il senso di spinta
assegnando alla posizione -forza  va in negativo quindi al contrario sia su X che su Y bisogna solo giocare
sull'inclinazione da dare alla pallina.


Ultima modifica effettuata da Thejuster il 27/01/2023 alle 14:52


https://mire.forumfree.it/ - Mire Engine
C# UI Designer
PM Quote