problem with type usage
BlitzMax Forums/BlitzMax Programming/problem with type usage
| ||
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 |
| ||
there is nothing wrong with that. assuming your sprite.jpg exists in the same folder as the sources, it should work. |
| ||
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. |
| ||
Your code does not throw any errors when I run it. |
| ||
it works fine for me, what error does it give you? (Is the image in the same directory as your source?) |
| ||
"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. |
| ||
I assume you own BlitzMax right? The demo is worthless (totally outdated and incompatible) and does NOT support the = within types at all. |
| ||
yes I know it is I have owned bmx for years, and it is up to date. |
| ||
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? |
| ||
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... |
| ||
try making sprite a global instead, |
| ||
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? |
| ||
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. |
| ||
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. |
| ||
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 |
| ||
Really? So there needs to be some delay between creating graphics and loading images? |
| ||
problem solved. |
| ||
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. |
| ||
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 |
| ||
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. |
| ||
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. |
| ||
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. |
| ||
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. |
| ||
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 ... |
| ||
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) |
| ||
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. |
| ||
ok thanks for the replies :) it was really helpful! |