problem with type usage

BlitzMax Forums/BlitzMax Programming/problem with type usage

z80jim(Posted 2008) [#1]
I'm trying to get back into using types, what's wrong with the following?

Graphics 640,480

Type Tsprite
Field sprite:timage=LoadImage("sprite.jpg",1)
Field x:Int
Field y:Int
End Type

Global player:Tsprite=New Tsprite

player.x=50
player.y=50
DrawImage player.sprite:timage,player.x,player.y
Flip
While Not KeyHit(key_q)

Wend


Dreamora(Posted 2008) [#2]
there is nothing wrong with that. assuming your sprite.jpg exists in the same folder as the sources, it should work.


z80jim(Posted 2008) [#3]
it exists, I know the image is good :( have you tried running it to see the error it gives? It gives it at the drawimage line.


Bremer(Posted 2008) [#4]
Your code does not throw any errors when I run it.


Perturbatio(Posted 2008) [#5]
it works fine for me, what error does it give you?

(Is the image in the same directory as your source?)


z80jim(Posted 2008) [#6]
"unhandled exception: attempt to access field or method of null object"
then it highlights the drawimage line. I did a drawrect line as follows,
drawrect player.x,player.y,50,50
and it works fine.


Dreamora(Posted 2008) [#7]
I assume you own BlitzMax right?
The demo is worthless (totally outdated and incompatible) and does NOT support the = within types at all.


z80jim(Posted 2008) [#8]
yes I know it is I have owned bmx for years, and it is up to date.


tonyg(Posted 2008) [#9]
Works here.
Might be worth double-checking the version of Bmax and posting the 'Help About' output.
If the code works for other people then it might be the image file so you might want to post a link to it.
Also try setting the sprite field within a Create() function rather than automatically. If that doesn't work then add a
 
if not sprite notify "Image file not loaded" 

and see what comes out.
Finally, what OS are you using?


z80jim(Posted 2008) [#10]
I'm using leopard, I used a catch to see if it actually was loading the image, and I found that according to my program the image doesn't exist. The name is exact, and the image is in the same folder...


slenkar(Posted 2008) [#11]
try making sprite a global instead,


tonyg(Posted 2008) [#12]
How do you know the program thinks it doesn't exist rather than has a problem loading it?
Have you tried another jpg and another image file (png, bmp)?
If it is a particular image file then post it here for somebody else to try.
Possibly the OS if everybody else here has tried on Win.
What level of Bmax are you using?


z80jim(Posted 2008) [#13]
I tried doing this outside of a type the why I normally would, and it still wouldn't work. I checked with other lines of loading code that I've written that work, and they're identical except for the name. I tried loading another image, again in the same directory and it still didn't work. Here's my latest code, slightly changed but still not running.

Graphics 640,480
Type Tsprite
Field sprite:timage=LoadImage("sprite.jpg",0)
Field x:Int
Field y:Int
End Type

Global player:Tsprite=New Tsprite

player.x=50
player.y=50
If sprite:timage=Null
Print "null image"
End
EndIf
While Not KeyHit(key_q)
DrawImage player.sprite:timage,player.x,player.y
Flip
Wend

excuse the not indenting but this is just testing I'll clean it up as soon as it works lol.


tonyg(Posted 2008) [#14]
How about point the loadimage to a file in another directory where you can get a program to load an image?
What version of Bmax are you using?

I checked with other lines of loading code that I've written that work, and they're identical except for the name.


I guess these programs still run OK? If so, what is different about them (e.g. different location etc). If they're in another location then use them but point the loadimage to the failing file in the other location.


skidracer(Posted 2008) [#15]
The trouble with that code is that the Global initialization of player could be executing before the call to Graphics and BlitzMax is unfortunately unable to loadimages when not in a graphics mode.

Try the following maybe to avoid a call to new TSprite before your program is actually running:

Global player:Tsprite

player=New Tsprite



tonyg(Posted 2008) [#16]
Really? So there needs to be some delay between creating graphics and loading images?


z80jim(Posted 2008) [#17]
problem solved.


tonyg(Posted 2008) [#18]
z80jim, can you say how? If it was Skids answer then why did your other programs not have the same problem if they're identical?
Skid, can you explain what the problem is? I understand what you're saying the cause is but not sure how the loadimage can fail as long as it is after the graphics command.


z80jim(Posted 2008) [#19]
I'm sorry I never even saw his post lol sorry skid!
I asked my dad to take a look, and he fixed it. Here is the updated code, with the fix noted.

Graphics 640,480
Type Tsprite
Field sprite : TImage'I was loading the image here... you can't do that because when the program comes to this line it should be a "general" line of code.
Field y:Int
End Type

Global player:Tsprite=New Tsprite

player.x=50
player.y=50
player.sprite =LoadImage("sprite.png")'after creating the tsprite "player", you are free to load the Timage with an image.

If player.sprite=Null
Print "null image"
EndIf

While Not KeyHit(key_q)
DrawImage player.sprite,player.x,player.y
Flip
Wend


Gabriel(Posted 2008) [#20]
TonyG: I think what Skidracer is saying is that initializers are evaluated once, as constants, when the type is initialized, and then that value is tucked away somewhere. I think he's saying that the initializer is not called on every new instance.

Which, if true, seems like a bug to me.


Brucey(Posted 2008) [#21]
z80jim, there was nothing wrong with your code, apart from the bit that ski pointed out.

you can't do that because when the program comes to this line it should be a "general" line of code.

Doing this:
Field sprite:timage=LoadImage("sprite.jpg",0)

is perfectly valid... as long as Graphics mode has started by the time LoadImage is called.

What version of BlitzMax are you using?
It's interesting that other people had this working, when you didn't.


z80jim(Posted 2008) [#22]
I don't know the exact number, but it IS up to date. I can't claim to be an expert, I didn't understand what ski said, and I was repeating what my dad said. Since a type isn't referring to a specific "object" you can't load the image there, rather have to do it later.


Brucey(Posted 2008) [#23]
Try taking your original example, and change the word "Global" to "Local" and it should work as you had originally expected :-)

Globals appear to be initialized "out of order", which is news to most people... me included.


Dreamora(Posted 2008) [#24]
globals initialization always worked different.
Within a function / method they behave even worse. If you have global someglob:ttype = new ttype this is a const initialize. it won't create a second instance. if you want a second one you must put the definition and instance creation on different lines.

Thats hard to catch and very totally not documented. Most learned it the "head against the bricks" way me including a long time ago ...


Brucey(Posted 2008) [#25]
If you have global someglob:ttype = new ttype this is a const initialize. it won't create a second instance.

I find this useful in Functions :-)

But I didn't realise it would initialise the variable before normal code got to run. I suppose because I've never had code in my functions in front of a Global variable...

Fun fun :o)


Dreamora(Posted 2008) [#26]
It is actually usefull as it allows you to do a "first run" init without the annoying if checks so you safe performance.
But it is a thing you will definitely fail to grasp on the first time.


z80jim(Posted 2008) [#27]
ok thanks for the replies :) it was really helpful!