Pong

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Hello !

Je suis en train de rédiger un tuto sur Pygame, et le TD est de faire un Pong (choix perso hein ;) )

Tout est codé, et je suis passé aux tests. Tout est presque correct, sauf … le déplacement de la balle :(

Les collisions sont correctes, oui, mais y a un truc problématique :

comme ma balle décide de se déplacer après une collision

petit schéma pour expliquer :

et le code :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import pygame
from pygame.locals import *
from constantes import *
from math import cos, acos, sqrt


class Balle:
    def __init__(self, ecran: pygame.Surface):
        self.ecran = ecran
        self.vect_dir = [-VITESSE_BALLE, VITESSE_BALLE]
        self.image = pygame.image.load("images/balle.png").convert_alpha()
        self.b_large = self.image.get_width()  # la taille de notre balle en x
        self.b_haut = self.image.get_height()  # et la taille en y
        self.pos = [(self.ecran.get_width() - self.b_large) // 2, (self.ecran.get_height() - self.b_haut) // 2]

    def move(self, raquette):
        tmp = self.pos[0] + self.vect_dir[0] * VITESSE_BALLE, self.pos[1] + self.vect_dir[1] * VITESSE_BALLE
        if raquette.collide_with_me(tmp, (self.b_large, self.b_haut)) or self.pos[0] <= 0 or self.pos[1] <= 0 \
                or self.pos[0] + self.b_large >= self.ecran.get_width() or self.pos[1] + self.b_haut >= self.ecran.get_height():
            # on a collidé soit avec la raquette, soit avec un des 4 murs :)
            hypothenuse = sqrt(pow(abs(self.pos[1] - tmp[1]), 2) + pow(abs(self.pos[0] - tmp[0]), 2))  # calcul vectoriel, vu en seconde
            # juste au cas où ;) :
            hypothenuse = hypothenuse if hypothenuse > 0 else 1
            angle = acos((abs(self.pos[1] - tmp[1]) / hypothenuse) * (3.1415926535897 / 180))  # on met bien l'angle en radians !
            beta = 0 if (self.pos[0] <= 0 or self.pos[0] + self.b_large >= self.ecran.get_width() or raquette.collide_with_me(tmp, (self.b_large, self.b_haut))) else 90
            angle = -angle + 2 * beta  # inversion de l'angle avec l'ajout de 2*beta
            const = -cos(angle) if angle < 0 else cos(angle)
            self.vect_dir[0] *= const
            self.vect_dir[1] *= const
        # dans tous les cas on déplace la balle !
        self.pos[0] += self.vect_dir[0]
        self.pos[1] += self.vect_dir[1]

    def render(self):
        self.ecran.blit(self.image, tuple(self.pos))

merci de votre aide :D !

Ma chaine YouTube ! | Seventh, un micro langage communautaire ! | Mon projet : Unamed (en pleine reprogrammation en C++11/SFML2.4) | Mon tuto sur Pygame !

+0 -0

Cette réponse a aidé l'auteur du sujet

Je suis pas sûr de bien comprendre ton problème, mais tu pourrais faire quelque chose qui ressemble à la réflexion d'un rayon de lumière par un miroir plan ? C'est à dire quelque chose comme ça : En rouge la vitesse à l'arrivée et en vert après le rebond

PS :

1
hypothenuse = sqrt(pow(abs(self.pos[1] - tmp[1]), 2) + pow(abs(self.pos[0] - tmp[0]), 2))  # calcul vectoriel, vu en seconde

1
hypothenuse = sqrt((self.pos[1] - tmp[1])**2 + (self.pos[0] - tmp[0])**2)

Suffirait non ? :p

Sivigik c'est juste ! | Un article sur le NE555

+2 -0
Auteur du sujet

hum non pas tellement (je pense)

si tu lances une balle contre un mur, avec un angle $x$ entre le rayon décrivant la trajectoire de la balle et la droite du mur, la balle n'aura pas un angle $x$ après collision avec la droite du mur, et c'est ce que j'essaye de reproduire ici

mais c'est vrai que c'est beaucoup plus simple à mettre en oeuvre ;)

sinon pour ton ps : oui c'est vrai, je suis tete en l'air des fois xD

Ma chaine YouTube ! | Seventh, un micro langage communautaire ! | Mon projet : Unamed (en pleine reprogrammation en C++11/SFML2.4) | Mon tuto sur Pygame !

+0 -0

Cette réponse a aidé l'auteur du sujet

Bah dans le cas d'une balle qui ne se déforme pas, c'est ce qui se passe à peu près il me semble ^^ mais tu peux aussi introduire un petit facteur qui simule la déformation de la balle sur la composante de la vitesse normale à la droite de collision

Édité par klafyvel

Sivigik c'est juste ! | Un article sur le NE555

+1 -0
Staff

Je ne comprends pas trop pourquoi tu te retrouves avec de la trigo dans cet exercice, mais je n'ai pas l'énoncé.

En fait, gérer les collisions dans un Pong-like est ultra-simple. Je suppose un calcul d'image tous les $T$ ms, les murs sont parallèle à l'axe $x$ et les raquette à l'axe $y$.

  • À chaque intervalle de temps, ta balle se déplace de $dX$ selon $x$ et de $dY$ selon $y$ (valeurs choisies au hasard à chaque nouvelle balle)
  • Collision parfaite contre un mur : la vitesse (donc le déplacement) selon $x$ ne change pas, la balle rebondit parfaitement donc $dY = -dY$
  • Collision parfaite contre une raquette : la vitesse (donc le déplacement selon $y$ ne change pas, la balle rebondit parfaitement donc $dX = -dX$

Après tu peux ajouter facilement des effets :

  • Rebonds imparfaits : tu multiplie $dX$ et $dY$ par une constante < 1
  • Effets dûs à la raquette : tu ajoutes une partie de la vitesse de la raquette à $dY$

Et voilà. Pas besoin de trigonométrie, ni de calculs compliqués comme des racines carrées, etc.

Édité par SpaceFox

Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte