j'arrive pas à crée une balle qui rebondis en X et Y

Programmation avancée de jeux en PureBasic
Lemaquis
Messages : 271
Inscription : mer. 25/déc./2013 7:34
Localisation : la corse

j'arrive pas à crée une balle qui rebondis en X et Y

Message par Lemaquis »

Bonjour
j'arrive pas à crée une balle qui rebondis en X et Y j'ai pas compris la partie 2 du tuto de falsam .

Merci

les images :
Balle :
Image
Fond :
Image
Raquette:
Image
MurHaut
Image
Mur gauche
Image
Mur droit
Image


Code : Tout sélectionner

;--Constante pour la fenetre jeux 
Enumeration
  #Main_jeux
EndEnumeration


; Sprite pour le fond , le mur en haut,mur de gauche et à droite 
Global S_Background,WallH,WallG,WallD

;Sprite pour la raquette avec la position X et Y 
Global Raquette,RaquetteX=350,RaquetteY =580

;Sprite pour la balle avec la position X et Y + et velocité Y
Global Balle,BalleX=400,BalleY=100,VelociteY=5


;Procedure de chargement des images pour les sprites 
Procedure Chargement_images()
  UseJPEGImageDecoder()
  UsePNGImageDecoder()
  ;Chargement de l'image du Background, du Mur en haut , à gauche et à droite 
  S_Background =  LoadSprite(#PB_Any ,"images\Fond.jpg")
  WallH = LoadSprite(#PB_Any ,"images\Wall.jpg")
  WallG=LoadSprite(#PB_Any ,"images\WallG.jpg")
  WallD=LoadSprite(#PB_Any ,"images\WallD.jpg")
  ;Chargement de l'image de la Raquette 
  Raquette =LoadSprite(#PB_Any,"images\Raquette.png", #PB_Sprite_AlphaBlending)
  ;Chargement de l'image de la balle 
  Balle =LoadSprite(#PB_Any,"images\Balle.png", #PB_Sprite_AlphaBlending)
  
EndProcedure


;Procedure de Mise à jour du jeux  

Procedure Game_Afficher()
    ;Evenement  du clavier
  ExamineKeyboard()
  
  ;Deplacement de la raquette à gauche 
  If KeyboardPushed(#PB_Key_Left)
  RaquetteX-5
EndIf
  ;Deplacement de la raquette àdroite
  If KeyboardPushed(#PB_Key_Right)
  RaquetteX+5
EndIf

; Deplacement de la balle en Y 
BalleY+VelociteY

  
  
  ;Affichage du Background et du mur en haut ,mur de gauche et droite
  DisplaySprite (S_Background,0,0)
  DisplaySprite(WallH,0,0)
  DisplaySprite(WallG,0,10)
  DisplaySprite(WallG,785,10)
  ;Affichage de la raquette 
  DisplayTransparentSprite(Raquette,RaquetteX,RaquetteY)
  ;Affichagfe de la balle 
  DisplayTransparentSprite(Balle,BalleX,BalleY)
  
  
  ;Collision de la balle entre la raquette et le mur d'en haut 
  If SpriteCollision(Balle,BalleX,BalleY,Raquette,RaquetteX,RaquetteY) Or SpriteCollision(Balle,BalleX,Balley,WallH,0,0)
    VelociteY*-1
  EndIf
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
EndProcedure

;Procedure GameStart
Procedure GameStart()
  ;Taille de la fenetre de jeux 
  Protected Taille_Width=800
  Protected Taille_Height=600
  
  ;On initialise l'environement 2D
  If InitSprite()=0 Or InitKeyboard()=0 Or InitMouse()=0
    MessageRequester("Erreur","l'Environement 2D  n'est pas etre initialisé",0)
  EndIf
  
  ;On crée la fenetre jeux 
  If OpenWindow(#Main_jeux,0,0,Taille_Width,Taille_Height,"KASSBRICK 2D",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
    If OpenWindowedScreen(WindowID(#Main_jeux),0,0,Taille_Width,Taille_Height)
      Chargement_images()
    EndIf
  EndIf
  ;Boucle  des evenements 
  Repeat
    Repeat
      Event=WindowEvent()
      Select Event
        Case #PB_Event_CloseWindow
          End
      EndSelect
    Until Event=0
    FlipBuffers()
    ClearScreen(RGB(0,0,0))
    Game_Afficher()
  Until KeyboardPushed(#PB_Key_Escape)
EndProcedure

GameStart()
LeMaquis
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: j'arrive pas à crée une balle qui rebondis en X et Y

Message par falsam »

Pour le moment on va s'abstenir de prendre tes images et prendre plutot les images fournies avec les exemples de Pure Basic.

En préambule .
L'axe des X représente l'axe horizontale de ton jeu 2D. Le bord gauche commence à 0
L'axe des Y représente l'axe verticale de ton jeu 2D. Le bord haut commence à 0

NB: Je précise bien en 2D car en 3D ce n'est pas le cas.

■ Ce premier code ne s'occupe que du déplacement vertical de la ball en fonction de son point d'impact avec le mur ou avec la raquette.

RacketX représente les coordonnées X de la raquette.
BallX et BallY représente les coordonnées X et Y de la balle.

VelocityY combine la notion de vitesse et celle de direction du mouvement de la balle.

VelocityY est constamment égale à 1 dans cette exemple

Pour changer la direction on multiplie VelocityY par -1

J'ai repris mon code du tutoriel en ajoutant des explications et en décomposant les collisions.

Code : Tout sélectionner

Enumeration
  #MainForm
EndEnumeration

;Sprite Background & mur
Global BackGround, Wall

;Sprite Ball: Position x & y de la ball et Velocité
Global Ball, BallX=400, BallY=100, VelocityY = 5

;Sprite Raquette: Position x & y de la raquette
Global Racket, RacketX=400, RacketY=500

;Cette procédure permet de charger les textures de chacun des sprites. 
Procedure GamePreload()
  UseJPEGImageDecoder()
  
  ;-Chargement du background
  Background = LoadSprite(#PB_Any, #PB_Compiler_Home +"Examples\3D\Data\Textures\soil_wall.jpg")
  ZoomSprite(BackGround, 800, 600) ;On lui donne la taille de la fenetre
    
  ;-Chargement de la texture représentant les murs
  Wall = LoadSprite(#PB_Any, #PB_Compiler_Home +"Examples\3D\Data\Textures\RustySteel.jpg")
  ZoomSprite(Wall, 800, 20) ;On donne une dimension car la texture est trop grande   
  
  ;-Chargement de l'image représentant la racket (Dimension 100x20)
  Racket = LoadSprite(#PB_Any, #PB_Compiler_Home +"Examples\3D\Data\Textures\Wood.jpg")
  ZoomSprite(Racket, 100, 20) ;On donne une dimension car la texture est trop grande
  
  ;-Chargement de l'image représentant la ball
  Ball = LoadSprite(#PB_Any, #PB_Compiler_Home +"Examples\3D\Data\Textures\grass.jpg")
  ZoomSprite(Ball, 32, 32) ;On donne une dimension car la texture est trop grande
  
EndProcedure

;Cette procédure va mettre à jour la position des sprites. Elle est appelé depuis la boucle évenementielle. 
Procedure GameUpdate()  
    
  ;-Evenements clavier
  ExamineKeyboard()
  
  ;Si la touche fléche gauche est préssée => La raquette se déplace à gauche de 5 unités
  If KeyboardPushed(#PB_Key_Left)
    RacketX - 5 ;Equivalent à RacketX = RacketX - 5
  EndIf
  
  ;Si la touche fléche Droite  est préssée => La raquette se déplace à droite de 5 unités
  If KeyboardPushed(#PB_Key_Right)
    RacketX + 5 ;Equivalent à RacketX = RacketX + 5
  EndIf 
  
  ;Pendant se temps là, la ball se déplace vericalement
  ;VelocityY = 5 (Vers le bas) ou -5 (Vers le haut)
  BallY + VelocityY ;Equivalent à BallY = BallY + VelocityY
  
  ;-Evenement collision
  
  ;Si Collision de la ball avec le mur => Inversion de la vitesse Y de la ball
  If SpriteCollision(Ball, BallX, BallY, Wall, 0, 0)
    VelocityY * -1 ;Inversion de la vélocité de la ball
  EndIf  
  
  ;Si Collision de la ball avec la  raquette => Inversion de la vitesse Y de la ball
  If SpriteCollision(Ball, BallX, BallY, Racket, RacketX, RacketY)    
    VelocityY * -1 ;Inversion de la vélocité de la ball
  EndIf  

  ;-Mise à jour de l'affichage
  ;Toutes les coordonnées des différents sprites sont mise à jour
  ;On affiche chaque sprite 
  DisplaySprite(BackGround, 0, 0) ;Le fond 
  DisplaySprite(Wall, 0, 0) ;Le mur
   
  DisplaySprite(Ball, BallX, BallY) ;La Ball 
  DisplaySprite(Racket, RacketX, RacketY) ;La raquette
  
EndProcedure

Procedure GameStart()
  Protected Width = 800
  Protected Height = 600
  
  If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0 And InitSound() = 0
    MessageRequester("Error", "Sprite system can't be initialized", 0)
    End
  EndIf
  
  If OpenWindow(#mainform, 0, 0, Width, Height, "2D Tutoriel", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
    If OpenWindowedScreen(WindowID(#mainform), 0, 0, Width, Height)
      GamePreload()
    EndIf
  EndIf
  
  Repeat  
    Repeat
      Event = WindowEvent()
     
      Select event    
        Case #PB_Event_CloseWindow
          End
      EndSelect  
    Until event=0
    
    FlipBuffers()
    ClearScreen(RGB(0,0,0))
    GameUpdate()
  
  Until KeyboardPushed(#PB_Key_Escape)
EndProcedure

GameStart()
La procédure GameUpdate() met à jour en permanence la position de chaque sprite. Dis moi si quelques chose est incompréhensible.

Si tu as compris cette première partie, nous passerons à la seconde partie qui consiste à déterminer si la balle rebondi sur la partie droite ou gauche de la raquette :
-Si la raquette touche la partie droite de la raquette, la balle partira à droite tout en continuant à monter.
-Si la raquette touche la partie gauche de la raquette, la balle partira à gauche tout en continuant à monter.
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Lemaquis
Messages : 271
Inscription : mer. 25/déc./2013 7:34
Localisation : la corse

Re: j'arrive pas à crée une balle qui rebondis en X et Y

Message par Lemaquis »

merci et en comment mettre vélocité x pour la balle??
LeMaquis
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: j'arrive pas à crée une balle qui rebondis en X et Y

Message par falsam »

Lemaquis a écrit :merci et en comment mettre vélocité x pour la balle??
Tout dépend si la balle rebondi sur la partie droite ou gauche de la raquette :

Rappelle toi que la raquette fait 100 unités de large.
-La partie gauche de la raquette mesure 50 unités dans l'intervalle 0|-->50
-La partie droite de la raquette mesure aussi 50 unités dans l'intervalle 50|-->100

-Si la raquette touche la partie droite de la raquette, la balle partira à droite tout en continuant à monter.
-Si la raquette touche la partie gauche de la raquette, la balle partira à gauche tout en continuant à monter.

Le reste des explications est dans le code qui suit

Code : Tout sélectionner

Enumeration
  #MainForm
EndEnumeration

;Sprite Background & mur
Global BackGround, Wall

;Sprite Ball: Position x & y de la ball et Velocité
Global Ball, BallX=400, BallY=100
Global VelocityX = 0, VelocityY = 5

;Sprite Raquette: Position x & y de la raquette
Global Racket, RacketX=400, RacketY=500

;Cette procédure permet de charger les textures de chacun des sprites. 
Procedure GamePreload()
  UseJPEGImageDecoder()
  
  ;-Chargement du background
  Background = LoadSprite(#PB_Any, #PB_Compiler_Home +"Examples\3D\Data\Textures\soil_wall.jpg")
  ZoomSprite(BackGround, 800, 600) ;On lui donne la taille de la fenetre
    
  ;-Chargement de la texture représentant les murs
  Wall = LoadSprite(#PB_Any, #PB_Compiler_Home +"Examples\3D\Data\Textures\RustySteel.jpg")
  ZoomSprite(Wall, 800, 20) ;On donne une dimension car la texture est trop grande   
  
  ;-Chargement de l'image représentant la racket
  Racket = LoadSprite(#PB_Any, #PB_Compiler_Home +"Examples\3D\Data\Textures\Wood.jpg")
  ZoomSprite(Racket, 100, 20) ;On donne une dimension car la texture est trop grande
  
  ;-Chargement de l'image représentant la ball
  Ball = LoadSprite(#PB_Any, #PB_Compiler_Home +"Examples\3D\Data\Textures\grass.jpg")
  ZoomSprite(Ball, 32, 32) ;On donne une dimension car la texture est trop grande
  
EndProcedure

;Cette procédure va mettre à jour la position des sprites. Elle est appelé depuis la boucle évenementielle. 
Procedure GameUpdate()  
    
  ;-Evenements clavier
  ExamineKeyboard()
  
  ;Si la touche fléche gauche est préssée => La raquette se déplace à gauche de 5 unités
  If KeyboardPushed(#PB_Key_Left)
    RacketX - 5 ;Equivalent à RacketX = RacketX - 5
  EndIf
  
  ;Si la touche fléche Droite  est préssée => La raquette se déplace à droite de 5 unités
  If KeyboardPushed(#PB_Key_Right)
    RacketX + 5 ;Equivalent à RacketX = RacketX + 5
  EndIf 
  
  ;Pendant se temps là, la ball se déplace verticalement
  ;VelocityY = 5 (Vers le bas) ou -5 (Vers le haut)
  BallX + VelocityX ;Equivalent à BallX = BallX + VelocityX
  BallY + VelocityY ;Equivalent à BallY = BallY + VelocityY
  
  ;-Evenement collision
  
  ;Si Collision de la ball avec le mur => Inversion de la vitesse Y de la ball
  If SpriteCollision(Ball, BallX, BallY, Wall, 0, 0)
    VelocityY * -1 ;Inversion de la vélocité de la ball
  EndIf  
  
  
  ;*** Rappelles toi que la raquette fait 100 unités de large
  
  ;Si Collision de la ball avec le bord droit de la raquette 
  ;.Inversion de la vitesse Y de la ball (Elle monte)
  ;.La balle par à droite avec une vélocité X à 1
  If SpriteCollision(Ball, BallX, BallY, Racket, RacketX+50, RacketY)    
    VelocityY * -1  ;Inversion de la vélocité de la ball
    VelocityX = 1   ;La balle par à droite 
  
  ;Si Collision de la ball avec le bord gauche de la raquette => Inversion de la vitesse Y de la ball
  ;.Inversion de la vitesse Y de la ball (Elle monte)
  ;.La balle par à gauche avec une vélocité X à -1  
  ElseIf SpriteCollision(Ball, BallX, BallY, Racket, RacketX, RacketY)    
    VelocityY * -1  ;Inversion de la vélocité de la ball
    VelocityX = -1  ;La balle par à gauche 
    
  EndIf  
  
  ;-Mise à jour de l'affichage
  ;Toutes les coordonnées des différents sprites sont mise à jour
  ;On affiche chaque sprite 
  DisplaySprite(BackGround, 0, 0) ;Le fond 
  DisplaySprite(Wall, 0, 0) ;Le mur
   
  DisplaySprite(Ball, BallX, BallY) ;La Ball 
  DisplaySprite(Racket, RacketX, RacketY) ;La raquette
  
EndProcedure

Procedure GameStart()
  Protected Width = 800
  Protected Height = 600
  
  If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0 And InitSound() = 0
    MessageRequester("Error", "Sprite system can't be initialized", 0)
    End
  EndIf
  
  If OpenWindow(#mainform, 0, 0, Width, Height, "2D Tutoriel", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
    If OpenWindowedScreen(WindowID(#mainform), 0, 0, Width, Height)
      GamePreload()
    EndIf
  EndIf
  
  Repeat  
    Repeat
      Event = WindowEvent()
     
      Select event    
        Case #PB_Event_CloseWindow
          End
      EndSelect  
    Until event=0
    
    FlipBuffers()
    ClearScreen(RGB(0,0,0))
    GameUpdate()
  
  Until KeyboardPushed(#PB_Key_Escape)
EndProcedure

GameStart()
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Lemaquis
Messages : 271
Inscription : mer. 25/déc./2013 7:34
Localisation : la corse

Re: j'arrive pas à crée une balle qui rebondis en X et Y

Message par Lemaquis »

merci je vais etudié ça
LeMaquis
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: j'arrive pas à crée une balle qui rebondis en X et Y

Message par Backup »

Perso , je divise mes raquettes en 3

[aaaabbbbccccc]

partie aaaa , environs -45 degres
Partie bbbb rebond environ +-60 degres (fonction du deplacement x de la balle)
Partie ccccc , environ +45 degres

de cette façon une balle qui arrive avec un angle prononcé , peut etre rattrapé si on la recupere avec le centre de la raquette
puisque l'angle diminue sur cette partie
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: j'arrive pas à crée une balle qui rebondis en X et Y

Message par falsam »

Dobro a écrit :Perso , je divise mes raquettes en 3
Et même en 5 mais j'ai voulu rester simple pour répondre à la question de Lemaquis. j'ai même commencé par un simple rebond vertical comme tu as pu le voir. Pas de division de la raquette dans le premier code.

Dans le second code j'ai divisé la raquette en deux pour montrer comment la balle se déplace à droite ou à gauche suivant le point d'impact de la balle sur la raquette.

PS: Lemaquis, Je t'assure que l'utilisation de la fonction debug est un plus en programmation :)
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Lemaquis
Messages : 271
Inscription : mer. 25/déc./2013 7:34
Localisation : la corse

Re: j'arrive pas à crée une balle qui rebondis en X et Y

Message par Lemaquis »

Pourquoi diviser la raquette en 3?
LeMaquis
Avatar de l’utilisateur
venom
Messages : 3136
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: j'arrive pas à crée une balle qui rebondis en X et Y

Message par venom »

Par ce que ça te permet de renvoyé la balle sous differant angle selon ou elle touche la raquette. :wink:
exemple de Dobro

aaaabbbbccccc
en gros:

si ta balle touche la raquette dans la zone aaaa et bien elle repartira vers le haut gauche de l’écran.
si ta balle touche la raquette dans la zone bbb et bien elle repartira plus vers le haut centre de l’écran.
si ta balle touche la raquette dans la zone cccc et bien elle repartira vers le haut droit de l’écran.

un petit schema fait vite fait:
Image
Les flèches représentent la direction de la balle après impacte.






@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Lemaquis
Messages : 271
Inscription : mer. 25/déc./2013 7:34
Localisation : la corse

Re: j'arrive pas à crée une balle qui rebondis en X et Y

Message par Lemaquis »

merci venom ton explication mais j'ai un peux dur pour à comprendre je suis pas matheux
LeMaquis
Répondre