#include <windows.h> #include "ball.h" #include "math.h" #define NUM 2 ball * b[NUM]; bool cb; STATE ballstate[NUM][NUM]; const char g_szClassName[] = "myWindowClass"; void Init(); speedVec unit(speedVec temp); void GameAction(HWND hWnd); enum WHERE { CORRECT , SL, }; WHERE wh; LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_CREATE: Init(); break; case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wc; HWND hwnd; MSG Msg; wc.cbSize = sizeof(WNDCLASSEX); wc.style = 0; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName = NULL; wc.lpszClassName = g_szClassName; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if(!RegisterClassEx(&wc)) { MessageBox(NULL, "Window Registration Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; } hwnd = CreateWindowEx( WS_EX_CLIENTEDGE, g_szClassName, "M", WS_OVERLAPPEDWINDOW| WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 800, 600, NULL, NULL, hInstance, NULL); if(hwnd == NULL) { MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK); return 0; } ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); //InvalidateRect(hwnd,NULL,TRUE); //强制刷新窗口 /* 消息循环 */ while(true) { if(PeekMessage(&Msg,NULL,0,0,PM_REMOVE)) //接收消息 { if(Msg.message==WM_QUIT) //如果是退出消息,则退出循环 break; TranslateMessage(&Msg); //将虚拟键消息转换为字符消息 DispatchMessage(&Msg); //处理消息 } else { GameAction(hwnd); } } return Msg.wParam; } void Init() { cb = TRUE; POINT pt1; pt1.x = 170; pt1.y = 150; speedVec V1; V1.x = 0; V1.y = 3; b[0] = new ball(pt1,V1); POINT pt2; pt2.x = 170; pt2.y = 350; speedVec V2; V2.x = -0; V2.y = -4; b[1] = new ball(pt2,V2); POINT pt3; pt3.x = 500; pt3.y = 230; speedVec V3; V3.x = -3; V3.y = 5; b[2] = new ball(pt3,V3); POINT pt4; pt4.x = 400; pt4.y = 300; speedVec V4; V4.x = 3; V4.y = -4; b[3] = new ball(pt4,V4); POINT pt5; pt5.x = 100; pt5.y = 200; speedVec V5; V5.x = 2; V5.y =-1; b[3] = new ball(pt5,V5); POINT pt6; pt6.x = 200; pt6.y = 350; speedVec V6; V6.x = 0.3; V6.y = 3; b[5] = new ball(pt6,V6); POINT pt7; pt7.x = 170; pt7.y = 270; speedVec V7; V7.x = 3; V7.y = 3; b[6] = new ball(pt7,V7); POINT pt8; pt8.x = 480; pt8.y = 380; speedVec V8; V8.x = 3; V8.y = 0.8; b[7] = new ball(pt8,V8); POINT pt9; pt9.x = 190; pt9.y = 200; speedVec V9; V9.x = 5; V9.y = 3; b[8] = new ball(pt9,V9); POINT pt10; pt10.x = 420; pt10.y = 300; speedVec V10; V10.x = 1; V10.y = 2; b[9] = new ball(pt10,V10); for( int i= 0;i<NUM;i++) for (int j = 0;j < NUM;j++) { ballstate[i][i] = NO; } } void GameAction(HWND hWnd) { HBITMAP hbm; HDC dchbm; HDC hDC; hDC = GetDC(hWnd); dchbm=CreateCompatibleDC(hDC); hbm = CreateBitmap(800,600, 1, 1, NULL); ;//创建存放图象的显示缓 ::SelectObject (dchbm,hbm); ::Sleep (100); UpdateWindow(hWnd); double dis ; double temp; for (int i = 0;i< NUM;i++) for( int j = 0;j < NUM && i!=j;j++) { if(ballstate[i][j] == NO)//两球没有撞 { if(b[i]->m_s == NO) //球i没有碰面 { b[i]->m_pt.x += b[i]->m_V.x; b[i]->m_pt.y += b[i]->m_V.y; } if(b[i]->m_s == YES) { b[i]->m_pt.x += b[i]->m_newV.x; b[i]->m_pt .y += b[i]->m_newV.y; b[i]->m_V =b[i]->m_newV; } if(b[j]->m_s == NO) //球j没有碰面 { b[j]->m_pt.x += b[j]->m_V.x; b[j]->m_pt.y += b[j]->m_V.y; } if(b[j]->m_s == YES) { b[j]->m_pt.x += b[j]->m_newV.x; b[j]->m_pt.y += b[j]->m_newV.y; b[j]->m_V =b[j]->m_newV; } } if( ballstate[i][j] == YES) //两球相撞 { b[i]->m_pt.x += b[i]->m_V.x; b[i]->m_pt.y += b[i]->m_V.y; b[j]->m_pt.x += b[j]->m_V.x; b[j]->m_pt.y += b[j]->m_V.y; b[i]->m_V = b[i]->m_newV; b[j]->m_V = b[j]->m_newV; } temp = (b[i]->m_pt.x - b[j]->m_pt.x)* (b[i]->m_pt.x - b[j]->m_pt.x) + (b[i]->m_pt.y - b[j]->m_pt.y)* (b[i]->m_pt.y - b[j]->m_pt.y); dis = sqrt (temp); if ( dis > b[i]->m_r + b[i]->m_r) { cb = TRUE; } if(dis <=b[i]->m_r + b[i]->m_r && cb == TRUE) { //MessageBox(NULL,"sdf","df",NULL); ballstate[i][j] = YES; double dx,dy; dx = b[j]->m_pt.x -b[i]->m_pt.x; dy = b[j]->m_pt.y -b[i]->m_pt.y; double ax,ay ; ax = dx / dis; ay = dy / dis; if( b[j]->m_V .x * b[i]->m_V .x <= 0 || b[j]->m_V .y * b[i]->m_V .y <= 0 ) { speedVec pt1pt2;//两球连线向量 pt1pt2.x = b[j]->m_pt.x - b[i]->m_pt.x; pt1pt2.y = b[j]->m_pt.y - b[i]->m_pt.y; speedVec Normal;//两球连线向量 if( pt1pt2.y == 0 && pt1pt2.x == 0) { }else if( pt1pt2.y == 0 && pt1pt2.x != 0) { Normal.x = 1 ; Normal.y = 0; wh = CORRECT; }else if( pt1pt2.x == 0 && pt1pt2.y != 0) { Normal.x = 0 ; Normal.y = 1; wh = CORRECT; } else if( pt1pt2.y != 0 && pt1pt2.y != 0 ) { speedVec t; t.x = - pt1pt2.y/pt1pt2.x ; //法向量 t.y = 1; double s; s = t.x * t.x + t.y * t.y; double d; d = sqrt (s ); Normal.x = t .x / d ; //法向量 Normal.y = t .y / d; wh = SL; } switch(wh) { case CORRECT: speedVec Ni,Nj; double temp_i,temp_j; temp_i = -( b[i]->m_V.x * Normal.x + b[i]->m_V.y * Normal.y) ; temp_j = -( b[j]->m_V.x * Normal.x + b[j]->m_V.y * Normal.y) ; Ni.x = temp_i * Normal.x ; Ni.y = temp_i * Normal.y ; Nj.x = temp_j * Normal.x ; Nj.y = temp_j * Normal.y ; b[i]->m_newV.x =2*Ni.x + b[i]->m_V.x; b[i]->m_newV.y =2*Ni.y + b[i]->m_V.y; b[j]->m_newV.x =2*Nj.x + b[j]->m_V.x; b[j]->m_newV.y =2*Nj.y + b[j]->m_V.y; cb = false ; break; case SL: double tem_i,tem_j; tem_i= b[i]->m_V.x * b[i]->m_V.x + b[i]->m_V.y * b[i]->m_V.y; tem_j= b[j]->m_V.x * b[j]->m_V.x + b[j]->m_V.y * b[j]->m_V.y; double S_i = sqrt (tem_i); double S_j = sqrt (tem_j); double tempVn_i,tempVn_j; tempVn_i = S_i * ax; tempVn_j = S_j * ay; speedVec Vn_i,Vn_j; Vn_i.x = tempVn_i * Normal.x; Vn_i.y = tempVn_i * Normal.y; Vn_j.x = tempVn_j * Normal.x; Vn_j.y = tempVn_j * Normal.y; double tempVt_i,tempVt_j; tempVt_i = S_i * ay; tempVt_j = S_j * ax; speedVec Vt_i,Vt_j; Vt_i.x = tempVn_i * Normal.x; Vt_i.y = tempVn_i * Normal.y; Vt_j.x = tempVn_j * Normal.x; Vt_j.y = tempVn_j * Normal.y; b[i]->m_newV.x =Vt_i.x - Vn_i.x; b[i]->m_newV.y =Vt_i.y - Vn_i.y; b[j]->m_newV.x = Vt_j.x - Vn_j.x; b[j]->m_newV.y = Vt_j.y - Vn_j.y; break; } } } } for (int i = 0; i < NUM;i++) { b[i]->drawEllipse(dchbm);//显示 b[i]->checkAge(); b[i]->moveBall();//运动 b[i]->colliteSur(); } ::BitBlt (hDC,0,0,800,600,dchbm,0,0,SRCCOPY); UpdateWindow(hWnd); DeleteDC(hDC); DeleteDC(dchbm); DeleteObject (hbm); DeleteObject (SelectObject (dchbm,hbm)); }