윈도우 프로그래밍으로 자동차 교차로 만드는데 문제가 있습니다
글쓴이: seungdam / 작성시간: 일, 2019/03/31 - 2:45오전
#include <windows.h> #include <windowsx.h> #include <TCHAR.h> #include <time.h> #include <math.h> #include <iostream> #include <cstdlib> #define BSIZE 50 HINSTANCE g_hInst; LPCTSTR lpszClass = L"Window Class Name"; LPCTSTR lpszWindowName = L"Window Programming LAb"; LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wPARAM, LPARAM lParam); int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow) { HWND hWnd; MSG Message; WNDCLASSEX WndClass; g_hInst = hInstance; WndClass.cbSize = sizeof(WndClass); WndClass.style = CS_HREDRAW | CS_VREDRAW; WndClass.lpfnWndProc = (WNDPROC)WndProc; WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.hInstance = hInstance; WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); WndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); WndClass.lpszMenuName = NULL; WndClass.lpszClassName = lpszClass; WndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); RegisterClassEx(&WndClass); hWnd = CreateWindow(lpszClass, lpszWindowName, WS_OVERLAPPEDWINDOW, 0, 0, 1400,1000, NULL, (HMENU)NULL, hInstance, NULL); ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); while (GetMessage(&Message, 0, 0, 0)) { TranslateMessage(&Message); DispatchMessage(&Message); } return Message.wParam; } double LengthPts(int x1, int y1, int x2, int y2) { return (sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1))); } BOOL InCircle(int x, int y, int mx, int my) { if (LengthPts(x, y, mx, my) < BSIZE) { return TRUE; } else { return FALSE; } } LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; static POINT xypos[8] = { {0,430},{100,470}, // 1번 버스 좌표 01 {1000,570},{900,530}, // 2번 버스 좌표 23 {570,0},{530,100}, // 3번 버스 좌표 45 {430,1000},{470,900} }; // 4번 버스 좌표 67 static POINT xypos_sub[8] = { {0,430},{0,470}, // 1번 좌표 버스 복사본 {1000,570},{1000,530}, // 2번 좌표 버스 복사본 {570,0},{530,0}, // 3번 좌표 버스 복사본 {430,1000},{470,1000} };// 4번 좌표 버스 static POINT xypos_human[2] = { {340,340},{370,370} }; HBRUSH blueBrush; HBRUSH yelloBrush; HBRUSH greenBrush; HBRUSH redBrush; HBRUSH oldBrush; HPEN oldpen, hpen; static int mouseXpos, mouseYpos; static int selectLight; static int speed1; static int speed2; static int speed3; static int speed4; static int stop[8]; // 1번버스 xypos 01 2번버스 23 3번 버스 45 4번 버스 56 switch (iMessage) { case WM_CREATE: selectLight = 0; SetTimer(hWnd, 1, 30, NULL); SetTimer(hWnd, 2, 2, NULL); SetTimer(hWnd, 3, 10, NULL); SetTimer(hWnd, 4, 2, NULL); break; case WM_CHAR: break; case WM_PAINT: // 파란불 if (selectLight == 3) { SetTimer(hWnd, 1, 30, NULL); SetTimer(hWnd, 2, 40, NULL); SetTimer(hWnd, 3, 50, NULL); SetTimer(hWnd, 4, 60, NULL); } // 멈췄다가 다시가기 if ((xypos[6].y < 400 || xypos[4].y > 600 ) && stop[0] == 1) { SetTimer(hWnd, 1, 30, NULL); stop[0] = 0; } else if ((xypos[4].y > 600 || xypos[6].y < 400 )&& stop[1] == 2) { SetTimer(hWnd, 2, 40, NULL); stop[1] = 0; } else if ((xypos[0].x > 600 || xypos[2].x < 400 ) && stop[2] == 3) { SetTimer(hWnd, 3, 30, NULL); stop[2] = 0; } else if ((xypos[0].x > 600 || xypos[2].x < 400) && stop[3] == 4) { SetTimer(hWnd, 4, 60, NULL); stop[3] = 0; } hdc = BeginPaint(hWnd, &ps); blueBrush = CreateSolidBrush(RGB(0, 0, 255)); yelloBrush = CreateSolidBrush(RGB(255, 255, 0)); greenBrush = CreateSolidBrush(RGB(0, 255, 0)); redBrush = CreateSolidBrush(RGB(255, 0, 0)); // ---- 맵 그리기 ---- Rectangle(hdc, 0, 0, 400, 400); Rectangle(hdc, 600, 0, 1000, 400); Rectangle(hdc, 0, 600, 400, 1000); Rectangle(hdc, 600, 600, 1000, 1000); Rectangle(hdc, 400, 400, 600, 600); hpen = CreatePen(PS_DASH, 1, RGB(150, 150, 150)); oldpen = (HPEN)SelectObject(hdc, hpen); MoveToEx(hdc, 500, 0, NULL); LineTo(hdc, 500, 1000); MoveToEx(hdc, 0, 500, NULL); LineTo(hdc, 1000, 500); SelectObject(hdc, oldpen); DeleteObject(hpen); DeleteObject(oldpen); //----- 신호등 그리기 ------ Rectangle(hdc, 1200, 0, 1400, 300); oldBrush = (HBRUSH)SelectObject(hdc, greenBrush); Ellipse(hdc, 1250, 0, 1350, 100); SelectObject(hdc, oldBrush); DeleteObject(oldBrush); oldBrush = (HBRUSH)SelectObject(hdc, yelloBrush); Ellipse(hdc, 1250, 100, 1350, 200); Ellipse(hdc, xypos_human[0].x, xypos_human[0].y, xypos_human[1].x, xypos_human[1].y); SelectObject(hdc, oldBrush); oldBrush = (HBRUSH)SelectObject(hdc, redBrush); Ellipse(hdc, 1250, 200, 1350, 300); SelectObject(hdc, oldBrush); DeleteObject(oldBrush); DeleteObject(yelloBrush); DeleteObject(redBrush); DeleteObject(greenBrush); // --- 자동차 그리기 --- oldBrush = (HBRUSH)SelectObject(hdc, blueBrush); // 새로운 브러시 선택하기 Rectangle(hdc, xypos[0].x, xypos[0].y, xypos[1].x, xypos[1].y); Rectangle(hdc, xypos[2].x, xypos[2].y, xypos[3].x, xypos[3].y); Rectangle(hdc, xypos[4].x, xypos[4].y, xypos[5].x, xypos[5].y); Rectangle(hdc, xypos[6].x, xypos[6].y, xypos[7].x, xypos[7].y); // -- 자동차 복사본 그리기 -- Rectangle(hdc, xypos_sub[0].x, xypos_sub[0].y, xypos_sub[1].x, xypos_sub[1].y); Rectangle(hdc, xypos_sub[2].x, xypos_sub[2].y, xypos_sub[3].x, xypos_sub[3].y); Rectangle(hdc, xypos_sub[4].x, xypos_sub[4].y, xypos_sub[5].x, xypos_sub[5].y); Rectangle(hdc, xypos_sub[6].x, xypos_sub[6].y, xypos_sub[7].x, xypos_sub[7].y); SelectObject(hdc, oldBrush); DeleteObject(blueBrush); DeleteObject(oldBrush); EndPaint(hWnd, &ps); break; case WM_TIMER: switch (wParam) { case 1: // 1번 버스; if (xypos[1].x < 1000 && xypos[0].x < 1000) { xypos[0].x += 5; xypos[1].x += 5; if (xypos[0].x >= 250 && xypos[1].x <= 400) { // 정지선에 위치할때 if ((xypos[7].y < 500 &&xypos[7].y > 400) || (xypos[5].y < 500 && xypos[4].y > 400) || (xypos[6].y < 500 && xypos[6].y > 400) || (xypos[4].y < 500 && xypos[4].y > 400)) { // 멈출 조건 KillTimer(hWnd, 1); stop[0] = 1; } else if (selectLight == 1) { KillTimer(hWnd, 1); } } } else if (xypos[0].x < 1000 && xypos[1].x == 1000) { xypos[0].x += 5; xypos_sub[1].x += 5; } else if (xypos[1].x == 1000 && xypos[0].x == 1000) { xypos_sub[1].x = 0; xypos[0].x = 0; xypos[1].x = 100; } break; case 2: // 2번 버스 if (xypos[3].x > 0 && xypos[2].x > 0) { xypos[2].x -= 5; xypos[3].x -= 5; if (xypos[2].x <= 750 && xypos[3].x >= 600 ) { // 정지선에 위치할때 if ((xypos[7].y < 600 && xypos[7].y > 500) || (xypos[5].y > 500 && xypos[5].y < 600) || (xypos[6].y < 600 && xypos[6].y > 500) || xypos[4].y > 500 && xypos[4].y < 600) { // 멈출 조건 KillTimer(hWnd, 2); stop[1] = 2; } else if (selectLight == 1) { KillTimer(hWnd, 2); } } } else if (xypos[2].x > 0 && xypos[3].x == 0) { xypos[2].x -= 5; xypos_sub[3].x -= 5; } else if (xypos[2].x == 0 && xypos[3].x == 0) { xypos_sub[3].x = 1000; xypos[2].x = 1000; xypos[3].x = 900; } break; case 3: if (xypos[4].y < 1000 && xypos[5].y < 1000) { xypos[4].y += 5; xypos[5].y += 5; if (xypos[4].y >= 250 && xypos[5].y <= 400) { // 정지선에 위치할때 if ((xypos[1].x < 600 && xypos[1].x > 500) || (xypos[3].x > 500 && xypos[3].x < 600) || (xypos[0].x < 600 && xypos[0].x > 500) || (xypos[2].x > 500 && xypos[2].x < 600)) { // 멈추 조건 KillTimer(hWnd, 3); stop[2] = 3; } else if (selectLight == 1) { KillTimer(hWnd, 3); } } } else if (xypos[4].y < 1000 && xypos[5].y == 1000) { xypos[4].y += 5; xypos_sub[5].y += 5; } else if (xypos[4].y == 1000 && xypos[5].y == 1000) { xypos_sub[5].y = 0; xypos[4].y = 0; xypos[5].y = 100; } break; case 4: if (xypos[6].y > 0 && xypos[7].y > 0) { xypos[6].y -= 5; xypos[7].y -= 5; if ((xypos[7].y >= 600 && xypos[6].y <= 750) ) { // 정지선에 위치할때 if ((xypos[1].x < 500 && xypos[1].x > 400) || (xypos[3].x > 400 && xypos[3].x < 500) || (xypos[0].x > 400 && xypos[0].x < 500) || (xypos[2].x > 400 && xypos[2].x < 500)) { // 멈출 조건 KillTimer(hWnd, 4); stop[3] = 4; } else if (selectLight == 1) { KillTimer(hWnd, 4); } } } else if (xypos[6].y > 0 && xypos[7].y == 0) { xypos[6].y -= 5; xypos_sub[7].y -= 5; } else if (xypos[6].y == 0 && xypos[7].y == 0) { xypos_sub[7].y = 1000; xypos[6].y = 1000; xypos[7].y = 900; } break; } InvalidateRgn(hWnd, NULL, TRUE); break; case WM_LBUTTONDOWN: mouseXpos = LOWORD(lParam); mouseYpos = HIWORD(lParam); if (InCircle(1300, 50, mouseXpos, mouseYpos)) { selectLight = 3; } else if (InCircle(1300, 150, mouseXpos, mouseYpos)) { selectLight = 2; } else if (InCircle(1300, 250, mouseXpos, mouseYpos)) { selectLight = 1; } InvalidateRgn(hWnd, NULL, TRUE); break; case WM_DESTROY: KillTimer(hWnd, 1); KillTimer(hWnd, 2); KillTimer(hWnd, 3); KillTimer(hWnd, 4); PostQuitMessage(0); return 0; } return(DefWindowProc(hWnd, iMessage, wParam, lParam)); }
자동차가 정지선 앞에 있을때 그 자동차 앞에 다른 자동차가 있으면 정지했다가
지나간 후에 움직이도록 코딩했는데 자동차가 정지하는게 서로 잘 맞지가 않습니다.
3시간동안 고민했는데 잘 모르겠네요..
자동차가 멈추는 조건은 주석으로 멈출 조건이라고 적어놓았습니다.
Forums:
댓글 달기