Skocz do zawartości

[WinApi]Problem z podwójnym buforowaniem.


elo720

Polecane posty

Jak w temacie, dołączam obrazek i kod.

Przed zastosowaniem podwójnego bufora

http://postimg.org/image/emjjuzp4x/

Po zastosowaniu podwójnego bufora

http://postimg.org/image/fem7u6tc1/

Kod

#include "defines.h"
int WINAPI WinMain (HINSTANCE hThisInstance,
				HINSTANCE hPrevInstance,
				LPSTR lpszArgument,
				int nCmdShow)
{
HWND hwnd;   			/* This is the handle for our window */
MSG messages;        	/* Here messages to the application are saved */
WNDCLASSEX wincl;    	/* Data structure for the windowclass */
/* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure;  	/* This function is called by windows */
wincl.style = CS_DBLCLKS; 				/* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);
/* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; 				/* No menu */
wincl.cbClsExtra = 0;                  	/* No extra bytes after the window class */
wincl.cbWndExtra = 0;                  	/* structure or the window instance */
/* Use Windows's default colour as the background of the window */
wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
   	return 0;
/* The class is registered, let's create the program*/
hwnd = CreateWindowEx (
  		0,   				/* Extended possibilites for variation */
  		szClassName, 		/* Classname */
  		"Shooters",      	/* Title Text */
  		WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_SYSMENU, /* default window */
  		CW_USEDEFAULT,   	/* Windows decides the position */
  		CW_USEDEFAULT,   	/* where the window ends up on the screen */
  		366, 				/* The programs width */
  		333, 				/* and height in pixels */
  		HWND_DESKTOP,    	/* The window is a child-window to desktop */
  		NULL,            	/* No menu */
  		hThisInstance,   	/* Program Instance handler */
  		NULL 				/* No Window Creation data */
  		);
GetClientRect(hwnd, &rcOkno);
SetTimer( hwnd, 1, 1, NULL );
/* Make the window visible on the screen */
ShowWindow (hwnd, nCmdShow);
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
   	/* Translate virtual-key messages into character messages */
   	TranslateMessage(&messages);
   	/* Send message to WindowProcedure */
   	DispatchMessage(&messages);
}
/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}

/*  This function is called by the Windows function DispatchMessage()  */
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)              	/* handle the messages */
{
   	case WM_KEYDOWN:
   	{
       	paint(hwnd);
   	}break;
   	case WM_TIMER:
   	{
       	if(HIBYTE(GetAsyncKeyState(VK_RIGHT)) && Red.x+30<rcOkno.right)
       	{
           	Red.x+=2;
           	Red.dir=0;
       	}
       	if(HIBYTE(GetAsyncKeyState(VK_LEFT)) && Red.x>0)
       	{
           	Red.x-=2;
           	Red.dir=1;
       	}
       	if(HIBYTE(GetAsyncKeyState(VK_UP)) && Red.y==280)
       	{
           	Red.jump=5;
           	Red.jumpWait=3;
           	Red.jumpUp=1;
       	}
       	if(Red.jumpUp)
       	{
           	jumpUp(Red);
       	}
       	if(Red.jumpDown)
       	{
           	jumpDown(Red);
       	}
       	if(Red.shootWait!=0)
           	Red.shootWait--;
       	if(HIBYTE(GetAsyncKeyState(VK_RETURN)) && Red.shootWait==0)
       	{
           	Red.shootWait=100;
           	shootX=Red.x+30;
       	}
////////////////////////////////////////////////////////////////////////
       	if(HIBYTE(GetAsyncKeyState(0x44)) && Blue.x+30<rcOkno.right)
       	{
           	Blue.x+=2;
           	Blue.dir=0;
       	}
       	if(HIBYTE(GetAsyncKeyState(0x41)) && Blue.x>0)
       	{
           	Blue.x-=2;
           	Blue.dir=1;
       	}
       	if(HIBYTE(GetAsyncKeyState(0x57)) && Blue.y==280)
       	{
           	Blue.jump=5;
           	Blue.jumpWait=3;
           	Blue.jumpUp=1;
       	}
       	if(Blue.jumpUp)
       	{
           	jumpUp(Blue);
       	}
       	if(Blue.jumpDown)
       	{
           	jumpDown(Blue);
       	}
       	shootX+=5;
       	paint(hwnd);
   	}break;
   	case WM_PAINT:
       	paint(hwnd);
       	break;
   	case WM_DESTROY:
       	PostQuitMessage (0);   	/* send a WM_QUIT to the message queue */
       	break;
   	default:                  	/* for messages that we don't deal with */
       	return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}

#include <windows.h>
/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
/*  Make the class name into a global variable  */
char szClassName[ ] = "CodeBlocksWindowsApp";
/////////////////////////////////////////////////////////////////////////////////
RECT rcOkno;
HBITMAP CreateBitmapMask(HBITMAP hbmColour, COLORREF crTransparent);
HBITMAP bmp_0=(HBITMAP) LoadImage(NULL, "Shooters_0.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE),
   	bmp_0Mask=CreateBitmapMask(bmp_0, 0xff00ff),
   	bmp_1=(HBITMAP) LoadImage(NULL, "Shooters_1.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE),
   	bmp_1Mask=CreateBitmapMask(bmp_1, 0xff00ff);
int shootX=0;
struct PLAYER
{
int x;
int y;
int hp;
bool const colour;
bool dir;
int jump;
int jumpWait;
bool jumpUp;
bool jumpDown;
int shootWait;
};
PLAYER Red=
{
20,
280,
5,
0,
0,
0,
0,
0,
0,
0,
};
PLAYER Blue=
{
310,
280,
5,
1,
1,
0,
0,
0,
0,
0,
};
struct SHOOT
{
int x;
int y;
bool dir;
int state;
};
/////////////////////////////////////////////////////////////////////////////////
HBITMAP CreateBitmapMask( HBITMAP hbmColour, COLORREF crTransparent )
{
HDC hdcMem, hdcMem2;
HBITMAP hbmMask, hbmOld, hbmOld2;
BITMAP bm;
GetObject( hbmColour, sizeof( BITMAP ), & bm );
hbmMask = CreateBitmap( bm.bmWidth, bm.bmHeight, 1, 1, NULL );
hdcMem = CreateCompatibleDC( NULL );
hdcMem2 = CreateCompatibleDC( NULL );
hbmOld =( HBITMAP ) SelectObject( hdcMem, hbmColour );
hbmOld2 =( HBITMAP ) SelectObject( hdcMem2, hbmMask );
SetBkColor( hdcMem, crTransparent );
BitBlt( hdcMem2, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY );
BitBlt( hdcMem, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem2, 0, 0, SRCINVERT );
SelectObject( hdcMem, hbmOld );
SelectObject( hdcMem2, hbmOld2 );
DeleteDC( hdcMem );
DeleteDC( hdcMem2 );
return hbmMask;
}
void RysZiemia(HDC hdc)
{
HPEN pen=CreatePen(PS_SOLID, 3, 0x000000);
SelectObject(hdc, pen);
MoveToEx(hdc, 0, 280, 0);
LineTo(hdc, 360, 280);
}
void RysHP(PLAYER ply, HDC hdc, HDC pomoc)
{
SelectObject(pomoc, bmp_0);
BitBlt(hdc, 290*ply.colour+10, 10, 50, 10, pomoc, 60, 20*ply.colour, SRCCOPY);
BitBlt(hdc, 290*ply.colour+10, 10, 10*ply.hp, 10, pomoc, 60, 20*ply.colour+10, SRCCOPY);
SelectObject(pomoc, bmp_1Mask);
BitBlt(hdc, 250*ply.colour+50, 10, 10, 10, pomoc, 10*ply.hp, 0, SRCAND);
SelectObject(pomoc, bmp_1);
BitBlt(hdc, 250*ply.colour+50, 10, 10, 10, pomoc, 10*ply.hp, 0, SRCPAINT);
}
void RysPlayer(PLAYER ply, HDC hdc, HDC pomoc)
{
SelectObject(pomoc, bmp_0Mask);
BitBlt(hdc, ply.x, ply.y-40, 30, 40, pomoc, 30*ply.colour, 0, SRCAND);
SelectObject(pomoc, bmp_0);
BitBlt(hdc, ply.x, ply.y-40, 30, 40, pomoc, 30*ply.colour, 0, SRCPAINT);
SelectObject(pomoc, bmp_1Mask);
BitBlt(hdc, ply.x+30-40*ply.dir, ply.y-40, 10, 10, pomoc, 10*ply.dir, 10, SRCAND);
SelectObject(pomoc, bmp_1);
BitBlt(hdc, ply.x+30-40*ply.dir, ply.y-40, 10, 10, pomoc, 10*ply.dir, 10, SRCPAINT);
}
void RysBluePlayer(HDC hdc, HDC pomoc)
{
SelectObject(pomoc, bmp_0Mask);
BitBlt(hdc, Blue.x, Blue.y-40, 30, 40, pomoc, 30, 0, SRCAND);
SelectObject(pomoc, bmp_0);
BitBlt(hdc, Blue.x, Blue.y-40, 30, 40, pomoc, 30, 0, SRCPAINT);
SelectObject(pomoc, bmp_1Mask);
BitBlt(hdc, Blue.x+30-40*Blue.dir, Blue.y-40, 10, 10, pomoc, 10*Blue.dir, 10, SRCAND);
SelectObject(pomoc, bmp_1);
BitBlt(hdc, Blue.x+30-40*Blue.dir, Blue.y-40, 10, 10, pomoc, 10*Blue.dir, 10, SRCPAINT);
}
void RysShoot(HDC hdc, HDC pomoc)
{
SelectObject(pomoc, bmp_1);
BitBlt(hdc, shootX, Red.y-40, 10, 4, pomoc, 30, 10, SRCCOPY);
}
void paint(HWND hwnd)
{
PAINTSTRUCT ps;
HDC hdcPaint=BeginPaint(hwnd, &ps);
HDC hdc=GetDC(hwnd);
HDC pomoc=CreateCompatibleDC(hdc);
HDC buf=CreateCompatibleDC(hdc);
HBITMAP bmBuf=CreateCompatibleBitmap(buf, rcOkno.right, rcOkno.bottom);
SelectObject(buf, bmBuf);
FillRect(buf, &rcOkno,(HBRUSH) GetStockObject(LTGRAY_BRUSH));
RysZiemia(buf);
RysHP(Red, buf, pomoc);
RysHP(Blue, buf, pomoc);
RysPlayer(Red, buf, pomoc);
RysPlayer(Blue, buf, pomoc);
RysShoot(buf, pomoc);
BitBlt(hdc, 0, 0, rcOkno.right, rcOkno.bottom, buf, 0, 0, SRCCOPY);
ReleaseDC(hwnd, hdc);
DeleteDC(pomoc);
DeleteDC(buf);
DeleteObject(bmBuf);
EndPaint(hwnd, &ps);
}
void jumpUp(PLAYER &ply)
{
ply.y-=ply.jump;
switch (ply.jump)
{
   	case 5:
   	{
       	if(ply.jumpWait==1)
       	{
           	ply.jump--;
           	ply.jumpWait=4;
       	}
       	else
       	{
           	ply.jumpWait--;
       	}
   	}break;
   	case 4:
   	{
       	if(ply.jumpWait==1)
       	{
           	ply.jump--;
           	ply.jumpWait=7;
       	}
       	else
       	{
           	ply.jumpWait--;
       	}
   	}break;
   	case 3:
   	{
       	if(ply.jumpWait==1)
       	{
           	ply.jump--;
           	ply.jumpWait=5;
       	}
       	else
       	{
           	ply.jumpWait--;
       	}
   	}break;
   	case 2:
   	{
       	if(ply.jumpWait==1)
       	{
           	ply.jump--;
           	ply.jumpWait=4;
       	}
       	else
       	{
           	ply.jumpWait--;
       	}
   	}break;
   	case 1:
   	{
       	if(ply.jumpWait==1)
       	{
           	ply.jumpUp=0;
           	ply.jumpDown=1;
           	ply.jumpWait=4;
           	ply.jump=1;
       	}
       	else
       	{
           	ply.jumpWait--;
       	}
   	}break;
}
}
void jumpDown(PLAYER &ply)
{
ply.y+=ply.jump;
switch (ply.jump)
{
   	case 1:
   	{
       	if(ply.jumpWait==1)
       	{
           	ply.jump++;
           	ply.jumpWait=5;
       	}
       	else
       	{
           	ply.jumpWait--;
       	}
   	}break;
   	case 2:
   	{
       	if(ply.jumpWait==1)
       	{
           	ply.jump++;
           	ply.jumpWait=7;
       	}
       	else
       	{
           	ply.jumpWait--;
       	}
   	}break;
   	case 3:
   	{
       	if(ply.jumpWait==1)
       	{
           	ply.jump++;
           	ply.jumpWait=4;
       	}
       	else
       	{
           	ply.jumpWait--;
       	}
   	}break;
   	case 4:
   	{
       	if(ply.jumpWait==1)
       	{
           	ply.jump++;
           	ply.jumpWait=3;
       	}
       	else
       	{
           	ply.jumpWait--;
       	}
   	}break;
   	case 5:
   	{
       	if(ply.jumpWait==1)
       	{
           	ply.jumpDown=0;
           	ply.jumpWait--;
       	}
       	else
       	{
           	ply.jumpWait--;
       	}
   	}break;
}
}

Zmiany, które wprowadziłem są tylko w funkcji paint() i według mnie tylko w niej znajduje się błąd.

Link do komentarza
Udostępnij na innych stronach

Poszukałem w google i w końcu znalazłem, że przy tworzeniu bitmapy bufora wystarczyło podać kontekst pamięciowy okna, a nie bufora:

HBITMAP bmBuf=CreateCompatibleBitmap(hdc, rcOkno.right, rcOkno.bottom);

zamiast:

HBITMAP bmBuf=CreateCompatibleBitmap(buf, rcOkno.right, rcOkno.bottom);

Link do komentarza
Udostępnij na innych stronach

Zarchiwizowany

Ten temat jest archiwizowany i nie można dodawać nowych odpowiedzi.

×
×
  • Utwórz nowe...