Headache with LoadAnimImage

BlitzMax Forums/BlitzMax Beginners Area/Headache with LoadAnimImage

Matt Vinyl(Posted 2007) [#1]
Global gfx_cards=LoadAnimImage("gfx\cards.png",52,70,1,52)


This line worked perfectly 'this morning', and having not changed anything, now returns a Memory Exception. I'm tearing my hair out as I can't understand why it has stopped.

The master image size is 676 x 280 and is stored here:

C:\Documents and Settings\Matthew Finch\Desktop\Development\Games In Development\BlitzMAX\5-Liner\gfx


The BMax file is stored here:

C:\Documents and Settings\Matthew Finch\Desktop\Development\Games In Development\BlitzMAX\5-Liner


Is there something that I'm missing as I've been looking at it for far too long... ;)

Cheers,
M


GfK(Posted 2007) [#2]
You're trying to load 52 frames starting from frame 1. The frame count starts at 0, therefore your code is trying to read 52 images, ignoring the first one (so, 53 in total).

Your image is not large enough to contain 53 images of the specified size.

Change the 1 to a 0. That should sort it.


Matt Vinyl(Posted 2007) [#3]
Fantastic! Do you know I'd have put money on it working with that 1 there originally. ;)

Anyway, sorted, and in a very timely fashion I might add. Cheers!


Matt Vinyl(Posted 2007) [#4]
SeedRnd MilliSecs()

Graphics 1024,768

Global cards=LoadAnimImage("gfx\cards.png",52,70,0,52)

Local numbersa[53]
Local numbersb[53]

Local countera=52
Local counterb=52

While countera>0
	randoma=Rand(1,52)
	If numbersa[randoma]=0 Then
		numbersa[randoma]=countera
		countera:-1
	End If
Wend

While counterb>0
	randomb=Rand(1,52)
	If numbersb[randomb]=0 Then
		numbersb[randomb]=counterb
		counterb:-1
	End If
Wend

Local total[105]

For a=1 To 104
	If a<=52 Then
		total[a]=numbersa[a]
	End If
	If a>52 Then
		total[a]=numbersb[a-52]
	End If
Next

Local board[14,9]

For x=1 To 13
	For y=1 To 8
		b:+1	
		board[x,y]=total[b]
		Print board[x,y]
	Next
Next


Repeat
	Cls
	For e=1 To 13
		For f=1 To 8
			DrawImage cards,e*52,f*70,board[e,f]
		Next
	Next
	Flip
Until KeyHit(KEY_ESCAPE)


I now get an error on this line (Trying to index array element beyond array length) :

DrawImage cards,e*52,f*70,board[e,f]


As a test, I've printed to debug the values that should be in board[e,f] and I get the expected 104 random values.


GfK(Posted 2007) [#5]
Try using Rand(0,51) (two occurences of it) instead of Rand(1,52)

Just about everything in Blitzmax is zero-based rather than 1-based. This means you're wasting a fair bit of space in your Board array. If you need 14x9 elements, then you should use board[14,9], and use elements starting from 0 (the created array actually has elements from 0-13, and 0-8.


Matt Vinyl(Posted 2007) [#6]
Cheers - have changed that (unfortunately, still doesn't work :() I was so comfortable with B3D this recent change to BMAX (Which provides me with so much more than I could've hoped for from B3D!) has really thrown me...!


GfK(Posted 2007) [#7]
Just having a play with the code.

One more important thing - declare 'cards' as a TImage.


GfK(Posted 2007) [#8]
K, I checked the debug output from your code. The array has two 52's in it, when from what I can see, the array should only contain values from 0-51?

That's likely whats causing the problem.


Matt Vinyl(Posted 2007) [#9]
Thanks, sound advice there with the TImage - I should 'Strict up' my code. :)

Essentially, I want to have two of each numbers in the final set. which would then convert to (in each suit!) 2 aces, 2 twos etc. up to 2 kings.

You may well be right there - I think it comes down to problems with me mixing up 1's and 0's (didn't B3D have 11 elements in an array if you declared it as

Array(10)


?

Anyways, I'll try and take a look (tomorrow now though, my eyes have just about given up on me!)

Thanks for your continued help though - hopefully will nail it tomorrow.


GfK(Posted 2007) [#10]
(didn't B3D have 11 elements in an array if you declared it as

Array(10)
Yeah it did. Blitzmax doesn't, though.

Confused? You will be. ;)


Matt Vinyl(Posted 2007) [#11]
I've been testing further, ans it's definitely something to do with the frame I'm trying to display.

DrawImage cards,e*52,f*70,board[e,f]


I changed this to:

DrawImage cards,e*52,f*70,board[e,1]


and it draws 13x8 cards, but all rows are the same. I can't work out why the 'f' is causing the problem. Is there perhaps an easier way to do this? I need the 2 dimensional array so as I can display the cards in a grid, but couldn't think of another way to populate this, other than what I have done... :(


GfK(Posted 2007) [#12]
Have you checked the contents of the array? Do you still have 52s in there?

Every value in the array should be between 0 and 51, otherwise (in the event of a 52) you're trying to draw an image frame that simply isn't there.

Try changing it to this:
Local r:int
DebugStop
For e=1 To 13
  For f=1 To 8
    r = board[e,f]
    DrawImage cards,e*52,f*70,r
  Next
Next
Step through the loop, checking the value of 'r' each time. You'll probably find that it works right up to the point where it comes across a 52, when it will throw an error.


Matt Vinyl(Posted 2007) [#13]
Ah, I seem to be in the range 1-52 as opposed to 0-51. How could I change that? I'm certainly getting confused here - as from my loadanimimage routine, it looks like I'm loading 53 images in the range 0-52. Argh! lol


GfK(Posted 2007) [#14]
Nah, your use of LoadAnimImage is fine. You're loading 52 frames, starting from frame 0.

The 0 and 52 represent the first frame, and the total number of frames (not the first and last frame). The index of the last frame you've loaded is 51.

Try changing this bit of your code:
Local countera=51 'THIS LINE CHANGED
Local counterb=51 'THIS LINE CHANGED

While countera>=0 'THIS LINE CHANGED
	randoma=Rand(0,51) 'THIS LINE CHANGED
	If numbersa[randoma]=0 Then
		numbersa[randoma]=countera
		countera:-1
	End If
Wend

While counterb>=0 'THIS LINE CHANGED
	randomb=Rand(0,51) 'THIS LINE CHANGED
	If numbersb[randomb]=0 Then
		numbersb[randomb]=counterb
		counterb:-1
	End If
Wend


It really will pay to get used to using 0 instead of 1 as a base for everything. Your code will be a lot more consistent and understandable. :)


Matt Vinyl(Posted 2007) [#15]
Ah-ha!!! Spot on! Many thanks my man... ;0) Yes, I will remember that from now on - very sound advise. Thanks once again for your help. I can now press on with the more exciting part of my programme. ;0)


Matt Vinyl(Posted 2007) [#16]
Heh, having said that, I've found a minor bug. Here's the (sorted) numbers that are returned from one example run (In all tests, the additional 0 is present, but one number may be missing from anywhere else in the list:

0
0
0 <---Should not be here
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
9
9
10
10
11
11
12
12
13
13
14
14
15
15
16
16
17
17
18
18
19
19
20
20
21
21
22
22
23
23
24
24
25
xx <---Should be another 25 here
26
26
---All further numbers are fine.

Flumoxed currently, but will take a further look...


TomToad(Posted 2007) [#17]
Not sure, but if you haven't changed this code yet, it might be your problem:
change this:
Local total[105]

For a=1 To 104
	If a<=52 Then
		total[a]=numbersa[a]
	End If
	If a>52 Then
		total[a]=numbersb[a-52]
	End If
Next

to this
Local total[104]

For a=0 To 103
	If a<52 Then
		total[a]=numbersa[a]
	End If
	If a>=52 Then
		total[a]=numbersb[a-52]
	End If
Next



Matt Vinyl(Posted 2007) [#18]
Ah, perfect! So simple, and yet so right! :0
Cheers!