想做個超級瑪麗,小游戲,控制元件采用的picturebox,定時器timer,重繪頻率10,autoredraw = true,在不用Refresh時,畫面定格,用Refresh時,畫面小間斷出現白色閃屏,已經用了雙緩沖還這樣,本人自學,很多東西都不太會,希望高人指點,謝謝
Public Sub MakeMapHDc(ByVal DrawObj As Object, ByVal ObjWidth As Long, ByVal ObjHeight As Long)
Set DrawObject.Objects = DrawObj
DrawObject.Width = ObjWidth
DrawObject.Height = ObjHeight
GameMap.mHDc = CreateCompatibleDC(DrawObj.hDC)
GameMap.mBmp = CreateCompatibleBitmap(DrawObj.hDC, ObjWidth, ObjHeight)
GameMap.hBrush = CreateSolidBrush(GameMap.BackColor)
'DrawObject.Objects.Cls
SelectObject GameMap.mHDc, GameMap.mBmp
SetRect r, 0, 0, DrawObject.Width, DrawObject.Height
FillRect GameMap.mHDc, r, GameMap.hBrush
Dim X As Long, Y As Long, X1 As Long, X2 As Long, Y1 As Long, Y2 As Long, dx As Long, dy As Long
X1 = Abs(Int(GameMap.Left / GameMap.PieceWidth))
Y1 = Abs(Int(GameMap.Top / GameMap.PieceHeight))
X2 = Int(DrawObject.Width / GameMap.PieceWidth) + Abs(CInt(GameMap.Left / GameMap.PieceWidth))
If X2 > GameMap.Column Then X2 = GameMap.Column
Y2 = Int(DrawObject.Height / GameMap.PieceHeight) + Abs(CInt(GameMap.Top / GameMap.PieceHeight))
If Y2 > GameMap.Line Then Y2 = GameMap.Line
dx = GameMap.Left Mod GameMap.PieceWidth
dy = GameMap.Top Mod GameMap.PieceHeight
For X = X1 To X2
For Y = Y1 To Y2
If TY_map(X, Y).Value > 0 Then BitBlt GameMap.mHDc, (X - X1) * GameMap.PieceWidth - dx, (Y - Y1) * GameMap.PieceHeight - dy, GameMap.PieceWidth, GameMap.PieceHeight, GameMap.TextureHDc, 0, TY_map(X, Y).Value * GameMap.PieceHeight, &HCC0020
Next
Next
BitBlt DrawObject.Objects.hDC, 0, 0, DrawObject.Width, DrawObject.Height, GameMap.mHDc, 0, 0, &HCC0020
'DrawObject.Objects.Refresh
end Sub
uj5u.com熱心網友回復:
這些create出來的都是需要銷毀的,或者在函式之外做成全域,或者函式結束之后銷毀GameMap.mHDc = CreateCompatibleDC(DrawObj.hDC)
GameMap.mBmp = CreateCompatibleBitmap(DrawObj.hDC, ObjWidth, ObjHeight)
GameMap.hBrush = CreateSolidBrush(GameMap.BackColor)
然后Refresh是需要加的。
uj5u.com熱心網友回復:
這個我有做全域,代碼我沒給全Public Sub MakeMapHDc(ByVal DrawObj As Object, ByVal ObjWidth As Long, ByVal ObjHeight As Long)
Set DrawObject.Objects = DrawObj
DrawObject.Width = ObjWidth
DrawObject.Height = ObjHeight
If GameMap.TextureHDc = 0 Then Map_Load
GameMap.mHDc = CreateCompatibleDC(DrawObj.hDC)
GameMap.mBmp = CreateCompatibleBitmap(DrawObj.hDC, ObjWidth, ObjHeight)
GameMap.hBrush = CreateSolidBrush(GameMap.BackColor)
End Sub
Public Function DrawGame() As Long
Dim tj As Long
tj = timeGetTime
Dim r As RECT
SelectObject GameMap.mHDc, GameMap.mBmp
'hBrush = CreateSolidBrush(GameMap.BackColor)
SetRect r, 0, 0, DrawObject.Width, DrawObject.Height
FillRect GameMap.mHDc, r, GameMap.hBrush
Dim X As Long, Y As Long, X1 As Long, X2 As Long, Y1 As Long, Y2 As Long, dx As Long, dy As Long
X1 = Abs(Int(GameMap.Left / GameMap.PieceWidth))
Y1 = Abs(Int(GameMap.Top / GameMap.PieceHeight))
X2 = Int(DrawObject.Width / GameMap.PieceWidth) + Abs(CInt(GameMap.Left / GameMap.PieceWidth))
If X2 > GameMap.Column Then X2 = GameMap.Column
Y2 = Int(DrawObject.Height / GameMap.PieceHeight) + Abs(CInt(GameMap.Top / GameMap.PieceHeight))
If Y2 > GameMap.Line Then Y2 = GameMap.Line
dx = GameMap.Left Mod GameMap.PieceWidth
dy = GameMap.Top Mod GameMap.PieceHeight
For X = X1 To X2
For Y = Y1 To Y2
If TY_map(X, Y).Value > 0 Then BitBlt GameMap.mHDc, (X - X1) * GameMap.PieceWidth - dx, (Y - Y1) * GameMap.PieceHeight - dy, GameMap.PieceWidth, GameMap.PieceHeight, GameMap.TextureHDc, 0, TY_map(X, Y).Value * GameMap.PieceHeight, &HCC0020
Next
Next
BitBlt DrawObject.Objects.hDC, 0, 0, DrawObject.Width, DrawObject.Height, GameMap.mHDc, 0, 0, &HCC0020
DrawObject.Objects.Refresh
DrawGame = timeGetTime - tj
End Function
uj5u.com熱心網友回復:
沒細看代碼,光看描述就有問題1)定時器的實際頻率只有18次/秒,超過這個重繪頻率不僅無用,還會影響顯示。
2)autoredraw = true 已經是自動實作雙緩沖了,你再加一個緩沖,不沖突才怪
3)用VB自帶的繪圖方法就能實作(比如PictureBox.PaintPicture 已經封裝好了 BitBlt)
uj5u.com熱心網友回復:
1.定時器改成了18以后,確實不那么閃了。謝謝
2.請問應該怎么改,我不太明白,請指點,謝謝
3.現在的代碼,在改完定時器以后,每次變動的時候,會有發白的感覺,閃一下,不太嚴重,移動大的話,不明顯,每次left+1的話就比較明顯,就是重繪的時候白一下,請幫忙說詳細點,先謝謝了!!!!!
uj5u.com熱心網友回復:
gdiplus吧,你要搞游戲,肯定要這種型別最基本的啦!那也可以用什么3d,或者是dirextxuj5u.com熱心網友回復:
這個可以不用那個refreshuj5u.com熱心網友回復:
'背景滾屏的例子
'
'新建表單 Form1
'添加1個PictueBox、1個Timer
Option Explicit
Private m_MapBlock As IPictureDisp
Private m_MapWidth As Long
Private m_ScrollX As Long
Private m_X As Long
Private Sub Form_Load()
Set m_MapBlock = LoadPicture("C:\WINDOWS\Coffee Bean.bmp")
m_MapWidth = 128
m_ScrollX = 2
m_X = m_ScrollX
Picture1.ScaleMode = vbPixels
Picture1.BackColor = vbWhite
Picture1.AutoRedraw = True
Timer1.Interval = 1000 \ 18
End Sub
Private Sub Timer1_Timer()
Dim x As Long
m_X = (m_X - m_ScrollX) Mod m_MapWidth
'Picture1.Cls '上個繪圖會被徹底覆寫,不需要清屏'
For x = m_X To Picture1.ScaleWidth Step m_MapWidth
Picture1.PaintPicture m_MapBlock, x, 0
Next
End Sub
uj5u.com熱心網友回復:
CreateSolidBrush 也需要 deleteobject的每次重繪的時候如果hbmp用的全域的需要清除掉原來畫面,畫個大框把原來的都蓋起來。
如果用timer來定時的話,最好在timer最前邊加上
Timer1.Enable=false
結束的地方加Timer1.Enable=True
繪圖的時間遠遠會超過timer的定時時間。
uj5u.com熱心網友回復:
autoredraw = true,應該不是雙緩沖,比如視窗被別的視窗擋了個角,視窗移開的時候,autoredraw = true會自動重繪這個角uj5u.com熱心網友回復:
此時沒有 Paint 事件,自動直接用后臺圖片貼到前臺視窗。
后臺繪圖、前臺貼圖的不叫雙緩沖?那么什么叫雙緩沖?
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/62438.html
標籤:VB基礎類
