物体匀速运动的实现

本文介绍了一个使用Windows API和C++实现的简单二维物体运动模拟程序。该程序通过不断更新物体的位置并重新绘制,来展示物体在碰撞墙壁时的速度反转效果。程序还实现了基本的键盘监听功能,允许用户通过按下ESC键退出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

 

#include <Windows.h>
#include <iostream>

 

const int X=200,Y=50;    //程序窗口左上角相对于屏幕的坐标 
const int WIDTH=640,HEIGHT=480;  // //程序窗口的宽与高

 

DWORD tPre,tNow;      //tPre记录上一次绘图的时间,tNow记录此次准备绘图的时间
int x=50,y=50,vx=10,vy=10;   //x、y表示物体的初始位置,vx、vy表示物体在x方向与y方向的速度变化量

 

HDC hdc,mdc,bufdc;
HBITMAP bg,dra;
RECT rect;

 

void MyPaint(HDC);
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);

 

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
 const std::string szTitle="匀速运动";

 WNDCLASS winclass={CS_HREDRAW|CS_VREDRAW,WndProc,0,0,hInstance,LoadIcon(NULL,IDI_APPLICATION),
  LoadCursor(NULL,IDC_ARROW),(HBRUSH)GetStockObject(WHITE_BRUSH),NULL,szTitle.c_str()};

 if(!RegisterClass(&winclass))
  return false;

 HWND hWnd=CreateWindow(szTitle.c_str(),szTitle.c_str(),WS_OVERLAPPEDWINDOW,X,Y,WIDTH,HEIGHT,
  NULL,NULL,winclass.hInstance,NULL);

 if(0==hWnd)
  return 0;

 ShowWindow(hWnd,SW_SHOWDEFAULT);
 UpdateWindow(hWnd);

 MSG msg;
 ZeroMemory(&msg,sizeof(MSG));

 while(msg.message!=WM_QUIT)
 {
  if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
  {
   TranslateMessage(&msg);
   DispatchMessage(&msg);
  }
  else
  {
   tNow=GetTickCount(); 
   while(tNow-tPre>=100)  //tNow-tRre:当此次循环运行与上次绘图时间相差0.1秒时再进行重绘操作
    MyPaint(hdc);
  }
 }
 return msg.wParam;
}

 

LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
 HBITMAP bmp;

 switch(message)
 {
 case WM_CREATE:
  {
   hdc=GetDC(hWnd);
   mdc=CreateCompatibleDC(hdc);
   bufdc=CreateCompatibleDC(hdc);
   bmp=CreateCompatibleBitmap(hdc,WIDTH,HEIGHT);
   SelectObject(mdc,bmp);

   //加载物体位图
   bg=(HBITMAP)LoadImage(NULL,"bg.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
   dra=(HBITMAP)LoadImage(NULL,"dra.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);

   GetClientRect(hWnd,&rect);  //取得内部窗口区域大小
  }
  break;

 case WM_KEYDOWN:
  {
   if(wParam==VK_ESCAPE)
    DestroyWindow(hWnd);
  }
  break;

 case WM_DESTROY:
  {
   DeleteDC(bufdc);
   DeleteDC(mdc);
   DeleteObject(bg);
   DeleteObject(dra);
   ReleaseDC(hWnd,hdc);
   PostQuitMessage(0);
  }
  break;

 default:
  return DefWindowProc(hWnd,message,wParam,lParam);
 }
 return 0;
}

 

void MyPaint(HDC hdc)
{
 //贴背景图
 SelectObject(bufdc,bg);
 BitBlt(mdc,0,0,WIDTH,HEIGHT,bufdc,0,0,SRCCOPY);

 //贴物体图
 SelectObject(bufdc,dra);
 BitBlt(mdc,x,y,50,50,bufdc,50,0,SRCAND);
 BitBlt(mdc,x,y,50,50,bufdc,0,0,SRCPAINT);
 BitBlt(hdc,0,0,WIDTH,HEIGHT,mdc,0,0,SRCCOPY);

 

 //计算x轴方向物体坐标与速度
 x+=vx;
 if(x<=0)
 {
  x=0;
  vx=-vx;
 }

 else if(x>=rect.right-50)
 {
  x=rect.right-50;
  vx=-vx;
 }

 

 //计算y轴方向物体坐标与速度
 y+=vy;
 if(y<=0)
 {
  y=0;
  vy=-vy;
 }

 else if(y>=rect.bottom-50)
 {
  y=rect.bottom-50;
  vy=-vy;
 }

 

 //记录此次绘图时间
 tPre=GetTickCount();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值