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. |