Drawing pixels on top of player sprite

BlitzMax Forums/BlitzMax Beginners Area/Drawing pixels on top of player sprite

SpectreNectar(Posted 2010) [#1]
Hi there,

I'm new to Blitz Basic and would like to know the following:


How would I go about creating a lovely stoneskin effect for the characters in my RPG game, where grayscale values from the sprite's pixels are drawn from the bottom up (like a mosaic transition) with alpha?

:-)

Actually, I got stuck when I couldn't find a loadAnimPixmap() like function, and figured I'd descripe what I am trying to do hoping one of you can point me in the right direction


Jesse(Posted 2010) [#2]
do you want to draw directly to the sprite? If that is the case, then that is a little bit advanced:
first you would have to load the image("LoadImage") or animated image("loadAnimImage")."LockImage" give you acces to the image pixmap. then You would need to use "ReadPixel" and "WritePixel" to access and modify the pixels in the image. the last two commands use integers, to write and read the colors from the pixmap. depending on what format the pixmap is, you would have to pass the color in that specific format.

now, I don't know how good your programming skills are but this might be a little too complicated for you. If you have an animation that mimics the effect then that is a lot simpler. All you have to do is load the animated sprite:
local width:int = 32 ' width of the sprite in the png
local height:int = 32 ' height of the sprite in the png
local first:int = 0 ' starting from the first sprite in the png(0,0)
local count:int = 6 ' the number of sprites to load
local image:timage = LoadAnimImage("image.png",width,height,first,count)

to draw an individual sprite:
local index:int = 3 ' the fourth sprite in animation. 
DrawImage(image,x,y,index)


note that first you have to put the image in the same directory as the same folder as your Bmax file or specify the directory of your image file for loading before executing.

If you post some code, it might be easier to help you as it might be easier to figure out what you are doing.
Anyway I hope this helps.


SpectreNectar(Posted 2010) [#3]
Nice!

I had a little trouble grasping the concept of making pixmaps from sprites as their functions seemed so different from each other, but "lockimage" was just what I was looking for :-)

I now have a character that dissolves into nothing slowly, hehe


Thanks so very much for your reply, this is what I came up with:

Method update()
	
	Local i% = (ply.dir Mod ply.animation.dirs)*ply.animation.length+ply.animation.frame
	Local temppix:TPixmap = LockImage(ply.animation.bmp, i)
	For Local t%=0 To 20
		Local a%, r%, g%, b%
		a = 255
		r = Rand(0,255)
		g = Rand(0,255)
		b = Rand(0,255)
		Local rgb% = 256*256*256*a + 256*256*b + 256*g + r
		WritePixel(temppix, Rand(temppix.width)-1, Rand(temppix.height)-1, rgb)
	Next
	UnlockImage(ply.animation.bmp, i)
EndMethod



SpectreNectar(Posted 2010) [#4]
"One" tiny more beginner question:
I'm now creating images on the fly each frame, and figure they should be deleted after they are drawn. I need another function.

-or-

The reason it "must" be each frame is that my sprite sizes are different and when they change they still need to have the effect applied to them. Is it better to make a huge image and possibly having to resize it or store a lot of unneccesary pixels? I'm also thinking of dublicating all creature sprites so I can use that for overlay effects such as my stoneskin (gray'ish sprite), and other things like blurring the character etc
Another option is plotting directly to the screen without using an image

Any thoughts?

Thanks!


chimaera(Posted 2010) [#5]
Is there a way for you to upload a small video of what you are doing? It would be a bit easier to see it.


SpectreNectar(Posted 2010) [#6]
It uses a tiny bit of memory but you can try it if you want:
http://www.64digits.com/download.php?name=HEdit5.zip&id=28480

up/down/left/right/ctrl/space/pageup/pagedown/mouse

Method draw()
		
		Local i% = (ply.dir Mod ply.animation.dirs)*ply.animation.length+ply.animation.frame
		
		Local imgply:TImage = ply.animation.bmp
		Local pixply:TPixmap = LockImage(imgply, i)
		Local imgdraw:TImage = CreateImage(pixply.width, pixply.height, 1, DYNAMICIMAGE|MASKEDIMAGE|FILTEREDIMAGE)
		Local pixdraw:TPixmap = LockImage(imgdraw)
		
		' clear newly created img
		ClearPixels(pixdraw)
		
		Local linemax%
		
		For Local yy%=imgdraw.height-1 To 0 Step -1
			'If yy > liney Then
			'Continue
			'EndIf
			
			For Local xx%=0 To imgdraw.width-1
				
				'apply magic through a curve
				linemax = liney - Int(Float(imgdraw.width/2)*(3.0/4.0)*Cos(Float(xx-imgdraw.width/2)/Float(imgdraw.width)*(180)))
				
				If yy>linemax Then
					Continue
				EndIf
				
				Local pixrgb% = ReadPixel(pixply, xx,pixply.height-1-yy)
				
				If pixrgb<>0 Then
					Local lineit% = False
					If yy = linemax Then
						lineit = True
					ElseIf yy > linemax-10 And Rand(0,10-(yy-(linemax-10)))=0 Then
						Continue
					EndIf
					
					Local oldcolor:TColor = TColor.forInt(pixrgb)
					Local ch!, cs!, cv!
					oldcolor.toHSV(ch, cs, cv)
					If lineit Then
						oldcolor = oldcolor.initWithHSV(ch,0.1, 0.3+cv*0.7)
					Else
						oldcolor = oldcolor.initWithHSV(ch,0.1, cv)
					EndIf
					
					WritePixel(pixdraw, xx,pixdraw.height-1-yy, oldcolor.toInt())
				Else
					'WritePixel(pixdraw, xx,yy, ARGB(100,0,255,255))
				EndIf
				
			Next
		Next
		UnlockImage(imgply, i)
		UnlockImage(imgdraw)
		
		DrawImage(imgdraw, Floor(ply.get_x()-ply.animation.width/2), Floor(ply.get_y()-ply.animation.height))
		'DrawLine(ply.get_x()-10, ply.get_y()-liney, ply.get_x()+10, ply.get_y()-liney)
		
		
	EndMethod