简易的Win32小球碰撞程序

Posted 独饮月色的猫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了简易的Win32小球碰撞程序相关的知识,希望对你有一定的参考价值。

//--------------------------------------------------------------
// - classes.cpp 
// -        To define different classes 
//--------------------------------------------------------------



// Marcos and constants
#define TITLE_NAME "Running Ball"
#define WINDOW_CLASS_NAME "DrimoonA1"


#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)


	
const int WINDOW_WIDTH = GetSystemMetrics(SM_CXFULLSCREEN);
const int WINDOW_HEIGHT = (GetSystemMetrics(SM_CYFULLSCREEN)+77);



// Structs and Classes
struct Point

	int x, y;
;

class Velo

public:
	int vx, vy;
	Velo()
	
		vx=0, vy=0;
	

	double GetVelo();
;

class Ball

public:
	Point p;
	Velo v;
    int r;
	HPEN pen;

public:
	Ball();
	void InitPos(int, int);
	void DrawBall(HDC hDC);
	void Control();
	void Process();
    bool IsCollision(Ball* ball);
	void SwapVelo(Ball* ball);
;



//--------------------------------------------------------------
// - functions.cpp 
// -        To define functions of different classes 
//--------------------------------------------------------------


#include <windows.h>



#include <cmath>

#include "classes.h"


// Point class function

              

// Velo class function
double Velo::GetVelo()

    return sqrt(vx*vx+vy*vy);




// Ball class function
Ball::Ball()

    p.x=50, p.y=50;
	v.vx=10, v.vy=10;
	r=50;
	pen=NULL;




void Ball::InitPos(int x0, int y0)

	p.x=x0, p.y=y0;



void Ball::DrawBall(HDC hDC)

	Arc(hDC,p.x-r,p.y-r,p.x+r,p.y+r,0,0,0,0);



void Ball::Control()

	
	if (KEYDOWN(VK_DOWN))
    
		v.vy++;
	 
	if (KEYDOWN(VK_UP))
    
        v.vy--;
	 
	if (KEYDOWN(VK_LEFT))
    
        v.vx--;
	 
	if (KEYDOWN(VK_RIGHT))
    
        v.vx++;
	 
	if (KEYDOWN(VK_SPACE))
    
        v.vx=0, v.vy=0;
	 



void Ball::Process()

	
	   p.x += v.vx;	
	   p.y += v.vy;

       if (p.x <= r || p.x >= WINDOW_WIDTH - r)
          

            v.vx = -v.vx;

            p.x += v.vx;
          

       if (p.y <= r || p.y >= WINDOW_HEIGHT - r)
          

            v.vy = -v.vy;

            p.y += v.vy;			
          




bool Ball::IsCollision(Ball* ball)

	int disX = (this->p.x+this->v.vx)-(ball->p.x+ball->v.vx);
	int disY = (this->p.y+this->v.vy)-(ball->p.y+ball->v.vy);

	int dis = disX*disX+disY*disY;

	if(dis <= 4*r*r)
		return true;
	return false;


void Ball::SwapVelo(Ball* ball)


	Velo tmp;
    tmp = v;
	v = ball->v;
	ball->v = tmp;




//--------------------------------------------------------------
// - main.cpp 
// -        To demo Running Ball 
//--------------------------------------------------------------

#include <windows.h>

#include <ctime>

#include "classes.h"
#define WIN32_LEAN_AND_MEAN

// Global varibles	
HDC g_hDC=NULL; 

const int BALL_NUM = 10;

Ball ball[BALL_NUM];

RECT rect=0,0,WINDOW_WIDTH,WINDOW_HEIGHT;

HBRUSH myBrush = (HBRUSH)GetStockObject(WHITE_BRUSH);


// Function prototype
ATOM			MyRegisterClass(HINSTANCE hInstance);   
BOOL			InitInstance(HINSTANCE, int);         
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);

void Erase();
void Frame();


// WinMain
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)

	HWND  hWnd;
	MSG   msg;
    int i;

   
	MyRegisterClass(hInstance);   

        hWnd = CreateWindowEx(NULL,              
                  WINDOW_CLASS_NAME, 
			      TITLE_NAME,            
			      WS_POPUP | WS_VISIBLE,  
			      0,0,	  
			      WINDOW_WIDTH,WINDOW_HEIGHT, 
			      NULL,	  
			      NULL,	  
			      hInstance,  
			      NULL);	  
      
        if(!hWnd)
		   return 0;

        SetWindowLong(hWnd,GWL_EXSTYLE,GetWindowLong(hWnd,GWL_EXSTYLE)|WS_EX_LAYERED);
        SetLayeredWindowAttributes(hWnd,0,220,LWA_ALPHA);
  
	    g_hDC=GetDC(hWnd);
        
        srand((unsigned)(time(0)));


        for(i=0;i<BALL_NUM;i++)
		
            ball[i].InitPos(ball[i].r+rand()%(WINDOW_WIDTH-2*ball[i].r),ball[i].r+rand()%(WINDOW_HEIGHT-2*ball[i].r));
           
		

		for (i = 0; i < BALL_NUM; i++)
		
			for (int j = i + 1; j < BALL_NUM; j++)
			
				if (ball[i].IsCollision(&ball[j]))
				
					ball[i].InitPos(ball[i].r + rand() % (WINDOW_WIDTH - 2 * ball[i].r), ball[i].r + rand() % (WINDOW_HEIGHT - 2 * ball[i].r));
				
			
		


        while(TRUE)
	  

			DWORD start_time = GetTickCount();

	     if( PeekMessage(&msg,NULL,0,0,PM_REMOVE) )
	     
           if(msg.message == WM_QUIT)
                   break;
	
	       TranslateMessage(&msg);

	       DispatchMessage(&msg);
	     
     
      
         Frame();

	     while((GetTickCount() - start_time) < 33);
       
	     if (KEYDOWN(VK_ESCAPE))
             SendMessage(hWnd, WM_CLOSE, 0, 0); 
       
	  

     

      return msg.wParam;



// Register window class
ATOM MyRegisterClass(HINSTANCE hInstance)

	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX); 

	wcex.style			= CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
	wcex.lpfnWndProc	= (WNDPROC)WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon		    = LoadIcon(hInstance, IDI_APPLICATION);
	wcex.hCursor		= LoadCursor(hInstance, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)GetStockObject(WHITE_BRUSH);
	wcex.lpszMenuName	= NULL;
	wcex.lpszClassName	= WINDOW_CLASS_NAME;
	wcex.hIconSm		= NULL;

	return RegisterClassEx(&wcex);


void Erase()
       
        SelectObject(g_hDC,myBrush);
		FillRect(g_hDC,&rect,myBrush);
		DeleteObject(myBrush);
 

void Frame()


	int i;

	Erase();

 	ball[0].Control();


	for(i=0; i<BALL_NUM; i++)
	    
		switch(i%6)
		
		case 0:			
            ball[i].pen=CreatePen(PS_SOLID,3,RGB(255,0,0));
			SelectObject(g_hDC,ball[i].pen);
			break;

		case 1:		
            ball[i].pen=CreatePen(PS_SOLID,3,RGB(0,255,80));
			SelectObject(g_hDC,ball[i].pen);
			break;

		case 2:		
            ball[i].pen=CreatePen(PS_SOLID,3,RGB(0,0,255));
			SelectObject(g_hDC,ball[i].pen);
			break;

		case 3:		
            ball[i].pen=CreatePen(PS_SOLID,3,RGB(0,255,200));
			SelectObject(g_hDC,ball[i].pen);
			break;

		case 4:		
            ball[i].pen=CreatePen(PS_SOLID,3,RGB(125,0,255));
			SelectObject(g_hDC,ball[i].pen);
			break;

		case 5:		
            ball[i].pen=CreatePen(PS_SOLID,3,RGB(255,120,0));
			SelectObject(g_hDC,ball[i].pen);
			break;

		default:
			break;
		
     	
       	ball[i].DrawBall(g_hDC);

		DeleteObject(ball[i].pen);
		ball[i].Process();
	
    
	for(i=0; i<BALL_NUM; i++)
	
		for(int j=i+1; j<BALL_NUM; j++)
		
			if(ball[i].IsCollision(&ball[j]))
			
				ball[i].SwapVelo(&ball[j]);
                  

				//PlaySound(".\\\\Hit.wav",NULL,SND_ALIAS|SND_ASYNC);
			
				Ball tmp;
				tmp=ball[i];
				ball[i]=ball[j];
				ball[j]=tmp;               
			
		
	
    
 


// Window Process
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

	PAINTSTRUCT ps;
	HDC hdc;



	switch (message) 
	
	    case WM_CREATE:
		

			return 0;
		

		case WM_TIMER:
		

			return 0;
		
		case WM_PAINT:
				  
		    hdc = BeginPaint(hWnd, &ps);

			RECT rt;
			GetClientRect(hWnd, &rt);

			EndPaint(hWnd, &ps);
			return 0;
		

		case WM_DESTROY:
		

			PostQuitMessage(0);

			return 0;
		

		default: break;
	 

    return DefWindowProc(hWnd, message, wParam, lParam);



注意:

1、Windows Application,纯Windows API写的,  #define WIN32_LEAN_AND_MEAN 表示不使用MFC相关内容。

2、小球碰撞的物理逻辑不够完善,非对心碰撞的物理逻辑尚未完成。

3、为什么没有注释?因为大多是一些框架代码,相信阅读起来很简单,只是代码看起来多一点。。。下次注意!

4、实现窗口半透明代码要用到WS_EX_LAYERED宏,此宏在VC++6.0那个年代里。。windows API中还没有加入Window EX Style。。所以请在高阶的VC++2005(就是VS2005装C++版本)啊什么的运行,当然了,你把它注释掉或者换用

SetWindowLong(hWnd,GWL_EXSTYLE,GetWindowLong(hWnd,GWL_EXSTYLE)^0x80000);
HINSTANCE hInst = LoadLibrary(_T("User32.DLL"));
if(hInst != NULL)

    typedef BOOL (WINAPI *MYFUNC)(HWND, COLORREF, BYTE, DWORD);
    MYFUNC pFunc=(MYFUNC)GetProcAddress(hInst,"SetLayeredWindowAttributes");
    if(pFunc!=NULL)
    
        pFunc(m_hWnd,0,220,2);
    
    FreeLibrary(hInst);
    hInst=NULL;

以上是关于简易的Win32小球碰撞程序的主要内容,如果未能解决你的问题,请参考以下文章

鸡年大吉,不知道写点啥,放个demo(小球碰撞)吧,有兴趣的看看

2019年春第四次程序设计实验报告

1-2018-3-2小球碰撞

小球碰撞

碰撞的小球 ccf (模拟)

canvas实现动态小球碰撞