Visual C++游戏编程基础之匀速运动

一、基本思路

1.匀速运动:物体在每一个时刻的速度是相同的,即Vx和Vy保持不变;

2.关于下次的贴图坐标:

                                     下次X的坐标=当前X的坐标 + Vx;

                                     下次Y的坐标=当前Y的坐标 + Vy;

3.设小球匀速运动,碰到窗口边缘则反弹;

二、效果

三、代码如下


#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=50,y=50,vx=20,vy=20;//小球的贴图坐标及速度分量

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,10,10,600,450,true);
	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);
	
	hdc = GetDC(hWnd);
	mdc = CreateCompatibleDC(hdc);
	bufdc = CreateCompatibleDC(hdc);
	bmp = CreateCompatibleBitmap(hdc,640,480);
	
	SelectObject(mdc,bmp);
	
	bg = (HBITMAP)LoadImage(NULL,"bg.bmp",IMAGE_BITMAP,640,480,LR_LOADFROMFILE);
	ball = (HBITMAP)LoadImage(NULL,"ball.bmp",IMAGE_BITMAP,52,26,LR_LOADFROMFILE);
	
	GetClientRect(hWnd,&rect);//取得内部窗口区域的大小;利用rect中的内容判断判断小球移动是否碰到窗口边缘
	
	MyPaint(hdc);
	
	return TRUE;
}
//1.窗口贴图
//2.计算小球贴图坐标并判断小球是否碰到窗口边缘
void MyPaint(HDC hdc)
{
	SelectObject(bufdc,bg);
	BitBlt(mdc,0,0,640,480,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,640,480,mdc,0,0,SRCCOPY);
	
	x += vx;
	if(x <= 0)
	{
		x = 0;
		vx = -vx;
	}
	else if(x >= rect.right-26)
	{
		x = rect.right - 26;//rect.right:矩形右下角x点的坐标
		vx = -vx;
	}
	
	y += vy;		
	if(y<=0)
	{
		y = 0;
		vy = -vy;
	}
	else if(y >= rect.bottom-26)
	{
		y = rect.bottom - 26;
		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/93136486
今日推荐