arbeitsweisen / code optimierung

Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Neue Antwort erstellen

 

Thoniel

Betreff: arbeitsweisen / code optimierung

BeitragSa, Apr 07, 2007 21:57
Antworten mit Zitat
Benutzer-Profile anzeigen
hi
kann sein das der titel missverstanden wird Wink
ich fang grad erst richtig an mit bmax und möchte von anfang an möglichst "optimal" die möglichkeiten nutzen. das heisst ich will types/methods/listen etc in einer vernünftigen art und weise nutzen so das es effizient ist.

daher dachte ich, ich poste hier mal den code den ich grade geschrieben hab.
is nichts besonders. mit der linken taste kann man halt blöcke erstellen welche man wieder mit rechts löschen kann.
aber es geht nicht darum was man damit kann, sondern nur darum meine arbeitsweise zu optimieren Wink

ich würd halt gern tipps haben wie: diese methode solltest du lieber da hin schreiben, mit der verknüpfen... das ist als funktion besser.. etc etc.

würde mich total freuen Wink

mfg
thoniel


Code: [AUSKLAPPEN]
' Konstanten

' Medien Laden

' Initialisieren
Global Einheitenliste:TList = CreateList()

Graphics 640,480

' Schleife
Repeat
   Cls
   
   For Einheit:Tpanzer = EachIn Einheitenliste
      Einheit.StatusUpdate()
      Einheit.Entfernen()
      Einheit.Malen()
   Next
   
   If MouseHit(1)
      x:Tpanzer = Tpanzer.Erstellen(MouseX(),MouseY())
   End If
   
   Flip
Until(KeyDown(KEY_ESCAPE)) Or AppTerminate()
End

' Types
Type Tpanzer
   Field x:Int
   Field y:Int
   Field HP:Int = 100
   Field status:Int = 1 '1-unmarkiert 0-markiert
   
   Function Erstellen:Tpanzer(xstart:Int, ystart:Int)
      Tank:Tpanzer = New Tpanzer
      Tank.x = xstart
      Tank.y = ystart
      ListAddLast Einheitenliste, Tank
   End Function
   
   Method StatusUpdate()
      If HP<=0 'wenn hp 0 dann einheit loeschen
         Tod()
      EndIf
      
      If MouseOver(x, y, 20, 20) 'ist die einheit markiert (2) oder nicht (1)
         status = 2
      Else
         status = 1
      End If      
   End Method
   
   Method Malen() 'einheit jeh nach status malen
      If status = 1
         SetColor(255,255,255)
      ElseIf status = 2
         SetColor(255,100,100)
      End If
      DrawRect(x, y, 20, 20)
   End Method
   
   Method Entfernen() 'bei rechtsklick und markierung wird die einheit geloescht
      If status = 2 And MouseDown(2)
         Tod()
      End If
   End Method   
   
   Method Tod()
      ListRemove(Einheitenliste, Self)
   End Method
   
End Type

Function MouseOver(x,y,width,height)
   If MouseX() < x+width And MouseX() > x And MouseY() < y+height And MouseY() > y
      Return 1
   Else
      Return 0
   End If
End Function

Blitzcoder

Newsposter

BeitragSa, Apr 07, 2007 22:04
Antworten mit Zitat
Benutzer-Profile anzeigen
Sieht doch recht brauchbar aus für den Anfang. Ein kleiner Tipp, man kann Globals in Types erstellen:

Code: [AUSKLAPPEN]

type TDings
global var1,var2
global var3

field x,y

end type




Wenn Der Type nur eine Liste benötigt, wie in deinem Fall, schreibe ich die Liste jeweils als Global in den Type. Sodass man dann TDings.list hat. Das schafft Übersicht.

MfG Blitzcoder
P4 3 Ghz@3,55Ghz|GF 6600GT 256MB|Samsung 80GB | 2x Samsung 160GB|2048MB DDR-400 RAM|6 Mbit Flatrate | Logitech G15 | Samsung 225BW-TFT | Ubuntu Gutsy Linux | Windows Vista | Desktop | Blog | CollIDE | Worklog
________________
|°°°°°°°°°°°°°°||'""|""\__,_
|______________ ||__ |__|__ |)
|(@) |(@)"""**|(@)(@)****|(@)
  • Zuletzt bearbeitet von Blitzcoder am Mi, Apr 11, 2007 12:34, insgesamt einmal bearbeitet
 

maw

Betreff: Memory Leak nach ListRemove?

BeitragDi, Apr 10, 2007 14:36
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo, ich habe ebenfalls gerade angefangen und zum Einstieg ein kleines Spiel gemacht, einen Vertikal-Shooter.

Wenn Schüsse aus dem Bild fliegen, werden sie per ListRemove aus der Liste meiner Objekte gelöscht. Sollte der gesamte von ihnen belegte Speicher danach nicht vom GC wieder frei gegeben werden? Er gibt aber nur einen Teil frei, so dass der Speicher irgendwann ziemlich voll und das Spiel ziemlich langsam ist...

Dankeschön schonmal,

Marc.

Justus

BeitragDi, Apr 10, 2007 15:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Na endlich mal zwei Leute, die sich offensichtlich Mühe beim Erlernen von BlitzMax geben...

Das mit dem GC ist so eine Sache, eigentlich hast du natürlich Recht. Nachdem du das Objekt aus der Liste löschst, setze es mal "= Null", dann sollte es eigentlich funktionieren.

Thoniel: Das sieht eigentlich schon recht gut aus. Blitzcoders Tipp ist allerdings noch ein Punkt, den du beherzigen solltest. Außerdem empfehle ich dir, mit SuperStrict zu arbeiten.
Setze einfach ganz an den Anfang deines Codes SuperStrict. Dadurch wirst du gezwungen, alle Variablen als lokal oder global zu deklarieren und gleichzeitig ihren Typ festzulegen. Das heißt bevor du eine bspw. eine String-Variable nutzen kannst, musst du sie z.B. mit
Code: [AUSKLAPPEN]
Local mystring:String
deklarieren.
Ich persönlich finde es extrem cool, wenn man in Methoden die Felder mit self. klar diesem Objekt zuordnet. Bei deinem Code würde ich zum Beispiel in den TPanzer-Methoder self.status anstatt nur status schreiben, aber das ist sicherlich Geschmackssache. Es erlaubt halt, dass man gleichnamige Variablen benutzen kann...

Edit: Jo, hast Recht, JP, habe mich im Wort geirrt.
  • Zuletzt bearbeitet von Justus am Mi, Apr 11, 2007 11:42, insgesamt einmal bearbeitet

Lunatix

BeitragDi, Apr 10, 2007 16:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Justus ... hast gerade einen Denkfehler, oder ich ?

Code: [AUSKLAPPEN]

Local d:TDing = new TDing
DingsList.addlast d

d=Null
DingsList.remove d    '<- Liste -> Löschen -> Null ...


oO
[size=9]Pro|gram|mier|er: Ein Organismus, der Koffein in Software umwandelt.
Geben Sie eine beliebige 11-stellige Primzahl ein, um fortzusetzen...

Farbfinsternis

BeitragDi, Apr 10, 2007 16:34
Antworten mit Zitat
Benutzer-Profile anzeigen
Hier noch ein schmaler Tipp wie Du das erzeugen einer TList ausserhalb der Klasse vermeiden kannst:
Code: [AUSKLAPPEN]

Type TFoo
  Global _list:TList
  Field bar:String

  Function Add:TFoo(bar:String)
    Local foo:TFoo = New TFoo
    If foo._list = Null Then foo._list = New TList
    foo._list.AddLast(foo)
    foo.bar = bar

    Return foo
  End Function

  ' Referenz sicher entfernen
  Method Free()
    Self._list.Remove(Self)
    GCCollect()
  End Method
End Type

Global myFoo:TFoo = TFoo.Add("Hallo Welt")

myFoo.Free()

End
Farbfinsternis.tv

Lunatix

BeitragDi, Apr 10, 2007 18:07
Antworten mit Zitat
Benutzer-Profile anzeigen
Mann könnte aber auch einfach....
Code: [AUSKLAPPEN]

Type TFoo
  Global _list:TList = new TList
  Field bar:String

  Function Add:TFoo(bar:String)
    Local foo:TFoo = New TFoo
    _list.Addlast foo
    foo.bar = bar
    Return foo
  End Function

  ' Referenz sicher entfernen
  Method Free()
    Self._list.Remove(Self)
    GCCollect()
  End Method
End Type

Global myFoo:TFoo = TFoo.Add("Hallo Welt")

myFoo.Free()

End


...machen, was dann nähmlich auch funktionieren würde. Denn "foo._list" gibts nicht, ist schliesslich nen Global und kein Field...

Mit nem Feld kann man auch...
Code: [AUSKLAPPEN]

  Method New()
    self._list = new TList
  End Method


machen.
[size=9]Pro|gram|mier|er: Ein Organismus, der Koffein in Software umwandelt.
Geben Sie eine beliebige 11-stellige Primzahl ein, um fortzusetzen...
 

maw

Betreff: Fehler gefunden, Problem bleibt bestehen...

BeitragMi, Apr 11, 2007 11:37
Antworten mit Zitat
Benutzer-Profile anzeigen
Vielen Dank, ich hab das Leak gefunden... es waren die Channels für mein Schussgeräusch (der einzige Soundeffekt bisher), die nach und nach den Speicher gefüllt haben.

Vorher hab ich auch noch mal in der Hilfe nachgesehen... dort steht, dass link.remove effizienter als listremove sein soll - hab aber keinen Unterschied fest stellen können... Gibt es wirklich einen? Ich nehme mal an, dass ersteres direkt den link, den man ja als field hat, löscht, und das listremove erstmal die ganze Liste durchgehen und vergleichen muss... Stimmt das?

Ach ja, zum "Nullen": in der Hilfe steht, dass das fast nie nicht nötig sei, und die Leute es nur aus Vorsicht täten... Stimmt das wiederum?


Das aber nur am Rande, denn leider bleibt mein Problem bestehen: nach und nach wird das Spiel unglaublich langsam. Und das muss wohl an den Schüssen liegen, obwohl die wie gesagt gelöscht werden, wenn sie außerhalb des Sichtfeldes liegen.

Ich weiß allerdings nicht, wie hilfreich es wäre, hier meinen Code zu posten, denn der ist mittlerweile etwas länger...


Vielleicht weiß ja noch einer einen Rat.

Marc.

Suco-X

Betreff: .......

BeitragMi, Apr 11, 2007 11:46
Antworten mit Zitat
Benutzer-Profile anzeigen
Mit dem Link hast du recht. Es ist auch schneller, vielleicht hast du einfach nur zu wenige Objekte da um einen Unterschied zu merken.
Nullen musst du deine Sachen auch nicht. Ich kann dir versichern, dass der GC alles unnötige aus dem Speicher schmeißt wenn es nötig wird. Wenn dein Spiel immer langsamer wird, gibt es da wohl eine Kleinigkeit die du übersehen hast. Wenn du das Problem nicht isolieren kannst, bleibt dir nichts anderes übrig als den Code zu veröffentlichen.
Mfg Suco
Intel Core 2 Quad Q8300, 4× 2500 MHz, 4096 MB DDR2-Ram, GeForce 9600GT 512 MB
 

Thoniel

BeitragMi, Apr 11, 2007 21:06
Antworten mit Zitat
Benutzer-Profile anzeigen
Junkprogger hat Folgendes geschrieben:
Mann könnte aber auch einfach....
Code: [AUSKLAPPEN]

----


machen.


hi
wäre super wenn du dazu noch n bisschen was erläutern könntest. is mir nich ganz so klar wo der vorteil liegt und vorallem, was genau du da veranstaltest xD

Lunatix

BeitragMi, Apr 11, 2007 21:31
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich erstelle ein neues Handle der Klasse TFoo... naja und in der Klasse ist eine Global variable _list:Tlist = new TList

diese variable ist Global, aber nur in der Klasse gültig.

Was mir grad noch einfällt, anstatt
Code: [AUSKLAPPEN]
For Local cl:TClient = eachin ClientList
  Print cl.Name
  _list.remove cl
Next


kann man auch :
Code: [AUSKLAPPEN]
Local Link:TLink
Link = _list.firstlink()
While True
 Link = Link.NextLink()
 If Link = Null Exit
 Print TClient(Link._value).Name
 Link.remove()
Wend


Obs schneller ist, weissich jetzt nicht, allerdings kann man mit LastLink() und PrevLink() dann ganz einfach auch Rückwärts durch die Liste gehen
[size=9]Pro|gram|mier|er: Ein Organismus, der Koffein in Software umwandelt.
Geben Sie eine beliebige 11-stellige Primzahl ein, um fortzusetzen...
 

maw

BeitragFr, Apr 13, 2007 9:15
Antworten mit Zitat
Benutzer-Profile anzeigen
So, ich werde heute oder morgen versuchen, die Problemstelle zu isolieren. Das mache ich wohl am besten, indem ich Schritt für Schritt Elemente des Codes entferne, bis nur noch das allernötigste da ist, oder? Habt Ihr Tipps, wo ich anfangen sollte etc.?

Falls das nicht klappt, bleibt mir wohl nur noch Rapidshare...

Bis dann,

Marc.
 

maw

Betreff: Fehler gefunden...

BeitragFr, Apr 13, 2007 15:58
Antworten mit Zitat
Benutzer-Profile anzeigen
...ich habe das Problem gefunden und eliminiert. Dieser Fehler ist mir allerdings ziemlich peinlich. Sagen wir es so... es ist nicht praktikabel, als Ziel einer 60 Mal in der Sekunde durchlaufenen for-Schleife eine Variable zu wählen, deren Wert im Laufe der Zeit auf ein paar Millionen anwächst.

Tja, so macht man seine Erfahrungen.

Marc.

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group