Oppure

Loading
22/01/23 7:50
Gemini
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..

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

Ultima modifica effettuata da Gemini 22/01/23 8:53
23/01/23 8:19
Thejuster
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.



mire.forumfree.it/ - Mire Engine
C# UI Designer
23/01/23 9:22
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
23/01/23 10:40
Thejuster
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++

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.
i.ibb.co/XVJ0kXg/…

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 23/01/23 10:46
mire.forumfree.it/ - Mire Engine
C# UI Designer
24/01/23 23:26
Gemini
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. 


*_*

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ò!!!!
26/01/23 20:56
Thejuster
: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


youtu.be/…


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


 public class Pad
    {
        //Campi privati
        Rectangle source;
        Texture2D pads;
        MouseState ms;
        Vector2 position;
        Vector2 size = new Vector2(128, 30);



        //Campi Pubblici
        public Vector2 Posizione { get => position; set => position = value; }
        public Vector2 Size { get => size; set => size = value; }

        public Pad(Texture2D Atlas)
        {
            source = new Rectangle(148, 302,(int)Size.X,(int)Size.Y);
            pads = Atlas;
            position = new Vector2(800 / 2, 600 - 50); //Posizione di partenza, prendo in rif la risoluzione di gioco
        }


        public void Update(GameTime gameTime)
        {
            ms = Mouse.GetState();
            position = new Vector2(ms.X, 600 - 50);
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(pads, position, source, Color.White);
        }
}




Classe della pallina


   public class Ball
    {
        //Campi privati
        private Vector2 posizione;
        private Rectangle source;
        private Texture2D palla;
        private float forza = 150f;
        private Vector2 velocità;
        private Vector2 size = new Vector2(32, 32);


        //Campi pubblici
        public float Forza { get => forza; set => forza = value; }
        public Vector2 Posizione { get => posizione; set => posizione = value; } 
        public Vector2 Velocita { get => velocità; set => velocità = value; }
        public Vector2 Size { get => size; set => size = value; }

        //Delegati
        delegate void LeftBorderTouch();
        delegate void RightBorderTouch();
        delegate void TopBorderTouch();
        delegate void BottomBorderTouch();

        //Eventi
        event LeftBorderTouch OnLeftBorderTouch;
        event RightBorderTouch OnRightBorderTouch;
        event TopBorderTouch OnTopBorderTouch;
        event BottomBorderTouch OnBottomBorderTouch;


        /// <summary>
        /// Costruttore della palla
        /// </summary>
        /// <param name="sheet">Richiede Atlas</param>
        public Ball(Texture2D sheet)
        {
            //Posizione sorgente della palla
            source = new Rectangle(96, 160, 32, 32);
            palla = sheet;
            posizione = new Vector2(100, 100);
            velocità = new Vector2(forza, forza);

            //Sub Moduli
            OnBottomBorderTouch += () => { velocità = new Vector2(velocità.X, -forza); };
            OnTopBorderTouch += () => { velocità = new Vector2(velocità.X, forza); };
            OnRightBorderTouch += () => { velocità = new Vector2(-forza, velocità.Y); };
            OnLeftBorderTouch += () => { velocità = new Vector2(forza, velocità.Y); };
        }



        /// <summary>
        /// Metodo di Aggiornamento
        /// </summary>
        /// <param name="gameTime">Temp di Gioco</param>
        public void Update(GameTime gameTime)
        {

            posizione += velocità * (float)gameTime.ElapsedGameTime.TotalSeconds;
            CheckBounds();
        }


        /// <summary>
        /// Metodo Draw
        /// </summary>
        /// <param name="spriteBatch">Device del Disegno</param>
        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(palla, posizione, source, Color.White);
        }



        /// <summary>
        /// Controlla se vengono toccati i bordi esterni
        /// </summary>
        void CheckBounds()
        {
            if (posizione.Y >= (600 - source.Height))
                OnBottomBorderTouch();

            if (posizione.Y <= 0)
                OnTopBorderTouch();

            if (posizione.X >= (800 - source.Width))
                OnRightBorderTouch();

            if (posizione.X <= 0)
                OnLeftBorderTouch();

        }
    }




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


void CollisionePad(Ball ball,Pad pad)
        {
            Rectangle br = new Rectangle((int)ball.Posizione.X,(int)ball.Posizione.Y,(int)ball.Size.X,(int)ball.Size.Y);
            Rectangle pr = new Rectangle((int)pad.Posizione.X, (int)pad.Posizione.Y, (int)pad.Size.X, (int)pad.Size.Y);

            if(br.Intersects(pr))
            {
                float relativo = (pad.Posizione.X + pad.Size.X / 2) - (ball.Posizione.X + ball.Size.X / 2);
                float normalizzato = relativo / (pad.Size.X / 2);
                float angolo = normalizzato * 30; //Oppure (float)(Math.PI/3)  dipende da come vuoi settare il gioco.

                ball.Velocita = new Vector2((float)Math.Sin(angolo), -1) * ball.Velocita.Length();
            }
         }



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 27/01/23 13:52
mire.forumfree.it/ - Mire Engine
C# UI Designer