daft 2d graphics question
BlitzMax Forums/BlitzMax Beginners Area/daft 2d graphics question
| ||
I needed something to do to get into coding in BlitzMax so I figured I would write yet another space invaders clone. It was all going well till I get to the bit where I have to apply damage to the shields when a bullet or bomb hits them. Each shield is a TImage. Im probably being a div but I cant see how I can delete a group of pixels from the shield image. Initially I just thought I would have a small explosion bitmap and I could just remove my explosion image from my shield image. But looking through the help I cant see how I can do it. So.. please.. can someone explain to me how I am supposed to achieve what Im after ? Thanx |
| ||
a) there are no buffers that you can intermix b) you would be better off having several smaller images that you combine to make a shield and then remove one image at a time to represent a damage being made |
| ||
Or you could use LockImage/UnlockImage to remove pixels with WritePixel (you can't draw to a locked image). Not sure if there's a speed issue here, but it should be plenty fast enough for your purposes. |
| ||
There is a very bad speed drop if you do LockImage / UnlockImage. In this case you better stay on pixmap with the graphic if it happens often. (as lockimage will convert to image and back where back is the slowest part in the whole thing) |
| ||
ok.. here is another weird problem Im getting. Im probably juts doing things wrong. At the start of the program I loadimage('filename') into a Tpixmap. I have a shield type which has an TImage field which I use LoadImage ( pixmap, DYNAMICIMAGE ) to populate it in the New() method. When a shot hits the shield I then do a LockImage to a pixmap. I write some blank pixels then unlock it. The problem is very odd. I hit the first shield a few times and all is as it should be. Then when I move across and hit the next shield this shield now appears to contain all the damage from the first image plus the damage just inflicted. As so on on all the shields. Its as if the lockimage always locks the original image. As a final resort I changed the code so instead of the loadimage(pixmap) for each shield type i used loadimage('filename') and now everything works perfectly. Am I just doing it wrong or is this a bug of some sort ? I just wanted to load the image once then use a copy of it for each shield. Im sorry if the explanation is confusing. When I get some time I can try to reduce the code into a simple example. |
| ||
If you only have 1 shield image every damage will be drawn to that. If it shall be a different for any ship you will have to hold one for each of them, as you did. (doing over loading or copying. Just set it to all types does not help as this does not copy it, they all access the same image |
| ||
well.. I can see what you are saying. But.. if each loadimage(Piximage) really just creates a single TImage and all the shields point to the same image I would expect that when I hit the first shield and applied the damage to it then ALL the shields on the screen would show the same damage. But they do not. What happens on screen is : I hit the first shield. I do the lockimage on it.. apply the damage.. and unlock it. On the screen only the first shield shows damage. the other three are still undamaged. When I shoot the second shield.. I lock it.. apply the damage.. unlock it.. Now the first shield still has the original damage.. the second shield has the same damage as the first shield + the damage I just inflicted. it is almost like the lockimage is remembering the previous lockimage <shrug>. I guess its hard to explain. Hopefully when I get a working ( non working) simple example it might make more sense. |
| ||
Ah Now I got it ... That's indeed really strange ... The behavior that should happen ... at least if working "normal", it should be drawn to all images when applied to 1 shield as all point to the same image reference. But you say that this "backreference" happens on the pixmap step of lockimage which indicates that somehow the other images are not refreshed ... assuming that unlock creates a new reference still does not explain, why the change of the 2nd shield "knows" of the damage to the first. if the behavior with not refreshing was meant this way, then this is the bug, otherwise the not refreshing Are you using image:TIMAGE pixmap:TPixmap or int handles btw? in later it might be an error with that ... |
| ||
Im using TImage and TPixmap here is an example I knocked together. press space to cause damage to each shield in turn. press escape to end the program. Im now pretty sure Im doing something stupid. when you run it as it is the typeshield does a loadimage(pixmap,DYNAMICIMAGE). The damage appears as red blocks and carry over between shields. If you comment the loadimage and uncomment the loadimage line above that does not use the DYNAMICIMAGE parameter the damage appears as black dots and now work correctly. the image is a 44 x 32 4bit per pixel png. Global PixmapShield:TPixmap Type typeShield Field image:TImage Field x,y Method New() ' image = LoadImage(PixmapShield) image = LoadImage(PixmapShield,DYNAMICIMAGE) End Method Method draw() DrawImage(image,x,y) End Method Method hit(xhit, yhit) Local shieldPix:TPixmap shieldPix = LockImage( image,0 ) ' remove hit pixel WritePixel(shieldPix, xhit,yhit,255 Shl 16 ) WritePixel(shieldPix, xhit+1,yhit,255 Shl 16 ) WritePixel(shieldPix, xhit,yhit+1,255 Shl 16 ) WritePixel(shieldPix, xhit+1,yhit+1,255 Shl 16 ) UnlockImage(image,0) End Method End Type Graphics 640,480,0 loadGraphics() Global shieldList:typeShield[4] init() play() End Function play() Local shield:typeShield Local s Local currentShield While Not KeyHit(KEY_Escape) Cls If KeyHit(KEY_Space) Then Local x,y x = Rand(0,20) * 2 y = Rand(0,20) * 2 shieldList[currentShield].hit(x,y) currentShield = ( currentShield + 1 ) Mod 4 End If For s = 0 To 3 shieldList[s].draw() Next Flip End While End Function Function loadGraphics() PixmapShield = LoadPixmap("images\shield.png") End Function Function init() Local shield:typeShield shield = New typeShield shield.x = 50 shield.y = 300 shieldList[0] = shield shield = New typeShield shield.x = 150 shield.y = 300 shieldList[1] = shield shield = New typeShield shield.x = 250 shield.y = 300 shieldList[2] = shield shield = New typeShield shield.x = 350 shield.y = 300 shieldList[3] = shield End Function |
| ||
OK.. so I changed my program so each new shield does a LoadImage(pixmap) without the DYNAMICIMAGE parameter and everything works fine now. Which is odd because I thought you had to supply the DYNAMICIMAGE parameter if you wanted to lock it. |