Reading and writing map data?

BlitzMax Forums/BlitzMax Beginners Area/Reading and writing map data?

Amon_old(Posted 2005) [#1]
I have a function that reads and writes the map data for my game. The map array "map:int[mapx,mapy]" is filled with random number from 0 to 15.

What is the best way to save the data so that its readable and also what is the best way to read the data back in to the program so that it fills my map array?

This is my current code. Example code would be better for me as I can learn from it better.

To explain more, say for instance I had a tilemap editor which I do :). And when someone makes a level they want to save it to file or load it back in once they have saved it. How can this be done? Can Someone also choose the filname for the saved map? Can someone choose where to save the mapfile?

I know its a lot of question but I'm kindof stuck. I have no clue as to how to do this. I dont get the BlitzMax examples in the docs.

Thanks :)
Function saveload_map()

If KeyHit(KEY_F2)

	If FileType("map.txt") = 0 Then 
 		Local new_map_file = CreateFile("map.txt")
	End If


	Local write_map_file = WriteFile("map.txt")
	For Local x:Int = 0 To mapx-1
		For Local y:Int = 0 To mapy-1
			WriteInt(write_map_file,map[x,y])
		Next
	Next
	CloseStream(write_map_file)

EndIf

If KeyHit(KEY_F1)
	
	Local x:Int = 0
	Local y:Int = 0
	
	Local read_map = ReadFile("map.txt")
	While Not Eof(read_map)
		map[x,y] = Readint(read_map)
		
			x:+1
			y:+1
			
			If x > 5 Then Exit
			If y > 5 Then Exit	
	Wend
	
	CloseStream(read_map)
	
EndIf


End Function



RGR(Posted 2005) [#2]
Why don't you learn programming first - and then start to write programs?
What you are doing is so stupid - it's unbelievable.
Sorry about that, but looking at your website... and seeing what you have done already, I cannot believe that YOU wrote the code above or YOU wrote one piece of that stuff there... doesn't fit somehow... and its unbelievable that you made all this with the help of Ryan Moody, Scott Shaver, klepto2 and so on, as seen in other threads you started...

Look at your code: when you save your map, x=0 while y is in a loop from 0 to mapy-1 - means that you may save 25 Numbers (in case mapx=5 and mapy=5)
Now when you load, x and y are both 0 or 1 or 2 and so on.. means that after 5 numbers read, your "Load-Program" exits...

So why don't you for a start save the variables mapx and mapy into your file (gives you this great opportunity to have a variable mapsize), then loop to save map[x,y] as you did...
Then, when you want to load it, you do exact the opposite.
Read the variables into mapx and mapy - then use the same loops for reading into map[x,y]

And to all your other questions: You do not expect, that the forum members write your programs, or do you?


Amon_old(Posted 2005) [#3]
Why don't you learn programming first - and then start to write programs?


How are you supposed to learn to program without making programs?

What you are doing is so stupid - it's unbelievable.
Sorry about that, but looking at your website... and seeing what you have done already, I cannot believe that YOU wrote the code above or YOU wrote one piece of that stuff there... doesn't fit somehow...


Theres no need to apologise.

Look at your code: when you save your map, x=0 while y is in a loop from 0 to mapy-1 - means that you may save 25 Numbers (in case mapx=5 and mapy=5)


Are you talking of the code below? If not then I dont know what you mean.

	Local write_map_file = WriteFile("map.txt")
	For Local x:Int = 0 To mapx-1
		For Local y:Int = 0 To mapy-1
			WriteInt(write_map_file,map[x,y])
		Next
	Next


Now when you load, x and y are both 0 or 1 or 2 and so on.. means that after 5 numbers read, your "Load-Program" exits...[quote]

Thats exactly what I want it to do. If I increase the numbers then it exits after a further read. The reason I have that in there is to also make sure that when reading the file that it doesnt exceed the map array, which is what happens when I remove it.

If I take out those nits I get array errors so I was experimenting reading in the information bit by bit.
The code below gives an error.

If KeyHit(KEY_F1)
	
	Local x:Int = 0
	Local y:Int = 0
	
	Local read_map = ReadFile("map.txt")
	While Not Eof(read_map)
		map[x,y] = Readint(read_map)
		
			x:+1
			y:+1

	Wend
	
	CloseStream(read_map)
	
EndIf


[quote]So why don't you for a start save the variables mapx and mapy into your file (gives you this great opportunity to have a variable mapsize), then loop to save map[x,y] as you did...
Then, when you want to load it, you do exact the opposite.
Read the variables into mapx and mapy - then use the same loop for reading into map[x,y]


eh!


RGR(Posted 2005) [#4]
How are you supposed to learn to program without making programs?

Wow - what a clever answer ;-)
With only 0.1 % of that energy you could have solved that easy problem above...

don't you see, that in your code x and y are incremented at the same time?
you must increment y in a loop and x in an outer loop as you did while saving....

instead of being offended, read what I wrote, word for word... that's the way you may get into it... if you read Data from a File it helps if you use the same algorithm - only instead of writing use reading.

btw: program is not program ... you know that I meant "such high end programs" you are working on ;-) ?


Ryan Moody(Posted 2005) [#5]
RaGR, you have a point, but there was no need to be rude. What he's trying to say is that maybe you should keep trying to solve the problems until you are certain you cannot do so.

For example, the answer to your question "Can Someone also choose the filname for the saved map?" is obviously yes, otherwise you'ld have to create a finite number of empty files, making the user choose which one to save to, which isn't the case in most games as it's not practical. The key to programming is logical thinking. If it helps, write down your algorithms on paper to plan how to tackle them.

looking at your website... and seeing what you have done already, I cannot believe that YOU wrote the code above or YOU wrote one piece of that stuff there


I hate to admit it, but that's what I was thinking.

Ryan


RGR(Posted 2005) [#6]
I am speaking out what I think - sometimes it is not the best - but in a Forum its the best way to get hated... ;-)
If I wouldn't have looked at his website and seen all his threads here - I wouldn't have answered that way at all...


Amon_old(Posted 2005) [#7]
hahaahahaha I know it may seem like something impossible but the Games on my website are written by me. Lol I know I ask some dumbass questions sometimes but as RaGR mentions I would usually figure things out if I just applied some thought to them.

Anyway as I know its my fault that I cant get things done I'll try the methods you stated RaGR. :)

I have a dream


RGR(Posted 2005) [#8]
Amon - And if you are on MSN Messenger... and have urgent questions that are better explained Q&A in realtime... for instance as the one above...
Get in touch ;-) (email is in my profile)


Kevin_(Posted 2005) [#9]
RaGR....

You have to appreciate that some people here have never programmed for industry and therefore don't follow the typical system development life cycle. Many people here just load up Blitz and program straight away and that is why they have problems. They dont realize that typing a program in an IDE is one of the last things to do, not the first.


LarsG(Posted 2005) [#10]
Amon:
Here's a very simple load and save example (taken from my own MAP type source).. It's not commented very good,
but should be fairly self-explanatory... (I hope)

	'****************************************************************************
	' Loads a map from a map file
	Method LoadMap(map:String = "")
		Local x:Int, y:Int
		Local file:Tstream
		' loads a MAP file
		If map = "" Then Return -1
		' load v0.01
		file = ReadFile(map)
		If file
			self.width = Readint(file) ; self.height = Readint(file)
			'resize array
			self.TileArray	= New Int[width,height]
			For y = 0 To self.height-1
				For x = 0 To self.width-1
					self.TileArray[x,y] = Readint(file)
				Next
			Next
			CloseFile(file)
			Return 0
		Else
			Return -1
		EndIf
	EndMethod
	
	'****************************************************************************
	' Saves the current map (array) to a map file
	Method SaveMap(map:String = "")
		Local x:Int, y:Int
		Local file:Tstream
		' save a MAP file
		If map = "" Then Return -1
		' save v0.01
		file = WriteFile(map)
		If file
			WriteInt(file, self.Width) ; WriteInt(file, self.Height)
			For y = 0 To self.height-1
				For x = 0 To self.width-1
					WriteInt(file,self.TileArray[x,y])
				Next
			Next
			CloseFile(file)
			Return 0
		Else
			Return -1
		EndIf
	EndMethod



Will(Posted 2005) [#11]
Regarding the first reply to this post - "I cannot believe that YOU wrote the code above or YOU wrote one piece of that stuff there... doesn't fit somehow..."

Although I guess this isnt the case here, I'm sure some of us have family members we are teaching to code, who use our blitz accounts for hte support forums. I know sometimes im posting as myself, proud owner, and sometimes my brother posts under this name as he is just learning (although he is doing really well for a HS freshman!)


Anyway, I wrote tile loading and saving code for a now-abandoned tile game. (Funny how all my projects seem abandoned now) I'll print it below:

[code]
Function SaveTileMap(map:TileMap, path:String, gPile:GraphicPile)
DeleteFile(path)
success = CreateFile(path)
If Not success RuntimeError ("couldnt create save file " + path)
File = OpenFile(path)

WriteLine File, "Level Creator File"
WriteLine File, "Tilemap:"
WriteLine File, "Tilemap X Tile Count"
WriteLine File, map.xtiles
WriteLine File, "Tilemap Y Tile Count"
WriteLine File, map.ytiles
WriteLine File, "Tilemap X Tile Size"
WriteLine File, map.tilewidth
WriteLine File, "Tilemap Y Tile Size"
WriteLine File, map.tileheight
WriteLine File, "Tile Information Follows:"
map.UpdateTilePositions()

WriteLine File, "Number of tile attributes:"
WriteLine File, TileAttributeCount
WriteLine File, "Tile Format is as Follows:"
WriteLine File, "Tile.xloc - int"
WriteLine File, "Tile.yloc - int"
WriteLine File, "Tile.mygraphic - int"
WriteLine File, "Tile.drawR - int"
WriteLine File, "Tile.drawG - int"
WriteLine File, "Tile.drawB - int"
WriteLine File, "Tile.Attributes[1] - int"
WriteLine File, "Tile.Attributes[2] - int"
WriteLine File, "Tile.Attributes[3] - int"
WriteLine File, "Tile.Attributes[...] - int"
WriteLine File, "Tile.Attributes[" + TileAttributeCount + "] - int"
WriteLine File, "starting with top left tile, working across each row"

For r = 0 To map.ytiles - 1
For i = 0 To map.xtiles -1
WriteLine File, map.Tiles[i,r].xloc
WriteLine File, map.Tiles[i,r].yloc
WriteLine File, gpile.names[map.Tiles[i,r].mygraphic]
WriteLine File, map.Tiles[i,r].drawR
WriteLine File, map.Tiles[i,r].drawG
WriteLine File, map.Tiles[i,r].drawB
For j = 0 To TileAttributeCount - 1
WriteLine File, map.Tiles[i,r].Attributes[j]
Next
Next
Next

WriteLine File, "End of Tilemap"
CloseStream File
End Function

Function LoadTileMap:TileMap(map:TileMap, gPile:graphicPile, path:String)
Local line:String
Local File:Int
file = ReadFile(path)
If Not file Return map
line = ReadLine(file)

If line <> "Level Creator File" Then
Return map
End If

line = ReadLine(File) 'WriteLine File, "Tilemap:"
line = ReadLine(File) 'WriteLine File, "Tilemap X Tile Count:"
xtiles:Int = Int(ReadLine(file)) 'WriteLine File, map.xtiles
line = ReadLine(File) 'WriteLine File, "Tilemap Y Tile Count:"
ytiles:Int = Int(ReadLine(file)) 'WriteLine File, map.ytiles
line = ReadLine(File) 'WriteLine File, "Tilemap X Tile Size"
tilewidth:Int = Int(ReadLine(file)) 'WriteLine File, map.tilewidth
line = ReadLine(File) 'WriteLine File, "Tilemap Y Tile Size"
tileheight:Int = Int(ReadLine(file)) 'WriteLine File, map.tileheight
line = ReadLine(File) 'WriteLine File, "Tile Information Follows:"
line = ReadLine(File) 'WriteLine File, "Number of tile attributes:"
TileAttributeCount = Int(ReadLine(file)) 'WriteLine File, TileAttributeCount

line = ReadLine(File) 'WriteLine File, "Tile Format is as Follows:"
line = ReadLine(File) 'WriteLine File, "Tile.xloc - int"
line = ReadLine(File) 'WriteLine File, "Tile.yloc - int"
line = ReadLine(File) 'WriteLine File, "Tile.mygraphic - int"
line = ReadLine(File) 'WriteLine File, "Tile.drawR - int"
line = ReadLine(File) 'WriteLine File, "Tile.drawG - int"
line = ReadLine(File) 'WriteLine File, "Tile.drawB - int"
line = ReadLine(File) 'WriteLine File, "Tile.Attributes[1] - int"
line = ReadLine(File) 'WriteLine File, "Tile.Attributes[2] - int"
line = ReadLine(File) 'WriteLine File, "Tile.Attributes[3] - int"
line = ReadLine(File) 'WriteLine File, "Tile.Attributes[...] - int"
line = ReadLine(File) 'WriteLine File, "Tile.Attributes[" + TileAttributeCount + "] - int"
line = ReadLine(File) 'WriteLine File, "starting with top left tile, working across each row"

map:tilemap = TileMap.create(xtiles, ytiles, tilewidth, tileheight)

CT:Tile = Tile.Create(0, gpile, 0, 0) 'CT stands for Current Tile (we load stats into one tile, and save copies of it into the tilemap

For r = 0 To map.ytiles - 1
For i = 0 To map.xtiles -1
CT.mygPile = gpile
CT.xloc = Int(ReadLine(file)) 'WriteLine File, map.Tiles[i,r].xloc
CT.yloc = Int(ReadLine(file)) 'WriteLine File, map.Tiles[i,r].yloc
CT.mygraphic = gPile.getIndex(ReadLine(file)) 'WriteLine File, gpile.names[map.Tiles[i,r].mygraphic]
CT.drawR = Int(ReadLine(file)) 'WriteLine File, map.Tiles[i,r].drawR
CT.drawG = Int(ReadLine(file)) 'WriteLine File, map.Tiles[i,r].drawG
CT.drawB = Int(ReadLine(file)) 'WriteLine File, map.Tiles[i,r].drawB
For j = 0 To TileAttributeCount - 1
CT.Attributes[j] = Int(ReadLine(file)) 'WriteLine File, map.Tiles[i,r].Attributes[j]
Next
map.Tiles[i,r] = CT.duplicate()
Next
Next

map.UpdateTilePositions()

line = ReadLine(File) 'WriteLine File, "End of Tilemap"
CloseStream File
Return map
End Function