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.