Programmierung der Feuertaste auf Gamepad

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Tanaghra
Beiträge: 28
Registriert: 13.05.2017 01:44

Programmierung der Feuertaste auf Gamepad

Beitrag von Tanaghra »

Hallo,

nach einigen GUI-Projekten wollte ich schon immer mal etwas im Bereich der 2D-Programmierung versuchen, und nach Möglichkeit etwas Sinnvolles wie ein einfaches Spiel. Mein Problem ist definitiv ein Anfängerproblem, aber da es nun einmal die Rubrik "Grafik- & Sound-Programmierung" gibt, schien es mir nicht richtig, es im Anfänger-Forum zu posten.

Um die Sprites und Bilder zu sehen, müßt ihr die folgenden 5 Bilddateien auf euren Rechner laden, hier die Links:

https://www.magentacloud.de/lnk/TzrPLXKB
https://www.magentacloud.de/lnk/s9LPLPbr
https://www.magentacloud.de/lnk/yQrPrkd1
https://www.magentacloud.de/lnk/KsrvL5ip
https://www.magentacloud.de/lnk/RJLPrWTj

Außerdem muß der Pfad der Konstanten #SprV in Zeile 17 im meinem Kode entsprechend geändert werden, damit die Sprites und Bilder auch gefunden werden:

Code: Alles auswählen

EnableExplicit

Enumeration Sprites
  #UB1: #UB2: #UB3  ;     U-Boote 0–2
  #lT1: #lT2=7: #lT3=11 ; laufende Torpedos unten
  #Fro=15: #Frw ;         Frachtschiffe    ost/-westwärts
  #Zsto: #Zstw  ;         Zerstörer        ost-/westwärts
  #Pbo: #Pbw  ;           Patrouillenboote ost-/westwärts
EndEnumeration

Enumeration Bilder
  #nT1lo: #nT1ro: #nT1lu: #nT1ru  ; nachgeladene Torpedos Spieler 1
  #nT2lo: #nT2ro: #nT2lu: #nT2ru  ;                       Spieler 2
  #nT3lo: #nT3ro: #nT3lu: #nT3ru  ;                       Spieler 3
EndEnumeration

#SprV="D:\Programmierung\Basic-Programme\PureBasic\Sea Wolf\Sprites\"
; Sprite-Verzeichnis

If Not InitSprite() Or Not InitKeyboard() Or Not InitJoystick()
  MessageRequester("Abbruch", ~"Sprites, Tastatur oder Joystick konnten\n"+
    "nicht initialisiert werden.",
    #PB_MessageRequester_Ok|#PB_MessageRequester_Error)
  End
EndIf

If OpenScreen(1280,960, 32, "Sea Wolf")
  UsePNGImageDecoder()
  LoadFont(1, "Arial", 24, #PB_Font_Bold)
  
  Define A, K, AaT1, AaT2, AaT3, PUB1=580, PUB2=580, PUB3=580, Sp, Spa=2, T,
  x  ; Abbruch, Anzahl abgefeuerter Torpedos Spieler 1/2/3, Kennzeichner,
; Positionen der U-Boote Spieler 1/2/3, Spieler, Spieleranzahl, Torpedo

  Dim wPlT(Spa, 3): Dim sPlT(Spa, 3)  ; waage-/senkrechte Pos. d. lauf. Torpedos
  Dim Fr(5, Spa): Dim Zst(5, Spa): Dim Pb(5, Spa)

; ------------------------- Sprites für Spieler-U-Boote -----------------------

  CatchSprite(#UB1, ?UB): CopySprite(#UB1, #UB2): CopySprite(#UB1, #UB3)
  StartDrawing(SpriteOutput(#UB2)): FillArea(60,18, 0, $8aff): StopDrawing()
  StartDrawing(SpriteOutput(#UB3)): FillArea(60,18, 0, $9a89ea): StopDrawing()

; ------------------------ Sprites für laufende Torpedos ----------------------

  CatchSprite(#lT1, ?lT, 8) ; 8 = #PB_Sprite_AlphaBlending
  CopySprite(#lT1, #lT2, 8): CopySprite(#lT1, #lT3, 8)
  StartDrawing(SpriteOutput(#lT2)): FillArea(7,14, 0, $8aff): StopDrawing()
  StartDrawing(SpriteOutput(#lT3)): FillArea(7,14, 0, $9a89ea): StopDrawing()

; ------------------- Sprites für die zu bekämpfenden Schiffe -----------------

  LoadSprite(#Frw,  #SprV+"Frachtschiff fw.png")
  LoadSprite(#Fro,  #SprV+"Frachtschiff fo.png")
  LoadSprite(#Zstw, #SprV+"Zerstörer fw.png")
  LoadSprite(#Zsto, #SprV+"Zerstörer fo.png")
  LoadSprite(#Pbw,  #SprV+"Patrouillenboot fw.png")
  LoadSprite(#Pbo,  #SprV+"Patrouillenboot fo.png")

; --------------------- Bilder für nachzuladende Torpedos ---------------------

  CatchImage(0, ?Tn): CopyImage(0, 1): CopyImage(0, 2): CopyImage(0, 3)
  CopyImage(0, 4)

  StartDrawing(ImageOutput(4)): FillArea(60,9, 0, $8aff): StopDrawing()
  CopyImage(4, 5): CopyImage(4, 6): CopyImage(4, 7)
  CopyImage(0, 8)
  StartDrawing(ImageOutput(8)): FillArea(60,9, 0, $9a89ea): StopDrawing()
  CopyImage(8, 9): CopyImage(8, 10): CopyImage(8, 11)

; -----------------------------------------------------------------------------

  Repeat
    FlipBuffers()
    ClearScreen(0)  ; a schwarzen Bildschirm hab’ ich!
    StartDrawing(ScreenOutput())  ;             R    G    B 
      Box(0,0,   1280,110, $cce300) ; türkis     0, 227, 204 = 13.427.456
      Box(0,110, 1280,260, $ff8f85) ; hellblau 133, 143, 255 = 16.748.427
      Box(0,370, 1280,290, $d50c00) ; blau       0,  12, 213 = 13.962.240

      DrawImage(ImageID(#nT1lo),  80,870): DrawImage(ImageID(#nT1ro),  210,870)
      DrawImage(ImageID(#nT1lu),  80,900): DrawImage(ImageID(#nT1ru),  210,900)
      DrawImage(ImageID(#nT2lo), 515,870): DrawImage(ImageID(#nT2ro),  645,870)
      DrawImage(ImageID(#nT2lu), 515,900): DrawImage(ImageID(#nT2ru),  645,900)
      DrawImage(ImageID(#nT3lo), 950,870): DrawImage(ImageID(#nT3ro), 1080,870)
      DrawImage(ImageID(#nT3lu), 950,900): DrawImage(ImageID(#nT3ru), 1080,900)

      DrawingMode(#PB_2DDrawing_Transparent)
      DrawingFont(FontID(1))
      DrawText(287,15, "höchster bisher erreichter Punktestand:", #Red)
      DrawText(50, 60, "Spieler 1:", #Black)
      DrawText(520,60, "Spieler 2:", #Black)
      DrawText(987,60, "Spieler 3:", #Black)
      DrawText(383,812, "verbleibende Spielzeit:", #White)
    StopDrawing()  

    DisplaySprite(#UB1, PUB1, 670)  ; U-Boot Spieler 1
    DisplaySprite(#UB2, PUB2, 715)  ; U-Boot Spieler 2
    DisplaySprite(#UB3, PUB3, 760)  ; U-Boot Spieler 3
  
    DisplaySprite(#Fro, 250, 132) ; Frachter oben
    DisplaySprite(#Frw, 550, 214) ; Frachter Mitte
    K=CopySprite(#Fro, #PB_Any): DisplaySprite(K, 850, 298) ; Frachter unten

    ExamineJoystick(0): ExamineJoystick(1)
    If JoystickButton(0, 2)
      AaT1+1
      wPlT(0, 0)=PUB1+54: sPlT(0, 0)=628
      DisplayTransparentSprite(#lT1, wPlT(0, 0), sPlT(0, 0))
    ElseIf JoystickButton(0, 5)
      PUB1-18
    ElseIf JoystickButton(0, 6)
      PUB1+18
    ElseIf JoystickButton(1, 5)
      PUB2-18
    ElseIf JoystickButton(1, 6)
      PUB2+18
    EndIf

    If sPlT(0, 0)<629 And sPlT(0, 0)>110
      sPlT(0, 0)-10
      DisplayTransparentSprite(#lT1, wPlT(0, 0), sPlT(0, 0))
    Else
      sPlT(0, 0)=-1
    EndIf
    

    ExamineKeyboard()
    If KeyboardReleased(#PB_Key_Escape): A=#True: EndIf

  Until A=#True

Else
  MessageRequester("Abbruch", ~"Bildschirm konnte nicht mit den\n"+
    "angegebenen Parametern geöffnet werden.",
    #PB_MessageRequester_Ok|#PB_MessageRequester_Error)
EndIf

End


DataSection
  UB: ; U-Boot (Sprite)
    IncludeBinary #SprV+"U-Boot.png"
  Tn: ; Torpedo nachladen (Bild)
    IncludeBinary #SprV+"Torpedo nachladen.png"
  lT: ; laufender Torpedo
    IncludeBinary #SprV+"Torpedo läuft.png"
EndDataSection
Es handelt sich um eine Art Windows-Remake des C64-Spiels „Sea Wolf“, nur für 3 und nicht nur 2 Spieler. Im hellblauen Bereich fahren Schiffe (siehe die 3 Frachtschiffe) herum, die dann von den 3 U-Booten im unteren (schwarzen) Bereich mit Torpedos abgeschossen werden. Die 4 Torpedos je Spieler unter den U-Booten werden, nachdem sie verschossen worden sind, nachgeladen, was 3 Sekunden dauert, in denen nicht gefeuert werden kann. Die U-Boote werden nur nach links und rechts bewegt, um in die richtige Abschußposition zu kommen). Sie werden mit Gamepad-Tasten – JoystickButton(0, 5) bzw. (0, 6) – gesteuert, ebenso natürlich das Abfeuern der Torpedos (0, 2). So weit die Spielidee.

Ich bin bis zu dem Punkt gekommen, daß sich das gelbe und braune U-Boot wie gewünscht nach links und rechts bewegen. Auch das Abfeuern des Torpedos mit Gamepad funktioniert „prinzipiell“.

Das Problem besteht aber darin, daß, solange ich JoystickButton(0, 2) nicht loslasse, der Torpedo nicht losläuft, sondern erst, wenn ich ihn loslasse. Das ist natürlich unerwünscht; es soll vielmehr egal sein, wie lange der JoystickButton gedrückt gehalten wird. Ferner sollte es möglich sein, mehrere Torpedos hintereinander abzufeuern (maximal, wie gesagt, 4), selbst dann, wenn der erste abgefeuert Torpedo noch läuft.

Kann mir jemand helfen, die im letzten Absatz beschriebenen Probleme zu lösen?
Windows 7 x64; geposteter Kode bezieht sich (sofern nicht anders angegeben) immer auf das aktuellste PureBasic 64-Bit

Erst wenn man es seiner Schwiegermutter erklären kann, hat man es verstanden.
As gsündeste is oiwei guad essn und dringa und ned grang wern.
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: Programmierung der Feuertaste auf Gamepad

Beitrag von Mijikai »

Nette Spiel Idee :)

Ich hab leider kein GamePad aber zum anderen Problem etwas Code.

Code: Alles auswählen

EnableExplicit

Structure TORPEDO_STRUCT
  active.i
  x.f
  y.f
EndStructure

Structure WEAPON_STRUCT
  launched.i
  torpedo.TORPEDO_STRUCT[4]
EndStructure

Global u1_weapons.WEAPON_STRUCT
Global torpedo_id.i

Enumeration Sprites
  #UB1: #UB2: #UB3  ;     U-Boote 0–2
  #lT1: #lT2=7: #lT3=11 ; laufende Torpedos unten
  #Fro=15: #Frw ;         Frachtschiffe    ost/-westwärts
  #Zsto: #Zstw  ;         Zerstörer        ost-/westwärts
  #Pbo: #Pbw  ;           Patrouillenboote ost-/westwärts
EndEnumeration

Enumeration Bilder
  #nT1lo: #nT1ro: #nT1lu: #nT1ru  ; nachgeladene Torpedos Spieler 1
  #nT2lo: #nT2ro: #nT2lu: #nT2ru  ;                       Spieler 2
  #nT3lo: #nT3ro: #nT3lu: #nT3ru  ;                       Spieler 3
EndEnumeration

#SprV=""
; Sprite-Verzeichnis

If Not InitSprite() Or Not InitKeyboard() ;Or Not InitJoystick()
  MessageRequester("Abbruch", ~"Sprites, Tastatur oder Joystick konnten\n"+
    "nicht initialisiert werden.",
    #PB_MessageRequester_Ok|#PB_MessageRequester_Error)
  End
EndIf

If OpenScreen(1280,960, 32, "Sea Wolf")
  UsePNGImageDecoder()
  LoadFont(1, "Arial", 24, #PB_Font_Bold)
  
  Define A, K, AaT1, AaT2, AaT3, PUB1=580, PUB2=580, PUB3=580, Sp, Spa=2, T,
  x  ; Abbruch, Anzahl abgefeuerter Torpedos Spieler 1/2/3, Kennzeichner,
; Positionen der U-Boote Spieler 1/2/3, Spieler, Spieleranzahl, Torpedo

  Dim wPlT(Spa, 3): Dim sPlT(Spa, 3)  ; waage-/senkrechte Pos. d. lauf. Torpedos
  Dim Fr(5, Spa): Dim Zst(5, Spa): Dim Pb(5, Spa)

; ------------------------- Sprites für Spieler-U-Boote -----------------------

  CatchSprite(#UB1, ?UB): CopySprite(#UB1, #UB2): CopySprite(#UB1, #UB3)
  StartDrawing(SpriteOutput(#UB2)): FillArea(60,18, 0, $8aff): StopDrawing()
  StartDrawing(SpriteOutput(#UB3)): FillArea(60,18, 0, $9a89ea): StopDrawing()

; ------------------------ Sprites für laufende Torpedos ----------------------

  CatchSprite(#lT1, ?lT, 8) ; 8 = #PB_Sprite_AlphaBlending
  CopySprite(#lT1, #lT2, 8): CopySprite(#lT1, #lT3, 8)
  StartDrawing(SpriteOutput(#lT2)): FillArea(7,14, 0, $8aff): StopDrawing()
  StartDrawing(SpriteOutput(#lT3)): FillArea(7,14, 0, $9a89ea): StopDrawing()

; ------------------- Sprites für die zu bekämpfenden Schiffe -----------------

  LoadSprite(#Frw,  #SprV+"Frachtschiff fw.png")
  LoadSprite(#Fro,  #SprV+"Frachtschiff fo.png")
;   LoadSprite(#Zstw, #SprV+"Zerstörer fw.png")
;   LoadSprite(#Zsto, #SprV+"Zerstörer fo.png")
;   LoadSprite(#Pbw,  #SprV+"Patrouillenboot fw.png")
;   LoadSprite(#Pbo,  #SprV+"Patrouillenboot fo.png")

; --------------------- Bilder für nachzuladende Torpedos ---------------------

  CatchImage(0, ?Tn): CopyImage(0, 1): CopyImage(0, 2): CopyImage(0, 3)
  CopyImage(0, 4)

  StartDrawing(ImageOutput(4)): FillArea(60,9, 0, $8aff): StopDrawing()
  CopyImage(4, 5): CopyImage(4, 6): CopyImage(4, 7)
  CopyImage(0, 8)
  StartDrawing(ImageOutput(8)): FillArea(60,9, 0, $9a89ea): StopDrawing()
  CopyImage(8, 9): CopyImage(8, 10): CopyImage(8, 11)

; -----------------------------------------------------------------------------

  Repeat
    FlipBuffers()
    ClearScreen(0)  ; a schwarzen Bildschirm hab’ ich!
    StartDrawing(ScreenOutput())  ;             R    G    B 
      Box(0,0,   1280,110, $cce300) ; türkis     0, 227, 204 = 13.427.456
      Box(0,110, 1280,260, $ff8f85) ; hellblau 133, 143, 255 = 16.748.427
      Box(0,370, 1280,290, $d50c00) ; blau       0,  12, 213 = 13.962.240

      DrawImage(ImageID(#nT1lo),  80,870): DrawImage(ImageID(#nT1ro),  210,870)
      DrawImage(ImageID(#nT1lu),  80,900): DrawImage(ImageID(#nT1ru),  210,900)
      DrawImage(ImageID(#nT2lo), 515,870): DrawImage(ImageID(#nT2ro),  645,870)
      DrawImage(ImageID(#nT2lu), 515,900): DrawImage(ImageID(#nT2ru),  645,900)
      DrawImage(ImageID(#nT3lo), 950,870): DrawImage(ImageID(#nT3ro), 1080,870)
      DrawImage(ImageID(#nT3lu), 950,900): DrawImage(ImageID(#nT3ru), 1080,900)

      DrawingMode(#PB_2DDrawing_Transparent)
      DrawingFont(FontID(1))
      DrawText(287,15, "höchster bisher erreichter Punktestand:", #Red)
      DrawText(50, 60, "Spieler 1:", #Black)
      DrawText(520,60, "Spieler 2:", #Black)
      DrawText(987,60, "Spieler 3:", #Black)
      DrawText(383,812, "verbleibende Spielzeit:", #White)
    StopDrawing()  

    DisplaySprite(#UB1, PUB1, 670)  ; U-Boot Spieler 1
    DisplaySprite(#UB2, PUB2, 715)  ; U-Boot Spieler 2
    DisplaySprite(#UB3, PUB3, 760)  ; U-Boot Spieler 3
  
    DisplaySprite(#Fro, 250, 132) ; Frachter oben
    DisplaySprite(#Frw, 550, 214) ; Frachter Mitte
    K=CopySprite(#Fro, #PB_Any): DisplaySprite(K, 850, 298) ; Frachter unten
    
    
    ExamineKeyboard()
    
    If KeyboardReleased(#PB_Key_1)
      ;AaT1+1
      ;wPlT(0, 0)=PUB1+54: sPlT(0, 0)=628
      ;DisplayTransparentSprite(#lT1, wPlT(0, 0), sPlT(0, 0))

      If u1_weapons\launched < 4;<- wir habe 4 torpedos / solange weniger laufen sende ein neues
        u1_weapons\torpedo[u1_weapons\launched]\x = PUB1
        u1_weapons\torpedo[u1_weapons\launched]\y = 628
        u1_weapons\torpedo[u1_weapons\launched]\active = #True
        u1_weapons\launched + 1
      EndIf
      
      
    EndIf
    
    If u1_weapons\launched ;<- grafik für alle laufenden torpedos aktualisieren
      For torpedo_id = 0 To u1_weapons\launched - 1
        If u1_weapons\torpedo[torpedo_id]\active
          u1_weapons\torpedo[torpedo_id]\y - 5
          If u1_weapons\torpedo[torpedo_id]\y < 0
            u1_weapons\torpedo[torpedo_id]\active = #False
          EndIf
          DisplayTransparentSprite(#lT1,u1_weapons\torpedo[torpedo_id]\x,u1_weapons\torpedo[torpedo_id]\y)
        EndIf
      Next
    EndIf    
    
    If KeyboardPushed(#PB_Key_2)
      PUB1-18
    EndIf
    If KeyboardPushed(#PB_Key_3)
      PUB1+18
    EndIf
    If KeyboardPushed(#PB_Key_4)
      PUB2-18
    EndIf
    If KeyboardPushed(#PB_Key_5)
      PUB2+18
    EndIf
    
    
;     ExamineJoystick(0): ExamineJoystick(1)
;     If JoystickButton(0, 2)
;       AaT1+1
;       wPlT(0, 0)=PUB1+54: sPlT(0, 0)=628
;       DisplayTransparentSprite(#lT1, wPlT(0, 0), sPlT(0, 0))
;     ElseIf JoystickButton(0, 5)
;       PUB1-18
;     ElseIf JoystickButton(0, 6)
;       PUB1+18
;     ElseIf JoystickButton(1, 5)
;       PUB2-18
;     ElseIf JoystickButton(1, 6)
;       PUB2+18
;     EndIf

    If sPlT(0, 0)<629 And sPlT(0, 0)>110
      sPlT(0, 0)-10
      DisplayTransparentSprite(#lT1, wPlT(0, 0), sPlT(0, 0))
    Else
      sPlT(0, 0)=-1
    EndIf
    

    ExamineKeyboard()
    If KeyboardReleased(#PB_Key_Escape): A=#True: EndIf

  Until A=#True

Else
  MessageRequester("Abbruch", ~"Bildschirm konnte nicht mit den\n"+
    "angegebenen Parametern geöffnet werden.",
    #PB_MessageRequester_Ok|#PB_MessageRequester_Error)
EndIf

End


DataSection
  UB: ; U-Boot (Sprite)
    IncludeBinary #SprV+"U-Boot.png"
  Tn: ; Torpedo nachladen (Bild)
    IncludeBinary #SprV+"Torpedo nachladen.png"
  lT: ; laufender Torpedo
    IncludeBinary #SprV+"Torpedo läuft.png"
EndDataSection
Antworten