最近デバイスコンテキストを何とか理解してきたので、実験的に『上から物体が振ってくるのを避ける』というゲームを作ってみようと思い作り始めました。
『←』が押されれば、棒人間を左に、『→』が押されれば、棒人間を右に移動させる処理と、ランダムで●が上から落ちてくるという処理をタイマーを使ってやってみました。(スレッドとかはまだ勉強していないので)
一応完成はしたのですが、棒人間を動かすと、どうしても●がちらつきます。
この場合は、どういう風に処理をすればいいのでしょうか?
プログラムはこう書きました。
グローバル変数
Dim hBmp01 As HWND
Dim hBmp02 As HWND
Dim hBmp03 As HWND
Dim hBmp04 As HWND
Dim hMemDC As HDC
Dim BmpInfo As Long
Dim hBomDC As HWND
Dim Bomxy As RECT
Dim x As Long
Dim y As Long
Dim bx As Long
Dim by As Long
Dim n As Long
'----------------------------------------------------
省略
'-----------------------------------------------------
Sub MainWnd_Destroy()
DeleteObject(hBmp01)
DeleteObject(hBmp02)
DeleteObject(hBmp03)
DeleteObject(hBmp04)
YokeGame_DestroyObjects()
PostQuitMessage(0)
End Sub
Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)
SetWindowText(hMainWnd,"画像描写テスト ~爆弾的なものを避けるゲーム~")
hBmp01 = LoadImage(0,".\画像\人\普通.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE)
hBmp02 = LoadImage(0,".\画像\人\右.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE)
hBmp03 = LoadImage(0,".\画像\人\左.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE)
hBmp04 = LoadImage(0,".\画像\爆弾\ボム.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE)
GetWindowRect(hBmp04,Bomxy)
If hBmp01=0 or hBmp02=0 or hBmp03=0 or hBmp04=0 Then
MessageBox(hMainWnd,Ex"画像の読み込みに失敗しました\r\n強制終了します。","Error",MB_OK or MB_ICONHAND)
DeleteObject(hBmp01)
DeleteObject(hBmp02)
DeleteObject(hBmp03)
DeleteObject(hBmp04)
SendMessage(hMainWnd,WM_CLOSE,0,0)
End If
x=290
y=275
BmpInfo=1
bx = 320
by = 0
SetTimer(hMainWnd,0,300,0)
End Sub
Sub Kettei()
Dim ok As Long
by=0
Do
Randomize
bx = Fix(Rnd()*100)
If bx>0 and 630>bx Then
ok=TRUE
End If
Loop Until ok=TRUE
End Sub
Sub MainWnd_Paint(hDC As HDC)
hMemDC = CreateCompatibleDC(hDC)
hBomDC = CreateCompatibleDC(hDC)
If BmpInfo = 1 Then
SelectObject(hMemDC,hBmp01)
Else If BmpInfo = 2 Then
SelectObject(hMemDC,hBmp02)
Else If BmpInfo = 3 Then
SelectObject(hMemDC,hBmp03)
End If
BitBlt(hDC,x,y,40,50,hMemDC,0,0,SRCCOPY)
Sleep(30)
SelectObject(hMemDC,hBmp01)
BitBlt(hDC,x,y,40,50,hMemDC,0,0,SRCCOPY)
Sleep(30)
SelectObject(hBomDC,hBmp04)
BitBlt(hDC,bx,by,9,9,hBomDC,0,0,SRCCOPY)
DeleteDC(hMemDC)
DeleteDC(hBomDC)
BmpInfo = 1
End Sub
Sub MainWnd_KeyDown(KeyCode As Long, flags As Long)
If KeyCode = 37 Then
If x<=0 Then
x=0
Exit Sub
End If
x = x - 10
BmpInfo=3
End If
If KeyCode = 39 Then
If x>=600 Then
x = 600
Exit Sub
End If
x = x + 10
BmpInfo=2
End If
InvalidateRect(hMainWnd,ByVal 0,TRUE)
End Sub
Sub MainWnd_Timer(TimerID As DWord)
If TimerID = 0 Then
by = by + 10
InvalidateRect(hMainWnd,Byval 0,TRUE)
If by >=360 Then
Kettei()
End If
End If
End Sub
っと、このようになりました。(一応動きます)
strictには、チェックを入れていません。
バージョンは、4.23.00を使っています。
それと、InvalidateRect関数なのですが、
InvalidateRect(hMainWnd,Byval 0,TRUE)
の、二つ目のパラメータ(?)部分に、全体を再描写させるときに何故『Byval 0』と表記するのでしょうか?
ヘルプには、NULL を指定すると、クライアント領域全体が更新領域に設定されますと書かれていますが、NULLを指定すると無効な識別となります。
すみませんが、分かる方がいらっしゃいましたら、ご教授をお願いします。
No.1ベストアンサー
- 回答日時:
こんにちは。
チラつくのは、BitBltの後にSleepを過剰に呼び出してしまっているからでしょう。
キー入力の方向に対応した人間をBitBltした後、爆弾をBitBltしてから、Sleepをかければ良いでしょう。
また、デバイスコンテキストは、可能な限り直に開放した方が良いです。
後、細かい事に言及すると、MainWnd_KeyUpイベントを処理してその中で、←か→のボタンが離されたら、BmpInfo=1として人間を普通の向きにしてあげると良いと思います。
「ByVal 0」に関しては、本来その部分にはRECT*と言うポインタが入ります。NULLを指定すると全体を再描画出来ます。
「NULLについて」
http://www.valley.ne.jp/~ryouga/machine/tips/c00 …
まぁ、要は「0」の事です。
「ByVal 0」と書く理由に関しては(しかし、0である事位は容易に想像出来る)、当方もActiveBasicの事をもっと勉強してみないと名言は出来ません。
で、肝心なチラつき対策の方ですが、実際にActiveBasic5で試して見ました。以下参考程度に。
'再描画イベント(チラつき修正)
Sub MainWnd_Paint(hDC As HDC)
hMemDC = CreateCompatibleDC(hDC)
hBomDC = CreateCompatibleDC(hDC)
'キーに対応した方向の人間の絵を選択
If BmpInfo = 1 Then
SelectObject(hMemDC,hBmp01)
Else If BmpInfo = 2 Then
SelectObject(hMemDC,hBmp02)
Else If BmpInfo = 3 Then
SelectObject(hMemDC,hBmp03)
End If
'人間を描く
BitBlt(hDC,x,y,40,50,hMemDC,0,0,SRCCOPY)
'ボムの絵を選択
SelectObject(hBomDC,hBmp04)
'ボムの絵を描く
BitBlt(hDC,bx,by,9,9,hBomDC,0,0,SRCCOPY)
'先にデバイスコンテキストを開放した方がよい
DeleteDC(hMemDC)
DeleteDC(hBomDC)
'ココで休む
Sleep(30)
End Sub
'キーが離された時(追加)
Sub MainWnd_KeyUp(KeyCode As Long, flags As Long)
'←又は→が離された
If KeyCode = 37 or KeyCode = 39 Then
'普通の向きにしてから再描画する
BmpInfo=1
InvalidateRect(hMainWnd,ByVal 0,TRUE)
End If
End Sub
なるほど・・・
DCは早めに開放しなければいけなかったのですか・・・
勉強になりました!
スリープの数ですね?早速試してみます。
ありがとうございました
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 【VBA】写真の貼り付けコードがうまく機能しません。 5 2022/09/01 18:43
- Visual Basic(VBA) VBAで質問ですが、皆さんはどの様に導き出しているのでしょうか? 6 2022/05/03 21:53
- Visual Basic(VBA) 【Excel VBA】自動メール送信の機能追加 5 2022/09/29 12:53
- Visual Basic(VBA) 【変更】ファイルを閉じてダイアログで保存した時、更新したシートだけの処理の実行をする 5 2022/03/26 18:31
- Visual Basic(VBA) 【追加】ファイルを閉じてダイアログで保存した時だけ処理の実行をする 3 2022/03/23 15:43
- Excel(エクセル) VBAについて 3 2022/06/19 18:19
- Visual Basic(VBA) batからexeを実行し戻り値を受け取る バッチからEXEの結果を受け取りたいのですが、 下記のバッ 1 2023/07/04 15:13
- Visual Basic(VBA) VBA 別ブックからの転記の高速化について VBA 別ブックからの転記の高速化についてご教授下さい。 19 2022/07/26 13:07
- Visual Basic(VBA) EXCEL VBAにて動的にCheckBOXを複数作成し、同BOXにイベントを追加したい 1 2023/03/16 07:05
- Excel(エクセル) 2つのVBAを一緒にしたら機能しなくなりました(エクセル) 7 2022/06/02 12:41
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
画面がチカチカする
-
BeginPaintの使い方
-
GetPixelに使うHDCの作り方
-
コンテキスト依存とは?
-
Win32APIにて、アイコンの情報...
-
ダブルバッファの作り方
-
エクセルで作った新しいウイン...
-
「アイテムは収集されました」...
-
コントロールの書式設定で、“コ...
-
グラフの交点の求め方(Excel)
-
検索の画面がでなくなってしま...
-
コンボボックス内の文字サイズ変更
-
vbaから他のアプリを終了
-
フォントの大きさ
-
PCで「使用可能な場合はグラフ...
-
ラジオボタンの初期指定
-
チェックボックスの箱のサイズ...
-
VBAのフォント変更(エクセルか...
-
文字色 エクリプス
-
ボタンの表示の色、フォントを...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
コンテキスト依存とは?
-
Win32APIにて、アイコンの情報...
-
PlgBltでの透過
-
画面がチカチカする
-
GetDC()とCreateCompatibleDC()
-
VBでFD、USBの有効・無効...
-
VC++でBitmapとText文字を表示...
-
コントロール内の文字の背景色
-
画像処理 ビットマップ ダブ...
-
BitBlt関数について教えてください
-
メモリデバイスコンテキスト&...
-
Rectangleで、リソースが解放さ...
-
画面のちらつきについて
-
Windowsプログラミング 画面描...
-
ビットマップ(表示速度とサイズ)
-
メモリデバイスコンテキストを...
-
ダブルバッファの作り方
-
TextOutについて
-
SetWindowRgn()関数について。
-
領域を塗りつぶしたい
おすすめ情報