Code w/ animation creates "Illegal Memory Address"
Blitz3D Forums/Blitz3D Programming/Code w/ animation creates "Illegal Memory Address"
| ||
I have rewritten a program of mine with a different theme now, and it now has an animated player (or was supposed to), and with this code, and it unfortunately, gives me an "Illegal Memory Address" message when I actually go and play it. I'm not too sure where that would occur, since all of my graphics do exist. This is the weirdest thing I believe I've ever seen. Here's the code below:; Plasmorg.bb - This is the source code for the game project, "Plasmorg: Star of Celestial Combat" ; (c)2006, Robert A. Morin, RAM Digital Media ; ------------------------------------------- ; First, set the graphics resolution to 640x480 Graphics3D 800,600 ; Initialize the default settings for AutoMidHandle and BackBuffer AutoMidHandle True SetBuffer BackBuffer() ; Now, load in the images for the background and foreground images ; This first image is the red/purple/magenta smoke in the background Global redimage = LoadImage("redsmoke.bmp") ; The front image is the yellow/cyan/periwinkle image of smoke Global yellowimage = LoadImage("yellowsmoke.bmp") ; Now, load in the spooky background sound in the background Global backsound = LoadSound("background.wav") Global bulletsound = LoadSound("zapper.wav") Global magicsound = LoadSound("magic.wav") Global explosionsound = LoadSound("explode.wav") ; Now, take a variable to track the scrolling of these images scrolly = 0 ; The following are the constants used for this game Const PLAYERSPEED = 10 Const ENEMYSPEED = 5 Const NORMALBULLET = 1, MISSILE = 2 ; Below, load the type used to move the player's object around the screen Type player Field x, y ; These define the coordinates that the player moves on Field frame ; This defines the frames that are drawn from the animation Field collision ; This defines the collision done between you and your enemy Field hits ; These are the hits that you knock down your enemy with Field image ; This defines the image for the player End Type Type enemy Field x, y ; These define the coordinates that the enemy moves on Field xv, yv ; These define the velocity that the enemy AI uses Field image ; This defines the image that the enemy uses End Type Type bullet Field x, y ; These define the coordinates that the bullet takes Field image ; This is the image definition for the bullet Field bullettype ; This defines whether you have a short spike or a magic brick block End Type ; Now, the following will create the player for the game ; Provide the starting values for the player and the enemy Global player.player = New player player\x = 400 player\y = 400 player\frame = 0 player\collision = 0 player\image = LoadAnimImage("player.bmp",64,64,0,6) Global enemy.enemy = New enemy enemy\x = 400 enemy\y = 200 enemy\xv = Rand(-5,5) enemy\yv = Rand(-5,5) enemy\image = LoadImage("enemy.bmp") ; Start playing the sound while the background loads LoopSound backsound PlaySound backsound ; Below starts the main loop for this part of the program While Not KeyDown(1) ; Next, make sure that the screen is clear before setting the smoke Cls ; Now, tile the red smoke below, and the brighter smoke on the second layer TileImage redimage,0,scrolly TileImage yellowimage,0,scrolly*2 ; Increase the value of the scrolly variable scrolly = scrolly + 1 ; Once the tracking variable exceeds the maximum value, reset it to 0 If scrolly >= ImageHeight(yellowimage) scrolly = 0 EndIf ; Display the image's coordinates for his movements Text 0,0, "X Coord:\> " + player\x Text 0,12, "Y Coord:\> " + player\y Text 0,500, "PLAYER SCORE:\> " + player\hits Text 0,512, "ENEMY SCORE :\> " + player\collision TestEnemyCollisions() TestKeys() CollisionCrash() If KeyDown(57) bullets.bullet = New bullet bullets\x = player\x bullets\y = player\y bullets\image = LoadImage("bullet.bmp") bullets\bullettype = NORMALBULLET PlaySound bulletsound EndIf If KeyDown(14) bullets.bullet = New bullet bullets\x = player\x bullets\y = player\y bullets\image = LoadImage("block.bmp") bullets\bullettype = MISSILE PlaySound magicsound EndIf UpDateBullets() ; Below is the enemy's image specifications enemy\image = LoadImage("enemy.bmp") ; Move the airplane in the same direction as the player does, thus, trying to crash into him If player\y > enemy\y enemy\y = enemy\y + ENEMYSPEED EndIf If player\x < enemy\x enemy\x = enemy\x - ENEMYSPEED EndIf If player\y < enemy\y enemy\y = enemy\y - ENEMYSPEED EndIf If player\x > enemy\x enemy\x = enemy\x + ENEMYSPEED EndIf ; The following will keep the enemy in motion and try to fly around you, and collide into you enemy\x = enemy\x + enemy\xv enemy\y = enemy\y + enemy\yv ; Once the enemy reaches the edges of the screen, move him back into range If enemy\x <= 0 enemy\x = 0 ElseIf enemy\x >= 800 enemy\x = 800 EndIf If enemy\y <= 0 enemy\y = 0 ElseIf enemy\y >= 600 enemy\y = 600 EndIf ; Now, draw the images of both you and the enemy DrawImage enemy\image, enemy\x, enemy\y DrawImage player\image, player\x, player\y, player\frame ; Once the left key is pressed, move the player in that direction and decrease the frame If KeyDown (203) player\x = player\x - PLAYERSPEED player\frame = player\frame - 1 EndIf ; Once the right key is pressed, move the player in that direction, and increase the frame If KeyDown (205) player\x = player\x + PLAYERSPEED player\frame = player\frame + 1 EndIf ; Once the down key is pressed, move the player in that direction, and decrease the frame If KeyDown (208) player\y = player\y + PLAYERSPEED player\frame = player\frame - 1 EndIf ; Once the up key is pressed, move the player in that direction, and increase the frame If KeyDown (200) player\y = player\y - PLAYERSPEED player\frame = player\frame + 1 EndIf ; Once the frame exceeds its maximum value, reset it to the zero position If player\frame > 5 player\frame = 0 ; One that same token, if the frame is lower than the minimum value, reset it to the middle frame ElseIf player\frame < 0 player\frame = 5 EndIf ; Set the frag limit to 20, and display the final score and game over If player\hits = 20 GameOver() EndIf If player\collision = 20 GameOver() EndIf If player\frame > 5 player\frame = 0 ElseIf player\frame < 0 player\frame = 5 EndIf ; Allow for a brief delay Delay 100 Flip Wend ; This officially ends the program loop Function TestEnemyCollisions() ; Reverse the enemy's velocity if he hits an edge of the screen If enemy\x < 0 enemy\xv = -enemy\xv EndIf If enemy\x > 800 enemy\xv = -enemy\xv EndIf If enemy\y < 0 enemy\yv = -enemy\yv EndIf If enemy\y > 600 enemy\yv = -enemy\yv EndIf End Function Function TestKeys() ; Once the left key is pressed, move the player in that direction and decrease the frame If KeyDown (203) player\x = player\x - PLAYERSPEED player\frame = player\frame - 1 EndIf ; Once the right key is pressed, move the player in that direction, and increase the frame If KeyDown (205) player\x = player\x + PLAYERSPEED player\frame = player\frame + 1 EndIf ; Once the down key is pressed, move the player in that direction, and decrease the frame If KeyDown (208) player\y = player\y + PLAYERSPEED player\frame = player\frame - 1 EndIf ; Once the up key is pressed, move the player in that direction, and increase the frame If KeyDown (200) player\y = player\y - PLAYERSPEED player\frame = player\frame + 1 EndIf End Function Function UpDateBullets() For bullets.bullet = Each bullet bullets\y = bullets\y - 5 DrawImage bullets\image,bullets\x,bullets\y If (ImagesOverlap(enemy\image,enemy\x,enemy\y,bullets\image,bullets\x,bullets\y)) PlaySound explosionsound Cls Text 300,300, "Enemy Down! Player Scores..." player\hits = player\hits + 1 Text 300,312, "Player:\> " + player\hits Text 300,324, "Enemy :\> " + player\collision Flip Delay 4000 ; Remove all bullets from the screen For bullets.bullet = Each bullet Delete bullets Next ; Place the positions of the enemy and yourself player\x = 400 player\y = 400 ; Load the player image player\image = LoadAnimImage("player.bmp",64,64,0,6) ; Now, place the enemy's position enemy\x = 400 enemy\y = 200 ; Provide the velocity range for the enemy enemy\xv = Rand (-5,5) enemy\yv = Rand (-5,5) Return EndIf If bullets\y = 0 Delete bullets EndIf Next End Function Function CollisionCrash() If (ImagesOverlap(player\image,player\x,player\y,enemy\image,enemy\x,enemy\y)) PlaySound explosionsound Cls Text 300,300, "The enemy crashed into you! Enemy Scores..." player\collision = player\collision + 1 Text 300,312, "Player:\> " + player\hits Text 300,324, "Enemy :\> " + player\collision Flip Delay 4000 ; Remove all bullets from the screen For bullets.bullet = Each bullet Delete bullets Next player\x = 400 player\y = 400 player\image = LoadAnimImage("player.bmp",64,64,0,6) enemy\x = 400 enemy\y = 200 enemy\xv = Rand(-5,5) enemy\yv = Rand(-5,5) EndIf End Function Function GameOver() Cls For bullets.bullet = Each bullet Delete bullets Next Text 300,300, "G A M E O V E R ! ! !" Text 300,312, "-----------------------" Text 300,324, "Final Score..." Text 300,336, "Player:\> " + player\hits Text 300,348, "Enemy :\> " + player\collision Text 0,512, "Press <ESC> to Quit: " WaitKey End Function Yeah, it's the same code as DodgeFlight, but I'm making an "RPG-Shooter" hybrid out of it now, just getting away from that flight thing altogether. It's gonna be called "Plasmorg." Weird name, but once you play it, you'll understand why I call it that, that is, once this "Illegal Memory Address" is resolved. |
| ||
When you load your images,player\image = LoadAnimImage("player.bmp",64,64,0,6) check that player\image does not equal 0 and that there are 6 frames in the image strip. If you could post the media too it would help in tracking down the problem. |
| ||
Okay, here's that little "Star of Combat" right here: ![]() |
| ||
I never had a "Illegal Memory Address", are you sure? Or do you mean "Memory Allocation Violation" ? Well first make sure to use Version 1.91. Then whenever a MAV pops up turn on the Debugging Mode and run it again, this may give you a more detailed information about the error. If you cannot find the error this way start using Debuglog at various positions inside your code to find the line that causes the error. You may also simply use "End" instead to find the line that causes the error. |
| ||
Well, the proof is in the pudding.![]() Sorry about this being so small, but that's ImageShack for ya. |
| ||
Not sure it matters but why do you keep reloading player.bmp? Can't see anything on the screenshot either. Finally, did you check player\image is populated as suggested by Shambler? |
| ||
Iron bob, I fonud that i get problems with animation stips that are an exact fit for the frames, IE, With your frame above, I would add another frame (or two) blank on the end of it. Strange, but worth a try? |
| ||
I think I've had something similar when trying to implement animated surface brushes, but I put it to one side and haven't revisited it. I'll give Cygnus's suggestion a go and see if that helps. |
| ||
Yeah, I added a blank frame, and it still does that. I'm sort of wondering if you can't mix animations in the background and the player at the same time. Maybe I need some rewriting of the code, I dunno. I'll have to sit down with this one tomorrow, I'm a bit bushed, had to put in a full day due to the President's Day holiday yesterday. I'm lucky I even have energy tonight to post. |
| ||
Your player\frame is getting to -1 and that is why it is crashing hereDrawImage player\image, player\x, player\y, player\frame The reason why it goes to -1 is that you call the function 'TestKeys()' which alters the frame number but you are not checking if the frame has gone <0 or >5 before the DrawImage command. I would put the code which checks the frame number at the end of the TestKeys() function. Currently you are doing the check after the DrawImage command and you are doing it twice... ; Once the frame exceeds its maximum value, reset it to the zero position If player\frame > 5 player\frame = 0 ; One that same token, if the frame is lower than the minimum value, reset it to the middle frame ElseIf player\frame < 0 player\frame = 5 EndIf ; Set the frag limit to 20, and display the final score and game over If player\hits = 20 GameOver() EndIf If player\collision = 20 GameOver() EndIf If player\frame > 5 player\frame = 0 ElseIf player\frame < 0 player\frame = 5 EndIf You are also duplicating the KeyDown tests, once in the main routine and again in the TestKeys() function, I think you have a code skeleton there ;) Running your code in debug mode you should have got an 'Image frame out of range' error. |
| ||
Ah, yeah, now that makes sense, and that was the culprit. Now it's playing without too much difficulty now. This plays the way it was intended to now. Now that that's done, now it's time to introduce the joystick to the mix (make it play like an XBox game to a point). Maybe the trigger buttons to fire the magic zaps and cast mass-magic casts on the enemies (this is sort of like an RPG/Shooter/Sci-Fi hybrid. It's gonna have a weird theme, even more so than DodgeFlight had. It's gonna look more 3D than ever before, too. It's gonna look like flying through a lava lamp/plasma ball in the background. Looks like a winner of a game theme here. |
| ||
Now I ran into a problem making the enemy animated, the same message came about with this one. Here's the updated code below, and the image of the enemy's animation:; Plasmorg.bb - This is the source code for the game project, "Plasmorg: Star of Celestial Combat" ; (c)2006, Robert A. Morin, RAM Digital Media ; ------------------------------------------- ; First, set the graphics resolution to 640x480 Graphics3D 800,600 ; Initialize the default settings for AutoMidHandle and BackBuffer AutoMidHandle True SetBuffer BackBuffer() ; Now, load in the images for the background and foreground images ; This first image is the red/purple/magenta smoke in the background Global redimage = LoadImage("redsmoke.bmp") ; The front image is the yellow/cyan/periwinkle image of smoke Global yellowimage = LoadImage("yellowsmoke.bmp") ; Now, load in the spooky background sound in the background Global backsound = LoadSound("background.wav") Global bulletsound = LoadSound("zapper.wav") Global magicsound = LoadSound("magic.wav") Global explosionsound = LoadSound("explode.wav") ; Now, take a variable to track the scrolling of these images scrolly = 0 ; The following are the constants used for this game Const PLAYERSPEED = 10 Const ENEMYSPEED = 10 Const NORMALBULLET = 1, MISSILE = 2 ; Below, load the type used to move the player's object around the screen Type player Field x, y ; These define the coordinates that the player moves on Field frame ; This defines the frames that are drawn from the animation Field collision ; This defines the collision done between you and your enemy Field hits ; These are the hits that you knock down your enemy with Field image ; This defines the image for the player End Type Type enemy Field x, y ; These define the coordinates that the enemy moves on Field xv, yv ; These define the velocity that the enemy AI uses Field image ; This defines the image that the enemy uses Field frame ; This will define the frames used in the rotation of the enemy when he moves End Type Type bullet Field x, y ; These define the coordinates that the bullet takes Field image ; This is the image definition for the bullet Field bullettype ; This defines whether you have a short spike or a magic brick block Field frame ; This defines the frame for the animations when the bullet or missile is fired End Type ; Now, the following will create the player for the game ; Provide the starting values for the player and the enemy Global player.player = New player player\x = 400 player\y = 400 player\frame = 0 player\collision = 0 player\image = LoadAnimImage("player.bmp",64,64,0,6) Global enemy.enemy = New enemy enemy\x = 400 enemy\y = 200 enemy\xv = Rand(-5,5) enemy\yv = Rand(-5,5) enemy\image = LoadAnimImage("enemy.bmp",64,64,0,8) enemy\frame = 0 ; Start playing the sound while the background loads LoopSound backsound PlaySound backsound ; Below starts the main loop for this part of the program While Not KeyDown(1) ; Next, make sure that the screen is clear before setting the smoke Cls ; Now, tile the red smoke below, and the brighter smoke on the second layer TileImage redimage,0,scrolly TileImage yellowimage,0,scrolly*2 ; Increase the value of the scrolly variable scrolly = scrolly + 1 ; Once the tracking variable exceeds the maximum value, reset it to 0 If scrolly >= ImageHeight(yellowimage) scrolly = 0 EndIf ; Display the image's coordinates for his movements Text 0,0, "X Coord:\> " + player\x Text 0,12, "Y Coord:\> " + player\y Text 0,500, "PLAYER SCORE:\> " + player\hits Text 0,512, "ENEMY SCORE :\> " + player\collision TestEnemyCollisions() TestKeys() CollisionCrash() If KeyDown(57) bullets.bullet = New bullet bullets\x = player\x bullets\y = player\y bullets\image = LoadAnimImage("bullet.bmp",12,12,0,4) bullets\bullettype = NORMALBULLET bullets\frame = 0 PlaySound bulletsound EndIf If KeyDown(14) bullets.bullet = New bullet bullets\x = player\x bullets\y = player\y bullets\image = LoadAnimImage("block.bmp",32,32,0,4) bullets\bullettype = MISSILE bullets\frame = 0 PlaySound magicsound EndIf UpDateBullets() ; Below is the enemy's image specifications enemy\image = LoadAnimImage("enemy.bmp",64,64,0,8) If enemy\frame > 7 enemy\frame = 0 ElseIf enemy\frame < 0 enemy\frame = 7 EndIf ; Move the enemy in the same direction as the player does, thus, trying to crash into him If player\y > enemy\y enemy\y = enemy\y + ENEMYSPEED enemy\frame = enemy\frame - 1 EndIf If player\x < enemy\x enemy\x = enemy\x - ENEMYSPEED enemy\frame = enemy\frame - 1 EndIf If player\y < enemy\y enemy\y = enemy\y - ENEMYSPEED enemy\frame = enemy\frame + 1 EndIf If player\x > enemy\x enemy\x = enemy\x + ENEMYSPEED enemy\frame = enemy\frame + 1 EndIf ; The following will keep the enemy in motion and try to fly around you, and collide into you enemy\x = enemy\x + enemy\xv enemy\y = enemy\y + enemy\yv ; Once the enemy reaches the edges of the screen, move him back into range If enemy\x <= 0 enemy\x = 0 ElseIf enemy\x >= 800 enemy\x = 800 EndIf If enemy\y <= 0 enemy\y = 0 ElseIf enemy\y >= 600 enemy\y = 600 EndIf ; Now, draw the images of both you and the enemy DrawImage enemy\image, enemy\x, enemy\y, enemy\frame DrawImage player\image, player\x, player\y, player\frame ; Once the left key is pressed, move the player in that direction and decrease the frame If KeyDown (203) player\x = player\x - PLAYERSPEED player\frame = player\frame - 1 EndIf ; Once the right key is pressed, move the player in that direction, and increase the frame If KeyDown (205) player\x = player\x + PLAYERSPEED player\frame = player\frame + 1 EndIf ; Once the down key is pressed, move the player in that direction, and decrease the frame If KeyDown (208) player\y = player\y + PLAYERSPEED player\frame = player\frame - 1 EndIf ; Once the up key is pressed, move the player in that direction, and increase the frame If KeyDown (200) player\y = player\y - PLAYERSPEED player\frame = player\frame + 1 EndIf ; Once the frame exceeds its maximum value, reset it to the zero position If player\frame > 5 player\frame = 0 ; One that same token, if the frame is lower than the minimum value, reset it to the middle frame ElseIf player\frame < 0 player\frame = 5 EndIf ; Set the frag limit to 20, and display the final score and game over If player\hits = 20 GameOver() EndIf If player\collision = 20 GameOver() EndIf If player\frame > 5 player\frame = 0 ElseIf player\frame < 0 player\frame = 5 EndIf ; Allow for a brief delay Delay 100 Flip Wend ; This officially ends the program loop Function TestEnemyCollisions() ; Reverse the enemy's velocity if he hits an edge of the screen If enemy\x < 0 enemy\xv = -enemy\xv EndIf If enemy\x > 800 enemy\xv = -enemy\xv EndIf If enemy\y < 0 enemy\yv = -enemy\yv EndIf If enemy\y > 600 enemy\yv = -enemy\yv EndIf End Function Function TestKeys() ; Once the left key is pressed, move the player in that direction and decrease the frame If KeyDown (203) player\x = player\x - PLAYERSPEED EndIf ; Once the right key is pressed, move the player in that direction, and increase the frame If KeyDown (205) player\x = player\x + PLAYERSPEED EndIf ; Once the down key is pressed, move the player in that direction, and decrease the frame If KeyDown (208) player\y = player\y + PLAYERSPEED EndIf ; Once the up key is pressed, move the player in that direction, and increase the frame If KeyDown (200) player\y = player\y - PLAYERSPEED EndIf End Function Function UpDateBullets() For bullets.bullet = Each bullet bullets\y = bullets\y - 5 bullets\frame = bullets\frame + 1 If bullets\frame > 3 bullets\frame = 0 ElseIf bullets\frame < 0 bullets\frame = 3 EndIf DrawImage bullets\image,bullets\x,bullets\y,bullets\frame If (ImagesOverlap(enemy\image,enemy\x,enemy\y,bullets\image,bullets\x,bullets\y)) PlaySound explosionsound Cls Text 300,300, "Enemy Down! Player Scores..." player\hits = player\hits + 1 Text 300,312, "Player:\> " + player\hits Text 300,324, "Enemy :\> " + player\collision Flip Delay 4000 ; Remove all bullets from the screen For bullets.bullet = Each bullet Delete bullets Next ; Place the positions of the enemy and yourself player\x = 400 player\y = 400 ; Load the player image player\image = LoadAnimImage("player.bmp",64,64,0,6) ; Now, place the enemy's position enemy\x = 400 enemy\y = 200 ; Provide the velocity range for the enemy enemy\xv = Rand (-5,5) enemy\yv = Rand (-5,5) Return EndIf If bullets\y = 0 Delete bullets EndIf Next End Function Function CollisionCrash() If (ImagesOverlap(player\image,player\x,player\y,enemy\image,enemy\x,enemy\y)) PlaySound explosionsound Cls Text 300,300, "The enemy crashed into you! Enemy Scores..." player\collision = player\collision + 1 Text 300,312, "Player:\> " + player\hits Text 300,324, "Enemy :\> " + player\collision Flip Delay 4000 ; Remove all bullets from the screen For bullets.bullet = Each bullet Delete bullets Next player\x = 400 player\y = 400 player\image = LoadAnimImage("player.bmp",64,64,0,6) enemy\x = 400 enemy\y = 200 enemy\xv = Rand(-5,5) enemy\yv = Rand(-5,5) EndIf End Function Function GameOver() Cls For bullets.bullet = Each bullet Delete bullets Next Text 300,300, "G A M E O V E R ! ! !" Text 300,312, "-----------------------" Text 300,324, "Final Score..." Text 300,336, "Player:\> " + player\hits Text 300,348, "Enemy :\> " + player\collision Text 0,512, "Press <ESC> to Quit: " WaitKey End Function Now the animation of the enemy: ![]() |
| ||
Now that I'm looking at it, do you think that the velocity values have something to do with it? I'm sort of curious about that now... I even wonder if you can mix animations with AI for the computer, that's what's getting me concerned. To me, it seems like that may be the problem, if the enemy's trying to follow you around, there's obviously no way that the CPU can rotate the enemy around while he's chasing and dodging into you, that would be cool if he did (sort of like an asteroid or something like that). |
| ||
This is a similar problem, you are adjusting the enemy\frame value but you are not testing the result in the right place. Just move the test to here ; Move the enemy in the same direction as the player does, thus, trying to crash into him If player\y > enemy\y enemy\y = enemy\y + ENEMYSPEED enemy\frame = enemy\frame - 1 EndIf If player\x < enemy\x enemy\x = enemy\x - ENEMYSPEED enemy\frame = enemy\frame - 1 EndIf If player\y < enemy\y enemy\y = enemy\y - ENEMYSPEED enemy\frame = enemy\frame + 1 EndIf If player\x > enemy\x enemy\x = enemy\x + ENEMYSPEED enemy\frame = enemy\frame + 1 EndIf If enemy\frame > 7 enemy\frame = 0 ElseIf enemy\frame < 0 enemy\frame = 7 EndIf Also you still have the duplicate testing of the keys and the duplicate checking of the player\frame value in there. |
| ||
Okay, that fixed things. I also tried code that you can be shot down and the enemy scores if you trip over your own bullets, too. Unfortunately, this also means that once you shoot, you will shoot yourself down right away, which isn't what I was intending. I wanted this, so that if you are chasing the enemy around, if you run into your bullets before they go off the screen, the bullet will hit you or the enemy. If the bullet hits you, it's just like the enemy crashing into you, he will score. That may be impossible to code the bullet to penetrate you well after you shoot it, not right when you shoot it on contact. Also, I believe that setting about three different difficulty tiers won't be out of the question, either. Like, to increase the speed of the bullets and the enemy when you select a more difficult round. Might want to consider programming this around my joystick, make it play like an XBox or PS2-style game, all that should make this game complete once and for all, just need a title screen, a menu, and maybe more enemies to shoot at, then we got it going gold. |