PDA

View Full Version : level loading



leniz
29-05-2007, 07:53 PM
System: Windows XP, AMD Sempron +2800 , nVidia GeForce FX 5500
Compiler/IDE: Delphi 2006 for Win32
API: DelphiX

Did not find any info, so I'm going to ask here:
I'm loading my main map from a text file in the onFormCreate event:
procedure TForm22.FormCreate(Sender: TObject);
begin
form22.setupmap(mapfile);
end;

with this procedure:

procedure tform22.SetupMap(MapFile:string);
var stream:TFilestream;
C : Char;
x, y : Word;
tempbuffer : array[ 0..32, 0..24 ] of Char;
begin
Stream:=tfilestream.Create(mapfile, fmopenread);

try
try
for y:=0 to 24 do
begin
for x := 0 to 31 do
begin
stream.ReadBuffer(C, SizeOf(C));
tempbuffer[x][y]:=c;

end;
end;
except on e:exception do
messagedlg(e.Message, mterror, [mbok], 0);
end;
finally
stream.free
end;

for y := 0 to 25 do
begin
for x := 0 to 32 do
begin
case tempbuffer[x][y] of
//grass
'0':
begin
map[x][y].Tile:=0;
end;
//path
'1' :
begin
map[x][y].Tile:=1;
end;
//water
'2' :
begin
map[x][y].Tile:=2;
end;
end;
end;
end;


end;


but since one map in game is not good, I want to load different maps. I tried loading them in doLoad procedure, like this:

procedure doLoad;
begin
form22.SetupMap('map.map');
gamestate:= gsgame;
end;


//and I try to engage the doLoad procedure like this

procedure TForm22.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
...
//other keys that control menu
...
if (key = vk_space) and (gamestate = gsgame) then
begin
gamestate:= gsload;
end;
end;


but everytime I only get a "stream read error".
I guess I'm could use some kind of simple procedure, but I can't think of any.
Cheers, leniz[/pascal]

jdarling
29-05-2007, 07:57 PM
As usual, give us more information and some source code. Compiler, Platform, and a simple sample that shows your problem is about the minimum to get an answer. Otherwise no one knows what your talking about. If your referencing a previous posts source, then place a link (we don't fish for your source).

jasonf
30-05-2007, 01:47 PM
Does Map.map exist in your exe path?

leniz
30-05-2007, 01:56 PM
Yes it does. And no matter what filename or filetype I use, it's all the same error.

jasonf
30-05-2007, 02:02 PM
What happens when you step through the code? where do you get the error? Is it when it does the Stream:=tfilestream.Create(mapfile, fmopenread);

or on one of the stream.ReadBuffer(C, SizeOf(C)); statements?

If it is on the file open, then there's a problem with the file location/filename and the app can't find it.

If it's on one of the ReadBuffers then the file isn't big enough for the array..

I'm not at a Delphi PC at the moment, so I can't test anything.

Angelo
30-05-2007, 02:03 PM
Yes like jason said maybe map.map doesn't exist?

I think the procedure could better be something like this...

[code]
procedure doLoad(MapName: string);
begin
form22.SetupMap(MapName+'.map');
gamestate:= gsgame;
end;

leniz
30-05-2007, 02:41 PM
I get my error in the doLoad procedure:
procedure doLoad;
begin
form22.SetupMap('map.map'); <---- right about here is the error
gamestate:= gsgame;
end;

Then I can't go further, because my BDS2006 locks up and I have to "ctrl+alt+del" it.

jasonf
30-05-2007, 02:55 PM
but you can step into that function before it locks up and see what line of code causes the problem...

Setharian
30-05-2007, 03:13 PM
that "lock-up" is partially a bug, go to BDS->Tools->Debugger Options->BDS Debuggers (I have CodeGear Debuggers here)->Native OS Exception->Select all and toggle "Handled by debugger" and "Run unhandled"...no longer an exception should lock up the IDE....

Angelo
30-05-2007, 03:14 PM
If the error occurs there, it means that inside the procedure is an error.

Go to debugger options...

EDIT: Argh someone was already before me...

leniz
30-05-2007, 06:32 PM
Well isn't that nice... I have solved half of my problem. The map is now loading. I just had to mingle with my array sizes and now it's working. But one problem is still folowing me... The map is not displayed correctly - many of the tiles are not bu the text file. that is still a mystery.

jdarling
30-05-2007, 07:30 PM
One problem is that your creating an array of 0..32, 0..24 and then in the lower loops accessing it as 0 to 25 and 0 to 32. Make sure that your indexing it properly or that you have sized it properly. I'm guessing that your indexing should be 0 to 24.

You also index it as 0 to 31 (top loop).

All of this combined will give you crazy results. Instead try using constants and making sure that your indexing to value-1.

Now, as for your read char by char. Ditch that and go with a block read as your array is in order. So it goes from:Stream:=tfilestream.Create(mapfile, fmopenread);

try
try
for y:=0 to 24 do
begin
for x := 0 to 31 do
begin
stream.ReadBuffer(C, SizeOf(C));
tempbuffer[x][y]:=c;

end;
end;
except on e:exception do
messagedlg(e.Message, mterror, [mbok], 0);
end;
finally
stream.free;
end;

to:Stream:=tfilestream.Create(mapfile, fmopenread);
try
try
if stream.size <> COLS* ROWS then
raise exception.CreateFmt('Data file "%s" size incorrect!', [MapFile]);
stream.ReadBuffer(@tempbuffer[0][0], 25*32);
except on e:exception do
messagedlg(e.Message, mterror, [mbok], 0);
end;
finally
stream.free;
end;

A final re-work of your entire source could be (This only works if there are no line breaks in the file):const
COLS = 25;
ROWS = 24;

procedure form22.SetupMap(MapFile:string);
var
Stream:TFilestream;
C : Char;
x, y : Word;
tempbuffer : array[ 0..COLS-1, 0..ROWS-1 ] of Char;
begin
Stream:=tfilestream.Create(mapfile, fmopenread);
try
try
if stream.size <> COLS* ROWS then
raise exception.CreateFmt('Data file "%s" size incorrect!', [MapFile]);
Stream.ReadBuffer(tempbuffer[0, 0], COLS*ROWS);
except on e:exception do
messagedlg(e.Message, mterror, [mbok], 0);
end;
finally
Stream.free
end;

for y := 0 to ROWS-1 do
for x := 0 to COLS-1 do
case tempbuffer[x][y] of
'0' : map[x][y].Tile:=0; //grass
'1' : map[x][y].Tile:=1; //path
'2' : map[x][y].Tile:=2; //Water
end;
end;

BTW: For the love of god will you name your forms and use some spacing :).

leniz
31-05-2007, 03:18 PM
Well, I used your piece of code to load my maps, but strangely, I get all the same messed up map as before. Oh, and my file has to be just a one long line of chars, right?

jdarling
31-05-2007, 05:23 PM
Yes, it needs to be one long line of chars, no line breaks in it at all.

Can you post up a zip file containing a simple sample application that shows the problem? That would make this much easier to try and debug, simply make it a single form that calls the loading method and then draws the map to a TImage (once). This way we can quickly look and see what you may or may not be doing wrong :)

leniz
31-05-2007, 05:52 PM
Ah hell, I'll just post my whole project because I'm to lazy to create another project :D
Here's the link to my problem:
http://rapidshare.com/files/34477479/gamestate_project.exe

Cheers, leniz[/url]

Angelo
31-05-2007, 06:29 PM
Why not using ini files anyway?

jdarling
31-05-2007, 08:39 PM
My bad, small typo on my behalf:procedure TForm1.SetupMap(mapfile: AnsiString);
var stream:TFilestream;
C : Char;
x, y : Word;
tempbuffer : array[ 0..Rows-1, 0..Cols-1] of Char; // Typo was here
begin
Stream:=tfilestream.Create(mapfile, fmopenread);
try
try
if stream.size <> cols* rows then
raise exception.CreateFmt('Data file "%s" size incorrect!', [MapFile]);
Stream.ReadBuffer(tempbuffer[0, 0], cols*rows);
except on e:exception do
messagedlg(e.Message, mterror, [mbok], 0);
end;
finally
Stream.free
end;


for y := 0 to rows - 1 do
for x := 0 to cols - 1 do
case tempbuffer[y, x] of
'0' : map[x][y].Tile:=0; //grass
'1' : map[x][y].Tile:=1; //path
'2' : map[x][y].Tile:=2; //Water
end;
end;

Download a running example here: http://www.eonclash.com/PGD/leniz.zip

leniz
01-06-2007, 02:56 PM
YES!! Oh what joy it is to see a fully functional map :D now comes the hardest part for me: combat mode developing and iteM creation. Oh well, wish me luck :wink:

jdarling
04-06-2007, 01:28 PM
Good luck.

Before you go that far, might I suggest that you expand your mapping system a bit. Also when you get into combat and other try looking at a scripting language for support. They can be really helpful and make debugging/quick mods very fast. The final advantage is that its easy to convert a script file into raw source if you find you have a need :).