[RESOLVED] Alternative to using LoadPicture
I'm making a game that involves a lot of different characters, and each time I want to change one of their motions I have to use LoadPicture to change the picture of the pictureBox that the Bitblt is reffering to, to paint it. I've noticed that LoadPicture is very inefficient and causes a little lag. Is there any other way I can reference the picture differently, instead of loading it to a picturebox? I can try to clarify this a little more if you don't understand. :o
I originally had very large sprite sheets for each character, that contained all the movements, but as I keep adding more characters I get the can't autoredraw image error. So the only thing I can think of to fix it is to split each big sprite sheet up into a sheet for each movement and use LoadPicture when changing motions. This lags a little bit each time it loads a picture though, so I was wondering if there was another way to to either load a picture into a picturebox or to somehow set the picture itself to a variable or something for the Bitblt statement to refer to for the .hdc value.
Re: Alternative to using LoadPicture
LoadPicture is the way to bring an image into a stdPicture object, like a Picturebox's .Picture property. AutoRedraw and size of image may be what is causing the lag you could be experiencing.
There are more advanced methods that use primarily APIs and can be more efficient/effective, but requires far more work and knowledge. These methods include creating/destroying DCs and bitmaps manually. But LoadPicture does conversions automatically for you when you load a gif or jpg for example; the APIs do not (GDI+ being an exception).
Maybe you can provide more details. Specifically, how often are you changing the images, what sizes are these images, and how noticable is the lag?
Re: Alternative to using LoadPicture
Well, I have about 15 different characters and objects that are being "animated" with Bitblt. Originally I had one big sprite sheet for each one, with about 40 x 8 frames with a width of 96 pixels, but I've been having to split some of them up to avoid the autoredraw errors. So for the sheets that have been split up, they have a width of about 10 x 8 frames with each frame having a width of 96 pixels. So I don't want all this mixed code, I'd rather do one method for all of them so I don't have to change the code each time I add something.
The motions, or pictures, change between 5 and 10 seconds for each character, or when the user activates the motion by pressing space for example. The lag is a fraction of a second, but with each character changing pictures every couple seconds it gets a little annoying.
I guess I'll just split them all up for now, and see if I can improve the rest of the code to reduce some of the lag.
Re: Alternative to using LoadPicture
Try using a Resource File, instead!! But you still have to call the file, using the LoadPicture command, as standard.
Re: Alternative to using LoadPicture
Load all the pictures into a stdPicture Array (Dim MyPicsCharacter01(1 to 8, 1 to 12) As stdPicture) (1 to 8 = facing, 1 to 12 = animation frames), Then bitblt from this array (or (1 to x = number of characters or animation type for single character, 1 to 8 = facing, 1 to x = number of frames in animation))
Good Luck
Re: Alternative to using LoadPicture
So are you trying to make a puppet or something like an avatar, for your program???
Re: Alternative to using LoadPicture
No, it's an RPG. There's different people, like a miner, carpenter, queen, fisherman, etc.
And I like that idea of loading the pictures in the begining, I think I'll try that.
Re: Alternative to using LoadPicture
Is this kind of game chess or checkers. Because I don't know how the program is going to work out. Seeing that I cannot, I can't help you. Until you message us more about the functions of the program.
Re: Alternative to using LoadPicture
Yes, loading the pictures in the beginning will be able to keep the program from lagging. But then when all of the pictures and the audio, are loading. Then there will be a consideable lagging in that area of the program. But then you have to work on caching the program, using certain commands, like: DoEvents, WhileEvents and use these two types of commands to work with and then they will do you great help in what you are trying to achieve.
Re: Alternative to using LoadPicture
ImP, that is what splash screens are for... :)
Re: Alternative to using LoadPicture
Yes, I know that part. I am using one in my isometric strategy game!!
Re: Alternative to using LoadPicture
Let's back up a little and consider this alternative. Design a control array of images or picture boxes. Images work faster so use them if possible.
Load all the picture files into the controls first using LoadPicture. Set them all invisible except the one that is needed when loaded. When a new one is needed, make the old one invisible and perhaps move the new one to the same location as the old one. Make the the new one visible. Repeat as required. :ehh:
Re: Alternative to using LoadPicture
Well, I'm using bitblt to paint the images, so i would have to use pictureboxes and they would always have to be invisible. I think I'll make a control array like you said, and just change the coordinates when changing images.
Re: Alternative to using LoadPicture
Just a warning, an array of picture boxes will consume more resources than an array of stdPicture object. And since you are using bitblt, you would just need one invisible picture box and you could do something like...
Set MyInvisiblePictureBox.Picture = MyStdPictureArray(1, 1, 1)
before you do your required bitblt with this image...
Good Luck
Re: Alternative to using LoadPicture
Re: [RESOLVED] Alternative to using LoadPicture
I know you have this as resolved, but there is yet one more option which could be faster because you don't need a picturebox to store the stdPicture object and you don't use BitBlt.
1. Load your images in a stdPicture array as you are now doing...
Code:
Dim myImages(xxxx) As stdPicture
' load each image: Set myImages(x) = LoadPicture(filename)
2. Call this homemade function to "BitBlt" it to the destination picturebox/form
Code:
Private Sub RenderPicture(imgObj As StdPicture, destObj As Object, _
ByVal X As Long, ByVal Y As Long, _
Optional ByVal Width As Long, Optional ByVal Height As Long, _
Optional ByVal RefreshObject As Boolean)
' pass imgObj as the stdPicture item to be drawn
' pass destObj as the picturebox or form
' pass width,height as zero to render image in full size, else pass the requested dimensions in target's scalemode
' If RefreshObject is passed as True, the object's AutoRedraw should be set to True
Dim destScaleMode As ScaleModeConstants
On Error GoTo EH
destScaleMode = destObj.ScaleMode
With imgObj
X = ScaleX(X, destScaleMode, vbPixels)
Y = ScaleY(Y, destScaleMode, vbPixels)
If Width = 0& Then
Width = ScaleX(imgObj.Width, vbHimetric, vbPixels)
Else
Width = ScaleX(Width, destScaleMode, vbPixels)
End If
If Height = 0& Then
Height = ScaleY(imgObj.Height, vbHimetric, vbPixels)
Else
Height = ScaleY(Height, destScaleMode, vbPixels)
End If
.Render destObj.hDC, X + 0&, Y + 0&, Width + 0&, Height + 0&, 0&, .Height, .Width, -.Height, ByVal 0&
End With
If RefreshObject Then destObj.Refresh
EH:
If Err Then
MsgBox "Error loading image" & vbNewLine & Err.Description, vbExclamation + vbOKOnly
Err.Clear
End If
End Sub
A sample call, if you did have a myImages() array:
:: RenderPicture myImages(1), Picture1, 0, 0, , , True
P.S. One advantage, you don't need BitBlt and this routine will handle GIFs, transparent GIFs, JPGs, icons, cursors, WMF/EMFs, and of course bitmaps. However, it does not handle partial rendering of the stdPicture object; all of it is rendered, but as you can see it can be rendered at different dimensions. Partial rendering can be done, but requires several more lines of code to make it more similar to StretchBlt vs BitBlt.
Edited: If the target is a memory DC, this can be easily adjusted to render to it instead; just let me know.
For those in the know, this routine is very similar to VB's PaintPicture, but VB's PaintPicture does not do transparent GIFs.