2D : Un mur, une raquette et une ball.

Programmation avancée de jeux en PureBasic
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

2D : Un mur, une raquette et une ball.

Message par falsam »

. Comment charger la texture d'un sprite non animé ?
. Comment afficher un sprite ?
. Comment gérer le déplacement d'un sprite ?
. Comment gérer les collisions ?

Ces quatre fonctionnalités seront incluses dans le code commenté ci-dessous.

Nous utiliserons successivement
LoadSprite() pour charger une texture représentant un sprite.
DisplaySprite() pour afficher un sprite dans un systéme de coordonnées x, y.
SpriteCollision() pour gérer les collisions entres deux sprites.

La gestion du déplacement des touches ◄- et -► est assurée par la fonction KeyboardPushed(). Cette fonctionnalité devra être au préalable initialisé par la fonction ExamineKeyboard().

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
  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()
  
  If KeyboardPushed(#PB_Key_Left)
    RacketX - 5 ;Déplacement de la raquette à gauche
  EndIf
  
  If KeyboardPushed(#PB_Key_Right)
    RacketX + 5 ;Déplacement de la raquette à droite 
  EndIf
  
  ;Déplacement verical de la ball
  BallY + VelocityY
  
  ;Mise à jour de l'affichage
  DisplaySprite(BackGround, 0, 0) ;Background
  DisplaySprite(Wall, 0, 0) ;Mur haut
   
  DisplaySprite(Ball, BallX, BallY) ;Ball 
  DisplaySprite(Racket, RacketX, RacketY) ;Racket
  
  ;Collision de la ball avec la racket ou le mur du haut
  If SpriteCollision(Ball, BallX, BallY, Racket, RacketX, RacketY) Or
     SpriteCollision(Ball, BallX, BallY, Wall, 0, 0)
    
    VelocityY * -1 ;Inversion de la vélocité de la ball
    
  EndIf  
EndProcedure

Procedure GameStart()
  Protected Width = 800
  Protected Height = 600
  
  ;Environnement 2D
  If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0 And InitSound() = 0
    MessageRequester("Error", "Sprite system can't be initialized", 0)
    End
  EndIf
  
  ;Fenetre
  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
  
  ;Boucle evenementielle
  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()
N'hésitez pas à consulter l'aide consacrée aux sprites ainsi que l'aide sur les fonctionnalités du clavier en particulier ExamineKeyboard(), KeyboardPushed() quand une touche est pressée et KeyboardReleased() quand une touche est relâchée.

Attention, je ne gère pas le rebond de la ball en fonction de l'origine du départ de la ball et du point d'impact.
Configuration : Windows 11 Famille 64-bit - PB 6.03 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: 2D : Un mur, une raquette et une ball.

Message par Lemaquis »

Merci de ton tuto

Juste un truc comment faire pour la raquette ne sorte pas de l'ecran ?
Dernière modification par Lemaquis le sam. 10/mai/2014 8:58, modifié 1 fois.
LeMaquis
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: 2D : Un mur, une raquette et une ball.

Message par Fig »

Bon tuto; mais ça manque juste un peu d'angle pour la balle, histoire de mettre un peu d'animation. :wink:

Code très propre en tout cas ! 8O
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: 2D : Un mur, une raquette et une ball.

Message par falsam »

Lemaquis a écrit :Juste un truc comment faire pour la raquette ne sorte pas de l'ecran ?
Ajoute des murs droit gauche et en bas et testes les collisions :)
Fig a écrit :Bon tuto; mais ça manque juste un peu d'angle pour la balle, histoire de mettre un peu d'animation. :wink:
C'est volontaire et je l'ai spécifié dans mon message précédent. Je voulais que le code soit le plus simple possible pour répondre à cette demande sur un autre topic.
Lemaquis a écrit :
TazNormand a écrit :Dobro, il ne te reste plus qu'à faire un tuto pour un casse-brique (simple pour commencer)
ça serait super pour apprendre , je demande pas beaucoup juste savoir pour bouger le raquette au clavier( avec ls touches fleche gauche et droite ) et bouger la balle
Comme tu as pu le voir .... j'ai fait simple.

Je vais ajouter quelques lignes pour ajouter de la vélocité gauche et droite à la ball ainsi que des murs supplémentaires. A plus tard .....
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
TazNormand
Messages : 1294
Inscription : ven. 27/oct./2006 12:19
Localisation : Calvados (14)

Re: 2D : Un mur, une raquette et une ball.

Message par TazNormand »

Bien joué Falsam

On te sent hyper motivé dans tous tes projets :D
Image
Image
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: 2D : Un mur, une raquette et une ball.

Message par falsam »

TazNormand a écrit :Bien joué Falsam : On te sent hyper motivé dans tous tes projets :D
:)

La suite du code consiste à :
. Ajouter les murs bas, gauche et droit.
Il sera inutile de charger à nouveau les textures. On utilisera cette fois çi la commande CopySprite() pour copier un sprite sur un autre.

. Ajouter de la vélocité horizontale à la ball.
Certains préfèrent calculer le point d'impact sur la raquette pour calculer cette vélocité. j'ai choisi de faire autrement et surtout, c'est bien plus simple :
J'ai partagé ma raquette en deux sprites. Une moitié gauche qui renverra la ball à gauche et une moitié droite qui renverra la ball à droite.

.Contrôler que la raquette reste dans les limites du jeu.
L'instruction ScreenWidth() permet de connaitre la largeur du jeu.
Les points principaux étant bien définis, voici le code.

Code : Tout sélectionner

EnableExplicit

Enumeration
  #MainForm
EndEnumeration

;Sprite Background & mur
Global BackGround, TopWall, BotWall, LeftWall, RightWall

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

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

;Evenement Window
Global Event

;Cette procédure permet de charger les textures de chacun des sprites. 
Procedure GamePreload()
  UseJPEGImageDecoder()
  UsePNGImageDecoder()
  
  ;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
  TopWall = LoadSprite(#PB_Any, #PB_Compiler_Home +"Examples\3D\Data\Textures\RustySteel.jpg")
  ZoomSprite(TopWall, 800, 20)
  
  ;Copie et redimensionnement de TopWall pour créer les autres murs
  BotWall = CopySprite(TopWall, #PB_Any) ;Deroutant cette copy hein ?
  ZoomSprite(BotWall, 800, 20)
  
  LeftWall = CopySprite(TopWall, #PB_Any)
  ZoomSprite(LeftWall, 20, 600)
  
  RightWall = CopySprite(TopWall, #PB_Any)
  ZoomSprite(RightWall, 200, 600)  
  
  ;Chargement de l'image représentant la raquette (Moitié droite et moitié gauche)
  ;Copy et redimensionnement de LeftRacket pour créer RightRacket
  LeftRacket = LoadSprite(#PB_Any, #PB_Compiler_Home +"Examples\3D\Data\Textures\Wood.jpg")
  ZoomSprite(LeftRacket, 50, 20) 
  
  RightRacket = CopySprite(LeftRacket, #PB_Any)
  ZoomSprite(RightRacket, 50, 20) 
  
  ;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) 
  
EndProcedure

;Cette procédure va mettre à jour la position des sprites. Elle est appelé depuis la boucle évenementielle. 
Procedure GameUpdate()  
    
  ;- U.T. Evenements clavier
  ExamineKeyboard()
  
  ;Le centre de la raquette doit etre distant de 70 pixels 
  ; du bord gauche et du bord droit
  
  If KeyboardPushed(#PB_Key_Left) And RacketX > 70
      RacketX - 5 ;Déplacement de la raquette à gauche
  EndIf
  
  If KeyboardPushed(#PB_Key_Right) And RacketX < ScreenWidth() - 70
    RacketX + 5 ;Déplacement de la raquette à droite 
  EndIf
   
  ;- U.T. Collision
  
  ;Collision de la ball avec la raquette moitié gauche.
  ;La velocité verticale doit etre positive (mouvement vers le bas)
  If SpriteCollision(Ball, BallX, BallY, LeftRacket, RacketX-50, RacketY) And VelocityY > 0
    VelocityY * -1 ;Inversion de la vélocité verticale de la ball
    VelocityX = -1 ;la ball partira à gauche grace à notre velocity negative
  EndIf  
  
  ;Collision de la ball avec la raquette moitié droite.
  ;La velocité verticale doit etre positive (mouvement vers le bas)
  If SpriteCollision(Ball, BallX, BallY, RightRacket, RacketX, RacketY) And VelocityY > 0
    VelocityY * -1 ;Inversion de la vélocité verticale de la ball
    VelocityX = 1
  EndIf  
   
  ;Collision de la ball avec le mur du haut
  If SpriteCollision(Ball, BallX, BallY, TopWall, 0, 0)
    VelocityY * -1 ;Inversion de la vélocité verticale de la ball
  EndIf
  
  ;Collision de la ball avec le mur de gauche ou droit
  If SpriteCollision(Ball, BallX, BallY, LeftWall, 0, 0) Or 
     SpriteCollision(Ball, BallX, BallY, RightWall, 780, 0)
    
    VelocityX * -1 ;Inversion de la vélocité verticale de la ball
  EndIf
  
  ;Collision de la ball avec le mur du bas
  If SpriteCollision(Ball, BallX, BallY, BotWall, 0, 580)
    VelocityY = 0 ;Fin du jeu
  EndIf
    
  ;Mise à jour de la position de la ball
  BallX + VelocityX
  BallY + VelocityY

  
  ;-U.T. Affichage des sprites
  
  ;Mise à jour de l'affichage
  DisplaySprite(BackGround, 0, 0) ;Background
  DisplaySprite(TopWall, 0, 0) ;Mur haut
  DisplaySprite(BotWall, 0, 580) ;Mur bas
  DisplaySprite(LeftWall, 0, 0) ;Mur gauche
  DisplaySprite(RightWall, 780, 0) ;Mur gauche
  
  DisplaySprite(Ball, BallX, BallY) ;Ball 
  DisplaySprite(LeftRacket, RacketX-50, RacketY) ;Raquette cotés gauche
  DisplaySprite(RightRacket, RacketX, RacketY) ;Raquette cotés droit

EndProcedure

Procedure GameStart()
  Protected Width = 800
  Protected Height = 600
  
  ;Environnement 2D
  If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0 And InitSound() = 0
    MessageRequester("Error", "Sprite system can't be initialized", 0)
    End
  EndIf
  
  ;Fenetre
  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
    
  ;Boucle evenementielle
  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()
J'ai chois délibérément de ne pas mettre le premier code à jour avec de garder le cheminement.
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: 2D : Un mur, une raquette et une ball.

Message par falsam »

Voila maintenant la dernière partie qui je crois constitue une base pour fabriquer un BreakOut.

. La raquette se compose maintenant de 4 parties : Deux partie centrales qui renvoient la balle à gauche ou à droite avec une vélocité horizontale de 1 et deux parties situées à chaque extrémité qui renvoient la balle avec une vélocité horizontale de 3.
Libre à vous de modifier ces paramètres.

. Ajout des blocks à détruire : 64 blocks stockés dans une liste chaînée qui contient l'identifiant de chaque sprite, ainsi que leurs position (x, y) respective sur le jeu. Cette liste chaînée permet de savoir aussi si le sprite est détruit ou pas.

Je ne traite pas de la gestion des vies. De temps en temps la balle traverse plusieurs briques consécutives comme si l'inversion de la vélocité verticale n'était pas pris en compte. En fait si elle est bien pris en compte, mais l'effet s'inverse quand la ball touche deux blocks en même temps.

Code : Tout sélectionner

EnableExplicit

Enumeration
  #MainForm
EndEnumeration

;Sprite Background & murs (Haut, bas, gauch et droit)
Global BackGround, TopWall, BotWall, LeftWall, RightWall

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

;Sprite Raquette: Position x & y de la raquette. La raquette est divisée en 4 sprites
Global ExtLeftRacket, LeftRacket, ExtRightRacket, RightRacket, RacketX=450, RacketY=500

;Les blocks : Ils seront stockés dans une liste chainé
Structure Block
  Actif.b
  BlockId.i  
  x.i
  y.i
EndStructure

Global NewList Blocks.Block(), Block

;Evenement Window
Global Event

;Cette procédure permet de charger les textures de chacun des sprites. 
Procedure GamePreload()
  Protected x, y
  
  UseJPEGImageDecoder()
  UsePNGImageDecoder()
  
  ;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
  TopWall = LoadSprite(#PB_Any, #PB_Compiler_Home +"Examples\3D\Data\Textures\RustySteel.jpg")
  ZoomSprite(TopWall, 800, 20)
  
  ;Copie et redimensionnement de TopWall pour créer les autres murs
  BotWall = CopySprite(TopWall, #PB_Any) ;Deroutant cette copy hein ?
  ZoomSprite(BotWall, 800, 20)
  
  LeftWall = CopySprite(TopWall, #PB_Any)
  ZoomSprite(LeftWall, 20, 600)
  
  RightWall = CopySprite(TopWall, #PB_Any)
  ZoomSprite(RightWall, 200, 600)  
  
  ;Chargement de l'image représentant la raquette (Moitié droite et moitié gauche)
  ;Copy et redimensionnement de LeftRacket pour créer les trois autres sprites de la raquette
  LeftRacket = LoadSprite(#PB_Any, #PB_Compiler_Home +"Examples\3D\Data\Textures\Wood.jpg")
  ZoomSprite(LeftRacket, 25, 20) 
  
  ExtLeftRacket = CopySprite(LeftRacket, #PB_Any)
  ZoomSprite(ExtLeftRacket, 25, 20) 

  RightRacket = CopySprite(LeftRacket, #PB_Any) 
  ZoomSprite(RightRacket, 25, 20) 
  
  ExtRightRacket = CopySprite(LeftRacket, #PB_Any)
  ZoomSprite(ExtRightRacket, 25, 20) 

  ;Chargement de l'image représentant la ball
  Ball = LoadSprite(#PB_Any, #PB_Compiler_Home +"Examples\3D\Data\Textures\grass.jpg")
  ZoomSprite(Ball, 20, 20) 
  
  ;Chargement de l'image représentant un block
  Block = LoadSprite(#PB_Any, #PB_Compiler_Home +"Examples\3D\Data\Textures\dirt.jpg")
  For y = 80 To 200 Step 40
    For x = 45 To 745 Step 45
      AddElement(Blocks())
      With Blocks()
        \Actif = #True
        \BlockId = CopySprite(Block, #PB_Any) : ZoomSprite(\BlockId, 40, 20) 
        \x = x
        \y = y
      EndWith
    Next
  Next
EndProcedure

;Cette procédure va mettre à jour la position des sprites. Elle est appelé depuis la boucle évenementielle. 
Procedure GameUpdate()  
    
  ;- U.T. Evenements clavier
  ExamineKeyboard()
  
  ;Le centre de la raquette doit rester distant de 75 pixels 
  ;du bord gauche et du bord droit
  
  If KeyboardPushed(#PB_Key_Left) And RacketX > 75
      RacketX - 7 ;Déplacement de la raquette à gauche
  EndIf
  
  If KeyboardPushed(#PB_Key_Right) And RacketX < ScreenWidth() - 75
    RacketX + 7 ;Déplacement de la raquette à droite 
  EndIf
   
  ;- U.T. Collision
  
  ;Collision de la ball avec la raquette moitié gauche.
  ;La velocité verticale doit etre positive (mouvement vers le bas)
  If SpriteCollision(Ball, BallX, BallY, LeftRacket, RacketX-25, RacketY) And VelocityY > 0
    VelocityY * -1 ;Inversion de la vélocité verticale de la ball
    VelocityX = -1 ;la ball partira à gauche grace à notre velocity negative
  EndIf  
  
  If SpriteCollision(Ball, BallX, BallY, ExtLeftRacket, RacketX-50, RacketY) And VelocityY > 0
    VelocityY * -1 ;Inversion de la vélocité verticale de la ball
    VelocityX = -3 ;la ball partira à gauche grace à notre velocity negative
  EndIf  
  
  ;Collision de la ball avec la raquette moitié droite.
  ;La velocité verticale doit etre positive (mouvement vers le bas)
  If SpriteCollision(Ball, BallX, BallY, RightRacket, RacketX, RacketY) And VelocityY > 0
    VelocityY * -1 ;Inversion de la vélocité verticale de la ball
    VelocityX = 1
  EndIf  
  
  If SpriteCollision(Ball, BallX, BallY, ExtRightRacket, RacketX+25, RacketY) And VelocityY > 0
    VelocityY * -1 ;Inversion de la vélocité verticale de la ball
    VelocityX = 3
  EndIf  
   
  ;Collision de la ball avec le mur du haut
  If SpriteCollision(Ball, BallX, BallY, TopWall, 0, 0)
    VelocityY * -1 ;Inversion de la vélocité verticale de la ball
  EndIf
  
  ;Collision de la ball avec le mur de gauche ou droit
  If SpriteCollision(Ball, BallX, BallY, LeftWall, 0, 0) Or 
     SpriteCollision(Ball, BallX, BallY, RightWall, 780, 0)
    
    VelocityX * -1 ;Inversion de la vélocité verticale de la ball
  EndIf
  
  ;Collision de la ball avec le mur du bas
  If SpriteCollision(Ball, BallX, BallY, BotWall, 0, 580)
    VelocityY = 0 ;Fin du jeu
  EndIf
  
  ;Collision avec un block
  ForEach(Blocks())
    With blocks()
      If \Actif = #True
        If SpriteCollision(Ball, BallX, BallY, \BlockId, \x, \y)
          \Actif = #False ; Le sprite n'est plus actif et on le détruit
          FreeSprite(\BlockId) 
          VelocityY * -1
        EndIf
      EndIf
    EndWith
  Next
  
  ;Mise à jour de la position de la ball
  BallX + VelocityX
  BallY + VelocityY

  
  ;-U.T. Affichage des sprites
  
  ;Mise à jour de l'affichage
  DisplaySprite(BackGround, 0, 0) ;Background
  DisplaySprite(TopWall, 0, 0) ;Mur haut
  DisplaySprite(BotWall, 0, 580) ;Mur bas
  DisplaySprite(LeftWall, 0, 0) ;Mur gauche
  DisplaySprite(RightWall, 780, 0) ;Mur gauche
  
  ForEach(Blocks())
    With Blocks()
      If \Actif
        DisplaySprite(\BlockId, \x, \y) ;Ball 
      EndIf
    EndWith
  Next
  
  DisplaySprite(Ball, BallX, BallY) ;Ball 
  
  DisplaySprite(ExtLeftRacket, RacketX-50, RacketY) ;Raquette cotés gauche
  DisplaySprite(LeftRacket, RacketX-25, RacketY) ;Raquette cotés gauche
  DisplaySprite(RightRacket, RacketX, RacketY) ;Raquette cotés droit
  DisplaySprite(ExtRightRacket, RacketX+25, RacketY) ;Raquette cotés droit

EndProcedure

Procedure GameStart()
  Protected Width = 800
  Protected Height = 600
  
  ;Environnement 2D
  If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0 And InitSound() = 0
    MessageRequester("Error", "Sprite system can't be initialized", 0)
    End
  EndIf
  
  ;Fenetre
  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
    
  ;Boucle evenementielle
  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.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: 2D : Un mur, une raquette et une ball.

Message par Micoute »

Du bon travail, comme d'habitude.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
raven
Messages : 222
Inscription : jeu. 06/janv./2005 15:45

Re: 2D : Un mur, une raquette et une ball.

Message par raven »

excellent,

merci pour ton partage :wink:
Pb5.24 Lts/5.31 Windows 7 64 nvidia 560 ti E8500 8g ram
Avatar de l’utilisateur
venom
Messages : 3072
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: 2D : Un mur, une raquette et une ball.

Message par venom »

Oui, merci pour ce partage de code très propre, et facilement lisible.
Il n'y a plus qu'a faire un casse brique maintenant :D






@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: 2D : Un mur, une raquette et une ball.

Message par falsam »

venom a écrit :.. et facilement lisible. Il n'y a plus qu'a faire un casse brique maintenant
Si tu regardes le dernier code, tu peux déjà casser des briques. Alors au boulot et ajoute la gestion des vies par exemple :)
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
Ar-S
Messages : 9477
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: 2D : Un mur, une raquette et une ball.

Message par Ar-S »

Du bon boulot comme d'hab. Pour les murs, je préfère pour ma part ne pas mettre de sprite et de jouer seulement avec les coord de la balle. ça fait moins de collision à gérer.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: 2D : Un mur, une raquette et une ball.

Message par falsam »

@Ar-S: Merci. Effectivement c'est assez simple de gérer les coordonnées dans ce cas. En plus je le fais pour la raquette.
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
venom
Messages : 3072
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: 2D : Un mur, une raquette et une ball.

Message par venom »

falsam a écrit :Si tu regardes le dernier code, tu peux déjà casser des briques. Alors au boulot et ajoute la gestion des vies par exemple :)
Oui oui j'avais lancer ton dernier code :wink: Ma phrase était bien pour dire (il n'y a plus qu'a ajouté des options) :P






@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: 2D : Un mur, une raquette et une ball.

Message par djes »

C'est du très bon boulot, propre et modulaire, bravo ! :D
falsam a écrit :De temps en temps la balle traverse plusieurs briques consécutives comme si l'inversion de la vélocité verticale n'était pas pris en compte. En fait si elle est bien pris en compte, mais l'effet s'inverse quand la ball touche deux blocks en même temps.
Oui et non, c'est surtout dû à la granularité du déplacement, c'est ce que je disais dans l'autre sujet. Le pas du déplacement, c'est à dire la distance qui sépare deux emplacements successifs de la balle, fait que parfois la balle passe "à travers" les briques, ou que la position suivant une collision fait que la balle se retrouve à l'intérieur d'une autre brique. Ca arrive surtout quand la collision concerne les coins des briques, ou pire si les briques se déplacent (ce qui n'est pas le cas ici). Il y a plusieurs façons de résoudre ce problème, et je dirais qu'à chaque programmeur sa solution, mais c'est beaucoup plus compliqué que ça en a l'air, et il y a peu de casse-briques qui échappent à quelques bugs de collision :)
Répondre