윈도우 프로그래밍으로 자동차 교차로 만드는데 문제가 있습니다
글쓴이: 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:


댓글 달기