Drawimage memory acess error.
Monkey Forums/Monkey Beginners/Drawimage memory acess error.
| ||
I am new to class and method/ object oriented programming. I was a wiz at darkbasic but im having a bit of trouble here. In my very short program I am just trying to get the bullet object drawn on screen when I click the mouse. I keep getting memory access error though when I put the DrawImage command. Can you tell me what Im doing wrong here ? Import mojo Class Game Extends App Field b:bullet Method OnCreate () SetUpdateRate 60 End Method OnRender () Cls 32, 64, 128 ' Clear screen DrawImage b.image2, b.x, b.y, 0, 0.25, 0.25 End Method OnUpdate () If MouseHit(MOUSE_LEFT) Then b = New bullet b.image2 = LoadImage ("bullet.png", 1, Image.MidHandle) 'DrawImage b.image2, b.x, b.y, 0, 0.25, 0.25 Print "Mouse Clicked" End If End End Class bullet Field x:Float = 100 Field y:Float = 100 Field image2:Image End Function Main () New Game End |
| ||
Hello, The problem occurs because the Methods OnUpdate() and OnRender() are executed at about 60 frames. When you try to access the image of your bullet (first frame) the chance that you already clicked and an bullet object has been created is very low. You can simply check if a bullet has been created before using. Instead of this Method OnRender () Cls 32, 64, 128 ' Clear screen DrawImage b.image2, b.x, b.y, 0, 0.25, 0.25 End you would use something like this. Method OnRender () Cls 32, 64, 128 ' Clear screen If b<> null then ' Check if bullet has been created DrawImage b.image2, b.x, b.y, 0, 0.25, 0.25 Endif End I am new to class and method/ object oriented programming. The most important thing to understand is probably to realize that two bullets created via new are unrelated to each other. The best way to see this yourself is to use DebugStop() (glfw / desktop only) which halts the program and allows you to see the differences. Import mojo Class Game Extends App Field b1:bullet Field b2:bullet Method OnCreate () SetUpdateRate 60 b1 = New bullet b2 = New bullet b1.x = 100 b2.x = 200 DebugStop() End Method OnRender () Cls() End Method OnUpdate () End End Class bullet Field x:Float = 100 Field y:Float = 100 Field image2:Image End Function Main () New Game End |
| ||
ah got it thanks that did the trick! I was trying to draw the image that did not exist. BTW how are you posting the code block ? /code ? |
| ||
There is a little forumcodes button just above the answer box ;) EDIT: I updated the above post, please take a look. |
| ||
I did and thanks :) |
| ||
Well Im making progress and I am loving monkey x. So much so I bought it all ignition, rube and jungle :) I have another question though. How do I destroy an object ? Bear with me I am new to object oriented programming. In my program I want to kill the bullet once it reaches the top of the screen so that another can be created. I tried to Null the handle but monkey does not like that. I Noted the point in the code where I am trying to destroy the object/class. Thanks for the help! If b <> Null Then If b.y > 0 Then DrawImage b.image2, b.x, b.y, 0, 0.25, 0.25 Else b = Null ' HOW DO I DESTROY THIS ??????????????????????????????? End If b.y > 0 Then b.y = b.y - 10 End End The whole program Import mojo Class Game Extends App Field b:bullet Field created:Int = 0 Field mx:Float Field my:Float Method OnCreate () SetUpdateRate 60 End Method OnRender () Cls 32, 64, 128 ' Clear screen If b <> Null Then If b.y > 0 Then DrawImage b.image2, b.x, b.y, 0, 0.25, 0.25 Else b = Null ' HOW DO I DESTROY THIS ??????????????????????????????? End If b.y > 0 Then b.y = b.y - 10 End End End Method OnUpdate () If b = Null If MouseHit(MOUSE_LEFT) Then ' b = New bullet 'b.image2 = LoadImage ("bullet.png", 1, Image.MidHandle) 'DrawImage b.image2, b.x, b.y, 0, 0.25, 0.25 b = New bullet b.image2 = LoadImage ("bullet.png", 1, Image.MidHandle) created = 1 Print "Mouse Clicked" End If End End End Class bullet Field x:Float = MouseX() Field y:Float = MouseY() Field image2:Image End Function Main () New Game End |
| ||
Hello, The problem comes from the fact that once the object has been set to null, none of its contents (fields) are accessible anymore. A hotfix would be to check for null before performing anyaction. Import mojo Class Game Extends App Field b:bullet Field created:Int = 0 Field mx:Float Field my:Float Method OnCreate () SetUpdateRate 60 End Method OnRender () Cls 32, 64, 128 ' Clear screen If b <> Null Then If b.y > 0 Then DrawImage b.image2, b.x, b.y, 0, 0.25, 0.25 Else b = Null ' HOW DO I DESTROY THIS ??????????????????????????????? End If b <> Null and b.y > 0 Then b.y = b.y - 10 End End End Method OnUpdate () If b = Null If MouseHit(MOUSE_LEFT) Then ' b = New bullet 'b.image2 = LoadImage ("bullet.png", 1, Image.MidHandle) 'DrawImage b.image2, b.x, b.y, 0, 0.25, 0.25 b = New bullet b.image2 = LoadImage ("bullet.png", 1, Image.MidHandle) created = 1 Print "Mouse Clicked" End If End End End Class bullet Field x:Float = MouseX() Field y:Float = MouseY() Field image2:Image End Function Main () New Game End That being said, it is advisable to use collections of multiple objects. One of the things thats makes programming with objects much better than conventional programming is the idea to move actions from your Game class to the object itself (the bullet updates itself). This way you know if bullet misbehaves that the error is very likely to be found in bullet itself and no where else. Compared with classical programming were you have a lot of global variables that are accessible from everywhere you can now better determine whos fault what is and the scalability of your programs increase. In this example a bullet list has been introduced to hold multiple bullets. Please also note that calling LoadImage() when ever you click will also very likely slow down your game. It should also be stated that putting behaviour/thinking/logic into onrender in not advisable as OnRender will slow down/ some misbehaviour might occur due to the fact that OnRender is sometimes called without reason and then your games continues to play but is also paused (e.g. OnUpdate is paused but OnRender() not because the window needs to be redrawn). Import mojo Class Game Extends App Field bulletList:List<bullet> = New List<bullet> ' A list of multiple bullets Field bulletImage:Image Field created:Int = 0 Field mx:Float Field my:Float Method OnCreate () SetUpdateRate 60 bulletImage = LoadImage("bullet.png", 1, Image.MidHandle) ' Dont reload the same image, we only need it once End Method OnRender () Cls 32, 64, 128 ' Clear screen ' take each bullet stored in bulletlist and step-by-step but them into i For Local i:bullet = EachIn bulletList' i changes as we store bullets here temporary i.OnRender() Next End Method OnUpdate () ' take each bullet stored in bulletlist and step-by-step but them into i For Local i:bullet = EachIn bulletList ' i changes as we store bullets here temporary i.OnUpdate() ' Next If bulletList.Count() < 10 Then If MouseHit(MOUSE_LEFT) Then ' b = New bullet 'b.image2 = LoadImage ("bullet.png", 1, Image.MidHandle) 'DrawImage b.image2, b.x, b.y, 0, 0.25, 0.25 Local b:bullet = New bullet b.image2 = bulletImage created = created + 1 b.listEntry = bulletList.AddLast(b) ' add b to the list; the list returns a listentry where b has been put into Print "Mouse Clicked" End If EndIf End End Class bullet Field x:Float = MouseX() Field y:Float = MouseY() Field image2:Image Field listEntry:list.Node<bullet> ' Store a list entry for bullets Method OnRender() DrawImage image2, x, y, 0, 0.25, 0.25 End Method OnUpdate() If y > 0 Then y = y - 10 ElseIf listEntry <> Null listEntry.Remove() ' Remove this exact bullet from the list End End End Function Main () New Game End |
| ||
Thanks very much for the restructure. As I am new I was not sure if I could load the image just 1 time and I was unsure as to where best to put the actions. I tried unsuccessfully to re arrange the code in a better fashion but was struggling due to my lack of experience with this type of language. (Hence the reason of just trying a small program to get things moving and working the way I want) The list also solves the next problem I was looking at which is multiple bullets. A++ for the comments this is exactly what I needed to help me get my head around the structure! This will keep me bust for a while and saved me a ton of head scratching moments. Thanks again! |