Array in datei speichern und einzelne felder bearbeiten

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

 

Inso

Betreff: Array in datei speichern und einzelne felder bearbeiten

BeitragDi, Nov 29, 2011 16:15
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo!
Also folgende ausgangssituation:
Ich hab ein Array:

map(mapbreite,maphöhe,attribut)
momentan hat jedes tile das attribut "1"
speichern und laden funktioniert super, allerdings würde ich gern die datei, in der die map gespeichert ist, während der runtime insofern bearbeiten, dass wenn ich in meinem array ein attribut änder, also z.b.
map(324,123,1) = 2
das ganze dann auch direkt in die datei gespeichert wird, und das wenns geht nicht zu rechenlastig.
also was gibt es dafür möglichkeiten?
hab überlegt das ganze mit seekfile zu machen, aber weiß irgendwie nicht so richtig wie ich das dann rechnen muss, um an die richtige(ausgewählte) stelle in der datei zu kommen.
kann mir jemand helfen?

ozzi789

BeitragDi, Nov 29, 2011 16:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo Inso

Das File 60 mal pro Sekunde zu updaten halte ich für nicht so sinnvoll.
Ich an deiner Stelle würde das, sagen wir mal alle 5 Sekunden machen.

Wenn du mir einen Code auszug gibst, oder erklärst wie das File aufgebaut ist, kann ich dir auch weiterhelfen Wink

Grüsse
0x2B || ! 0x2B
C# | C++13 | Java 7 | PHP 5
 

Inso

BeitragDi, Nov 29, 2011 17:11
Antworten mit Zitat
Benutzer-Profile anzeigen
Hey, danke für die Antwort!
Also es geht nicht darum, das File ständig zu updaten, sondern nur dann wenn ein Attribut geändert wird, und das passiert nur per Usereingabe.

Gespeichert hab ich das so:

mapsizex und y sind die Tiles der Map

Code: [AUSKLAPPEN]
For x = 1 To mapsizex
For y = 1 To mapsizey

writeint ( file, defaulttile )
writeint ( file, defaultattribute)
 

Next
Next


d.h. für jedes Tile wird einfach hintereinander ein Standarttile, und das Standartattribut gespeichert.

Wenn jetzt im Programm ein Tile geändert wird, will ich dass es direkt in die Datei gespeichert wird.


also quasi

if mousehit(1)
{attribut / tileänderung}
{änderung in datei speichern}
endif

Xeres

Moderator

BeitragDi, Nov 29, 2011 17:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Es macht mehr Sinn, alle Änderungen in einem Rutsch zu speichern (und die Datei einfach neu zu schreiben). Mach's dir nicht unnötig kompliziert.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)
 

Inso

BeitragDi, Nov 29, 2011 17:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja, aber darum gehts mir ja nicht.
Es geht darum, dass wenn der Mapeditor(was es wird) aus irgendeinem Grund mal abschmiert, ich genau da weiter machen kann, wo ich aufgehört habe. Jetz kann man ja sagen "dann speicher halt öfter", aber wies halt so ist, ist man irgendwann einfach "drin" und vergisst darüber mal kurz zu speichern, absturz -> alles weg -> demotivation. dem wollte ich vorbeugen..

ZEVS

BeitragDi, Nov 29, 2011 17:29
Antworten mit Zitat
Benutzer-Profile anzeigen
Du solltest ein anderes Problem beheben: Wieso stürzt der Map-Editor ab?
Es hat keinen Sinn, Abstürzen vorzubeugen, wenn man sie einfach verhindern kann (es ist daher für Microsoft nicht einfach, Betriebssystemabstürze zu verhindern). Alternativ: Automatisches Speichern (die Microsoft-Word-Methode, meine Güte, schon wieder gegen Microsoft...)
Gibt es Fehlermeldungen bei den Abstürzen? Lassen sie sich reproduzieren (Gleiches Verhelten -> Gleicher Absturz)?. Führst du DebugLog? Wenn Programminterne Endfunktionen verantworlich sind, kannst du auch hier ein Speichern einrichten.

ZEVS

Xeres

Moderator

BeitragDi, Nov 29, 2011 17:31
Antworten mit Zitat
Benutzer-Profile anzeigen
Gegen ein Autosave spricht ja auch gar nichts: Alle 5 Minuten, immer vor Beta-Feature X und/oder wenn Y Tiles geändert wurden. Die Bedingungen sind aber schneller & sicherer gemacht als alles andere.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)
 

Inso

BeitragDi, Nov 29, 2011 17:39
Antworten mit Zitat
Benutzer-Profile anzeigen
noch schmiert ja gar nix ab, soweit ist es ja noch nicht Wink
vielleicht sollte ich ein paar informationen geben was es im endeffekt wird.
kennt ihr das spiel harvest moon? so in etwa.
und das "attribut" das gespeichert wird ist nichts anderes als ein gegenstand der auf dem jeweiligen tile platziert werden kann, jedoch soll es in dem spiel keine speichern/laden funktion geben, nur spielstände die man permanent weiter spielen kann, wenn man was vergeigt, muss mans auslöffeln.deshalb wollt ich mir gleich im mapeditor eine lösung für das problem überlegen und 2 fliegen mit einer klappe schlagen.
ich hoffe ihr versteht mein problem jetzt Smile

würde ja ansich mit seekfile funktionieren denk ich, aber 1. weiß ich nicht ob das auf die performance schlägt, 2. weiß ich nicht so ganz wie ich ausrechne welcher wert in der mapdatei geändert werden muss, auf basis der ausgewählten x/y coordinaten
 

bjh

BeitragDi, Nov 29, 2011 17:49
Antworten mit Zitat
Benutzer-Profile anzeigen
ich würde die datei einfach mit writefile überschreiben:

for y=1 to map_height
for x=1 to map_width
writebyte stream,wert
next
next

so ungefähr (wahrscheinlich nicht, das was du brauchst Wink )

ZEVS

BeitragDi, Nov 29, 2011 17:50
Antworten mit Zitat
Benutzer-Profile anzeigen
Ganz einfach:
Nummer des Wertes = x*width+y
Länge eines Wertes = 2 Ints = 2*4 Bytes = 8 Bytes
=> Index des Wertes = 8*(x*width+y)

Die Frage ist, ob du nicht das Speichern einfach an das Beenden des Spieles setzt. Dann müsste der User immerhin den Prozess direkt killen (Wenn du aber in einer Datei speicherst, dass das Spiel angefangen wurde, kannst du beim nächsten Start auch dies feststellen und den Spielstand wegen cheatens löschen).
Zumal dann immer erschreckende Warnungen kommen (WARNUNG: Das Beenden eines Prozesse kann zu [...] Systeminstabiltät führen).

ZEVS

Xeres

Moderator

BeitragDi, Nov 29, 2011 17:51
Antworten mit Zitat
Benutzer-Profile anzeigen
Andauerndes speichern hilft aber prinzipiell auch nicht gegen Savescumming.

Wenn du es mit SeekFile machen möchtest: Die Position wird in Byte angegeben und ein Int besteht aus 4 Bytes.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Midimaster

BeitragDi, Nov 29, 2011 20:56
Antworten mit Zitat
Benutzer-Profile anzeigen
Die Vorschläge einfach die gesamte Datei neu zu speichern, auch wenn sich nur ein Feld im Map geändert hat sind nicht so dumm!

Mess doch erst mal die Zeit, die das Abspeichern des gesamten Map benötigt. Ich schätze mal das kann man auch nach jeder User-Änderung machen, ohne dass die Performance darunter leidet.

Es ist ja map-technisch völlig egal, ob du nur einen Wert in der Datei änderst, oder die gesamte Map neu speicherts. Sie enthält nachher so und so die gleichen Daten.


BlitzBasic: [AUSKLAPPEN]
Function SaveMap
zeit%=MilliSecs()
For x = 1 To mapsizex
For y = 1 To mapsizey
WriteInt ( file, defaulttile )
WriteInt ( file, defaultattribute)
Next
Next
DebugLog "Zeitverbrauch" + ( MilliSecs()-Zeit )
End Function
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe

BladeRunner

Moderator

BeitragDi, Nov 29, 2011 20:59
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich würde meine Festplatte nicht gerne mit so vielen Schreibzugriffen bombardieren wollen. Ganz im ernst, es ist überflüssig nach jedem Tile zu speichern. Wer sich entmutigen lässt wei die Arbeit der letzten 3 Minuten fehlt der war eh nicht motiviert. Und alle anderen werden das bissel was bei einem regelmäßigen Autosave verloren geht rasch wieder aufarbeiten.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

Midimaster

BeitragDi, Nov 29, 2011 21:08
Antworten mit Zitat
Benutzer-Profile anzeigen
ich denke das ist seine sache! Er fragt uns hier nur, wie man es technisch lösen könnte. Die Festplatte wird es nicht stressen, selbst wenn 1x pro Sekunde was geschrieben wird!
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe
 

Inso

BeitragDi, Nov 29, 2011 21:53
Antworten mit Zitat
Benutzer-Profile anzeigen
Habs mir jetzt super einfach gemacht, ich speicher in die datei einfach nur
die coordinaten die beim erstellen des objekts bestimmt werden, dazu die attribute usw und tadaa! ich kann jederzeit die map speichern, und zwar wird nach jedem gesetzten objekt einfach dieses objekt der map datei zugefügt Smile kaum rechenlastig weil ja im prinzip nur 4 variablen (vllt bald 6-7)gespeichert werden, pro klick Smile

ich habs mir viel zu kompliziert gemacht.

allerdings weiß ich jetzt noch nicht so genau wie ich ein objekt wieder lösch, also in der datei sieht es dann so aus:

id (interne objekt id)
x (is klar^^)
y (dito)
objId (was für eine art objekt ist es?)
yaw (drehungswinkel)

speichern tu ich es per writeline, auslesen per int(readline).

angenommen ich klicke jetzt ein objekt an, welches ich löschen will, liefere ich schonmal den ersten wert: ID
wie kann ich anhand dieser ID in die datei gehen, die richtigen einträge finden, und einfach löschen?
dann müssen die darauf folgenden einträge ja noch jeweils ein id = id - 1 bekommen.
wie lös ich das?

edit:
Oh, hatte das "antworten" fenster jetzt die ganze zeit beim lösen des problems offen und nicht gesehn dass noch wer geantwortet hat, aber trotzdem danke für die posts Smile

BladeRunner

Moderator

BeitragMi, Nov 30, 2011 3:06
Antworten mit Zitat
Benutzer-Profile anzeigen
Midimaster hat Folgendes geschrieben:
ich denke das ist seine sache! Er fragt uns hier nur, wie man es technisch lösen könnte. Die Festplatte wird es nicht stressen, selbst wenn 1x pro Sekunde was geschrieben wird!

Sicher ist es seine Sache- nur benutzen wollte ich ein Tool was so arbeitet nicht.
Selbst wenn es nur um eine vergleichsweise kleine Map mit 64*64 Feldern ginge hätte ich, angenommen jedes Feld wird nur einmal bearbeitet- schon 4096 mal die komplette Map gespeichert. In der Regel wird der Bearbeitungsaufwand sogar noch deutlich höher werden. Und ob das nun einmal pro Sekunde geschieht oder einmal die Minute ist mir dabei nebensächlich, Fakt ist dass der Lebenszyklus einer Platte eben auch begrenzt ist und ein solches Vorgehen lässt die Platte rapide altern. Und das unnötigerweise.
Machen kann man fast alles- ob es sinnvoll ist ist jedoch eine ganz andere Sache, und ich erlaube mir darauf hinzuweisen dass ich solch ein Vorgehen für kontraproduktiv halte.
Inso: das Speichern per writeline bläht deinen Save massiv auf. Statt eines Integers (4 Byte) benötigt die selbe Information per Writeline bis zu 13 Byte an Platz ein.
Und: Sequentielles Löschen ist nicht so ohne weiteres machbar. In der Regel läuft es auf ein komplettes Neuspeichern ohne den gelöschten Eintrag hinaus.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92

ToeB

BeitragMi, Nov 30, 2011 14:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Also ich weiß nicht ob das hier ein paar Leute kennen, aber der Borland Pascal Editor, bei dem Speichert man einfach mit F2 die Aktuelle Datei. Wenn man das ein paar mal gemacht hat, dann speichert man immer selber nach jedem wichtigen Schritt. Vielleicht reicht es, wenn du einfach eine Taste festlegst, welche die Komplette map Speichert. Benutz der Benutzer das Programm häufiger, so gewöhnt auch er sich dran, nach jedem Wichtigen Map-Teil einmal zwischen zu speichern. Das würde weder die Festplatte mit unnötige Speicherzugriffen zumüllen, noch wäre gar kein Backup mehr da. Ich würde es so machen.


Lg
Religiöse Kriege sind Streitigkeiten erwachsener Männer darum, wer den besten imaginären Freund hat.
Race-Project - Das Rennspiel der etwas anderen Art
SimpleUDP3.0 - Neuste Version der Netzwerk-Bibliothek
Vielen Dank an dieser Stelle nochmal an Pummelie, welcher mir einen Teil seines VServers für das Betreiben meines Masterservers zur verfügung stellt!
 

PhillipK

BeitragMi, Nov 30, 2011 14:17
Antworten mit Zitat
Benutzer-Profile anzeigen
ToeB: Das wurde oben schonmal erklärt. Glaub ich ^^

Der TE gewöhnt sich das ganze andersrum an: Anfangs wird noch oft gespeichert, aber sobald es Routine ist, mit dem Editor umzugehen, wirds vernachlässigt.

Persönlich habe ich dieses Problem auch, mit zb blender. Fix mal n bissl was hingeklatscht und irgendwann - absturz. Kein Autosave, kein Quitsave, könnte jedesmal kotzen.

Um nun einen Konstruktiven vorschlag aus den beiden meinungen hier zu veröffentlichen:

Wie wärs mit einem Mix? Eine Variable, die speichert, wieviele "Schritte" getan wurden und ein Autosave auf zb 5minuten.
Ist nun die Zeit rum oder es wurden mehr als X schritte getätigt (zb 30 änderungen, je nachdem wie lange eine änderung dauert) gibts n autosave.
Evoila, keiner darf sich beschweren - ein intelligentes autosave ^^ Festplatte wird entlastete, die nerven des users auch.
Und natürlich nicht vergessen: Wenn die zeit rum ist und KEINE änderung stattgefunden hat, nicht speichern! Sondern lieber auf eine änderung warten. Sonst macht man sich frühstück und die map - unverändert - wurde 10x sinnlos gespeichert.

Midimaster

BeitragMi, Nov 30, 2011 20:39
Antworten mit Zitat
Benutzer-Profile anzeigen
@Inso

also jetzt bist Du auf dem falschen Weg. Zwar wird in deiner Methode wenig pro Click gespeichert, aber um an die Datei etwas anzuhängen muss sie (rein physikalisch) jedesmal komplett durchgescannt werden. Es ist also eine gleich intensive Nutzung der Platte, wie wenn Du gleich die gesamte Map speicherst.

Auf der anderen Seite kaufst Du dir jetzt jede Menge Ärger ein. Wie Du schon bemerkst ist das "Wiederfinden" einer Koordinatenstelle jetzt sehr umständlich.

Ich hab mal einige Zeitmessung durchgeführt:

für eine Map bis 300x300 kannst Du einfach die Map mit WriteInt() in eine Datei schreiben

für eine größere Map, solltest Du die Map einmal komplett erstellen und später mit SeekFile() die richtige Stelle in der Datei suchen:

BlitzBasic: [AUSKLAPPEN]
Graphics 800,600
Dim Map%(999,1999)

; dieses nur 1x um die Datei zu erzeugen:
locBank=CreateBank(4*1000*1000)
Datei=OpenFile("test.map")
WriteBytes locBank,Datei, 0, 4*1000*1000
CloseFile Datei


; Beispiel an der Koordinate 342/115 den Wert 1 eintragen:
Speichere 342, 115, 1
WaitKey()
End


Function Speichere(x%,y%,Wert%)
Zeit=MilliSecs()
Offset=4*1000*y + 4*x
Datei=OpenFile("test.map")
SeekFile Datei, OffSet
WriteInt Datei, Wert
CloseFile Datei
Text 100,100, (MilliSecs()-zeit)
End Function

Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe
 

Inso

BeitragFr, Dez 02, 2011 1:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Midimaster hat Folgendes geschrieben:
@Inso

[...]


Danke dir für deine Mühe! Smile Ich schau mir das ganze morgen mal genau an, bin jetzt zu Müde für sowas Smile

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group