Visual C++游戏编程基础之摩擦力、加速度、重力

一、基本思路

1.假设小球在空中只受到重力作用,一开始给它一个水平的速度,就像是平抛运动一样;

2.当小球碰到地面时,受到摩擦力作用,分为x方向和y方向;

3.在摩擦力作用下,1.减少水平方向的速度,2减少y方向的速度,并把Vy取负,实现触底反弹的效果;

4.反弹过程Vy在重力作用下不断减小,Vx不变,直到Vy=0到达最高点,然后Vy在重力下为正,开始下落,因为Vy在摩擦力

   作用下减小了,所以这次反弹高度比第一次低,同样,Vx也在摩擦力作用下减小了,水平方向上移动的距离也变小了;

5.反复重复过程4,直到全为0;

二、效果

三、代码如下


#include "stdafx.h"
#include <stdio.h>

HINSTANCE hInst;
HBITMAP bg,ball;
HDC		hdc,mdc,bufdc;
HWND	hWnd;
DWORD	tPre,tNow,tCheck;
RECT	rect;
int		x=0,y=100,vx=8,vy=0;
int		gy=1,fx=-1,fy=-4;//fx表示摩擦力在x方向的负向加速度;fy表示摩擦力在y方向的负向加速的

ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
void				MyPaint(HDC hdc);

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
	MSG msg;
	
	MyRegisterClass(hInstance);
	
	if (!InitInstance (hInstance, nCmdShow)) 
	{
		return FALSE;
	}
	
    while( msg.message!=WM_QUIT )
    {
        if( PeekMessage( &msg, NULL, 0,0 ,PM_REMOVE) )
        {
            TranslateMessage( &msg );
            DispatchMessage( &msg );
        }
		else
		{
			tNow = GetTickCount();
			if(tNow-tPre >= 40)
				MyPaint(hdc);
		}
    }
	
	return msg.wParam;
}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;
	
	wcex.cbSize = sizeof(WNDCLASSEX); 
	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= (WNDPROC)WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= NULL;
	wcex.hCursor		= NULL;
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= NULL;
	wcex.lpszClassName	= "canvas";
	wcex.hIconSm		= NULL;
	
	return RegisterClassEx(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
	HBITMAP bmp;
	hInst = hInstance;
	
	hWnd = CreateWindow("canvas", "绘图窗口" , WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
	
	if (!hWnd)
	{
		return FALSE;
	}
	
	MoveWindow(hWnd,100,100,750,400,true);
	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);
	
	hdc = GetDC(hWnd);
	mdc = CreateCompatibleDC(hdc);
	bufdc = CreateCompatibleDC(hdc);
	bmp = CreateCompatibleBitmap(hdc,750,400);
	
	SelectObject(mdc,bmp);
	
	bg = (HBITMAP)LoadImage(NULL,"bg.bmp",IMAGE_BITMAP,750,400,LR_LOADFROMFILE);
	ball = (HBITMAP)LoadImage(NULL,"ball.bmp",IMAGE_BITMAP,52,26,LR_LOADFROMFILE);
	
	GetClientRect(hWnd,&rect);
	
	MyPaint(hdc);
	
	return TRUE;
}


void MyPaint(HDC hdc)
{
	SelectObject(bufdc,bg);
	BitBlt(mdc,0,0,750,400,bufdc,0,0,SRCCOPY);
	
	SelectObject(bufdc,ball);
	BitBlt(mdc,x,y,26,26,bufdc,26,0,SRCAND);
	BitBlt(mdc,x,y,26,26,bufdc,0,0,SRCPAINT);
	
	BitBlt(hdc,0,0,750,400,mdc,0,0,SRCCOPY);
	
	x += vx;
	
	vy = vy + gy;
	y += vy;
	
	if(y >= rect.bottom-26)
	{
		y = rect.bottom - 26;
		
		vx += fx;					
		if(vx < 0)
			vx = 0;
		
		vy += fy;
		if(vy < 0)
			vy = 0;
		
		vy = -vy;
	}
	
	tPre = GetTickCount();
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	case WM_KEYDOWN:
		if(wParam==VK_ESCAPE)
			PostQuitMessage(0);
		break;
	case WM_DESTROY:
		DeleteDC(mdc);
		DeleteDC(bufdc);
		DeleteObject(bg);
		DeleteObject(ball);
		ReleaseDC(hWnd,hdc);
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Sruggle/article/details/94409650
今日推荐