Witam mam problem, dotyczący migotania bitmap. Chciałbym dodać do mojej gry podwójne buforowanie, lecz wszelkie tego próby kończą się fiaskiem. Robię tak jak każą. Przkopiowuje obraz ludka do buforu, a nastepnie do kontekstu okna. I co i nic lipa. Jak ktoś ogrania temat. Niech poda na konkretnym przykładzie zasadę działanai podwójnego buforowania moj numer gg 8153898 lub niech napisze tutaj. Buforowanie zastosowane w funkcji animuj. Mam oto taką grę(ogólnie chcę coś zrobić w stylu mario):
#include <windows.h>
#include <conio.h>
#include <cstdio>
#include <iostream>
#define SZEROKOSC 800
#define WYSOKOSC 640
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
bool czyWcisniety = false;
void Animuj(HWND hwnd);
RECT rozmiarOkna = {0, 0, SZEROKOSC, WYSOKOSC};
HWND g_hwnd;
HDC g_hdc;
struct POSITION
{
unsigned int x;
unsigned int y;
int Vx;
int Vy;
}posGAMER;
class cGamer
{
public:
bool DEAD;
int coins;
HBITMAP bmpMario;
BITMAP infBmp;
HDC hdcMem;
HGDIOBJ gdiObj;
cGamer()
{
DEAD = false;
coins = NULL;
bmpMario = (HBITMAP)LoadImage(NULL, "bmpMario.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
GetObject(bmpMario, sizeof(BITMAP), &infBmp);
hdcMem = CreateCompatibleDC(0);
gdiObj = SelectObject(hdcMem, bmpMario);
posGAMER.x = NULL;
posGAMER.y = 420;
posGAMER.Vx = NULL;
posGAMER.Vy = NULL;
}
void ChangePos(POSITION &PosGAMER, WPARAM wParam, UINT message);
void CountCoins(int &coins);
}GAMER;
void cGamer::ChangePos(POSITION &PosGAMER, WPARAM wParam, UINT message)
{
if(wParam == VK_RIGHT && message == WM_KEYDOWN)
{
posGAMER.Vx = 10;
posGAMER.x += posGAMER.Vx;
Sleep(9);
}
if(wParam == VK_LEFT && message == WM_KEYDOWN)
{
posGAMER.Vx = -10;
posGAMER.x += posGAMER.Vx;
Sleep(9);
}
if(wParam == VK_UP && message == WM_KEYDOWN)
{
posGAMER.Vy = 50;
posGAMER.y -= posGAMER.Vy;
Sleep(9);
}
if(posGAMER.y < 420)
{
posGAMER.y+= 2;
Sleep(3);
}
}
class cMap
{
public:
HBITMAP bmpBackground;
HDC hMemMAP;
HGDIOBJ hGdiMap;
BITMAP hInfoMap;
cMap()
{
bmpBackground = (HBITMAP)LoadImage(0,"background.bmp", IMAGE_BITMAP, 0 ,0 ,LR_LOADFROMFILE);
GetObject(bmpBackground, sizeof(BITMAP), &hInfoMap);
hMemMAP = CreateCompatibleDC(0);
hGdiMap = SelectObject(hMemMAP, bmpBackground);
}
void Przesowaj(WPARAM wParam, UINT message);
}MAP;
void CheckSTAN()
{
CHAR bufor[20];
sprintf_s(bufor, sizeof(bufor), "Px: %i Py: %i", posGAMER.x, posGAMER.y);
SetWindowText(g_hwnd, bufor);
}
HBRUSH pedzel;
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nCmdShow)
{
HWND hwnd;
WNDCLASSEX wincl;
MSG msg;
wincl.hInstance = hThisInstance;
wincl.lpszClassName = "CLASS";
wincl.lpfnWndProc = WindowProcedure;
wincl.style = CS_VREDRAW | CS_HREDRAW;
wincl.cbSize = sizeof (WNDCLASSEX);
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL;
wincl.cbClsExtra = 0;
wincl.cbWndExtra = 0;
pedzel = (HBRUSH)GetStockObject(BLACK_BRUSH);
wincl.hbrBackground = pedzel;
if (!RegisterClassEx (&wincl))
return 0;
AdjustWindowRectEx(&rozmiarOkna, WS_OVERLAPPEDWINDOW ^ WS_THICKFRAME ^ WS_MAXIMIZEBOX, NULL, NULL);
hwnd = CreateWindowEx (
0,
"CLASS",
"RADIO & TOMIO: Adventures",
WS_OVERLAPPEDWINDOW ^ WS_THICKFRAME ^ WS_MAXIMIZEBOX,
100, 100,
rozmiarOkna.right - rozmiarOkna.left,
rozmiarOkna.bottom - rozmiarOkna.top,
HWND_DESKTOP,
NULL,
hThisInstance,
NULL
);
ShowWindow (hwnd, nCmdShow);
UpdateWindow(hwnd);
g_hwnd = hwnd;
g_hdc = GetDC(hwnd);
for(;;)
{
if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)!=0)
{
if(msg.message == WM_QUIT)break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
Animuj(hwnd);
CheckSTAN();
}
return (int)msg.wParam;
}
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
GAMER.ChangePos(posGAMER, wParam, message);
switch (message)
{
case WM_KEYDOWN:
switch(wParam)
{
case VK_LEFT:
GAMER.ChangePos(posGAMER, wParam, message);
czyWcisniety = true;
break;
case VK_RIGHT:
czyWcisniety = true;
GAMER.ChangePos(posGAMER, wParam, message);
break;
case VK_UP:
GAMER.ChangePos(posGAMER, wParam, message);
czyWcisniety = true;
break;
default: MessageBox(NULL,"No defined key", "Warning", MB_OK);
}
break;
case WM_KEYUP:
switch(wParam)
{
case VK_LEFT:
GAMER.ChangePos(posGAMER, wParam, message);
czyWcisniety = false;
break;
case VK_RIGHT:
GAMER.ChangePos(posGAMER, wParam, message);
czyWcisniety = false;
break;
case VK_UP:
GAMER.ChangePos(posGAMER, wParam, message);
czyWcisniety = false;
break;
}
break;
case WM_DESTROY:
PostQuitMessage (0);
break;
}
return DefWindowProc (hwnd, message, wParam, lParam);
}
void Animuj(HWND hwnd)
{
InvalidateRect(hwnd, &rozmiarOkna, TRUE);
HDC buffor = CreateCompatibleDC(g_hdc);
//BitBlt(g_hdc, 0 , 0 ,MAP.hInfoMap.bmWidth, MAP.hInfoMap.bmHeight, MAP.hMemMAP, 0,0, SRCCOPY); // tło
BitBlt(buffor, posGAMER.x, posGAMER.y, GAMER.infBmp.bmWidth, GAMER.infBmp.bmHeight, GAMER.hdcMem, 0 ,0 , SRCCOPY);// GAMER.hdcMem to uchwyt do bitmapy z graczem
BitBlt(g_hdc, posGAMER.x, posGAMER.y, GAMER.infBmp.bmWidth, GAMER.infBmp.bmHeight, buffor, 0 ,0 , SRCCOPY);//
}