Seite 1 von 1

Structurverwaltung(gelöst) und Fehler in Winkelberechnung!

Verfasst: 10.11.2013 11:50
von N_Gnom
edit: ich wollte keinen extra thread aufmachen, daher frage ich weiter unten nach meinen winkelberechnungen.

Also ich würde in einem Spiel gern 5 Bälle erstellen und diese mittels einer Structur verwalten.
Also ich habe eine Structur welche Positionen enthält.
Zu beginn muss ich also 5 Bälle erstellen und diese dann für Flip aktualisieren.

Die Struktur habe ich, jedoch weiß ich nicht wie man genau automatisiert dann eine bestimmte Anzahl(mittels for next Schleife) erstellt, und diese im späteren Verlauf durchlaufen kann, um diese zu zeichnen.
Man muss ebenso einzelne Bälle auch entfernen können, wenn diese abgeschossen werden.

Re: Wie verwalte ich am einfachsten mit Structure?

Verfasst: 10.11.2013 12:11
von man-in-black
moin,

hab grad keine Zeit für ausführliche Erklärungen. Daher nur ein Pseudocode:

Code: Alles auswählen

structure ballEigenschaften
  x.l
  y.l
  ...
endstructure

global newlist baelle.ballEigenschaften()

procedure ballHinzufuegen(x,y,...)
  addElement(baelle())                          ;neue "Zeile"
  baelle()\x = x
  baelle()\y = y
  ...
endprocedure

procedure ballLoeschen([erkennungsmerkmal])
  foreach baelle()
    if [erkennungsmerkmal] [= baelle()\... ]
      deleteElement(baelle())                       ;geht von oben nach unten durch Tabelle (Liste+Struktur) und löscht gewünschte "Zeile"
      break
    endif 
  next
endprocedure

procedure baelleAnzeigen()
  foreach baelle()
    circle(baelle()\x,baelle()\y,...)
  next
endprocedure

Durch die Struktur fügst du der einfachen Liste noch Spalten hinzu.
"Zeilen" = Bälle
"Spalten" = Eigenschaften wie Positionen

----
P.S.: bei fester Ballanzahl kannst auch mit Arrays arbeiten, was dir die Indizierung der Bälle vereinfacht. Dafür muss sich jeder Ball aber merken, dass er "abgeschossen" wurde und nicht mehr gezeichnet werden braucht (Arrayelemente kann man nicht einfach so wie Listenelemente löschen, sondern schleift sie immer mit ;) ):

Code: Alles auswählen

for b=1 to ballAnzahl
  if baelle(b-1)\abgeschossen = #false
    circle(...)
  endif
next
MFG
MIB

Re: Wie verwalte ich am einfachsten mit Structure?

Verfasst: 10.11.2013 15:15
von N_Gnom
Also doch via Listen.
Danke für das Beispiel.

edit:
hab das jetzt mal probiert, aber irgendwo steckt ein fehler drin
es wird nicht die gewünschte anzahl an schüssen erstellt und der winkel stimmt auch nicht.

also...ich habe jetzt mal verschiedene winkel probiert.
0 grad, 90 grad gehen, aber bei 91 grad fliegt die kugel auf 180 grad.270 grad ist bei 0 grad.
sehr merkwürdig.

Code: Alles auswählen

Structure shoots
  winkel.f
  posx.i
  posy.i
  dir.i

EndStructure

Global NewList shootliste.shoots()
For a = 0 To 19
  AddElement(shootliste())
  shootliste()\posx.i = 320
  shootliste()\posy.i = 240
  shootliste()\dir.i = a*18
Next 

  
Repeat
  ClearScreen(000000)
  StartDrawing(ScreenOutput())
  ForEach shootliste()
    Circle(shootliste()\posx.i,shootliste()\posy.i, 10)
    shootliste()\posx.i = shootliste()\posx.i + Sin(shootliste()\dir.i)*1 ;1 = speed
    shootliste()\posy.i = shootliste()\posy.i + Cos(shootliste()\dir.i)*1 ;1 = speed 
 Next 
StopDrawing()
FlipBuffers()  
Release()   ; eigene eventfunktion
ForEver
End

Re: Structurverwaltung(gelöst) und Fehler in Winkelberechnun

Verfasst: 10.11.2013 18:48
von NicTheQuick
Also ich sehe im Code keinen Fehler. Und da ist auch nirgendwo etwas von 0°, 90° oder 180° zu sehen. Und warum schreibst du in 'dir' den Winkel, anstatt das Feld 'winkel' zu benutzen? :?

Da man den Code aber leider nicht testen kann, weil er nicht vollständig ist, kann ich dir auch nicht sagen, was du falsch machst.
Ich sehe nur, dass du da Winkel von 0 bis 342 Radian erstellst in Schritten von 18 Radian, also rund 1031°. Deine Schüsse sollten also in einem Winkel von ca. 48° linksdrehend wegfliegen.

Re: Structurverwaltung(gelöst) und Fehler in Winkelberechnun

Verfasst: 10.11.2013 19:44
von N_Gnom
Ja das mit Winkel hatte ich völlig übersehen.
Hab den code jetzt nochmal geändert, funktioniert auch, aber richtig gleichmässig sieht das nicht aus.
Der code ist jetzt komplett ausführbar.

Code: Alles auswählen

shootliste()\winkel = a*36
soll eigentlich für ein vielfaches von 36 grad sorgen, um bei 10 kugeln die 360 grad zu erreichen.

wenn ich die kugelanzahl auf 20 erhöhe und dafür 18 grad nehme oder 5 kugeln und dafür 72 grad, dann sieht das sehr komisch aus.
Oder verstehe ich da was an den winkelfunktionen falsch?
Sin(winkel) und Cos(Winkel) sollte doch werte zwischen -1 und 1 ausgeben.

Aber wahrscheinlich habe ich da einen Denkfehler in der Umsetzung des Ganzen.


Code: Alles auswählen

; Wir muessen vorher noch etwas initialisieren, da wir ein Vollbild erstellen und dies braucht DirectX.
If InitSprite() = 0                                               ; Wenn wir die Sprite Funktion nicht initialisieren koennen,
  MessageRequester("Fehler","Konnte dx nicht finden",0)           ; wird ein Fehler gemeldet, der die moegliche Ursache ausgibt.
EndIf 

If InitKeyboard()=0                                               ; Wenn wir die Keyboard Funktion nicht initialisieren koennen,
  MessageRequester("Fehler","Konnte dx nicht finden",0)           ; wird ein Fehler gemeldet, der die moegliche Ursache ausgibt.
EndIf                                                             ; Ende der Abfrage



; Jetzt wollen wir den Vollbild Modus erstellen.
 If OpenWindow(0, 0, 0, 1024,768,"Windowed",#PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget) = 0                    ; Wenn "Oeffne ein Vollbild" aus ist,
   MessageRequester("Fehler","Konnte kein Window erstellen ",0)  ; wird eine Fehlermeldung ausgegeben.
 EndIf 
 OpenWindowedScreen(WindowID(0), 0, 0, 1024, 768)
 ;OpenScreen(640,480,32,"screen")
 
Procedure Events()
  Define Event
  ; Repeat
      Event = WindowEvent()
     
      Select Event
        Case #PB_Event_Gadget
          If EventGadget() = 0
            End
          EndIf
       
        Case #PB_Event_CloseWindow
          End
      EndSelect
   ; Until Event = 0
    
 EndProcedure 
 
 Procedure Release()
   ExamineKeyboard() ; Keyboard aktualisieren
   Events() ; Abfangen der WindowEvents
   	 If KeyboardPushed(#PB_Key_Escape)                 ; Wenn die Taste Escape gedrueckt wird,
       End                                             ; wird das Programm beendet.
     EndIf ; Ende der Abfrage
   EndProcedure 
   
Structure shoots
  posx.f
  posy.f
  winkel.i

EndStructure

Global NewList shootliste.shoots()
ClearList(shootliste())
For a = 1 To 10
  AddElement(shootliste())
  shootliste()\posx = 500
  shootliste()\posy = 350
  shootliste()\winkel = a*36
Next 

  
Repeat
  ClearScreen(000000)
  StartDrawing(ScreenOutput())
  ForEach shootliste()
    Circle(shootliste()\posx,shootliste()\posy, 10)
    shootliste()\posx = shootliste()\posx + Cos(shootliste()\winkel)*1 ;1 = speed
    shootliste()\posy = shootliste()\posy + Sin(shootliste()\winkel)*1 ;1 = speed 
 
 Next 
 StopDrawing()

 FlipBuffers()  
 Release()   ; eigene eventfunktion
ForEver

End

Re: Structurverwaltung(gelöst) und Fehler in Winkelberechnun

Verfasst: 10.11.2013 20:13
von NicTheQuick
Was du übersiehst ist, dass Sin() und Cos() Radian erwarten und keine Grad. Siehe Hilfe.

Re: Structurverwaltung(gelöst) und Fehler in Winkelberechnun

Verfasst: 10.11.2013 20:26
von N_Gnom
Ah hab ich tatsächlich übersehen.
Funktioniert.winkel hab ich als winkel.f angegeben und folgendes ergänzt.
Super läuft tadellos.

Code: Alles auswählen

shootliste()\winkel = Radian(18*a)
Vielen Dank