キャラと背景の合成(重ね合わせ)
少し前にゲームを作る機会が有りその時に覚えたテクニックを紹介します。
背景とキャラを重ね合わせる場合、背景のCGとキャラのCGの他にマスクCGと呼ばれる
ものが必要になります。マスクCGはキャラCGを黒く塗ったものです。多くの解説書ではこの
マスクCGを自分で用意するように書かれているのですが、いちいち作るのは面倒です。
そこで、プログラムの内部でこれを作らせて重ね合わせをおこないたいと思います。
'=============Win32APIの宣言======================== 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 Declare Function CreateBitmap Lib "gdi32" (ByVal nWidth As Long, ByVal nHeight As Long, ByVal nPlanes As Long, ByVal nBitCount As Long, lpBits As Any) As Long Declare Function SetBkColor Lib "gdi32" (ByVal hdc As Long, ByVal crColor As Long) As Long Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long '======構造体======= Public Type RECT Left As Long Top As Long Right As Long Bottom As Long End Type '=====ラスターオペレーション=========================== 'D:コピー先 S:コピー先 P:ブラシ Public Const SRCCOPY = &HCC0020 'S Public Const SRCAND = &H8800C6 'S And D Public Const SRCINVERT = &H660046 'S Xor D Public Const SRCERASE = &H440328 'Not(D) And S Public Const SRCPAINT = &HEE0086 'S Or D Public Const BLACKNESS = &H42 '黒で塗りつぶす Public Const DSTINVERT = &H550009 'Not D Public Const MERGECOPY = &HC000CA 'S And P Public Const MERGEPAINT = &HBB0226 'Not(S) Or D Public Const NOTSRCCOPY = &H330008 'Not(S Or D) Public Const PATCOPY = &HF00021 'ブラシで塗りつぶす Public Const PATINVERT = &H5A0049 'P Xor D Public Const PATPAINT = &HFB0A09 '(P Or Not(S)) Or D Public Const WHITENESS = &HFF0062 '白で塗りつぶす '==================合成(重ね合わせ)関数================ Public Sub Transmit(OutPicDC As Long, BackDC As Long, ChrDC As Long, picrect As RECT, x As Integer, y As Integer, TC As Long) ' OutPicDC 出力先のデバイスコンテキスト(hDC) ' BackDC , ChrDC 背景、キャラのデバイスコンテキスト(hDC) ' picrect 合成領域 ' x , y 表示場所 ' TC 透過色 ' ====変数の宣言====================================== Dim R As Long 'API戻り値 Dim ChrWidth As Long, ChrHeight As Long '画像サイズ Dim MaskDC 'マスクCGのDC Dim hMask 'マスクCGのハンドル Dim MaskInvDC As Long, hMaskinv As Long 'ワーク(反転) Dim rBackDC As Long, hBack As Long Dim rChrDc As Long, hChr As Long Dim hObjMask As Long, hObjMaskinv As Long Dim hObjBack As Long, hObjChr As Long Dim Old As Long ' ====サイズの設定==================================== ChrWidth = (picrect.Right - picrect.Left) ChrHeight = (picrect.Bottom - picrect.Top) ' ====マスクCGの作成================================= MaskDC = CreateCompatibleDC(BackDC) MaskInvDC = CreateCompatibleDC(BackDC) hMask = CreateBitmap(ChrWidth, ChrHeight, 1, 1, ByVal 0&) hMaskinv = CreateBitmap(ChrWidth, ChrHeight, 1, 1, ByVal 0&) hObjMask = SelectObject(MaskDC, hMask) hObjMaskinv = SelectObject(MaskInvDC, hMaskinv) ' ==================================================== rBackDC = CreateCompatibleDC(BackDC) rChrDc = CreateCompatibleDC(ChrDC) hBack = CreateCompatibleBitmap(BackDC, ChrWidth, ChrHeight) hChr = CreateCompatibleBitmap(ChrDC, ChrWidth, ChrHeight) hObjBack = SelectObject(rBackDC, hBack) hObjChr = SelectObject(rChrDc, hChr) Old = SetBkColor(ChrDC, TC) R = BitBlt(MaskDC, 0, 0, ChrWidth, ChrHeight, ChrDC, 0, 0, SRCCOPY) TC = SetBkColor(ChrDC, Old) R = BitBlt(MaskInvDC, 0, 0, ChrWidth, ChrHeight, MaskDC, 0, 0, NOTSRCCOPY) R = BitBlt(rBackDC, 0, 0, ChrWidth, ChrHeight, BackDC, x, y, SRCCOPY) R = BitBlt(rBackDC, 0, 0, ChrWidth, ChrHeight, MaskDC, 0, 0, SRCAND) R = BitBlt(rChrDc, 0, 0, ChrWidth, ChrHeight, ChrDC, 0, 0, SRCCOPY) R = BitBlt(rChrDc, 0, 0, ChrWidth, ChrHeight, MaskInvDC, 0, 0, SRCAND) R = BitBlt(rBackDC, 0, 0, ChrWidth, ChrHeight, rChrDc, 0, 0, SRCINVERT) R = BitBlt(OutPicDC, x, y, ChrWidth, ChrHeight, rBackDC, 0, 0, SRCCOPY) ' ====後始末===================================================== hMask = SelectObject(MaskDC, hObjMask) DeleteObject hMask hMaskinv = SelectObject(MaskInvDC, hObjMaskinv) DeleteObject hMaskinv hBack = SelectObject(rBackDC, hObjBack) DeleteObject hBack hChr = SelectObject(rChrDc, hObjChr) DeleteObject hChr DeleteDC MaskDC DeleteDC MaskInvDC DeleteDC rBackDC DeleteDC rChrDc ' ================================================================ End Sub |
結構複雑ですが、ゲームを作るときには役に立つと思います。
使うには、スケールモードをピクセルにして
TColor=ChrPic.Point(0,0) With PR .Left=0 .Right=120 .Top=0 .Bottom=120 End With Transmit ShowPic.hDC , BackPic.hDC , ChrPic.hDC , PR , 0 , 0 , TColor |
というようにします。
この場合は、120×120のサイズでShowPicの(0,0)の位置にBasePicを背景にChrPicをキャラ、キャラCGの左上の色を透過色として重ね合わせて表示します。
実は、Windows98から同様のAPI関数が追加されたようです。そこで、次回はWin98ならばそのAPI関数を、その関数が使えない場合はこのTransmit関数を使うプログラムを書こうと思います。