Seite 1 von 1

Sprite in eine bestimmte Richtung fliegen lassen

Verfasst: 16.10.2008 18:49
von Tompazi
Wie kann ich ein Sprite(3d) in eine bestimmte Richtung fliegen lassen.?
Also sozusagen ein Schuss.

Ich habe ein Raumschiff und das soll in die Richtung shießen in das es gerade schaut.

Code: Alles auswählen

    If KeyboardPushed(#PB_Key_Right)
     RotateSprite3D(#SpaceShip_0,SpaceShipAngle+2,1)
    ElseIf KeyboardPushed(#PB_Key_Left)
     RotateSprite3D(#SpaceShip_0,SpaceShipAngle-2,1)
    EndIf
    
    If StartReloading
     Reloading = ElapsedMilliseconds() - (StartReloading + 500)
     If Reloading > 0
      Reloading = 0
     EndIf
     StartReloading = 0
    EndIf

    If KeyboardPushed(#PB_Key_Space) And Not Reloading
     StartReloading = ElapsedMilliseconds()      
      ;Hier Soll geschossen werden
    EndIf
MfG Tompazi

Verfasst: 16.10.2008 18:59
von Kaeru Gaman
für die Verwaltung der Schuss-"Objekte" schau dir mal das beiliegende WaponezII-Beispiel an, da wird eine schussliste verwaltet.
( MyPB\Examples\Sources - Advanced\Waponez II )

deine Rotation kommt mir falsch vor:

Code: Alles auswählen

RotateSprite3D(#SpaceShip_0,SpaceShipAngle+2,1)
erscheint mir nicht sinnvoll.
ich würde sagen:

Code: Alles auswählen

    If KeyboardPushed(#PB_Key_Right)
     SpaceShipAngle = ( SpaceShipAngle+2 ) % 360
    ElseIf KeyboardPushed(#PB_Key_Left)
     SpaceShipAngle = ( SpaceShipAngle-2 ) % 360
    EndIf
    RotateSprite3D(#SpaceShip_0,SpaceShipAngle,1)
denn es gaht ja darum, dass du in SpaceShipAngle die aktuelle Rotation speicherst.

... und mit der kannst du dann auch die schuss-steps errechnen:

Code: Alles auswählen

SchussDX =  SchussSpeed * Sin( SpaceShipAngle * #PI / 180 )
SchussDY = -SchussSpeed * Cos( SpaceShipAngle * #PI / 180 )

Verfasst: 18.10.2008 23:59
von Tompazi
Danke, fliegt jetzt in die richtige Richtung, aber ich kann nur einmal schießen :? und ich will die Bullet in die Richtige Richtung drehen aber

Code: Alles auswählen

 RotateSprite3D(Bullet()\Image,Bullet()\Angle,1)
dreht die Bullet ganz schnell im Kreis..

Code: Alles auswählen

Structure Bullet
  x.w
  y.w
  Width.w
  Height.w
  Image.w
  SpeedX.w
  SpeedY.w
  Angle.w
EndStructure

Global NewList Bullet.Bullet()

Procedure AddBullet(Sprite, x, y, SpeedX, SpeedY,Angle)
  AddElement(Bullet())           
  Bullet()\x      = x
  Bullet()\y      = y
  Bullet()\Width  = SpriteWidth(Sprite)
  Bullet()\Height = SpriteHeight(Sprite)
  Bullet()\Image  = Sprite
  Bullet()\SpeedX = SpeedX
  Bullet()\SpeedY = SpeedY
  Bullet()\Angle = Angle
EndProcedure

SchussSpeed = 5

Code: Alles auswählen

    If KeyboardPushed(#PB_Key_Space) And Not Reloading
      StartReloading = ElapsedMilliseconds()
      SchussDX =  SchussSpeed * Sin( SpaceShipAngle * #PI / 180 )
      SchussDY = -SchussSpeed * Cos( SpaceShipAngle * #PI / 180 )
      addBullet(#Bullet_0,DeskW/2,DeskH/2,SchussDX, SchussDY,SpaceShipAngle)
    EndIf
    
     ResetList(Bullet())
  While NextElement(Bullet())  ; Process all the bullet actualy displayed on the screen

    If Bullet()\y < 0          ; If a bullet is now out of the screen, simply delete it..
      DeleteElement(Bullet())
    Else
      If Bullet()\x < 0        ; If a bullet is now out of the screen, simply delete it..
        DeleteElement(Bullet())
      Else
        If Bullet()\x > DeskW-Bullet()\Width
          DeleteElement(Bullet())
        Else
          If Bullet()\y > DeskH
            DeleteElement(Bullet())
          Else
            DisplaySprite3D(Bullet()\Image, Bullet()\x, Bullet()\y)   ; Display the bullet..
            RotateSprite3D(Bullet()\Image,Bullet()\Angle,1)
            Bullet()\y + Bullet()\SpeedY
            Bullet()\x + Bullet()\SpeedX
          EndIf
        EndIf
      EndIf
    EndIf
    
  Wend
MfG Tompazi

Verfasst: 19.10.2008 00:04
von Kevin
mach statt der 1 eine 0 bei rotatesprite3d
wenn du wissen wilst wieso makiere im pb editor "rotatesprite3d" und drücke dann F1

Verfasst: 19.10.2008 03:17
von Kaeru Gaman
Tompazi hat geschrieben:aber ich kann nur einmal schießen
Kaeru Gaman hat geschrieben:für die Verwaltung der Schuss-"Objekte" schau dir mal das beiliegende WaponezII-Beispiel an, da wird eine schussliste verwaltet.
( MyPB\Examples\Sources - Advanced\Waponez II )
... die vollständigen Ratschläge befolgen ist manches Mal hilfreich ...

Verfasst: 22.10.2008 18:51
von Tompazi
@Kaeru Gaman
Das habe ich ja getan und ich erkenne keinen wirklichen Unterschied zwischen meinem Code und dem von WaponezII

das drehen funktioniert jetzt aber der Laserstrahl wurde vom drehen irgendwie ganz dick :?

MfG Tompazi

Verfasst: 22.10.2008 19:04
von Kaeru Gaman
hm...

also, es wäre nicht unhilfreich, wenn du nen code posten würdest, den man mal copy-paste-testen kann.
(also sprites on-the-fly erzeugen)

so beim draufgucken ist das immer so ein problem, alles zu erkennen...

also, dein rotieren musst du absolut machen, und vor dem darstellen.
das ist schon mal einer der punkte.

und nur einmal schießen, das liegt möglicherweise daran, dass du da ein "Not Reloading" drin hast.
aber das kann man hier nicht sehen, weil du den Teil wo du dich um dein Reloading-Flag kümmerst garnicht drinstehen hast.

Verfasst: 22.10.2008 19:15
von Tompazi
Danke du hast mich auf die richtige Fährte gebracht, beim Reloading war ein logischer Fehler ...

auch wenn ich das Sprite vor dem anzeigen drehe ist es etwa 5x mal so dick wie es sein sollte. (wenn ichs nicht drehe ist es normal "dünn")

MfG Tompazi

Edit: ach ja und wenn ich ein sprite von a nach richtung b fliegen lassen will wie geht das? ich habe das hier gefunden:
Josef Sniatecki hat geschrieben:Um den Winkel zur Maus zu bekommen, kann man folgende Prozedur nutzen:

Code: Alles auswählen

Procedure.f WinkelZu(StartX.f,StartY.f,EndX.f,EndY.f)
  ;EndX Und EndY ist der Vektor zu den der Winkel von
  ;StartX und StartY zeigen soll.
  
  Protected Angle.f ;Der gesuchte Winkel.
  Protected XDistance.f ;Der Abstand zwischen StartX und EndX.
  Protected YDistance.f ;Das Gleicher für StartY und EndY.
  Protected Distance.f ;Hypotenuse von X- und YDistance.
  
  XDistance=EndX-StartX
  YDistance=EndY-StartY
  Distance=Sqr(XDistance*XDistance+YDistance*YDistance)
  
  ;Nun kommt das wichtigste:
  Angle=ACos(XDistance/Distance)*57.295776
  
  If StartY<EndY : Angle=360-Angle : EndIf
  ProcedureReturn Angle
EndProcedure
Nun kann man den Schuss durch Cosinus und Sinus des angegebenen
Winkels (Natürlich im Bogenmaß) bewegen.
aber ein

Code: Alles auswählen

x + Cos(Angle) : y + Sin(Angle)
reicht nicht.