'Memory Access Violation"
Blitz3D Forums/Blitz3D Beginners Area/'Memory Access Violation"
| ||
I keep getting this error message when running my compiled code saying "Memory Access Violation". It happens in the first second of the program being run. Why is this happening? Here is my code:; map editor Graphics3D 800, 600, 32, 2 SetBuffer BackBuffer() AppTitle("Map Editor v1.0") Global t_menu = LoadImage("graphics\t_menu.bmp") MaskImage t_menu, 0, 255, 0 Global b_menu = LoadImage("graphics\b_menu2.bmp") MaskImage b_menu, 0, 255, 0 Global file = LoadImage("graphics\file.bmp") MaskImage file, 255, 255, 0 Global quit = LoadImage("graphics\quit.bmp") MaskImage quit, 255, 255, 0 Global n = LoadImage("graphics\n.bmp") MaskImage n, 255,255,255 Global p = LoadImage("graphics\p.bmp") MaskImage p, 255, 255, 255 Global tiles = LoadAnimImage("\Tiles\Terrains\terrain.bmp",64,64,0,5) MaskImage tiles, 255, 255, 255 Global pointer = LoadImage("graphics\mouse.bmp") Dim map(32, 24) Global currenttile#=1 Global mapx# = 32 Global mapy# = 24 Global gridon# = 0 Const erase#=0 While Not KeyHit(1) ; pointer coordinates p_x# = MouseX() p_y# = MouseY() Cls ; Button setup If ImagesOverlap(pointer, p_x#, p_y#, n, 101, 582) Then buttonon(n) If ImagesOverlap(pointer, p_x#, p_y#, n, 101, 582) And MouseHit(1) Then currenttile=currenttile+1 If currenttile > 4 Then currenttile = 1 If Not ImagesOverlap(pointer, p_x#, p_y#, n, 101, 582) Then buttonoff(n) If ImagesOverlap(pointer, p_x#, p_y#, p, 20, 582) Then button2on(p) If ImagesOverlap(pointer, p_x#, p_y#, p, 20, 582) And MouseHit(1) Then currenttile=currenttile-1 If currenttile < 0 Then currenttile = 4 If Not ImagesOverlap(pointer, p_x#, p_y#, p, 20, 582) Then button2off(p) If ImagesOverlap(pointer, p_x#, p_y#, quit, 73, 0) And MouseDown(1) Then End update() controls() Text 0,18,"X: "+MouseX() Text 0,28,"Y: "+MouseY() Text 0,38,"Press the 'G' key to enable the grid." Flip Wend End ; button mouse-over effects Function buttonon(n) FreeImage n n = LoadImage("Graphics\n2.bmp") End Function Function buttonoff(n) FreeImage n n = LoadImage("graphics\n.bmp") End Function Function button2on(p) FreeImage p p = LoadImage("graphics\p2.bmp") End Function Function button2off(p) FreeImage p p = LoadImage("graphics\p.bmp") End Function ; update Function update() For x#=0 To mapx# For y#=0 To mapy# DrawImage tiles, x#*64, y#*64,map(x#, y#) Next Next DrawImage t_menu, 0, 0 DrawImage file, 0, 0 DrawImage quit, 73, 0 DrawImage b_menu, 0, 540 DrawImage n, 101, 582 ; next button DrawImage p, 20, 582 ; previous button DrawImage tiles, 38, 540, currenttile End Function Function controls() tile_x# = MouseX()/64 tile_y# = MouseY()/64 DrawImage pointer, p_x, p_y ; mouse If MouseDown(1) And tile_x# < 32 And tile_y# < 24 Then map(tile_x#, tile_y#)=currenttile# If MouseDown(2) And tile_x# < 32 And tile_y# < 24 Then map(tile_x#, tile_y#)=0 If KeyHit(34) Then gridon# = +1 grid() End Function Function grid() If gridon# = 1 If gridon# > 1 Then gridon = 0 For x# = 0 To mapx# For y# = 0 To mapy# Rect x#*64, y#*64, 64, 64, 0 Next Next EndIf End Function |
| ||
Have you got Debug enabled? Otherwise the only errors you ever get are MAVs which don't tell yuo squat! |
| ||
Yes, I have debug enabled. Hmm.. I don't know what to do. So depressing. I deleted the grid function and everything involving it. Leaving me with the following code: ; map editor Graphics3D 800, 600, 32, 2 SetBuffer BackBuffer() AppTitle("Map Editor v1.0") Global t_menu = LoadImage("Graphics\t_menu.bmp") MaskImage t_menu, 0, 255, 0 Global b_menu = LoadImage("Graphics\b_menu.bmp") MaskImage b_menu, 0, 255, 0 Global file = LoadImage("Graphics\file.bmp") MaskImage file, 255, 255, 0 Global quit = LoadImage("Graphics\quit.bmp") MaskImage quit, 255, 255, 0 Global n = LoadImage("Graphics\n.bmp") MaskImage n, 255,255,255 Global p = LoadImage("Graphics\p.bmp") MaskImage p, 255, 255, 255 Global tiles = LoadAnimImage("\Tiles\Terrains\terrain.bmp",64,64,0,5) MaskImage tiles, 255, 255, 255 Global pointer = LoadImage("graphics\mouse.bmp") Dim map(32, 24) Global currenttile#=1 Global mapx# = 32 Global mapy# = 24 Const erase#=0 While Not KeyHit(1) ; pointer coordinates p_x# = MouseX() p_y# = MouseY() Cls ; Button setup If ImagesOverlap(pointer, p_x#, p_y#, n, 101, 582) Then buttonon(n) If ImagesOverlap(pointer, p_x#, p_y#, n, 101, 582) And MouseHit(1) Then currenttile=currenttile+1 If currenttile > 4 Then currenttile = 1 If Not ImagesOverlap(pointer, p_x#, p_y#, n, 101, 582) Then buttonoff(n) If ImagesOverlap(pointer, p_x#, p_y#, p, 20, 582) Then button2on(p) If ImagesOverlap(pointer, p_x#, p_y#, p, 20, 582) And MouseHit(1) Then currenttile=currenttile-1 If currenttile < 0 Then currenttile = 4 If Not ImagesOverlap(pointer, p_x#, p_y#, p, 20, 582) Then button2off(p) If ImagesOverlap(pointer, p_x#, p_y#, quit, 73, 0) And MouseDown(1) Then End update() controls() Text 0,18,"X: "+MouseX() Text 0,28,"Y: "+MouseY() Text 0,38,"Press the 'G' key to enable the grid." Flip Wend End ; button mouse-over effects Function buttonon(n) FreeImage n n = LoadImage("Graphics\n2.bmp") End Function Function buttonoff(n) FreeImage n n = LoadImage("graphics\n.bmp") End Function Function button2on(p) FreeImage p p = LoadImage("graphics\p2.bmp") End Function Function button2off(p) FreeImage p p = LoadImage("graphics\p.bmp") End Function ; update Function update() For x#=0 To mapx# For y#=0 To mapy# DrawImage tiles, x#*64, y#*64,map(x#, y#) Next Next DrawImage t_menu, 0, 0 DrawImage file, 0, 0 DrawImage quit, 73, 0 DrawImage b_menu, 0, 540 DrawImage n, 101, 582 ; next button DrawImage p, 20, 582 ; previous button DrawImage tiles, 38, 540, currenttile End Function Function controls() tile_x# = MouseX()/64 tile_y# = MouseY()/64 DrawImage pointer, p_x, p_y ; mouse If MouseDown(1) And tile_x# < 32 And tile_y# < 24 Then map(tile_x#, tile_y#)=currenttile# If MouseDown(2) And tile_x# < 32 And tile_y# < 24 Then map(tile_x#, tile_y#)=0 End Function Everything works like it should when I test run it, but once compiled into a .exe I am missing a few images, thus causing other parts of the program to not work. The images that are not showing up are n.bmp, n2.bmp, p.bmp, and p2.bmp. This is wierd :S Also, approximately 26 seconds the program gets the odd 'MAV' error.. |
| ||
I would guess it's because you are loading/freeing images on the fly so much like so:Function button2off(p) FreeImage p p = LoadImage("graphics\p.bmp") End FunctionI'm sure it would be better to just load all of the images at the beginning of the program and just Do or Don't draw the necessary ones. |
| ||
[edit] Arg! Someone beats me to it again. :P These lines: If ImagesOverlap(pointer, p_x#, p_y#, n, 101, 582) Then buttonon(n) If Not ImagesOverlap(pointer, p_x#, p_y#, n, 101, 582) Then buttonoff(n) cause the button image to be constantly freed and loaded. This is a very bad idea. While not syntactically wrong, it's probably causing chaos because it's being done so frequently. The best way is to load all your images outside of the main loop and then just display the correct image depending on whether you're pointing on the button, or not. Also, using global variable names of 'p' and 'n' is not such a good idea. They're not descriptive and simple variable names like this are often used for other things, like For/Next loops. |
| ||
Another reason you don't want to load them constantly, is that harddrive access is slower than memory access. Had this been a situation where you were loading from an old fashioned floppy disk, you would screamed at the agonizingly slow disk access. So I agree with the others: load them once at the beginning of your program, and then just draw them as needed. |
| ||
Thanks a ton guys! That got rid of the error. I also made the variables more obvious of what they are. I've learned alot here. Just one more problem, for some reason when I click the previous.bmp currenttile should subract 1 but it doesn't. Any clue why it's not? Again, here's my code: ; map editor Graphics3D 800, 600, 32, 2 SetBuffer BackBuffer() AppTitle("Map Editor v1.0") Global t_menu = LoadImage("Graphics\t_menu.bmp") MaskImage t_menu, 0, 255, 0 Global b_menu = LoadImage("graphics\b_menu.bmp") MaskImage b_menu, 0, 255, 0 Global file = LoadImage("graphics\file.bmp") MaskImage file, 255, 255, 0 Global quit = LoadImage("graphics\quit.bmp") MaskImage quit, 255, 255, 0 Global Next1 = LoadImage("graphics\n.bmp") MaskImage Next1, 255,255,255 Global next2 = LoadImage("graphics\n2.bmp") MaskImage next2, 255,255,255 Global previous = LoadImage("graphics\p.bmp") MaskImage previous, 255, 255, 255 Global previous2 = LoadImage("graphics\p2.bmp") MaskImage previous2, 255,255,255 Global tiles = LoadAnimImage("Tiles\Terrains\terrain.bmp",64,64,0,5) MaskImage tiles, 255, 255, 255 Global pointer = LoadImage("graphics\mouse.bmp") Dim map(32, 24) Global currenttile#=1 Global mapx# = 32 Global mapy# = 24 Global gridon# = 0 Const erase#=0 While Not KeyHit(1) ; pointer coordinates pointer_x# = MouseX() pointer_y# = MouseY() Cls update() DrawImage t_menu, 0, 0 DrawImage file, 0, 0 DrawImage quit, 73, 0 DrawImage b_menu, 0, 540 DrawImage tiles, 38, 540, currenttile DrawImage pointer, pointer_x, pointer_y ; Button setup If ImagesOverlap(pointer, pointer_x, pointer_y, Next1, 102, 582) Then DrawImage next2, 102, 582 If ImagesOverlap(pointer, pointer_x, pointer_y, Next1, 102, 582) And MouseHit(1) Then currenttile=currenttile+1 If currenttile > 4 Then currenttile = 0 If Not ImagesOverlap(pointer, pointer_x, pointer_y, next1, 102, 582) Then DrawImage Next1, 102, 582 If ImagesOverlap(pointer, pointer_x, pointer_y, previous, 20, 582) Then DrawImage previous2, 20, 582 If ImagesOverlap(pointer, pointer_x, pointer_y, previous, 20, 582) And MouseHit(1) Then currenttile=currenttile-1 If currenttile < 0 Then currenttile = 4 If Not ImagesOverlap(pointer, pointer_x, pointer_y, previous, 20, 582) Then DrawImage previous, 20, 582 If ImagesOverlap(pointer, pointer_x, pointer_y, quit, 73, 0) And MouseDown(1) Then End controls() Text 0,18,"X: "+MouseX() Text 0,28,"Y: "+MouseY() Text 0,38,"Press the 'G' key to enable the grid." Flip Wend End ; update Function update() For x#=0 To mapx# For y#=0 To mapy# DrawImage tiles, x#*64, y#*64,map(x#, y#) Next Next End Function Function controls() tile_x# = MouseX()/64 tile_y# = MouseY()/64 If MouseDown(1) And tile_x# < 32 And tile_y# < 24 Then map(tile_x#, tile_y#)=currenttile# If MouseDown(2) And tile_x# < 32 And tile_y# < 24 Then map(tile_x#, tile_y#)=0 If KeyHit(34) Then gridon# = +1 grid() End Function Function grid() If gridon# = 1 If gridon# > 1 Then gridon = 0 For x# = 0 To mapx# For y# = 0 To mapy# Rect x#*64, y#*64, 64, 64, 0 Next Next EndIf End Function |
| ||
You are using both currenttile(int?) & currenttile#(float?) Not sure if Blitz overlooks this. Also, as a matter of practive I always tend to use under scores between words (current_tile) - helps when you do stupid things like - currentttile and repeat letters within variable names. Rgds, |
| ||
I changed it to a int but I still get the same problem. |
| ||
The problem is your use of the command MouseHit(). Ironically, this is kinda similar to the image loading problem you encountered in the sense that you should only be doing it once per loop. You see, there is a buffer that holds the number of times that the mouse was hit since the last time you called the MouseHit() command. And every time you check that buffer with the MouseHit() command, the buffer is cleared (zeroed). In your code you check for a MouseHit() on this line: If ImagesOverlap(pointer, pointer_x, pointer_y, Next1, 102, 582) And MouseHit(1) Then currenttile=currenttile+1which is fine BUT then you check for it AGAIN on this line: If ImagesOverlap(pointer, pointer_x, pointer_y, previous, 20, 582) And MouseHit(1) Then currenttile=currenttile-1Now, since calling the MouseHit() command the first time cleared the MouseHit buffer, the second call to it will give you an incorrect result of zero hits. Do you understand this? To avoid this from happening you should only make ONE call to MouseHit() per loop of your game and save that value in a variable. Then you can check the value of that variable as many times as you want in your loop without it 'magically' changing value. At my Programming Tutorial, I give a few examples of how to do this in my code examples. Take a look. Here is one example: wkey = KeyDown(17) ;collect user input skey = KeyDown(31) ;It's a good practice to collect these inputs only once akey = KeyDown(30) ;per loop. This will prevent odd behaviors from happening, dkey = KeyDown(32) ;for instance if the state of a key changes between multiple mouse1 = MouseHit(1) ;checks of that key while still in the same loop. ;...later... If mouse1 = True ;check if left mouse button was pressed ;blah, blah, blah Also, just to be helpful, really long lines of code like this: If ImagesOverlap(pointer, pointer_x, pointer_y, Next1, 102, 582) Then DrawImage next2, 102, 582 If ImagesOverlap(pointer, pointer_x, pointer_y, Next1, 102, 582) And Mouse1 Then currenttile=currenttile+1 If currenttile > 4 Then currenttile = 0 If Not ImagesOverlap(pointer, pointer_x, pointer_y, next1, 102, 582) Then DrawImage Next1, 102, 582where you are using redundant If arguments can be reduced to a lot less code. This not only helps make it more readable, but actually makes it faster too since you are only performing the redundant check once. Try writing it like this (it works exactly the same way): If ImagesOverlap(pointer, pointer_x, pointer_y, Next1, 102, 582) DrawImage next2, 102, 582 If Mouse1 Then currenttile = currenttile + 1 If currenttile > 4 Then currenttile = 0 Else DrawImage Next1, 102, 582 EndIfYou see, we reduced the three ImagesOverlap checks to only one check. |
| ||
Thanks! Where on your website can I find this tutorial, I can't find it? |
| ||
?? The link is in my sig. BTW, I was editing my reply above some just a few minutes ago, so you might want to reread it, in case you didn't get the updated post. |
| ||
I'm all about speed, I'll make that syntax a habit. Thanks a ton! =) |