Click to See Complete Forum and Search --> : Autoredraw?!
DarkJedi9
Feb 19th, 2001, 10:23 AM
This whole autoredraw deal has been causing me a good bit of consternation lately. You see, I've got this little tank game, but if anything goes over it's picture or you switch windows and then go back, the picture is cleared. So I tried using autoredraw. Right after the city is drawn and the tanks are placed, I set autoredraw to true and then set the form's picture property to it's image property. Voila! My city and tanks stay on the form. Now here's the problem: I can't update the picture. If autoredraw is set to true, and I try to shoot at another tank, the shell's path and the explosion flicker and then disappear right away. So I tried setting the autoredraw to false and then drawing. This works, but now the image can be cleared again. If I set autoredraw to true again, all my changes are gone! :confused: It's really frustrating, so I apologize if this post seems a little angry or incoherent. :D
Dont set the picture property to the image propery. That makes the images permenent. All drawing methods go to the image, not the picture. Hope that helps
plenderj
Feb 19th, 2001, 10:56 AM
Why not blit all of your pictures ?
- jamie
DarkJedi9
Feb 19th, 2001, 11:10 AM
if I draw the city, place the tanks, and then set the autoredraw to true, but don't set the form's picture property, this image will not clear when I change screens. But, in order to draw the shell's path and the result of its explosion, I need to set autoredraw to false. If I set it to true after all the drawing, the drawing stays for the time being but will clear if I change windows and then come back again. Same deal if I leave it off after drawing the shell's path etc. I'm getting rather confused.
DarkJedi9
Feb 19th, 2001, 11:12 AM
Originally posted by plenderj
Why not blit all of your pictures ?
- jamie
because there is nowhere to blit them from. everything is done with line methods, circle methods, and setpixelV. I wanted to avoid having to use pictureboxes and package images with the app. I'm trying to keep size down.
plenderj
Feb 19th, 2001, 11:16 AM
Well blitting really is the quickest way of doing things.
You dont actually need to use source pictureboxes, as in this example from my game :
Public Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
Public Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Public Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
Public Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
Public Declare Function LoadImage Lib "user32" Alias "LoadImageA" (ByVal hInst As Long, ByVal lpsz As String, ByVal un1 As Long, ByVal n1 As Long, ByVal n2 As Long, ByVal un2 As Long) As Long
Public Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
Public Function GenerateDC(FileName As String) As Long
DC = CreateCompatibleDC(0)
If DC < 1 Then
GenerateDC = 0
End
Exit Function
End If
hBitmap = LoadImage(0, FileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE Or LR_CREATEDIBSECTION)
If hBitmap = 0 Then
DeleteDC DC
GenerateDC = 0
MsgBox FileName & "," & Dir(FileName)
Err.Raise vbObjectError + 2
Exit Function
End If
SelectObject DC, hBitmap
GenerateDC = DC
DeleteObject hBitmap
End Function
'THEN TO GENERATE THE DEVICE CONTEXTS ::
dc_ship(0) = GenerateDC(App.Path & "\images\ship_0.bmp")
For i = 1 To 35
dc_ship(i) = GenerateDC(App.Path & "\images\ship_" & i & "0.bmp")
Next i
dc_obj_0 = GenerateDC(App.Path & "\images\ship_0.bmp")
dc_blip_ship = GenerateDC(App.Path & "\images\radar_ship.bmp")
dc_blip_station = GenerateDC(App.Path & "\images\radar_station.bmp")
dc_fire_lasers = GenerateDC(App.Path & "\images\laser_1_0_.bmp")
dc_explode_craft_1 = GenerateDC(App.Path & "\images\explode_1.bmp")
dc_explode_craft_2 = GenerateDC(App.Path & "\images\explode_2.bmp")
'THEN IN-GAME, TO DO THE BLITTING :
BitBlt Me.hdc, .cords.x, .cords.y, 81, 81, dc_ship(.angle / 10), 0, 0, vbSrcInvert
Its real easy to muck around.
- jamie
DarkJedi9
Feb 19th, 2001, 04:59 PM
Is it possible for me to usecreatecompatibleDC to copy my form's DC, then do all my drawing to that and then blit from my invisible DC to my form's DC? I tried doing something like that before, but nothing happened - no drawings, no errors, nothing.
drewski
Feb 19th, 2001, 11:18 PM
hey where are you drawing all of this stuff to? the form? if you're using drawing commands put the drawing commands in the forms Paint event. when you change between forms if should then redraw what was the there before. i've had the same problem before with directx. i was only drawing to the screen when i needed to instead of having a continous loop. when i had a window open everything behind it disapeared until i had drawn to the screen again.
plenderj
Feb 20th, 2001, 02:15 AM
DarkJedi, thats what the code above does :)
It creates DCs in memory, and then blits from those onto your form.
Its real easy to work with.
Just try messing around with my code.
- jamie
plenderj
Feb 20th, 2001, 02:18 AM
You also need a couple of variables... unless you have the VC++ header files you'd be hard pushed to find these :
'' Device Contexts used for blitting
Public dc_ship(0 To 35) As Long
Public dc_obj_0 As Long '' Device Context (for blitting)
Public dc_blip_ship As Long '' Device Context for blitting ship radar blips
Public dc_blip_station As Long '' Device Context for blitting station radar blips
Public dc_fire_lasers As Long '' Device Context for blitting lasers
Public dc_station() As Long '' Device Context for blitting space stations
Public dc_explode_craft_1 As Long '' Device Context for blitting craft's explosion #1
Public dc_explode_craft_2 As Long '' Device Context for blitting craft's explosion #2
'' Variables used for GenerateDC Function
Public DC As Long '' Device Context object
Public hBitmap As Long '' Bitmap object
Const IMAGE_BITMAP As Long = 0
Const LR_LOADFROMFILE As Long = &H10
Const LR_CREATEDIBSECTION As Long = &H2000
Const LR_SHARED As Long = &H8000
Thats a copy-n-paste from my game, so some of it isnt needed.
- jamie
Arcom
Feb 20th, 2001, 04:43 AM
You must set the AutoRedraw to True BEFORE you draw anything on the Form/PictureBox. Then, after you've done drawing, call the Refresh method to display the contents. It's simple as that...
You dont need to call refresh, as the form will be refreshed as soon as the window gets a WM_PAINT message (Idle Time, or when the program hits a DoEvents)
DarkJedi9
Feb 20th, 2001, 10:50 PM
Originally posted by Arcom
You must set the AutoRedraw to True BEFORE you draw anything on the Form/PictureBox. Then, after you've done drawing, call the Refresh method to display the contents. It's simple as that...
But if I have autoredraw set to true, then the drawing flickers and all that while I'm drawing it. It looks pretty crappy.
Basically, I need to edit what the autoredraw is redrawing. Whatever I do doesn't seem to be working. Either that or I need to know why when I try to draw on a DC I created nothing happens.
plenderj
Feb 21st, 2001, 01:52 AM
DarkJedi,
Check out the thread I've just made :
http://forums.vb-world.net/showthread.php?s=&threadid=56233
Ive posted the source code to my game.
You can see how I've done the blitting.
- jamie
DarkJedi9
Feb 21st, 2001, 03:43 PM
So this code works when the autoredraw property is set to true. But only if I have the picture = image lines. This is okay, though. Only problem is: how do I clear out the picture property? Is there a way to do it besides just coloring over all my drawings with gray and then setting picture to image again? Also, what if I want to draw the shell's path? Will I have to set the picture to image every time I draw a pixel? That's what it seems like but that is pretty ridiculous.
Private Sub Command1_Click()
Dim FormDC As Long
Dim BackDC As Long
Dim OldBrush As Long
Dim OldPen As Long
Dim NewBrush As Long
Dim NewPen As Long
Dim Color As Long
NewPen = CreatePen(PS_SOLID, 9, &HFF)
OldPen = SelectObject(Form1.hdc, NewPen)
NewBrush = CreateSolidBrush(&HFF)
OldBrush = SelectObject(Form1.hdc, NewBrush)
Rectangle Form1.hdc, 50, 50, 100, 100
Form1.Picture = Form1.Image
SelectObject Form1.hdc, OldBrush
SelectObject Form1.hdc, OldPen
Rectangle Form1.hdc, 50, 50, 100, 100
Form1.Picture = Form1.Image
DeleteObject NewPen
End Sub
P.S. I still can't get the createcompatibleDC thing to work. Or maybe the DC works, but when I draw to it and try to blit it to my form it doesn't work. If anyone would like to look at my code, I'll put it in a new reply; this one is getting pretty lenghty.
YoungBuck
Feb 21st, 2001, 04:24 PM
To clear the Picture box of the Picture...
Picture1.Picture = LoadPicture("")
and to get the offscreen DC to work you need to use the CreateCompatibleBitmap function and select it into the DC first.
DarkJedi9
Feb 21st, 2001, 09:03 PM
Thanks so much! This has been p**sing (can I say that?)me off for days. Everybody who replied; thanks for your help. You guys are the best!
vbforums.com
Copyright Internet.com Inc., All Rights Reserved.