PDA

View Full Version : EInvalidPointer



Septimus
01-08-2003, 03:29 AM
I'm having a problem with a game I'm trying to make (I may even end up coming close to finishing this one!). It's basically a Snake clone, or Nibbles for all you QBasic fans. You know, you steer a constantly moving snake around eating things until it grows so large you die.

The problem currently is figuring out a movement routine. I thought it'd be good enough to just make a procedure that gives each segment of the snake the co-ords of the previous segment (except the head which is given new co-ords in the loop). That way the body of the snake would more or less follow where the head leads (that's my theory anyway).

Here's what I've come up with:
I think it's pretty self explanitary, Snake1 is an open array of a record
containing X, Y values. I tried just Snake1[i].X := Snake1[i - 1].X but
that just puts all of the segments on top of the head.
So I tried making another 2 arrays to store all of the co-ords and then
assign the X/Y all at once from those. But I get an invalid pointer error
if I do that. I've been up for too long to try think of another way (except
maybe 2 X/Y variables for each segment and alternating them each tick,
bleh).


procedure CalcSnakes;
var i: Integer;
PrevX, PrevY: array of Integer;
begin
SetLength(PrevX, High(Snake1));
SetLength(PrevY, High(Snake1));
for i := 1 to High(Snake1) do begin
PrevX[i] := Snake1[i - 1].X;
PrevY[i] := Snake1[i - 1].Y;
end;
for i := 1 to High(Snake1) do begin
Snake1[i].X := PrevX[i];
Snake1[i].Y := PrevY[i];
end;
end;


There's probably a heaps easier way, there always is.

cairnswm
01-08-2003, 05:58 AM
Store the coordinates in a list. To move the head add a new item at the end of the list. To delete the last link of the snake delete the first item in the list.

Sander
02-08-2003, 12:49 PM
The first method you had was good enough, it just had a minor flaw: YOu were assigning the x,y values of the head to the 2nd one, and then the 2nd one to the third one, which makes everything sit on the exact same coordinates. Thus, you need to cycle through the list in reversed order.:



snake1[0]:=inputcoords;
for i:= snake1.length-1 downto 1 do begin
snake1[i].x:=snake1[i-1].x;
snake1[i].y:=snake1[i-1].y;
end;


That should do it, I think....

Septimus
02-08-2003, 01:40 PM
[quote="cairnswm"]Store the coordinates in a list. To move the head add a new item at the end of the list. To delete the last ]

Could you give a little more info about this? What kind of list? I'll try running it backwards first, since that's pretty much implimented already, but when I get a little more adventurous I'd like to give this a go.

Crisp_N_Dry
02-08-2003, 11:13 PM
All you need to do is to take the tail piece and place it where the head will be on the next move. This will mean that the body stays the same length but moves ahead, and you won't even have to shift all of the body parts. Just make sure you keep track of where in the array the head and tail are otherwise you will be removing sections of the body because the head and tail won't always be at the start and end of the array, but it doesn'yt matter where in the array the parts are. Oh and, if you need to extend the length of the snake to increase the difficulty level then simply don't remove the tail end but add the head. Let me know if I need to rewrite this to make it more clearer, I have a habit of confusing people.

Septimus
03-08-2003, 01:43 PM
Yeah, I think I know what you mean. That method wouldn't really work for the way I've got things set up at the moment. I'm using bitmaps to represent the segments of the snake that move as little as one pixel at a time. But I'm considering simplifying it somewhat to just making a big grid and adding/removing boxes from the head/tail at least until I get the thing working.
If I do decided to go in that direction and get stuck then you'll probably be hearing from me.

For those who are interested, I think I've figured out how to get the thing moving and it's not as simple as I was hoping. I haven't tried it yet tho, so I don't know.

Eriken
03-08-2003, 02:38 PM
Did you try the stuff Shadowcore wrote? it should be as easy as that.. updating the x,y-coords from the tail and move forward.. :-)
_____
Eriken

Alimonster
04-08-2003, 10:51 AM
Hmm, I wrote code for an article that may be useful (http://www.alistairkeys.co.uk/states.shtml) to you a while back. Bear in mind that the code was just an example to demonstrate what the article talked about, but still...

EDIT: Direct link to the example code is here (http://www.alistairkeys.co.uk/download/states.zip) and you want to look at PlayingGameState.pas (or something like that).

Septimus
04-08-2003, 04:16 PM
Thanks for all the help guys. I got it working now. I wasn't as easy as I first thought, but a lot easier than I re-thought. Giving each segment the x,y of the previous one didn't work because the bitmaps are 24x24 (probably soon to be 12x12) and the snake moves 1 pixel at a time, so all the images were just bunching up 1 pixel before the previous one.

I had to write a procedure that just moved each segment 1 pixel and if the current segment wasn't moving in the same direction as the previous one then keep it moving forward until the X or Y was the same (depending on the direction they were both moving) and then change the direction to the same as the previous segment. It wasn't too difficult to do this, it only took about half a dozen lines so I still get around 100fps (assuming I'm calculating the fps right).

The only problem with this is if you turn 90A¬? and then 90A¬? back the other way too quickly then the number 2 segment thinks it's still following the head and disconnects to continue off into the wild blue yonder, taking the rest of the snake with it... I haven't put much thought into fixing this yet.

That game state article and code looks very handy too, thanks Ali. I already had something similar, but yours is a lot more detailed.