Probleme mit Types?

Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Neue Antwort erstellen

 

bruce85

Betreff: Probleme mit Types?

BeitragMo, Apr 20, 2009 12:47
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo nochmal,
ich habe mir überlegt ein anderes Kartenspiel zu schreiben, nur komme ich nicht so klar mit Types, da ich folgendes machen möchte:
Ich erstelle mit Types 4 Spieler und alle diese Spieler sollen 3 Felder haben, um die Karte dort abzulegen und nochmal 3 Felder sollen mit die 3 Felder verknüpft werden, um bei jedem Feld von der Karte ein Punk zuzuweisen.
z.B. so:
Code: [AUSKLAPPEN]
P.Card[1].Punk = 10

nur weiss ich nicht, wie ich das anstellen soll.

Ich habe so erstmal die Types für den Spieler erstellt:
Code: [AUSKLAPPEN]
Global PlayerList:TList = New TList
Type TPlayer
  Field Card:Int[3]
  Field PlayerNr:Int

  Method New()
    PlayerList.AddLast(Self)
  End Method
End Type

For Local i:Int=1 To 4
  Local P:TPlayer = New TPlayer
  P.PlayerNr = i
  P.Card[0] = Rnd(0,31)
  P.Card[1] = Rnd(0,31)
  P.Card[2] = Rnd(0,31)
  'P.Card[0].Punkt = 10
  'P.Card[1].Punkt = 10
  'P.Card[2].Punkt = 10
Next


Wie könnte ich das am besten machen?

Vielen Dank schonmal.

MfG
AMD Athlon(tm) II X2 250, 8 GB DDR, MSI MSI 770-C45, GeForce GTS 250

DAK

BeitragMo, Apr 20, 2009 12:54
Antworten mit Zitat
Benutzer-Profile anzeigen
dafür bräuchtest du wohl oder übel sowas:

BlitzMax: [AUSKLAPPEN]

Type TCard
Field Wert:Int
Field Punkt:Int
EndType


und beim Type TPlayer dann das rein:

BlitzMax: [AUSKLAPPEN]

Field Card:TCard[3]
Gewinner der 6. und der 68. BlitzCodeCompo
 

bruce85

BeitragMo, Apr 20, 2009 13:07
Antworten mit Zitat
Benutzer-Profile anzeigen
Genau das habe ich gebraucht, vielen Dank.

Edit: Wenn ich jetzt versuche einen Wert zuzuweisen:
Code: [AUSKLAPPEN]
P.Card[0].Punkt = 10


dann bekomme ich im Spiel folgende Fehlermeldung:
Code: [AUSKLAPPEN]
Unhandled Exception:Attempt to access field or method of Null object


habe ich vieleicht etwas vergessen?
Code: [AUSKLAPPEN]
Type TCard
  Field Wert:Int
  Field Punkt:Int
EndType

Global PlayerList:TList = New TList
Type TPlayer
  Field Card:TCard[3]
  Field PlayerNr:Int

  Method New()
    PlayerList.AddLast(Self)
  End Method
End Type

For Local i:Int=1 To 4
  Local P:TPlayer = New TPlayer
  P.PlayerNr = i
  P.Card[0].Punkt = 10
  P.Card[1].Punkt = 10
  P.Card[2].Punkt = 10
Next


Danke schonmal.

MfG
AMD Athlon(tm) II X2 250, 8 GB DDR, MSI MSI 770-C45, GeForce GTS 250

amon

BeitragMo, Apr 20, 2009 15:40
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja, dadurch das es nun ein benutzerdefinierter Type ist, musst Du nun das Array mit den Type "vorbelegen". Am einfachsten packst Du das noch in den Constructor (new) mit rein:

Code: [AUSKLAPPEN]
  Method New()
    For Local i:Int = 0 To 3-1
      Self.Card[i] = New TCard
    Next
    PlayerList.AddLast(Self)
  End Method
 

bruce85

BeitragMo, Apr 20, 2009 16:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Jetzt funktioniert es, vorher habe ich ja außerhalb des gültigen bereichs zugegriffen.

Vielen Dank für die Hilfe.

MfG
AMD Athlon(tm) II X2 250, 8 GB DDR, MSI MSI 770-C45, GeForce GTS 250
 

bruce85

BeitragMi, Apr 29, 2009 6:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo nochmal,
ich habe noch ein kleines Problem mit Types und möchte jetzt nicht extra einen neuen Thread eröffnen.

Es geht um folgendes:
In meinem Spiel kann man neue User anlegen, jedesmal wenn ich einen User anlegen möchte, vergrössere ich das Array um 1.
Wenn ich jetzt versuche mehr als einen User anzulegen, dann greife ich außerhalb des gültigen bereich zu.

Hier zeichne ich erstmal die Spieler vom Typ TSpieler:
Code: [AUSKLAPPEN]
For Local i:Int=0 To Len(Spieler)-1
  SetColor 50,50,50
  DrawText Spieler[i].Name,320,230+i*20
  DrawText Spieler[i].Punkte,GraphicsWidth()/2-TextWidth(Spieler[i].Punkte)/2+51,230+i*20
Next


und hier wird das Array immer um 1 vergrössert, wenn man neue User anlegen möchte:
Code: [AUSKLAPPEN]
AnzSpieler = AnzSpieler + 1
Spieler = New TSpieler[AnzSpieler]
Spieler[AnzSpieler-1] = New TSpieler.NewName(SpielerName)


Das Array wird immer um 1 vergrössert, ich habe es testhalber mal ausgeben lassen mit Len(Spieler), nur beim Zeichnen der Userliste bekomme ich dann einen Array-Zugriffsfehler.

Wo könnte der fehler denn liegen?

Danke euch schonmal.

MfG
AMD Athlon(tm) II X2 250, 8 GB DDR, MSI MSI 770-C45, GeForce GTS 250

Suco-X

BeitragMi, Apr 29, 2009 10:47
Antworten mit Zitat
Benutzer-Profile anzeigen
Code: [AUSKLAPPEN]

AnzSpieler = AnzSpieler + 1 ' schön
Spieler = New TSpieler[AnzSpieler] ' Du erstellst das array neu, also sind alle Spieler wieder auf Null
Spieler[AnzSpieler-1] = New TSpieler.NewName(SpielerName) ' Außer der eine Hier


versuch doch mal

Code: [AUSKLAPPEN]

AnzSpieler = AnzSpieler + 1
Spieler = spieler[..AnzSpieler]
Spieler[AnzSpieler-1] = New TSpieler.NewName(SpielerName)


Mfg Suco
Intel Core 2 Quad Q8300, 4× 2500 MHz, 4096 MB DDR2-Ram, GeForce 9600GT 512 MB
 

bruce85

BeitragMi, Apr 29, 2009 14:41
Antworten mit Zitat
Benutzer-Profile anzeigen
Cool, vielen Dank.
Jetzt funktioniert es perfekt und kann endlich Weitermachen. Wink

Edit: Komischerweise funktioniert das Speichern der Liste nicht mehr:
Code: [AUSKLAPPEN]
Function SpielerSave()
   Local Datei:TStream = WriteFile("data/save.dat")

   For Local i:Int=0 To Len(Spieler)-1
      WriteLine(Datei,Spieler[i].Name)
      WriteLine(Datei,String(Spieler[i].Punkte))
   Next
   CloseFile(Datei)
End Function


Das wird jetzt so gespeichert:
Code: [AUSKLAPPEN]
                                                                                                                                                 b          r            u             c              e                       8           5                                                                     

10


Ich danke Dir schonmal.

MfG

Suco-X

Betreff: ......

BeitragMi, Apr 29, 2009 15:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Mal abgesehen davon dass du nicht einfach WriteLine für alle Datentypen verwenden solltest, sieht dieser Teil des Codes soweit richtig aus. Der Fehler liegt wo anders.
Mfg Suco
Intel Core 2 Quad Q8300, 4× 2500 MHz, 4096 MB DDR2-Ram, GeForce 9600GT 512 MB
 

bruce85

BeitragMi, Apr 29, 2009 16:01
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke Dir.

Der fehler muss beim Speichern der Liste sein, wenn ich jetzt per Hand die Einträge in der save.dat eingebe, dann Funktioniert das laden und anzeigen der einträge korrekt.

Edit: Das ist nur der String, also der Spielername, der wird komisch in der save.dat eingetragen mit vielen Leerzeichen.
Ich versuche mal die ganzen Leerzeichen auszuschneiden.

MfG
AMD Athlon(tm) II X2 250, 8 GB DDR, MSI MSI 770-C45, GeForce GTS 250
  • Zuletzt bearbeitet von bruce85 am Mi, Apr 29, 2009 16:03, insgesamt einmal bearbeitet

d-bug

BeitragMi, Apr 29, 2009 16:03
Antworten mit Zitat
Benutzer-Profile anzeigen
Irre ich mich, oder werden die Spieler in einem Array gespeichert? Dann kannst du mit Len () nicht viel anfangen.

BlitzMax: [AUSKLAPPEN]
Local Stream:TStream = WriteFile ("MeinFile.dat")
For Local SpielerInstanz:TSpieler = EachIn Spieler
Stream.WriteLine (SpielerInstanz.Name)
Stream.WriteLine (SpielerInstanz.Punkte)
Next
Stream.Close ()


Oder für die prozeduralen unter uns:
BlitzMax: [AUSKLAPPEN]
Local Stream:TStream = WriteFile ("MeinFile.dat")
For Local SpielerInstanz:TSpieler = EachIn Spieler
WriteLine (Stream, SpielerInstanz.Name)
WriteLine (Stream, SpielerInstanz.Punkte)
Next
CloseFile (Stream)

Suco-X

Betreff: .....

BeitragMi, Apr 29, 2009 16:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Doch doch, Bug, Len kannst du für Strings und Array Einträge verwenden.
Vielleicht gibst du mal etwas mehr Code raus, Bruce, dann könnte man dir besser helfen.
Mfg Suco
Intel Core 2 Quad Q8300, 4× 2500 MHz, 4096 MB DDR2-Ram, GeForce 9600GT 512 MB

d-bug

BeitragMi, Apr 29, 2009 16:07
Antworten mit Zitat
Benutzer-Profile anzeigen
Oh, da ich es nie nutze wusste ich das nicht. :/
Wieder was gelernt.
 

bruce85

BeitragMi, Apr 29, 2009 16:07
Antworten mit Zitat
Benutzer-Profile anzeigen
Das ist schon so richtig, hier mal der Type:
Code: [AUSKLAPPEN]
'Type für Spieler
Type TSpieler
   Field Name:String
   Field Punkte:Int
   
   Function NewName:TSpieler(fName:String)
      Local S:TSpieler = New TSpieler
      S.Name = fName
      Return S
   End Function
End Type
Global AnzSpieler:Int=0
Global Spieler:TSpieler[] 'Variable Spieler vom Type TSpieler erzeugen


Dazu brauche ich keine Liste erzeugen, ich kann somit ganz einfach mit der FOR NEXT Schleife alle Spieler abfragen und bearbeiten.

Trotzdem, vielen Dank.

Edit: Wenn ich einen neuen User anlege, dann wird es gleich korrekt in der Liste angezeigt, wenn ich diese Liste dann speicher und das Spiel beende und das Spiel wieder starte, dann werden die Einträge nicht korrekt angezeigt, da die Einträge komischerweise so in der save.dat gespeichert werden:
Code: [AUSKLAPPEN]
                                                                                                                     b           r            u                  c              e                   8          5                                                                                 
0
                                                                                                                                                           U               s             e           r                              2                                                                                 
0


Das sagt ja wohl alles, also muss es an der Speicher Funktion liegen.

MfG
AMD Athlon(tm) II X2 250, 8 GB DDR, MSI MSI 770-C45, GeForce GTS 250

Suco-X

Betreff: ......

BeitragMi, Apr 29, 2009 16:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Tjoa, habs mal testweise nachgemacht. Klappt hier so wie es sollte und anders speicherst du ja auch nicht (Laut deinem Codefetzen von oben)

Code: [AUSKLAPPEN]

Strict

Type TSpieler
   Field name:String
   Field punkte:Int
   
   Function Create:TSpieler(name:String, punkte:Int)
      Local tmp:TSpieler
      tmp        = New TSpieler
      tmp.name   = name
      tmp.punkte = punkte
      Return tmp
   End Function
   
   Method SaveToStream(stream:TStream)
      If Not stream Throw "Stream existiert nicht"
      
      WriteLine stream, name
      WriteLine stream, punkte

   End Method
   
   Method Print()
      brl.standardio.Print("Name: "+name)
      brl.standardio.Print("Punkte: "+punkte)
      brl.standardio.Print("***************")
   End Method
   
End Type



Local names:String[]
Local spieler:TSpieler[]
Local streamOut:TStream


names   = ["Hans", "Max", "Susanne", "Fritz", "Honk"]
spieler = New TSpieler[10]

SeedRnd(MilliSecs())

For Local i:Int = 0 Until spieler.length
   spieler[i] = TSpieler.Create(names[Rand(0,names.length-1)], Rand(10,4000))
Next

streamOut = WriteFile("save.dat")

For Local i:Int = 0 Until spieler.length
   spieler[i].Print()
   spieler[i].SaveToStream(streamOut)
Next

CloseStream(streamOut)


Mfg Suco
Intel Core 2 Quad Q8300, 4× 2500 MHz, 4096 MB DDR2-Ram, GeForce 9600GT 512 MB
 

bruce85

BeitragMi, Apr 29, 2009 16:41
Antworten mit Zitat
Benutzer-Profile anzeigen
Vielen Dank für deine Mühe.

Endlich habe ich den fehler gefunden:
Code: [AUSKLAPPEN]
Local B:Int = GetChar()
SpielerName = SpielerName + Chr(B)
DrawText SpielerName,GraphicsWidth()/2-ImageWidth(message_png)/2+10,400+55


Wenn ich das z.B. auskommentiere und SpielerName direkt einen Wert zuweise, dann funktioniert das.

Ich versuche das mal zu beheben und vielen Dank, das ihr euch die Mühe gegeben habt mir zu helfen.

Edit: Jetzt funktioniert das.
Ich muss prüfen, ob B > 0 ist, weil ansonsten fügt er weitere Zeichen mit Chr(0) ein, wie ich es bemerkt habe.

MfG
AMD Athlon(tm) II X2 250, 8 GB DDR, MSI MSI 770-C45, GeForce GTS 250

Suco-X

Betreff: .....

BeitragMi, Apr 29, 2009 18:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Jetzt musst du dir nurnoch die Frage stellen ob es nicht sinnvoller wäre solche Daten binär zu speichern. Da ich davon ausgehe, dass es hier um einen Highscore geht, wäre das der beste Weg, die Daten vor der Manipulation des Spielers zu schützen.
Mfg Suco
Intel Core 2 Quad Q8300, 4× 2500 MHz, 4096 MB DDR2-Ram, GeForce 9600GT 512 MB
 

bruce85

BeitragMi, Apr 29, 2009 21:42
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja, es soll eine Highscoreliste werden.

Ich könnte ja die Punkte mit Bin in Binär String umwandeln und dann speichern, oder gibt es einen besseren Weg?

Noch eine Frage:
Wie kann ich einen 2 Dimensionales Array immer um 1 vergrößern?
So geht das nicht:
Code: [AUSKLAPPEN]
Spieler = Spieler[..AnzSpieler,..MaxSeite]


Danke schonmal.

Edit: Wenn ich mich nicht irre, nennt man das mit dem ein Dimensionales Array "Slicen" und funktioniert nicht mit 2 Dimensionales Array:
Code: [AUSKLAPPEN]
Spieler = Spieler[..AnzSpieler,..MaxSeite]


Ich lass mir was anderes einfallen.

Trotzdem, Danke.

MfG
AMD Athlon(tm) II X2 250, 8 GB DDR, MSI MSI 770-C45, GeForce GTS 250

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group