#include <windows.h> #include "ball.h" #include "math.h" #define NUM 4 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, BL, }; 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 = 100; pt1.y = 150; speedVec V1; V1.x = 5; V1.y = 3; b[0] = new ball(pt1,V1); POINT pt2; pt2.x = 280; pt2.y = 350; speedVec V2; V2.x = -3; 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[4] = 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; //if( b[j]->m_V .x * b[i]->m_V .x >= 0 || b[j]->m_V .y * b[i]->m_V .y >= 0 ) //{ // wh = BL; // goto a; //} 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; // speedVec t; //t.x = - pt1pt2.y/pt1pt2.x ; //法向量 //t.y = 1; double s; s = pt1pt2.x * pt1pt2.x + pt1pt2.y * pt1pt2.y; double d; d = sqrt (s ); Normal.x = pt1pt2 .x / d ; //法向量 Normal.y = pt1pt2 .y / d; wh = SL; } a: speedVec Ni,Nj; double temp_i,temp_j; switch(wh) { case CORRECT: 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: 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 BL: speedVec pt1_pt2;//两球连线向量 // pt1_pt2.x = b[j]->m_pt.x - b[i]->m_pt.x; // pt1_pt2.y = b[j]->m_pt.y - b[i]->m_pt.y; // // // speedVec pt1_pt2_unit;//两球连线单位向量 // if( pt1_pt2.y == 0 && pt1_pt2.x == 0) // { // }else if( pt1_pt2.y == 0 && pt1_pt2.x != 0) // { // pt1_pt2_unit.x = 1 ; // pt1_pt2_unit.y = 0; // }else if( pt1_pt2.x == 0 && pt1_pt2.y != 0) // { // pt1_pt2_unit.x = 0 ; // pt1_pt2_unit.y = 1; // } // else if( pt1_pt2.y != 0 && pt1_pt2.y != 0 ) // { // double s; // s = pt1_pt2.x * pt1_pt2.x + pt1_pt2.y * pt1_pt2.y; // double d; // d = sqrt (s ); // // pt1_pt2_unit.x = pt1_pt2.x/d ; // pt1_pt2_unit.y = pt1_pt2.y/d; // } // // speedVec pt1_pt2_unit_normal;//两球连线法单位向量 // if( pt1_pt2_unit.y == 0 && pt1_pt2_unit.x == 0) // { // }else if( pt1_pt2_unit.y == 0 && pt1_pt2_unit.x != 0) // { // pt1_pt2_unit_normal.x = 0 ; // pt1_pt2_unit_normal.y = 1; // }else if( pt1_pt2_unit.x == 0 && pt1_pt2_unit.y != 0) // { // pt1_pt2_unit_normal.x = 1 ; // pt1_pt2_unit_normal.y = 0; // } // else if( pt1_pt2_unit.y != 0 && pt1_pt2_unit.y != 0 ) // { // speedVec t; // t.x = - pt1_pt2_unit.y/pt1_pt2_unit.x ; //法向量 // t.y = 1; // // double s; // s = t.x * t.x + t.y * t.y; // double d; // d = sqrt (s ); // pt1_pt2_unit_normal.x = t .x / d ; // pt1_pt2_unit_normal.y = t .y / d; // } // // // double temp_i,temp_j; // temp_i= b[i]->m_V.x * b[i]->m_V.x + b[i]->m_V.y * b[i]->m_V.y; // temp_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 (temp_i); // double S_j = sqrt (temp_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 * pt1_pt2_unit.x; // Vn_i.y = tempVn_i * pt1_pt2_unit.y; // Vn_j.x = tempVn_j * pt1_pt2_unit.x; // Vn_j.y = tempVn_j * pt1_pt2_unit.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 * pt1_pt2_unit_normal.x; // Vt_i.y = tempVn_i * pt1_pt2_unit_normal.y; // Vt_j.x = tempVn_j * pt1_pt2_unit_normal.x; // Vt_j.y = tempVn_j * pt1_pt2_unit_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)); }