Balistique

Programmation avancée de jeux en PureBasic
comtois
Messages : 5172
Inscription : mer. 21/janv./2004 17:48
Contact :

Balistique

Message par comtois »

j'ai changé quelques petits détails , cette fois ci j'utilise des sprites de 32x32 , libre à chacun d'en mettre des plus beaux :)

il y a le source du jeu et le source d'un petit "éditeur" , bricolé en 1 heure , il ne faut pas trop en demander :)
mode d'emploi :
[F1] => Sauve le niveau
[F2] => Charge le niveau
[F5] => Décrémente le niveau
[F6] => Incrémente le niveau

Choisir une brique sur la droite ( clic gauche )
et cliquez sur la gauche , je m'aperçois en rédigeant le mode d'emploi que je n'ai pas affiché de cadre pour délimiter la zone de construction , mais c'est pas trop gênant, vous allez la découvrir en baladant la souris et en cliquant :)
Pour remplir la zone de construction avec une brique , clic droit ( de préférence la brique bleue )

Remarque : dans le jeu , il y a collision avec toutes les briques , sauf la brique bleue ( la dernière , juste avant la maison )

Pour placer les maisons
=> Sélectionnez la maison dans la liste à droite , puis :
=> Clic gauche dans la zone de construction pour placer la maison du joueur 0
=> Clic droit dans la zone de construction pour placer la maison du joueur 1

Si vous l'améliorez , merci de partager ici vos modifications :)

http://perso.wanadoo.fr/comtois/sources/canon1.zip
Avatar de l’utilisateur
Thyphoon
Messages : 2697
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Comme j'ai modifier le code du programme principal pour le rendre compatible avec PB4.10 autant en faire profiter a tout le monde :P

Code : Tout sélectionner

;Comtois
;Le 15/07/04
;PB 4.10  V0.3

#ScreenWidth  = 800
#ScreenHeight = 600
#ScreenDepth  = 32
#MaxX         = 25
#MaxY         = 17
#SizeX        = 32
#SizeY        = 32
#NbBrique     = 13
;Les sprites
Enumeration #NbBrique + 1
  #Maison        
  #Boulet    
  #Bandeau1    
  #Bandeau2    
  #Bandeau3    
EndEnumeration

#NiveauMax    = 7
#DegRad = 0.0174533


  
;{- Initialisation
If InitSprite() = 0 Or InitKeyboard() = 0 
  MessageRequester( "Erreur" , "Impossible d'initialiser DirectX 7 Ou plus" , 0 )
  End
ElseIf OpenScreen( #ScreenWidth , #ScreenHeight , #ScreenDepth , "M3D_Matrix3D" ) = 0
  MessageRequester( "Erreur" , "Impossible d'ouvrir l'écran " , 0 )
  End
EndIf

RandomSeed(ElapsedMilliseconds())
;}
UsePNGImageDecoder()
;Charge les sprites
For a = 1 To #NbBrique
  LoadSprite(a, "images\img" + Str(a) + "a.png")
Next
LoadSprite(#Maison,"Images\maison1.png")
LoadSprite(#Boulet,"Images\balle1.png")
LoadSprite(#Bandeau1,"Images\bandeau1.png")
LoadSprite(#Bandeau2,"Images\bandeau2.png")
LoadSprite(#Bandeau3,"Images\bandeau3.png")

;- Structures
Structure Joueur
  Tir.l
  X0.l      ; Position d'origine en X
  Y0.l      ; Position d'origine en Y
  Angle.f   ; Angle de tir
  V0.f      ; Vitesse initiale du tir
  Pas.f
  Score.l
EndStructure

Structure Boulet
  masse.l
  x.l
  y.l
EndStructure

Structure Brique
  no.l
  x.l
  y.l
  Collision.l
EndStructure

Global Boulet.Boulet  
Global Dim Joueur.Joueur(1)
Global g.f,Temps.f,Vent.l,Niveau.l,Inverse.l,ScrollX.l

Global Dim Map(#MaxX, #MaxY)
Global NewList Brique.Brique()
Global NewList Trace.Boulet()
g = 9.81
Boulet\masse = 20
Niveau = 0
Declare LoadNiveau()
Declare InverseMap() 
Declare AfficheNiveau()
Declare Affaide(Joueur)

;- Procedures
Procedure NewGame()
  ;Vent
  Vent = Random(100)-50
  ;Position Joueur 1
  Joueur(0)\Pas = 0.5
  ;Position Joueur 2
  Joueur(1)\Pas = -0.5
  If Inverse = 2 Or Inverse = 0
    Niveau + 1
    If Niveau < #NiveauMax Or Niveau = 1
      LoadNiveau()
    EndIf  
  ElseIf Inverse = 1
    InverseMap()
  EndIf  
EndProcedure  
Procedure Init(Joueur)
  Joueur(Joueur)\Angle = Abs((180 * Joueur) - 45) 
  Joueur(Joueur)\V0 = 80  
  Temps = 0
  Boulet\x = Joueur(Joueur)\X0
  Boulet\y = Joueur(Joueur)\Y0
  ClearList(Trace())
EndProcedure
Procedure Tir(Joueur)
  y.f =  (Joueur(Joueur)\V0 * Sin(Joueur(Joueur)\Angle * #DegRad) * Temps) -  ( (g / 2) * Temps * Temps)
  x.f = ((Vent / (2 * Boulet\masse)) * Temps * Temps) + (Joueur(Joueur)\V0 * (Cos(Joueur(Joueur)\Angle * #DegRad) * Temps))  
  
  Boulet\x = Joueur(Joueur)\X0 + x
  Boulet\y = Joueur(Joueur)\Y0 - y
  DisplayTransparentSprite(#Boulet,Boulet\x,Boulet\y)
  AddElement(Trace())
  Trace()\x = Boulet\x + 16
  Trace()\y = Boulet\y + 16
  Temps + 0.15
EndProcedure
Procedure ChangeJoueur(Joueur)
  Joueur(Joueur)\Tir = 0
  Joueur = 1 - Joueur
  Init(Joueur)
  ProcedureReturn Joueur
EndProcedure  
Procedure AfficheTrace()
  Repeat
    AfficheNiveau()
    x = - 1 
    y = - 1
    StartDrawing(ScreenOutput())
    ForEach Trace()
      If x <> - 1
        LineXY(x,y,Trace()\x,Trace()\y,RGB(255,0,0))
      EndIf  
      x = Trace()\x
      y = Trace()\y
    Next   
    StopDrawing() 
    DisplayTransparentSprite(#Boulet,Boulet\x,Boulet\y)
    Affaide(Joueur)
    FlipBuffers()

    ExamineKeyboard()
  Until KeyboardPushed(#PB_Key_All) 
EndProcedure  
Procedure LoadNiveau()
  Inverse = 1 
  If OpenFile(0, "Niveaux\Niveau" + Str(Niveau) + ".map")
    ClearList(Brique())
    Joueur(0)\X0 = ReadLong(0) * #SizeX
    Joueur(0)\Y0 = ReadLong(0) * #SizeY
    Joueur(1)\X0 = ReadLong(0) * #SizeX
    Joueur(1)\Y0 = ReadLong(0) * #SizeY
    For y = 0 To #MaxY - 1
      For x = 0 To #MaxX - 1
        Map(x, y) = ReadLong(0)
        If Map(x, y ) <> #NbBrique
          AddElement(Brique())
          Brique()\no = Map(x, y)
          Brique()\x = x * #SizeX
          Brique()\y = y * #SizeY
        EndIf  
      Next x
    Next y
    CloseFile(0)
  EndIf
EndProcedure     
Procedure InverseMap()
  ClearList(Brique())
  For y = 0 To #MaxY - 1 
    For x = 0 To (#MaxX - 1) / 2
      Brique =  Map(x, y)
      Map(x, y) = Map(#MaxX - x - 1, y)
      Map(#MaxX - x - 1, y) = Brique  
    Next x
  Next y  
  ; pour ne pas me casser la tête , je gère la liste après l'inversion 
  For y = 0 To #MaxY - 1
    For x = 0 To #MaxX - 1
      If Map(x, y ) <> #NbBrique
        AddElement(Brique())
        Brique()\no = Map(x, y)
        Brique()\x = x * #SizeX
        Brique()\y = y * #SizeY
      EndIf  
    Next x
  Next y
  interX = Joueur(0)\X0
  intery = Joueur(0)\Y0
  Joueur(0)\X0 = #MaxX * #SizeX - Joueur(1)\X0 - #SizeX
  Joueur(0)\Y0 = Joueur(1)\Y0
  Joueur(1)\X0 = #MaxX * #SizeX - interX - #SizeX
  Joueur(1)\Y0 = intery
  Inverse = 2
EndProcedure
Procedure AfficheNiveau()
  ClearScreen(0)
  For y = 0 To #MaxY - 1
    For x = 0 To #MaxX - 1
      If Map(x, y)
        DisplayTransparentSprite(Map(x, y), x * #SizeX, y * #SizeY)
      EndIf  
    Next x
  Next y  
  DisplayTransparentSprite(#Maison,Joueur(0)\X0,Joueur(0)\Y0)
  DisplayTransparentSprite(#Maison,Joueur(1)\X0,Joueur(1)\Y0)
  ;Affiche le vent ( voir pour faire un sprite ? 
  StartDrawing(ScreenOutput())
  x1=(#ScreenWidth-Vent*3)/2
  y1=50
  x2=x1+Vent*3
  y2=y1
  LineXY(x1,y1,x2,y2,RGB(255,255,255))
  If Vent > 0
    Line(x2,y2,-10,-5,RGB(255,255,255))
    Line(x2,y2,-10,5,RGB(255,255,255))
  Else
    Line(x2,y2,10,5,RGB(255,255,255))
    Line(x2,y2,10,-5,RGB(255,255,255))    
  EndIf  
  StopDrawing()
  
  DisplaySprite(#Bandeau1,608, #ScreenHeight - #SizeY)
  DisplaySprite(#Bandeau3,#MaxX * #SizeX - #SizeX, #ScreenHeight - #SizeY)
  For a = 1 To 4 
    DisplaySprite(#Bandeau2,608 + a * #SizeX , #ScreenHeight - #SizeY)
  Next a  
EndProcedure
Procedure Barre(x,y,largeur,Hauteur,Valeur,Mini,Maxi,CoulCadre,CoulBarre)
  Box(x,y,largeur,Hauteur,CoulCadre)
  For a = Mini To Maxi Step 10
    Line(x ,y + Hauteur,0,Hauteur/2,CoulCadre)
  Next a
EndProcedure  
Procedure Affaide(Joueur)
  StartDrawing(ScreenOutput())
  FrontColor(RGB(255,255,255))
  DrawingMode(1)
  ;Scroll titre 
  If Joueur 
    FrontColor(RGB(255,55,55))
  Else
    FrontColor(RGB(55,55,255))
  EndIf  
  texte$ = "Joueur " +  Str(Joueur) + ", utilisez les flèches haut et bas pour modifier l'angle ( barre verte ) , et les flèches gauche et droite pour modifier la vitesse ( barre orange )"
  DrawText(ScrollX, #ScreenHeight - 52,texte$)   
  ScrollX - 1
  If ScrollX < - TextWidth(texte$)
    ScrollX = #ScreenWidth
  EndIf  
  ;Score
  FrontColor(RGB(255,255,255))
  texte$ = Str(Joueur(0)\Score) + " /  " + Str(Joueur(1)\Score) 
  DrawText(#ScreenWidth - 50, 576,texte$) 
  
  ;Affiche l'angle et la vitesse en clair
  DrawText(630, 576,StrF(Abs(180 * Joueur - Joueur(Joueur)\Angle), 2) + " / " + StrF(Joueur(Joueur)\V0,2))
 
  ;barre angle
  Hauteur = 10
  x = 9
  y = 579
  DrawingMode(0)  
  ValeurAngle = Abs(180 * Joueur - Joueur(Joueur)\Angle) * 2
  Box(x + 1 , y , ValeurAngle,Hauteur - 2,RGB(55,255,55))
  DrawingMode(4)
  Box(x, y - 1, 181, Hauteur,RGB(255,255,255))
  y - 2
  For a = 0 To 180 Step 20
    Line(x + a ,y + Hauteur, 0, - Hauteur / 2,RGB(255,255,255))
  Next a
  For a = 10 To 180 Step 20
    Line(x + a ,y + Hauteur, 0, -Hauteur / 4,RGB(255,255,255))
  Next a
  ;barre Vitesse
  Hauteur = 10
  x = 200
  y = 579
  DrawingMode(0)  
  ValeurVitesse = Joueur(Joueur)\V0 * 2
  Box(x + 1 , y , ValeurVitesse,Hauteur - 2,RGB(255,155,55))
  DrawingMode(4)
  Box(x, y - 1, 401, Hauteur,RGB(255,255,255))
  y - 2
  For a = 0 To 400 Step 20
    Line(x + a ,y + Hauteur, 0, - Hauteur / 2,RGB(255,255,255))
  Next a
  For a = 10 To 400 Step 20
    Line(x + a ,y + Hauteur, 0, -Hauteur / 4,RGB(255,255,255))
  Next a
StopDrawing()  
  
EndProcedure  
;/
;- Boucle Principale
;/
Joueur = 0
NewGame()
Init(Joueur)

Repeat
  AfficheNiveau()
  If ExamineKeyboard()
    If KeyboardPushed(#PB_Key_Return)
      Joueur(Joueur)\Tir = 1
    EndIf  
    If Joueur(Joueur)\Tir = 0
      If KeyboardPushed(#PB_Key_Left) And Joueur(Joueur)\V0 > 0
        Joueur(Joueur)\V0 - 0.5
      ElseIf KeyboardPushed(#PB_Key_Right) And Joueur(Joueur)\V0 < 200
        Joueur(Joueur)\V0 + 0.5
      EndIf
      If KeyboardPushed(#PB_Key_Down) And Abs(180 * Joueur - Joueur(Joueur)\Angle) > 0
        Joueur(Joueur)\Angle - Joueur(Joueur)\Pas
      ElseIf KeyboardPushed(#PB_Key_Up) And Abs(180 * Joueur - Joueur(Joueur)\Angle) < 90
        Joueur(Joueur)\Angle + Joueur(Joueur)\Pas
      EndIf 
    EndIf  
  EndIf
  ForEach Brique()
    If SpritePixelCollision(#Boulet,Boulet\x,Boulet\y,Brique()\no,Brique()\x,Brique()\y)
      AfficheTrace()
      Joueur = ChangeJoueur(Joueur)
    ElseIf SpritePixelCollision(#Boulet,Boulet\x,Boulet\y,#Maison,Joueur(1 - Joueur)\X0,Joueur(1 - Joueur)\Y0)
      AfficheTrace()
      Joueur(Joueur)\Score + 1
      Joueur = ChangeJoueur(Joueur)
      NewGame()
      Init(Joueur)
    EndIf  
  Next  
  If  Boulet\y > #ScreenHeight
    AfficheTrace()
    Joueur = ChangeJoueur(Joueur)
  EndIf  
  If Joueur(Joueur)\Tir
    Tir(Joueur)
  EndIf  
  Affaide(Joueur)
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)  
Allez tant que j'y étais voici aussi l'editeur :)

Code : Tout sélectionner

;Comtois
;Le 18/07/04
;PB 3.91  V0.0

#ScreenWidth  = 1024
#ScreenHeight = 768
#ScreenDepth  = 32

#MaxX         = 25
#MaxY         = 17
#SizeX        = 32
#SizeY        = 32
#OffSetX      = 16
#OffSetY      = 16
#NbBrique     = 13
#Maison       = #NbBrique + 1
  
;{- Initialisation
If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0
  MessageRequester( "Erreur" , "Impossible d'initialiser DirectX 7 Ou plus" , 0 )
  End
ElseIf OpenScreen( #ScreenWidth , #ScreenHeight , #ScreenDepth , "M3D_Matrix3D" ) = 0
  MessageRequester( "Erreur" , "Impossible d'ouvrir l'écran " , 0 )
  End
EndIf

;}

UsePNGImageDecoder()

Structure Brique
  x.l
  y.l
EndStructure

Global Dim BriqueCollision(#NbBrique)
Global Dim Map(#MaxX, #MaxY)
Global Dim Maison.Brique(1)
Global Niveau
 
;Charge les sprites
For a = 1 To #NbBrique
  LoadSprite(a, "images\img" + Str(a) + "a.png")
Next
LoadSprite(#Maison, "images\maison1.png")

;- Procedures
Procedure SaveNiveau()
  If OpenFile(0, "Niveaux\Niveau" + Str(Niveau) + ".map")
    WriteLong(0,Maison(0)\x)
    WriteLong(0,Maison(0)\y)
    WriteLong(0,Maison(1)\x)
    WriteLong(0,Maison(1)\y)  
    For y = 0 To #MaxY - 1
      For x = 0 To #MaxX - 1
        WriteLong(0,Map(x, y))
      Next x
    Next y
    CloseFile(0)
  EndIf
EndProcedure  
Procedure LoadNiveau()
  If OpenFile(0, "Niveaux\Niveau" + Str(Niveau) + ".map")
    Maison(0)\x = ReadLong(0)
    Maison(0)\y = ReadLong(0)
    Maison(1)\x = ReadLong(0)
    Maison(1)\y = ReadLong(0)
    For y = 0 To #MaxY - 1
      For x = 0 To #MaxX - 1
        Map(x, y) = ReadLong(0)
      Next x
    Next y
    CloseFile(0)
  EndIf
EndProcedure 
Procedure FillMap(Brique.l)
  For y = 0 To #MaxY - 1
    For x = 0 To #MaxX - 1
      If Map(x, y) = 0
        Map(x,y) = Brique
      EndIf  
    Next x
  Next y  
EndProcedure     
Procedure AfficheNiveau()
  For y = 0 To #MaxY - 1
    For x = 0 To #MaxX - 1
      If Map(x, y)
        DisplayTransparentSprite(Map(x, y), x * #SizeX, y * #SizeY)
      EndIf  
    Next x
  Next y  
  DisplayTransparentSprite(#Maison,Maison(0)\x * #SizeX, Maison(0)\y * #SizeY) 
  DisplayTransparentSprite(#Maison,Maison(1)\x * #SizeX, Maison(1)\y * #SizeY) 
EndProcedure 
Procedure Affaide()
  StartDrawing(ScreenOutput())
  FrontColor(RGB(255,255,255))
  DrawingMode(1)
  DrawText(10,580,"Niveau    => " + Str(Niveau))   
  StopDrawing()  
EndProcedure  
  
;- Boucle principale
NoBrique = 1
Niveau = 1  
Repeat
  ClearScreen(0)
  ;Affiche les briques
  For a = 1 To #NbBrique
    DisplaySprite(a,#ScreenWidth - #SizeX, a * #SizeY)
  Next a
  DisplaySprite(#Maison,#ScreenWidth - #SizeX, #NbBrique * #SizeY + #SizeY)  
  AfficheNiveau()
    
  ;Affiche la souris
  DisplayTransparentSprite(NoBrique,MouseX() - #OffSetX,MouseY() - #OffSetY)
  StartDrawing(ScreenOutput())
  DrawingMode(4)
  Box(MouseX()- #OffSetX, MouseY()- #OffSetY, #SizeX, #SizeY, RGB(255,255,255))
  StopDrawing()
  ;Test la souris
  If ExamineMouse()
    If MouseButton(1)
      Mx = MouseX()
      My = MouseY()
      If Mx > #ScreenWidth - #SizeX And Mx < #ScreenWidth
        If My > #SizeY And My < #Maison * #SizeY + #SizeY 
          NoBrique = My / #SizeY 
        EndIf
      EndIf
      If Mx > 0 And Mx < #MaxX * #SizeX + #SizeX
        If My > 0 And My < #MaxY * #SizeY + #SizeY
          x = Mx / #SizeX
          y = My / #SizeY
          If NoBrique = #Maison
            Maison(0)\x = x
            Maison(0)\y = y
          Else  
            Map(x, y) = NoBrique
          EndIf  
        EndIf
      EndIf 
    EndIf
    If MouseButton(2)
      Mx = MouseX()
      My = MouseY()
      If Mx > 0 And Mx < #MaxX * #SizeX + #SizeX
        If My > 0 And My < #MaxY * #SizeY + #SizeY
          x = Mx / #SizeX
          y = My / #SizeY
          If NoBrique = #Maison
            Maison(1)\x = x
            Maison(1)\y = y
          Else
            FillMap(NoBrique)
          EndIf  
        EndIf
      EndIf 
    EndIf
  EndIf  
  ;Test le clavier
  If ExamineKeyboard()
    If KeyboardReleased(#PB_Key_F1)
      SaveNiveau()
    EndIf
    If KeyboardReleased(#PB_Key_F2)
      LoadNiveau()
      AfficheNiveau()
    EndIf  
    If KeyboardReleased(#PB_Key_F5) And Niveau > 1
      Niveau - 1
    EndIf
    If KeyboardReleased(#PB_Key_F6) 
      Niveau + 1
    EndIf
  EndIf

  Affaide()
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)  
  
  
  
Répondre