Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Движение по лабиринту / 25 сообщений из 28, страница 1 из 2
16.02.2013, 12:14
    #38153892
kot07
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Движение по лабиринту
Добрый день, не могу понять как сделать...
нужно при нажатии на клавиши стрелки чтобы объект двигался. Движение как я понял реализуется простым стиранием объекта из предыдущих координат и нарисовкой их в новых координатах,коды стрелок я поймал с помощью getchar отдельно
среда програмирования dev-c++
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
#include <graphics.h>
#include <windows.h>
int main()
{
   int gdriver = DETECT, gmode, errorcode;
   int xmax, ymax;
   initgraph (&gdriver, &gmode, "");
  errorcode = graphresult();
   if (errorcode != grOk) { /* an error occurred */
      printf("Graphics error: %s\n", grapherrormsg(errorcode));
      printf("Press any key to halt:");
      getch();
      exit(1);
   }
   setcolor(getmaxcolor());
   xmax = getmaxx();
   ymax = getmaxy();
 circle(115,40,10); /*объект движения*/
 line(40, 40, 100, 40); /*1*/
 line(100, 40, 100, 70);/*2*/
 line(100,70,130,70);/*3*/
 line(130, 70, 130, 100);/*4*/
 line(100, 100, 100, 160);/*5*/
 line(70, 70, 70, 130);/*6*/
 line(70, 130, 40, 130);/*7*/
 line(100, 160, 70, 160);/*8*/
 line(70, 160, 70, 220);/*9*/
 line(100, 190, 100, 220);/*10*/
 line(130, 160, 130, 340);/*11*/
 line(70, 250, 130, 250);/*12*/
 line(100, 130, 160, 130);/*13*/
 line(160, 130, 160, 40);/*14*/
 line(70, 280, 100, 280);/*15*/
 line(70, 280, 70, 340);/*16*/
 line(70, 310, 250, 310);/*17*/
 line(40, 40, 40, 370);/*18*/
 line(100, 340, 100, 370);/*19*/
 line(130,340,160,340);/*20*/
 line(190,310,190,370);/*21*/
 line(40,370,190,370);/*22*/
 line(160,130,160,210);/*23*/
 line(130,250,190,250);/*24*/
 line(160,100,190,100);/*25*/
 line(190,160,190,250);/*26*/
 line(190,160,220,160);/*27*/
 line(190,130,280,130);/*28*/
 line(220,70,220,130);/*29*/
 line(190,70,220,70);/*30*/
 line(130,40,340,40);/*31*/
 line(250,40,250,100);/*32*/
 line(280,70,280,130);/*33*/
 line(280,70,310,70);/*34*/
 line(310,70,310,160);/*35*/
 line(340,40,340,370);/*36*/
 line(310,190,340,190);/*37*/
 line(220,370,340,370);/*38*/
 line(220,190,220,280);/*39*/
 line(160,280,280,280);/*40*/
 line(250,130,250,250);/*41*/
 line(250,220,340,220);/*42*/
 line(280,160,280,220);/*43*/
 line(250,250,310,250);/*44*/
 line(280,280,280,340);/*45*/
 line(220,340,280,340);/*46*/
 line(220,340,220,370);/*47*/
 line(280,310,310,310);/*48*/
 line(310,280,310,340);/*49*/
    getch();
  closegraph();
   return 0;
}


коды клавиш стрелок
80 вниз
77 вправо
75 влево
72 вверх
Необязательно делать весь путь, буду очень рад если поажите как сделать хотя бы одно движение а дальше доделаю сам
...
Рейтинг: 0 / 0
17.02.2013, 00:08
    #38154289
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Движение по лабиринту
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
#include <graphics.h>
#include <windows.h>
int main()
{
    initgraph (&gdriver, &gmode, "");
    // здесь рисуешь лабиринт

    x=0; y=0; // начальные координаты твоего объекта
    while(TRUE) {
       setcolor(белый);  // сам придумаешь как задать цвет видимого объекта 
       circle(x, y, 10)  // рисуешь объект
       key = getch();    // ждешь кнопку
       setcolor(черный); // Цвет фона
       circle(x, y, 10); // рисуешь объект повторно (стираешь его)

       switch(key) {  // a потом обновляешь координаты
       case 80:   // на кнопку "вниз"
            y = y-10; 
            if (y<0) y = 0;
            break;
       default:  // на все остальные клавишы
           closegraph();
           return 1;
      }
   }
}
...
Рейтинг: 0 / 0
17.02.2013, 00:55
    #38154317
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Движение по лабиринту
Насколько я понимаю цепочка команд line(x,y,x1,y1);
рисует стенки лабиринта. Тогда для полноценного
решения задачи нужно проверять что шарик (circle)
не пересёк стенку. В таком виде как стенки заданы
сейчас эту задачу решать неудобно. Лучше задать
их в виде "матрицы проходимости". Это удобно
т.к. у нас есть декартовый порядок стенок
и индексирование не потребуется.
...
Рейтинг: 0 / 0
17.02.2013, 04:19
    #38154408
Пётр Седов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Движение по лабиринту
2 kot07:

kot07нужно при нажатии на клавиши стрелки чтобы объект двигался. Движение как я понял реализуется простым стиранием объекта из предыдущих координат и нарисовкой их в новых координатах,Так делали в древних (DOS-овских) играх, то есть перерисовывали только те части экрана, которые реально изменились. В те времена это было оправдано из-за медленного доступа к видео-памяти (с которой работали напрямую, чтобы что-то нарисовать). Сейчас это уже не актуально, современные игры рисуют картинку через высоко-уровневые аппаратно-ускоренные API (OpenGL (ES), Direct3D), каждый кадр рисуется с нуля.

kot07коды стрелок я поймал с помощью getchar отдельно
...
коды клавиш стрелок
80 вниз
77 вправо
75 влево
72 вверхВ WinAPI есть константы для стрелок: VK_LEFT, VK_RIGHT, VK_DOWN, VK_UP.

kot07
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
#include <graphics.h>
#include <windows.h>
int main()
{
   int gdriver = DETECT, gmode, errorcode;
   int xmax, ymax;
   initgraph (&gdriver, &gmode, "");
  errorcode = graphresult();
   if (errorcode != grOk) { /* an error occurred */
      printf("Graphics error: %s\n", grapherrormsg(errorcode));
      printf("Press any key to halt:");
      getch();
      exit(1);
   }
   setcolor(getmaxcolor());
   xmax = getmaxx();
   ymax = getmaxy();
   ...
  closegraph();
   return 0;
}

BGI устарела вместе с 16-битным DOS-ом.

kot07буду очень рад если поажите как сделать хотя бы одно движениеПоказываю:
код (использует WinAPI)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
#include <assert.h>
#define NOMINMAX
#include <windows.h>

bool _running = false;
bool _active = false;

void init_window();
void term_window();
void init_timer();
void term_timer();

int main() {
  init_window();
  init_timer();

  _running = true;
  // главный цикл
  while (_running) {
    MSG m;
    GetMessage(&m, /*hWnd:*/NULL, /*wMsgFilterMin:*/0, /*wMsgFilterMax:*/0);
    TranslateMessage(&m);
    DispatchMessage(&m);
  }

  term_timer();
  term_window();

  return 0;
}

const char* const _window_class_name = "maze";
ATOM _window_class_id = 0;
HWND _window_han = NULL;
// размеры клиентской области окна (client area)
int _window_client_width = -1;
int _window_client_height = -1;

LRESULT CALLBACK window_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

void init_window() {
  HINSTANCE exe_han = GetModuleHandle(NULL);

  // регистрируем оконный класс
  assert(_window_class_id == 0);
  WNDCLASSEX wc_params;
  wc_params.cbSize = sizeof(WNDCLASSEX);
  wc_params.style = 0;
  wc_params.lpfnWndProc = &window_proc;
  wc_params.cbClsExtra = 0;
  wc_params.cbWndExtra = 0;
  wc_params.hInstance = exe_han;
  wc_params.hIcon = NULL;
  wc_params.hCursor = LoadCursor(NULL, IDC_ARROW);
  wc_params.hbrBackground = NULL; // фон будем рисовать сами
  wc_params.lpszMenuName = NULL;
  wc_params.lpszClassName = _window_class_name;
  wc_params.hIconSm = NULL;
  _window_class_id = RegisterClassEx(&wc_params);

  // создаём окно
  assert(_window_han == NULL);
  _window_han = CreateWindowEx(
    /*dwExStyle:*/0,
    /*lpClassName:*/_window_class_name,
    /*lpWindowName:*/"Maze", // заголовок окна
    /*dwStyle:*/WS_OVERLAPPEDWINDOW | WS_VISIBLE,
    /*x:*/CW_USEDEFAULT,
    /*y:*/CW_USEDEFAULT,
    /*nWidth:*/CW_USEDEFAULT,
    /*nHeight:*/CW_USEDEFAULT,
    /*hWndParent:*/NULL,
    /*hMenu:*/NULL,
    /*hInstance:*/exe_han,
    /*lpParam:*/NULL
  );
}

void term_window() {
  if (_window_han != NULL) {
    DestroyWindow(_window_han);
    _window_han = NULL;
  }

  if (_window_class_id != 0) {
    HINSTANCE exe_han = GetModuleHandle(NULL);
    UnregisterClass(_window_class_name, exe_han);
    _window_class_id = 0;
  }
}

void request_paint() {
  assert(_window_han != NULL);
  // помечаем всю клиентскую область окна как требующую перерисовки
  InvalidateRect(_window_han, /*lpRect:*/NULL, /*bErase:*/false);
  // в ближайшее время система пришлёт нашему окну сообщение WM_PAINT
}

bool _double_buffered = true;
HDC _gdi_context = NULL;

void update();
void paint_maze();

// оконная процедура (указывается при регистрации оконного класса)
LRESULT CALLBACK window_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  switch (uMsg) {
  case WM_CLOSE:
    // завершаем главный цикл
    _running = false;
    return 0;
  case WM_SETFOCUS:
    _active = true;
    return 0;
  case WM_KILLFOCUS:
    _active = false;
    return 0;
  case WM_SIZE:
    _window_client_width = LOWORD(lParam);
    _window_client_height = HIWORD(lParam);
    return 0;
  case WM_USER: // посылается функцией tick (см. ниже)
    update();
    return 0;
  case WM_ERASEBKGND:
    // здесь ничего не делаем, фон рисуется в функции paint_maze
    return false; // не нарисовали фон
  case WM_PAINT: {
    PAINTSTRUCT ps;
    BeginPaint(hwnd, &ps);
    if (_double_buffered) {
      int x = ps.rcPaint.left;
      int y = ps.rcPaint.top;
      int w = ps.rcPaint.right - ps.rcPaint.left;
      int h = ps.rcPaint.bottom - ps.rcPaint.top;
      if ((w > 0) && (h > 0)) {
        // рисуем лабиринт в back buffer
        HBITMAP back_buf = CreateCompatibleBitmap(ps.hdc, w, h);
        assert(_gdi_context == NULL);
        _gdi_context = CreateCompatibleDC(ps.hdc);
        SelectObject(_gdi_context, back_buf);
        SetViewportOrgEx(_gdi_context, -x, -y, NULL);
        paint_maze();

        // копируем содержимое back buffer-а в окно
        BitBlt(ps.hdc, x, y, w, h, _gdi_context, x, y, SRCCOPY);

        DeleteDC(_gdi_context);
        _gdi_context = NULL;
        DeleteObject(back_buf);
      }
    } else {
      // рисуем лабиринт прямо в окно
      assert(_gdi_context == NULL);
      _gdi_context = ps.hdc;
      paint_maze();
      _gdi_context = NULL;
    }
    EndPaint(hwnd, &ps);
    return 0;
  }
  default:
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
  }
}

const int _update_interval = 20; // миллисекунд
UINT _timer_id = 0;

void CALLBACK tick(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2);

void init_timer() {
  // используем multimedia timer
  assert(_timer_id == 0);
  _timer_id = timeSetEvent(/*uDelay:*/_update_interval, /*uResolution:*/0, &tick, /*dwUser:*/0, TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
}

void term_timer() {
  UINT id = _timer_id;
  if (id != 0) {
    _timer_id = 0;
    timeKillEvent(id);
  }
}

// !!! вызывается в другом потоке (thread)
void CALLBACK tick(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) {
  if (_timer_id == 0) return;
  assert(uTimerID == _timer_id);
  assert(_window_han != NULL);
  SendMessage(_window_han, WM_USER, 0, 0);
}

bool key_is_down(int key) {
  if (!_active) return false;
  return static_cast<unsigned short>(GetKeyState(key)) >> 15;
}

struct Wall {
  int x1, y1;
  int x2, y2;
};

// координаты упорядочены следующим образом:
//   если x1 = x2, то y1 < y2
//   если y1 = y2, то x1 < x2
// это используется в функции obj_pos_is_valid (см. ниже)
const Wall _walls[] = {
  {40, 40, 100, 40},
  {100, 40, 100, 70},
  {100, 70, 130, 70},
  {130, 70, 130, 100},
  {100, 100, 100, 160},
  {70, 70, 70, 130},
  {40, 130, 70, 130},
  {70, 160, 100, 160},
  {70, 160, 70, 220},
  {100, 190, 100, 220},
  {130, 160, 130, 340},
  {70, 250, 130, 250},
  {100, 130, 160, 130},
  {160, 40, 160, 130},
  {70, 280, 100, 280},
  {70, 280, 70, 340},
  {70, 310, 250, 310},
  {40, 40, 40, 370},
  {100, 340, 100, 370},
  {130, 340, 160, 340},
  {190, 310, 190, 370},
  {40, 370, 190, 370},
  {160, 130, 160, 210},
  {130, 250, 190, 250},
  {160, 100, 190, 100},
  {190, 160, 190, 250},
  {190, 160, 220, 160},
  {190, 130, 280, 130},
  {220, 70, 220, 130},
  {190, 70, 220, 70},
  {130, 40, 340, 40},
  {250, 40, 250, 100},
  {280, 70, 280, 130},
  {280, 70, 310, 70},
  {310, 70, 310, 160},
  {340, 40, 340, 370},
  {310, 190, 340, 190},
  {220, 370, 340, 370},
  {220, 190, 220, 280},
  {160, 280, 280, 280},
  {250, 130, 250, 250},
  {250, 220, 340, 220},
  {280, 160, 280, 220},
  {250, 250, 310, 250},
  {280, 280, 280, 340},
  {220, 340, 280, 340},
  {220, 340, 220, 370},
  {280, 310, 310, 310},
  {310, 280, 310, 340},
};

// работает только для массивов, для указателей даст неверный результат
#define LEN(array) static_cast<int>(sizeof(array) / sizeof(array[0]))

int _obj_pos_x = 115;
int _obj_pos_y = 40;
const int _obj_radius = 10;
const int _obj_speed = 2;

bool obj_pos_is_valid(int obj_pos_x, int obj_pos_y);

// вызывается регулярно с интервалом _update_interval
void update() {
  bool vis_change = false;

  int dir_x = 0;
  if (key_is_down(VK_LEFT)) dir_x--;
  if (key_is_down(VK_RIGHT)) dir_x++;

  int dir_y = 0;
  if (key_is_down(VK_DOWN)) dir_y++;
  if (key_is_down(VK_UP)) dir_y--;

  if ((dir_x != 0) || (dir_y != 0)) {
    for (int i = 0; i < _obj_speed; i++) {
      int new_obj_pos_x = _obj_pos_x + dir_x;
      int new_obj_pos_y = _obj_pos_y + dir_y;
      if (obj_pos_is_valid(new_obj_pos_x, new_obj_pos_y)) {
        _obj_pos_x = new_obj_pos_x;
        _obj_pos_y = new_obj_pos_y;
        vis_change = true;
      } else {
        break;
      }
    }
  }

  if (vis_change) {
    request_paint();
  }
}

inline int squ(int n) {
  return n * n;
}

inline int clamp(int n, int min, int max) {
  assert(min <= max);
  if (n < min) return min;
  if (n > max) return max;
  return n;
}

bool obj_pos_is_valid(int obj_pos_x, int obj_pos_y) {
  // объект не должен проходить сквозь стены
  for (int i = 0; i < LEN(_walls); i++) {
    const Wall* w = &_walls[i];
    int x1 = w->x1;
    int y1 = w->y1;
    int x2 = w->x2;
    int y2 = w->y2;
    int closest_point_x, closest_point_y;
    if (x1 == x2) {
      assert(y1 < y2);
      closest_point_x = x1;
      closest_point_y = clamp(obj_pos_y, y1, y2);
    } else {
      assert(y1 == y2);
      assert(x1 < x2);
      closest_point_x = clamp(obj_pos_x, x1, x2);
      closest_point_y = y1;
    }
    if (squ(obj_pos_x - closest_point_x) + squ(obj_pos_y - closest_point_y) < squ(_obj_radius)) return false;
  }
  return true;
}

void paint_maze() {
  assert(_gdi_context != NULL);

  // рисуем фон
  RECT r = {0, 0, _window_client_width, _window_client_height};
  FillRect(_gdi_context, &r, static_cast<HBRUSH>(GetStockObject(GRAY_BRUSH)));

  // рисуем стены
  SelectObject(_gdi_context, GetStockObject(WHITE_PEN));
  for (int i = 0; i < LEN(_walls); i++) {
    const Wall* w = &_walls[i];
    MoveToEx(_gdi_context, w->x1, w->y1, NULL);
    LineTo(_gdi_context, w->x2, w->y2);
  }

  // рисуем объект
  SelectObject(_gdi_context, GetStockObject(WHITE_BRUSH));
  SelectObject(_gdi_context, GetStockObject(NULL_PEN));
  Ellipse(_gdi_context, _obj_pos_x - _obj_radius, _obj_pos_y - _obj_radius, _obj_pos_x + _obj_radius, _obj_pos_y + _obj_radius);
}

Обработка ошибок отсутствует, чтобы код был яснее. GDI (WinAPI-шные функции, работающие с HDC) использовал для простоты, для игр он не особо подходит.

2 mayton:
maytonНасколько я понимаю цепочка команд line(x,y,x1,y1);
рисует стенки лабиринта.Да:
...
Рейтинг: 0 / 0
17.02.2013, 08:08
    #38154429
kot07
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Движение по лабиринту
Вот это да, спасибо большое что так все переделали и исправили...мне лектор говорилиъ про WinApi но для ним меня это тьма....Может подскажите литературу полезную по C++ где подробно будет про WinApi?
...
Рейтинг: 0 / 0
17.02.2013, 08:16
    #38154431
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Движение по лабиринту
kot07Вот это да, спасибо большое что так все переделали и исправили...мне лектор говорилиъ про WinApi но для ним меня это тьма....Может подскажите литературу полезную по C++ где подробно будет про WinApi?Такой литературы не существует. WinAPI это C, а не C++. Поэтому WinAPI отдельно, С++ отдельно.
По WinAPI ищи Programming Windows by Charles Petzold. (переводы существуют)
...
Рейтинг: 0 / 0
17.02.2013, 10:13
    #38154446
kot07
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Движение по лабиринту
хорошо, спасибо большое...тему можно закрывать
...
Рейтинг: 0 / 0
17.02.2013, 20:43
    #38154843
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Движение по лабиринту
kot07хорошо, спасибо большое...тему можно закрывать
Поразительно. Я думал у тебя еще будет штук 10 вопросов.
...
Рейтинг: 0 / 0
18.02.2013, 02:32
    #38155082
Пётр Седов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Движение по лабиринту
2 kot07:

kot07Может подскажите литературу полезную по C++ где подробно будет про WinApi?Источники знаний по WinAPI:

1. Книги. Две классические книги по WinAPI:
* Charles Petzold «Programming Windows» (на английском, на русском)
* Jeffrey Richter «Programming Applications for Microsoft Windows» (на английском)
(файлы по ссылкам хранятся 10 дней после последнего скачивания)

Модератор: Пётр, твои ссылки на заливалку не работают, удалены. Если желаешь переопубликуй.

WinAPI не отлит в бронзе, Microsoft расширяет его с выходом новых версий Windows. Поэтому некоторые вещи в этих изданиях отсутствуют, например я не нашёл упоминания DC_BRUSH/SetDCBrushColor и DC_PEN/SetDCPenColor.

2. MSDN. Вводим в Google-овский поисковик, например, «MSDN FillRect», переходим по ссылке «FillRect function (Windows)», и читаем официальное описание WinAPI-шной функции FillRect.

3. Исходники Wine . Разработчики прилагают серьёзные усилия, чтобы Wine-овская реализация WinAPI вела себя так же, как виндовая реализация WinAPI. Поэтому читая исходники Wine можно лучше понять WinAPI.

4. Форумы. Например, форум «Программирование» здесь на SQL.ru. Прежде чем задать вопрос, очень желательно поискать по форуму, например введя в Google-овский поисковик «site:sql.ru FillRect».



kot07тему можно закрыватьМожно, но не нужно :).
...
Рейтинг: 0 / 0
14.03.2013, 17:45
    #38184404
kot07
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Движение по лабиринту
это вы правильно сделали что не закрыли темку
...
Рейтинг: 0 / 0
14.03.2013, 17:49
    #38184408
kot07
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Движение по лабиринту
куда вставить строчку чтобы при достижении выхода выдалось сообщение Лабиринт пройден
if (190;370;220;370) then
cout<<"Лабиринт пройден";
else
тут как бы логично что начинаем движение и вставляем в строку номер 277 но у меня компилятор начинает ругаться
...
Рейтинг: 0 / 0
14.03.2013, 18:34
    #38184505
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Движение по лабиринту
kot07куда вставить строчку чтобы при достижении выхода выдалось сообщение Лабиринт пройден
if (190;370;220;370) then
cout<<"Лабиринт пройден";
else
тут как бы логично что начинаем движение и вставляем в строку номер 277 но у меня компилятор начинает ругаться
Да да. Мы совершенно правильно сделали что не закрыли твою тему.

Вообще здесь нужно вставить смайлик "фейспалм" и вернуться в прошлое
где ты начал изучать С++. Язык ты объективно не знаешь и даже если
подсказать готовое решение - препод тебя завалит. Это не есть гуд.

Если хочешь разобраться совместно - то давай последнюю версию исходника
и протокол ошибок компиллера и мы посмотрим.
...
Рейтинг: 0 / 0
14.03.2013, 19:00
    #38184554
kot07
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Движение по лабиринту
вы прям как в воду глядели что появится 10 вопросов,препод не завалит она сама не знает своего предмета просто придраться может что не закончено + блок схему правильно не составить
...
Рейтинг: 0 / 0
14.03.2013, 19:03
    #38184560
kot07
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Движение по лабиринту
код вцелом не изменился подключил лишь библиотеку и закоментим линии чтобы найти нужный промежуток выхода
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
#include <assert.h>
#define NOMINMAX
#include <windows.h>

//#pragma comment(lib,"winmm.lib")

bool _running = false;
bool _active = false;

void init_window();
void term_window();
void init_timer();
void term_timer();

int main() {
  init_window();
  init_timer();

  _running = true;
  // &#227;&#235;&#224;&#226;&#237;&#251;&#233; &#246;&#232;&#234;&#235;
  while (_running) {
    MSG m;
    GetMessage(&m, /*hWnd:*/NULL, /*wMsgFilterMin:*/0, /*wMsgFilterMax:*/0);
    TranslateMessage(&m);
    DispatchMessage(&m);
  }

  term_timer();
  term_window();

  return 0;
}

const char* const _window_class_name = "maze";
ATOM _window_class_id = 0;
HWND _window_han = NULL;
// &#240;&#224;&#231;&#236;&#229;&#240;&#251; &#234;&#235;&#232;&#229;&#237;&#242;&#241;&#234;&#238;&#233; &#238;&#225;&#235;&#224;&#241;&#242;&#232; &#238;&#234;&#237;&#224; (client area)
int _window_client_width = -1;
int _window_client_height = -1;

LRESULT CALLBACK window_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

void init_window() {
  HINSTANCE exe_han = GetModuleHandle(NULL);

  // &#240;&#229;&#227;&#232;&#241;&#242;&#240;&#232;&#240;&#243;&#229;&#236; &#238;&#234;&#238;&#237;&#237;&#251;&#233; &#234;&#235;&#224;&#241;&#241;
  assert(_window_class_id == 0);
  WNDCLASSEX wc_params;
  wc_params.cbSize = sizeof(WNDCLASSEX);
  wc_params.style = 0;
  wc_params.lpfnWndProc = &window_proc;
  wc_params.cbClsExtra = 0;
  wc_params.cbWndExtra = 0;
  wc_params.hInstance = exe_han;
  wc_params.hIcon = NULL;
  wc_params.hCursor = LoadCursor(NULL, IDC_ARROW);
  wc_params.hbrBackground = NULL; // &#244;&#238;&#237; &#225;&#243;&#228;&#229;&#236; &#240;&#232;&#241;&#238;&#226;&#224;&#242;&#252; &#241;&#224;&#236;&#232;
  wc_params.lpszMenuName = NULL;
  wc_params.lpszClassName = _window_class_name;
  wc_params.hIconSm = NULL;
  _window_class_id = RegisterClassEx(&wc_params);

  // &#241;&#238;&#231;&#228;&#224;&#184;&#236; &#238;&#234;&#237;&#238;
  assert(_window_han == NULL);
  _window_han = CreateWindowEx(
    /*dwExStyle:*/0,
    /*lpClassName:*/_window_class_name,
    /*lpWindowName:*/"Maze", // &#231;&#224;&#227;&#238;&#235;&#238;&#226;&#238;&#234; &#238;&#234;&#237;&#224;
    /*dwStyle:*/WS_OVERLAPPEDWINDOW | WS_VISIBLE,
    /*x:*/CW_USEDEFAULT,
    /*y:*/CW_USEDEFAULT,
    /*nWidth:*/CW_USEDEFAULT,
    /*nHeight:*/CW_USEDEFAULT,
    /*hWndParent:*/NULL,
    /*hMenu:*/NULL,
    /*hInstance:*/exe_han,
    /*lpParam:*/NULL
  );
}

void term_window() {
  if (_window_han != NULL) {
    DestroyWindow(_window_han);
    _window_han = NULL;
  }

  if (_window_class_id != 0) {
    HINSTANCE exe_han = GetModuleHandle(NULL);
    UnregisterClass(_window_class_name, exe_han);
    _window_class_id = 0;
  }
}

void request_paint() {
  assert(_window_han != NULL);
  // &#239;&#238;&#236;&#229;&#247;&#224;&#229;&#236; &#226;&#241;&#254; &#234;&#235;&#232;&#229;&#237;&#242;&#241;&#234;&#243;&#254; &#238;&#225;&#235;&#224;&#241;&#242;&#252; &#238;&#234;&#237;&#224; &#234;&#224;&#234; &#242;&#240;&#229;&#225;&#243;&#254;&#249;&#243;&#254; &#239;&#229;&#240;&#229;&#240;&#232;&#241;&#238;&#226;&#234;&#232;
  InvalidateRect(_window_han, /*lpRect:*/NULL, /*bErase:*/false);
  // &#226; &#225;&#235;&#232;&#230;&#224;&#233;&#248;&#229;&#229; &#226;&#240;&#229;&#236;&#255; &#241;&#232;&#241;&#242;&#229;&#236;&#224; &#239;&#240;&#232;&#248;&#235;&#184;&#242; &#237;&#224;&#248;&#229;&#236;&#243; &#238;&#234;&#237;&#243; &#241;&#238;&#238;&#225;&#249;&#229;&#237;&#232;&#229; WM_PAINT
}

bool _double_buffered = true;
HDC _gdi_context = NULL;

void update();
void paint_maze();

// &#238;&#234;&#238;&#237;&#237;&#224;&#255; &#239;&#240;&#238;&#246;&#229;&#228;&#243;&#240;&#224; (&#243;&#234;&#224;&#231;&#251;&#226;&#224;&#229;&#242;&#241;&#255; &#239;&#240;&#232; &#240;&#229;&#227;&#232;&#241;&#242;&#240;&#224;&#246;&#232;&#232; &#238;&#234;&#238;&#237;&#237;&#238;&#227;&#238; &#234;&#235;&#224;&#241;&#241;&#224;)
LRESULT CALLBACK window_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  switch (uMsg) {
  case WM_CLOSE:
    // &#231;&#224;&#226;&#229;&#240;&#248;&#224;&#229;&#236; &#227;&#235;&#224;&#226;&#237;&#251;&#233; &#246;&#232;&#234;&#235;
    _running = false;
    return 0;
  case WM_SETFOCUS:
    _active = true;
    return 0;
  case WM_KILLFOCUS:
    _active = false;
    return 0;
  case WM_SIZE:
    _window_client_width = LOWORD(lParam);
    _window_client_height = HIWORD(lParam);
    return 0;
  case WM_USER: // &#239;&#238;&#241;&#251;&#235;&#224;&#229;&#242;&#241;&#255; &#244;&#243;&#237;&#234;&#246;&#232;&#229;&#233; tick (&#241;&#236;. &#237;&#232;&#230;&#229;)
    update();
    return 0;
  case WM_ERASEBKGND:
    // &#231;&#228;&#229;&#241;&#252; &#237;&#232;&#247;&#229;&#227;&#238; &#237;&#229; &#228;&#229;&#235;&#224;&#229;&#236;, &#244;&#238;&#237; &#240;&#232;&#241;&#243;&#229;&#242;&#241;&#255; &#226; &#244;&#243;&#237;&#234;&#246;&#232;&#232; paint_maze
    return false; // &#237;&#229; &#237;&#224;&#240;&#232;&#241;&#238;&#226;&#224;&#235;&#232; &#244;&#238;&#237;
  case WM_PAINT: {
    PAINTSTRUCT ps;
    BeginPaint(hwnd, &ps);
    if (_double_buffered) {
      int x = ps.rcPaint.left;
      int y = ps.rcPaint.top;
      int w = ps.rcPaint.right - ps.rcPaint.left;
      int h = ps.rcPaint.bottom - ps.rcPaint.top;
      if ((w > 0) && (h > 0)) {
        // &#240;&#232;&#241;&#243;&#229;&#236; &#235;&#224;&#225;&#232;&#240;&#232;&#237;&#242; &#226; back buffer
        HBITMAP back_buf = CreateCompatibleBitmap(ps.hdc, w, h);
        assert(_gdi_context == NULL);
        _gdi_context = CreateCompatibleDC(ps.hdc);
        SelectObject(_gdi_context, back_buf);
        SetViewportOrgEx(_gdi_context, -x, -y, NULL);
        paint_maze();

        // &#234;&#238;&#239;&#232;&#240;&#243;&#229;&#236; &#241;&#238;&#228;&#229;&#240;&#230;&#232;&#236;&#238;&#229; back buffer-&#224; &#226; &#238;&#234;&#237;&#238;
        BitBlt(ps.hdc, x, y, w, h, _gdi_context, x, y, SRCCOPY);

        DeleteDC(_gdi_context);
        _gdi_context = NULL;
        DeleteObject(back_buf);
      }
    } else {
      // &#240;&#232;&#241;&#243;&#229;&#236; &#235;&#224;&#225;&#232;&#240;&#232;&#237;&#242; &#239;&#240;&#255;&#236;&#238; &#226; &#238;&#234;&#237;&#238;
      assert(_gdi_context == NULL);
      _gdi_context = ps.hdc;
      paint_maze();
      _gdi_context = NULL;
    }
    EndPaint(hwnd, &ps);
    return 0;
  }
  default:
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
  }
}

const int _update_interval = 20; // &#236;&#232;&#235;&#235;&#232;&#241;&#229;&#234;&#243;&#237;&#228;
UINT _timer_id = 0;

void CALLBACK tick(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2);

void init_timer() {
  // &#232;&#241;&#239;&#238;&#235;&#252;&#231;&#243;&#229;&#236; multimedia timer
  assert(_timer_id == 0);
  _timer_id = timeSetEvent(/*uDelay:*/_update_interval, /*uResolution:*/0, &tick, /*dwUser:*/0, TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
}

void term_timer() {
  UINT id = _timer_id;
  if (id != 0) {
    _timer_id = 0;
    timeKillEvent(id);
  }
}

// !!! &#226;&#251;&#231;&#251;&#226;&#224;&#229;&#242;&#241;&#255; &#226; &#228;&#240;&#243;&#227;&#238;&#236; &#239;&#238;&#242;&#238;&#234;&#229; (thread)
void CALLBACK tick(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) {
  if (_timer_id == 0) return;
  assert(uTimerID == _timer_id);
  assert(_window_han != NULL);
  SendMessage(_window_han, WM_USER, 0, 0);
}

bool key_is_down(int key) {
  if (!_active) return false;
  return static_cast<unsigned short>(GetKeyState(key)) >> 15;
}

struct Wall {
  int x1, y1;
  int x2, y2;
};


// &#234;&#238;&#238;&#240;&#228;&#232;&#237;&#224;&#242;&#251; &#243;&#239;&#238;&#240;&#255;&#228;&#238;&#247;&#229;&#237;&#251; &#241;&#235;&#229;&#228;&#243;&#254;&#249;&#232;&#236; &#238;&#225;&#240;&#224;&#231;&#238;&#236;:
//   &#229;&#241;&#235;&#232; x1 = x2, &#242;&#238; y1 < y2
//   &#229;&#241;&#235;&#232; y1 = y2, &#242;&#238; x1 < x2
// &#253;&#242;&#238; &#232;&#241;&#239;&#238;&#235;&#252;&#231;&#243;&#229;&#242;&#241;&#255; &#226; &#244;&#243;&#237;&#234;&#246;&#232;&#232; obj_pos_is_valid (&#241;&#236;. &#237;&#232;&#230;&#229;)
const Wall _walls[] = {
  //{40, 40, 100, 40},
  //{100, 40, 100, 70},
  //{100, 70, 130, 70},
  //{130, 70, 130, 100},
  //{100, 100, 100, 160},
  //{70, 70, 70, 130},
  //{40, 130, 70, 130},
  //{70, 160, 100, 160},
  //{70, 160, 70, 220},
  //{100, 190, 100, 220},
  //{130, 160, 130, 340},
  //{70, 250, 130, 250},
  //{100, 130, 160, 130},
  //{160, 40, 160, 130},
  //{70, 280, 100, 280},
  //{70, 280, 70, 340},
  //{70, 310, 250, 310},
  //{40, 40, 40, 370},
  //{100, 340, 100, 370},
  //{130, 340, 160, 340},
  //{190, 310, 190, 370},
  {40, 370, 190, 370},
  //{160, 130, 160, 210},
  //{130, 250, 190, 250},
  //{160, 100, 190, 100},
  //{190, 160, 190, 250},
  //{190, 160, 220, 160},
  //{190, 130, 280, 130},
  //{220, 70, 220, 130},
  //{190, 70, 220, 70},
  //{130, 40, 340, 40},
  //{250, 40, 250, 100},
  //{280, 70, 280, 130},
  //{280, 70, 310, 70},
  //{310, 70, 310, 160},
  //{340, 40, 340, 370},
  //{310, 190, 340, 190},
  {220, 370, 340, 370},
  //{220, 190, 220, 280},
  //{160, 280, 280, 280},
  //{250, 130, 250, 250},
  //{250, 220, 340, 220},
  //{280, 160, 280, 220},
  //{250, 250, 310, 250},
  //{280, 280, 280, 340},
  //{220, 340, 280, 340},
  //{220, 340, 220, 370},
  //{280, 310, 310, 310},
  //{310, 280, 310, 340},
};

      
// &#240;&#224;&#225;&#238;&#242;&#224;&#229;&#242; &#242;&#238;&#235;&#252;&#234;&#238; &#228;&#235;&#255; &#236;&#224;&#241;&#241;&#232;&#226;&#238;&#226;, &#228;&#235;&#255; &#243;&#234;&#224;&#231;&#224;&#242;&#229;&#235;&#229;&#233; &#228;&#224;&#241;&#242; &#237;&#229;&#226;&#229;&#240;&#237;&#251;&#233; &#240;&#229;&#231;&#243;&#235;&#252;&#242;&#224;&#242;
#define LEN(array) static_cast<int>(sizeof(array) / sizeof(array[0]))

int _obj_pos_x = 115;
int _obj_pos_y = 40;
const int _obj_radius = 12;
const int _obj_speed = 2;

bool obj_pos_is_valid(int obj_pos_x, int obj_pos_y);

// &#226;&#251;&#231;&#251;&#226;&#224;&#229;&#242;&#241;&#255; &#240;&#229;&#227;&#243;&#235;&#255;&#240;&#237;&#238; &#241; &#232;&#237;&#242;&#229;&#240;&#226;&#224;&#235;&#238;&#236; _update_interval
void update() {
  bool vis_change = false;
  if (190;370;220;370) then 
cout<<"&#203;&#224;&#225;&#232;&#240;&#232;&#237;&#242; &#239;&#240;&#238;&#233;&#228;&#229;&#237;";
 else
  int dir_x = 0;
  if (key_is_down(VK_LEFT)) dir_x--;
  if (key_is_down(VK_RIGHT)) dir_x++;

  int dir_y = 0;
  if (key_is_down(VK_DOWN)) dir_y++;
  if (key_is_down(VK_UP)) dir_y--;

  if ((dir_x != 0) || (dir_y != 0)) {
    for (int i = 0; i < _obj_speed; i++) {
      int new_obj_pos_x = _obj_pos_x + dir_x;
      int new_obj_pos_y = _obj_pos_y + dir_y;
      if (obj_pos_is_valid(new_obj_pos_x, new_obj_pos_y)) {
        _obj_pos_x = new_obj_pos_x;
        _obj_pos_y = new_obj_pos_y;
        vis_change = true;
      } else {
        break;
      }
    }
  }

  if (vis_change) {
    request_paint();
  }
}

inline int squ(int n) {
  return n * n;
}

inline int clamp(int n, int min, int max) {
  assert(min <= max);
  if (n < min) return min;
  if (n > max) return max;
  return n;
}

bool obj_pos_is_valid(int obj_pos_x, int obj_pos_y) {
  // &#238;&#225;&#250;&#229;&#234;&#242; &#237;&#229; &#228;&#238;&#235;&#230;&#229;&#237; &#239;&#240;&#238;&#245;&#238;&#228;&#232;&#242;&#252; &#241;&#234;&#226;&#238;&#231;&#252; &#241;&#242;&#229;&#237;&#251;
  for (int i = 0; i < LEN(_walls); i++) {
    const Wall* w = &_walls[i];
    int x1 = w->x1;
    int y1 = w->y1;
    int x2 = w->x2;
    int y2 = w->y2;
    int closest_point_x, closest_point_y;
    if (x1 == x2) {
      assert(y1 < y2);
      closest_point_x = x1;
      closest_point_y = clamp(obj_pos_y, y1, y2);
    } else {
      assert(y1 == y2);
      assert(x1 < x2);
      closest_point_x = clamp(obj_pos_x, x1, x2);
      closest_point_y = y1;
    }
    if (squ(obj_pos_x - closest_point_x) + squ(obj_pos_y - closest_point_y) < squ(_obj_radius)) return false;
  }
  return true;
}

void paint_maze() {
  assert(_gdi_context != NULL);

  // &#240;&#232;&#241;&#243;&#229;&#236; &#244;&#238;&#237;
  RECT r = {0, 0, _window_client_width, _window_client_height};
  FillRect(_gdi_context, &r, static_cast<HBRUSH>(GetStockObject(GRAY_BRUSH)));

  // &#240;&#232;&#241;&#243;&#229;&#236; &#241;&#242;&#229;&#237;&#251;
  SelectObject(_gdi_context, GetStockObject(WHITE_PEN));
  for (int i = 0; i < LEN(_walls); i++) {
    const Wall* w = &_walls[i];
    MoveToEx(_gdi_context, w->x1, w->y1, NULL);
    LineTo(_gdi_context, w->x2, w->y2);
  }

  // &#240;&#232;&#241;&#243;&#229;&#236; &#238;&#225;&#250;&#229;&#234;&#242;
  SelectObject(_gdi_context, GetStockObject(WHITE_BRUSH));
  SelectObject(_gdi_context, GetStockObject(NULL_PEN));
  Ellipse(_gdi_context, _obj_pos_x - _obj_radius, _obj_pos_y - _obj_radius, _obj_pos_x + _obj_radius, _obj_pos_y + _obj_radius);
}
...
Рейтинг: 0 / 0
14.03.2013, 19:08
    #38184575
kot07
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Движение по лабиринту
Журнал компиляции:
Компилятор: Default compiler
Выполнение g++.exe...
g++.exe "C:\Users\Павел\Desktop\ñï.cpp" -o "C:\Users\Павел\Desktop\ñï.exe" -I"C:\Dev-Cpp\lib\gcc\mingw32\3.4.2\include" -I"C:\Dev-Cpp\include\c++\3.4.2\backward" -I"C:\Dev-Cpp\include\c++\3.4.2\mingw32" -I"C:\Dev-Cpp\include\c++\3.4.2" -I"C:\Dev-Cpp\include" -L"C:\Dev-Cpp\lib" -lbgi -lgdi32 -lcomdlg32 -luuid -loleaut32 -lole32 C:\Dev-Cpp\lib\libwinmm.a
C:\Users\Павел\Desktop\ñï.cpp: In function `void update()':
C:\Users\Павел\Desktop\ñï.cpp:277: error: expected `)' before ';' token

C:\Users\Павел\Desktop\ñï.cpp:277: error: expected `;' before ')' token
C:\Users\Павел\Desktop\ñï.cpp:279: error: expected primary-expression before "else"
C:\Users\Павел\Desktop\ñï.cpp:279: error: expected `;' before "else"
C:\Users\Павел\Desktop\ñï.cpp:281: error: `dir_x' undeclared (first use this function)
C:\Users\Павел\Desktop\ñï.cpp:281: error: (Each undeclared identifier is reported only once for each function it appears in.)

Выполнение завершено
...
Рейтинг: 0 / 0
14.03.2013, 20:57
    #38184716
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Движение по лабиринту
kot07,
Бейсик детектед
Код: plaintext
1.
if ... then



И вот это что за чудо?
Код: plaintext
1.
if (190;370;220;370) 
...
Рейтинг: 0 / 0
14.03.2013, 21:12
    #38184727
m_Sla
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Движение по лабиринту
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
#include <assert.h>
#define NOMINMAX
#include <windows.h>
#include <cstdio>

bool _running = false;
bool _active = false;

int _obj_pos_x = 115;
int _obj_pos_y = 40;
const int _obj_radius = 10;
const int _obj_speed = 2;

bool obj_pos_is_valid(int obj_pos_x, int obj_pos_y);
void init_window();
void term_window();

BOOL WINAPI CreateTimerQueueTimer(PHANDLE phNewTimer, HANDLE TimerQueue, PVOID Callback, PVOID Parameter,DWORD DueTime, DWORD Period,ULONG Flags);
BOOL WINAPI DeleteTimerQueueTimer( HANDLE TimerQueue, HANDLE Timer, HANDLE CompletionEvent);

int main()
{
    init_window();

    _running = true;
    // главный цикл
    while (_running)
    {
        MSG m;
        GetMessage(&m, /*hWnd:*/NULL, /*wMsgFilterMin:*/0, /*wMsgFilterMax:*/0);
        TranslateMessage(&m);
        DispatchMessage(&m);
    }

    term_window();

    return 0;
}

const char* const _window_class_name = "maze";
ATOM _window_class_id = 0;
HWND _window_han = NULL;
// размеры клиентской области окна (client area)
int _window_client_width = -1;
int _window_client_height = -1;

LRESULT CALLBACK window_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

void init_window()
{
    HINSTANCE exe_han = GetModuleHandle(NULL);

    // регистрируем оконный класс
    assert(_window_class_id == 0);
    WNDCLASSEX wc_params;
    wc_params.cbSize = sizeof(WNDCLASSEX);
    wc_params.style = 0;
    wc_params.lpfnWndProc = &window_proc;
    wc_params.cbClsExtra = 0;
    wc_params.cbWndExtra = 0;
    wc_params.hInstance = exe_han;
    wc_params.hIcon = NULL;
    wc_params.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc_params.hbrBackground = NULL; // фон будем рисовать сами
    wc_params.lpszMenuName = NULL;
    wc_params.lpszClassName = _window_class_name;
    wc_params.hIconSm = NULL;
    _window_class_id = RegisterClassEx(&wc_params);

    // создаём окно
    assert(_window_han == NULL);
    _window_han = CreateWindowEx(
                      /*dwExStyle:*/0,
                      /*lpClassName:*/_window_class_name,
                      /*lpWindowName:*/"Maze", // заголовок окна
                      /*dwStyle:*/WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                      /*x:*/CW_USEDEFAULT,
                      /*y:*/CW_USEDEFAULT,
                      /*nWidth:*/CW_USEDEFAULT,
                      /*nHeight:*/CW_USEDEFAULT,
                      /*hWndParent:*/NULL,
                      /*hMenu:*/NULL,
                      /*hInstance:*/exe_han,
                      /*lpParam:*/NULL
                  );
}

void term_window()
{
    if (_window_han != NULL)
    {
        DestroyWindow(_window_han);
        _window_han = NULL;
    }

    if (_window_class_id != 0)
    {
        HINSTANCE exe_han = GetModuleHandle(NULL);
        UnregisterClass(_window_class_name, exe_han);
        _window_class_id = 0;
    }
}

void request_paint()
{
    assert(_window_han != NULL);
    // помечаем всю клиентскую область окна как требующую перерисовки
    InvalidateRect(_window_han, /*lpRect:*/NULL, /*bErase:*/false);
    // в ближайшее время система пришлёт нашему окну сообщение WM_PAINT
}

bool _double_buffered = true;
HDC _gdi_context = NULL;

void update();
void paint_maze();

// оконная процедура (указывается при регистрации оконного класса)
LRESULT CALLBACK window_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_CREATE:
        SetTimer(hwnd, 1, 20, NULL);
        return 0;
    case WM_CLOSE:
        // завершаем главный цикл
        KillTimer(hwnd, 1);
        _running = false;
        return 0;
    case WM_SETFOCUS:
        _active = true;
        return 0;
    case WM_KILLFOCUS:
        _active = false;
        return 0;
    case WM_SIZE:
        _window_client_width = LOWORD(lParam);
        _window_client_height = HIWORD(lParam);
        return 0;
    case WM_TIMER: // посылается таймером см. WM_CREATE
        update();
        return 0;
    case WM_ERASEBKGND:
        // здесь ничего не делаем, фон рисуется в функции paint_maze
        return false; // не нарисовали фон
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        BeginPaint(hwnd, &ps);
        if (_double_buffered)
        {
            int x = ps.rcPaint.left;
            int y = ps.rcPaint.top;
            int w = ps.rcPaint.right - ps.rcPaint.left;
            int h = ps.rcPaint.bottom - ps.rcPaint.top;
            if ((w > 0) && (h > 0))
            {
                // рисуем лабиринт в back buffer
                HBITMAP back_buf = CreateCompatibleBitmap(ps.hdc, w, h);
                assert(_gdi_context == NULL);
                _gdi_context = CreateCompatibleDC(ps.hdc);
                SelectObject(_gdi_context, back_buf);
                SetViewportOrgEx(_gdi_context, -x, -y, NULL);
                paint_maze();
                RECT xy={50,400,150,450};
                char text[255];
                sprintf(text,"x=%d, y=%d",_obj_pos_x,_obj_pos_y);
                DrawTextA( _gdi_context, text, -1, &xy, DT_LEFT);


                // копируем содержимое back buffer-а в окно
                BitBlt(ps.hdc, x, y, w, h, _gdi_context, x, y, SRCCOPY);

                DeleteDC(_gdi_context);
                _gdi_context = NULL;
                DeleteObject(back_buf);
            }
        }
        else
        {
            // рисуем лабиринт прямо в окно
            assert(_gdi_context == NULL);
            _gdi_context = ps.hdc;
            paint_maze();
            _gdi_context = NULL;
        }
        EndPaint(hwnd, &ps);
        return 0;
    }
    default:
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
}

bool key_is_down(int key)
{
    if (!_active) return false;
    return static_cast<unsigned short>(GetKeyState(key)) >> 15;
}

struct Wall
{
    int x1, y1;
    int x2, y2;
};

// координаты упорядочены следующим образом:
//   если x1 = x2, то y1 < y2
//   если y1 = y2, то x1 < x2
// это используется в функции obj_pos_is_valid (см. ниже)
const Wall _walls[] =
{
    {40, 40, 100, 40},
    {100, 40, 100, 70},
    {100, 70, 130, 70},
    {130, 70, 130, 100},
    {100, 100, 100, 160},
    {70, 70, 70, 130},
    {40, 130, 70, 130},
    {70, 160, 100, 160},
    {70, 160, 70, 220},
    {100, 190, 100, 220},
    {130, 160, 130, 340},
    {70, 250, 130, 250},
    {100, 130, 160, 130},
    {160, 40, 160, 130},
    {70, 280, 100, 280},
    {70, 280, 70, 340},
    {70, 310, 250, 310},
    {40, 40, 40, 370},
    {100, 340, 100, 370},
    {130, 340, 160, 340},
    {190, 310, 190, 370},
    {40, 370, 190, 370},
    {160, 130, 160, 210},
    {130, 250, 190, 250},
    {160, 100, 190, 100},
    {190, 160, 190, 250},
    {190, 160, 220, 160},
    {190, 130, 280, 130},
    {220, 70, 220, 130},
    {190, 70, 220, 70},
    {130, 40, 340, 40},
    {250, 40, 250, 100},
    {280, 70, 280, 130},
    {280, 70, 310, 70},
    {310, 70, 310, 160},
    {340, 40, 340, 370},
    {310, 190, 340, 190},
    {220, 370, 340, 370},
    {220, 190, 220, 280},
    {160, 280, 280, 280},
    {250, 130, 250, 250},
    {250, 220, 340, 220},
    {280, 160, 280, 220},
    {250, 250, 310, 250},
    {280, 280, 280, 340},
    {220, 340, 280, 340},
    {220, 340, 220, 370},
    {280, 310, 310, 310},
    {310, 280, 310, 340},
};

// работает только для массивов, для указателей даст неверный результат
#define LEN(array) static_cast<int>(sizeof(array) / sizeof(array[0]))

// вызывается регулярно с интервалом _update_interval
void update()
{
    bool vis_change = false;

    // прошли лабиринт?
    if(_obj_pos_y > 370)
    {
        KillTimer(_window_han,1);
        MessageBoxW(NULL,L"Лабиринт Пройден!!!",L"",MB_OK);
    }

    int dir_x = 0;
    if (key_is_down(VK_LEFT)) dir_x--;
    if (key_is_down(VK_RIGHT)) dir_x++;

    int dir_y = 0;
    if (key_is_down(VK_DOWN)) dir_y++;
    if (key_is_down(VK_UP)) dir_y--;

    if ((dir_x != 0) || (dir_y != 0))
    {
        for (int i = 0; i < _obj_speed; i++)
        {
            int new_obj_pos_x = _obj_pos_x + dir_x;
            int new_obj_pos_y = _obj_pos_y + dir_y;
            if (obj_pos_is_valid(new_obj_pos_x, new_obj_pos_y))
            {
                _obj_pos_x = new_obj_pos_x;
                _obj_pos_y = new_obj_pos_y;
                vis_change = true;
            }
            else
            {
                break;
            }
        }
    }

    if (vis_change)
    {
        request_paint();
    }
}

inline int squ(int n)
{
    return n * n;
}

inline int clamp(int n, int min, int max)
{
    assert(min <= max);
    if (n < min) return min;
    if (n > max) return max;
    return n;
}

bool obj_pos_is_valid(int obj_pos_x, int obj_pos_y)
{
    // обойти лабиринт справа и слева не получится
    if(obj_pos_x < 50 || obj_pos_x > 330 || obj_pos_y < 10) return false;

    // объект не должен проходить сквозь стены
    for (int i = 0; i < LEN(_walls); i++)
    {
        const Wall* w = &_walls[i];
        int x1 = w->x1;
        int y1 = w->y1;
        int x2 = w->x2;
        int y2 = w->y2;
        int closest_point_x, closest_point_y;
        if (x1 == x2)
        {
            assert(y1 < y2);
            closest_point_x = x1;
            closest_point_y = clamp(obj_pos_y, y1, y2);
        }
        else
        {
            assert(y1 == y2);
            assert(x1 < x2);
            closest_point_x = clamp(obj_pos_x, x1, x2);
            closest_point_y = y1;
        }
        if (squ(obj_pos_x - closest_point_x) + squ(obj_pos_y - closest_point_y) < squ(_obj_radius)) return false;
    }
    return true;
}

void paint_maze()
{
    assert(_gdi_context != NULL);

    // рисуем фон
    RECT r = {0, 0, _window_client_width, _window_client_height};
    FillRect(_gdi_context, &r, static_cast<HBRUSH>(GetStockObject(GRAY_BRUSH)));

    // рисуем стены
    SelectObject(_gdi_context, GetStockObject(WHITE_PEN));
    for (int i = 0; i < LEN(_walls); i++)
    {
        const Wall* w = &_walls[i];
        MoveToEx(_gdi_context, w->x1, w->y1, NULL);
        LineTo(_gdi_context, w->x2, w->y2);
    }

    // рисуем объект
    SelectObject(_gdi_context, GetStockObject(WHITE_BRUSH));
    SelectObject(_gdi_context, GetStockObject(NULL_PEN));
    Ellipse(_gdi_context, _obj_pos_x - _obj_radius, _obj_pos_y - _obj_radius, _obj_pos_x + _obj_radius, _obj_pos_y + _obj_radius);
}

...
Рейтинг: 0 / 0
14.03.2013, 22:03
    #38184762
kot07
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Движение по лабиринту
Anatoly Moskovskykot07,
Бейсик детектед
Код: plaintext
1.
if ... then



И вот это что за чудо?
Код: plaintext
1.
if (190;370;220;370) 


это координаты выхода( нижнего пробела в лабиринте)
...
Рейтинг: 0 / 0
14.03.2013, 22:05
    #38184765
kot07
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Движение по лабиринту
m_Sla
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
#include <assert.h>
#define NOMINMAX
#include <windows.h>
#include <cstdio>

bool _running = false;
bool _active = false;

int _obj_pos_x = 115;
int _obj_pos_y = 40;
const int _obj_radius = 10;
const int _obj_speed = 2;

bool obj_pos_is_valid(int obj_pos_x, int obj_pos_y);
void init_window();
void term_window();

BOOL WINAPI CreateTimerQueueTimer(PHANDLE phNewTimer, HANDLE TimerQueue, PVOID Callback, PVOID Parameter,DWORD DueTime, DWORD Period,ULONG Flags);
BOOL WINAPI DeleteTimerQueueTimer( HANDLE TimerQueue, HANDLE Timer, HANDLE CompletionEvent);

int main()
{
    init_window();

    _running = true;
    // главный цикл
    while (_running)
    {
        MSG m;
        GetMessage(&m, /*hWnd:*/NULL, /*wMsgFilterMin:*/0, /*wMsgFilterMax:*/0);
        TranslateMessage(&m);
        DispatchMessage(&m);
    }

    term_window();

    return 0;
}

const char* const _window_class_name = "maze";
ATOM _window_class_id = 0;
HWND _window_han = NULL;
// размеры клиентской области окна (client area)
int _window_client_width = -1;
int _window_client_height = -1;

LRESULT CALLBACK window_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

void init_window()
{
    HINSTANCE exe_han = GetModuleHandle(NULL);

    // регистрируем оконный класс
    assert(_window_class_id == 0);
    WNDCLASSEX wc_params;
    wc_params.cbSize = sizeof(WNDCLASSEX);
    wc_params.style = 0;
    wc_params.lpfnWndProc = &window_proc;
    wc_params.cbClsExtra = 0;
    wc_params.cbWndExtra = 0;
    wc_params.hInstance = exe_han;
    wc_params.hIcon = NULL;
    wc_params.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc_params.hbrBackground = NULL; // фон будем рисовать сами
    wc_params.lpszMenuName = NULL;
    wc_params.lpszClassName = _window_class_name;
    wc_params.hIconSm = NULL;
    _window_class_id = RegisterClassEx(&wc_params);

    // создаём окно
    assert(_window_han == NULL);
    _window_han = CreateWindowEx(
                      /*dwExStyle:*/0,
                      /*lpClassName:*/_window_class_name,
                      /*lpWindowName:*/"Maze", // заголовок окна
                      /*dwStyle:*/WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                      /*x:*/CW_USEDEFAULT,
                      /*y:*/CW_USEDEFAULT,
                      /*nWidth:*/CW_USEDEFAULT,
                      /*nHeight:*/CW_USEDEFAULT,
                      /*hWndParent:*/NULL,
                      /*hMenu:*/NULL,
                      /*hInstance:*/exe_han,
                      /*lpParam:*/NULL
                  );
}

void term_window()
{
    if (_window_han != NULL)
    {
        DestroyWindow(_window_han);
        _window_han = NULL;
    }

    if (_window_class_id != 0)
    {
        HINSTANCE exe_han = GetModuleHandle(NULL);
        UnregisterClass(_window_class_name, exe_han);
        _window_class_id = 0;
    }
}

void request_paint()
{
    assert(_window_han != NULL);
    // помечаем всю клиентскую область окна как требующую перерисовки
    InvalidateRect(_window_han, /*lpRect:*/NULL, /*bErase:*/false);
    // в ближайшее время система пришлёт нашему окну сообщение WM_PAINT
}

bool _double_buffered = true;
HDC _gdi_context = NULL;

void update();
void paint_maze();

// оконная процедура (указывается при регистрации оконного класса)
LRESULT CALLBACK window_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_CREATE:
        SetTimer(hwnd, 1, 20, NULL);
        return 0;
    case WM_CLOSE:
        // завершаем главный цикл
        KillTimer(hwnd, 1);
        _running = false;
        return 0;
    case WM_SETFOCUS:
        _active = true;
        return 0;
    case WM_KILLFOCUS:
        _active = false;
        return 0;
    case WM_SIZE:
        _window_client_width = LOWORD(lParam);
        _window_client_height = HIWORD(lParam);
        return 0;
    case WM_TIMER: // посылается таймером см. WM_CREATE
        update();
        return 0;
    case WM_ERASEBKGND:
        // здесь ничего не делаем, фон рисуется в функции paint_maze
        return false; // не нарисовали фон
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        BeginPaint(hwnd, &ps);
        if (_double_buffered)
        {
            int x = ps.rcPaint.left;
            int y = ps.rcPaint.top;
            int w = ps.rcPaint.right - ps.rcPaint.left;
            int h = ps.rcPaint.bottom - ps.rcPaint.top;
            if ((w > 0) && (h > 0))
            {
                // рисуем лабиринт в back buffer
                HBITMAP back_buf = CreateCompatibleBitmap(ps.hdc, w, h);
                assert(_gdi_context == NULL);
                _gdi_context = CreateCompatibleDC(ps.hdc);
                SelectObject(_gdi_context, back_buf);
                SetViewportOrgEx(_gdi_context, -x, -y, NULL);
                paint_maze();
                RECT xy={50,400,150,450};
                char text[255];
                sprintf(text,"x=%d, y=%d",_obj_pos_x,_obj_pos_y);
                DrawTextA( _gdi_context, text, -1, &xy, DT_LEFT);


                // копируем содержимое back buffer-а в окно
                BitBlt(ps.hdc, x, y, w, h, _gdi_context, x, y, SRCCOPY);

                DeleteDC(_gdi_context);
                _gdi_context = NULL;
                DeleteObject(back_buf);
            }
        }
        else
        {
            // рисуем лабиринт прямо в окно
            assert(_gdi_context == NULL);
            _gdi_context = ps.hdc;
            paint_maze();
            _gdi_context = NULL;
        }
        EndPaint(hwnd, &ps);
        return 0;
    }
    default:
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
}

bool key_is_down(int key)
{
    if (!_active) return false;
    return static_cast<unsigned short>(GetKeyState(key)) >> 15;
}

struct Wall
{
    int x1, y1;
    int x2, y2;
};

// координаты упорядочены следующим образом:
//   если x1 = x2, то y1 < y2
//   если y1 = y2, то x1 < x2
// это используется в функции obj_pos_is_valid (см. ниже)
const Wall _walls[] =
{
    {40, 40, 100, 40},
    {100, 40, 100, 70},
    {100, 70, 130, 70},
    {130, 70, 130, 100},
    {100, 100, 100, 160},
    {70, 70, 70, 130},
    {40, 130, 70, 130},
    {70, 160, 100, 160},
    {70, 160, 70, 220},
    {100, 190, 100, 220},
    {130, 160, 130, 340},
    {70, 250, 130, 250},
    {100, 130, 160, 130},
    {160, 40, 160, 130},
    {70, 280, 100, 280},
    {70, 280, 70, 340},
    {70, 310, 250, 310},
    {40, 40, 40, 370},
    {100, 340, 100, 370},
    {130, 340, 160, 340},
    {190, 310, 190, 370},
    {40, 370, 190, 370},
    {160, 130, 160, 210},
    {130, 250, 190, 250},
    {160, 100, 190, 100},
    {190, 160, 190, 250},
    {190, 160, 220, 160},
    {190, 130, 280, 130},
    {220, 70, 220, 130},
    {190, 70, 220, 70},
    {130, 40, 340, 40},
    {250, 40, 250, 100},
    {280, 70, 280, 130},
    {280, 70, 310, 70},
    {310, 70, 310, 160},
    {340, 40, 340, 370},
    {310, 190, 340, 190},
    {220, 370, 340, 370},
    {220, 190, 220, 280},
    {160, 280, 280, 280},
    {250, 130, 250, 250},
    {250, 220, 340, 220},
    {280, 160, 280, 220},
    {250, 250, 310, 250},
    {280, 280, 280, 340},
    {220, 340, 280, 340},
    {220, 340, 220, 370},
    {280, 310, 310, 310},
    {310, 280, 310, 340},
};

// работает только для массивов, для указателей даст неверный результат
#define LEN(array) static_cast<int>(sizeof(array) / sizeof(array[0]))

// вызывается регулярно с интервалом _update_interval
void update()
{
    bool vis_change = false;

    // прошли лабиринт?
    if(_obj_pos_y > 370)
    {
        KillTimer(_window_han,1);
        MessageBoxW(NULL,L"Лабиринт Пройден!!!",L"",MB_OK);
    }

    int dir_x = 0;
    if (key_is_down(VK_LEFT)) dir_x--;
    if (key_is_down(VK_RIGHT)) dir_x++;

    int dir_y = 0;
    if (key_is_down(VK_DOWN)) dir_y++;
    if (key_is_down(VK_UP)) dir_y--;

    if ((dir_x != 0) || (dir_y != 0))
    {
        for (int i = 0; i < _obj_speed; i++)
        {
            int new_obj_pos_x = _obj_pos_x + dir_x;
            int new_obj_pos_y = _obj_pos_y + dir_y;
            if (obj_pos_is_valid(new_obj_pos_x, new_obj_pos_y))
            {
                _obj_pos_x = new_obj_pos_x;
                _obj_pos_y = new_obj_pos_y;
                vis_change = true;
            }
            else
            {
                break;
            }
        }
    }

    if (vis_change)
    {
        request_paint();
    }
}

inline int squ(int n)
{
    return n * n;
}

inline int clamp(int n, int min, int max)
{
    assert(min <= max);
    if (n < min) return min;
    if (n > max) return max;
    return n;
}

bool obj_pos_is_valid(int obj_pos_x, int obj_pos_y)
{
    // обойти лабиринт справа и слева не получится
    if(obj_pos_x < 50 || obj_pos_x > 330 || obj_pos_y < 10) return false;

    // объект не должен проходить сквозь стены
    for (int i = 0; i < LEN(_walls); i++)
    {
        const Wall* w = &_walls[i];
        int x1 = w->x1;
        int y1 = w->y1;
        int x2 = w->x2;
        int y2 = w->y2;
        int closest_point_x, closest_point_y;
        if (x1 == x2)
        {
            assert(y1 < y2);
            closest_point_x = x1;
            closest_point_y = clamp(obj_pos_y, y1, y2);
        }
        else
        {
            assert(y1 == y2);
            assert(x1 < x2);
            closest_point_x = clamp(obj_pos_x, x1, x2);
            closest_point_y = y1;
        }
        if (squ(obj_pos_x - closest_point_x) + squ(obj_pos_y - closest_point_y) < squ(_obj_radius)) return false;
    }
    return true;
}

void paint_maze()
{
    assert(_gdi_context != NULL);

    // рисуем фон
    RECT r = {0, 0, _window_client_width, _window_client_height};
    FillRect(_gdi_context, &r, static_cast<HBRUSH>(GetStockObject(GRAY_BRUSH)));

    // рисуем стены
    SelectObject(_gdi_context, GetStockObject(WHITE_PEN));
    for (int i = 0; i < LEN(_walls); i++)
    {
        const Wall* w = &_walls[i];
        MoveToEx(_gdi_context, w->x1, w->y1, NULL);
        LineTo(_gdi_context, w->x2, w->y2);
    }

    // рисуем объект
    SelectObject(_gdi_context, GetStockObject(WHITE_BRUSH));
    SelectObject(_gdi_context, GetStockObject(NULL_PEN));
    Ellipse(_gdi_context, _obj_pos_x - _obj_radius, _obj_pos_y - _obj_radius, _obj_pos_x + _obj_radius, _obj_pos_y + _obj_radius);
}


выдал ошибку
Illegal byte sequence
...
Рейтинг: 0 / 0
14.03.2013, 22:08
    #38184766
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Движение по лабиринту
kot07И вот это что за чудо?
Код: plaintext
1.
if (190;370;220;370) 


это координаты выхода( нижнего пробела в лабиринте)
И что по вашему этот оператор означает?
И главное в каком справочнике вы нашли такой синтаксис?
...
Рейтинг: 0 / 0
14.03.2013, 23:19
    #38184823
Sheraton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Движение по лабиринту
Anatoly MoskovskyИ что по вашему этот оператор означает?
И главное в каком справочнике вы нашли такой синтаксис?

:)) И самое главное, где почитать об инструкции then в С++ ? :))
...
Рейтинг: 0 / 0
15.03.2013, 01:16
    #38184884
mayton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Движение по лабиринту
Будет вам. Тролли...
...
Рейтинг: 0 / 0
15.03.2013, 02:44
    #38184908
m_Sla
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Движение по лабиринту
kot07выдал ошибку
Illegal byte sequenceу меня не выдает ошибку
mingw 4.6.2:

-------------- Clean: Debug in labirint (compiler: GNU GCC Compiler)---------------

Cleaned "labirint - Debug"

-------------- Build: Debug in labirint (compiler: GNU GCC Compiler)---------------

mingw32-g++.exe -Wall -g -march=core2 -std=c++0x -finput-charset=WINDOWS-1251 -msse4 -c Y:\Codeblocks\labirint\main.cpp -o obj\Debug\main.o
mingw32-g++.exe -o bin\Debug\labirint.exe obj\Debug\main.o C:\Windows\System32\Kernel32.dll -static-libgcc -static-libstdc++ -lgdi32 -luser32 -lkernel32 -lcomctl32
Output size is 155.01 KB
Process terminated with status 0 (0 minutes, 0 seconds)
0 errors, 0 warnings (0 minutes, 0 seconds)

На какую строку ругается?
...
Рейтинг: 0 / 0
15.03.2013, 03:24
    #38184917
m_Sla
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Движение по лабиринту
а так?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
#include <assert.h>
#define NOMINMAX
#include <windows.h>

bool _running = false;
bool _active = false;

int _obj_pos_x = 115;
int _obj_pos_y = 40;
const int _obj_radius = 10;
const int _obj_speed = 2;

bool obj_pos_is_valid(int obj_pos_x, int obj_pos_y);
void init_window();
void term_window();

int main()
{
    init_window();

    _running = true;
    // главный цикл
    while (_running)
    {
        MSG m;
        GetMessage(&m, /*hWnd:*/NULL, /*wMsgFilterMin:*/0, /*wMsgFilterMax:*/0);
        TranslateMessage(&m);
        DispatchMessage(&m);
    }

    term_window();

    return 0;
}

const char* const _window_class_name = "maze";
ATOM _window_class_id = 0;
HWND _window_han = NULL;
// размеры клиентской области окна (client area)
int _window_client_width = -1;
int _window_client_height = -1;

LRESULT CALLBACK window_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

void init_window()
{
    HINSTANCE exe_han = GetModuleHandle(NULL);

    // регистрируем оконный класс
    assert(_window_class_id == 0);
    WNDCLASSEX wc_params;
    wc_params.cbSize = sizeof(WNDCLASSEX);
    wc_params.style = 0;
    wc_params.lpfnWndProc = &window_proc;
    wc_params.cbClsExtra = 0;
    wc_params.cbWndExtra = 0;
    wc_params.hInstance = exe_han;
    wc_params.hIcon = NULL;
    wc_params.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc_params.hbrBackground = NULL; // фон будем рисовать сами
    wc_params.lpszMenuName = NULL;
    wc_params.lpszClassName = _window_class_name;
    wc_params.hIconSm = NULL;
    _window_class_id = RegisterClassEx(&wc_params);

    // создаём окно
    assert(_window_han == NULL);
    _window_han = CreateWindowEx(
                      /*dwExStyle:*/0,
                      /*lpClassName:*/_window_class_name,
                      /*lpWindowName:*/"Maze", // заголовок окна
                      /*dwStyle:*/WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                      /*x:*/CW_USEDEFAULT,
                      /*y:*/CW_USEDEFAULT,
                      /*nWidth:*/CW_USEDEFAULT,
                      /*nHeight:*/CW_USEDEFAULT,
                      /*hWndParent:*/NULL,
                      /*hMenu:*/NULL,
                      /*hInstance:*/exe_han,
                      /*lpParam:*/NULL
                  );
}

void term_window()
{
    if (_window_han != NULL)
    {
        DestroyWindow(_window_han);
        _window_han = NULL;
    }

    if (_window_class_id != 0)
    {
        HINSTANCE exe_han = GetModuleHandle(NULL);
        UnregisterClass(_window_class_name, exe_han);
        _window_class_id = 0;
    }
}

void request_paint()
{
    assert(_window_han != NULL);
    // помечаем всю клиентскую область окна как требующую перерисовки
    InvalidateRect(_window_han, /*lpRect:*/NULL, /*bErase:*/false);
    // в ближайшее время система пришлёт нашему окну сообщение WM_PAINT
}

bool _double_buffered = true;
HDC _gdi_context = NULL;

void update();
void paint_maze();

// оконная процедура (указывается при регистрации оконного класса)
LRESULT CALLBACK window_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_CREATE:
        SetTimer(hwnd, 1, 20, NULL);
        return 0;
    case WM_CLOSE:
        // завершаем главный цикл
        KillTimer(hwnd, 1);
        _running = false;
        return 0;
    case WM_SETFOCUS:
        _active = true;
        return 0;
    case WM_KILLFOCUS:
        _active = false;
        return 0;
    case WM_SIZE:
        _window_client_width = LOWORD(lParam);
        _window_client_height = HIWORD(lParam);
        return 0;
    case WM_TIMER: // посылается таймером см. WM_CREATE
        update();
        return 0;
    case WM_ERASEBKGND:
        // здесь ничего не делаем, фон рисуется в функции paint_maze
        return false; // не нарисовали фон
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        BeginPaint(hwnd, &ps);
        if (_double_buffered)
        {
            int x = ps.rcPaint.left;
            int y = ps.rcPaint.top;
            int w = ps.rcPaint.right - ps.rcPaint.left;
            int h = ps.rcPaint.bottom - ps.rcPaint.top;
            if ((w > 0) && (h > 0))
            {
                // рисуем лабиринт в back buffer
                HBITMAP back_buf = CreateCompatibleBitmap(ps.hdc, w, h);
                assert(_gdi_context == NULL);
                _gdi_context = CreateCompatibleDC(ps.hdc);
                SelectObject(_gdi_context, back_buf);
                SetViewportOrgEx(_gdi_context, -x, -y, NULL);
                paint_maze();
                RECT xy={50,400,150,450};
                wchar_t text[255];
                wsprintfW(text,L"x=%d, y=%d",_obj_pos_x,_obj_pos_y);
                DrawTextW(_gdi_context, text, -1, &xy, DT_LEFT);

                // копируем содержимое back buffer-а в окно
                BitBlt(ps.hdc, x, y, w, h, _gdi_context, x, y, SRCCOPY);

                DeleteDC(_gdi_context);
                _gdi_context = NULL;
                DeleteObject(back_buf);
            }
        }
        else
        {
            // рисуем лабиринт прямо в окно
            assert(_gdi_context == NULL);
            _gdi_context = ps.hdc;
            paint_maze();
            _gdi_context = NULL;
        }
        EndPaint(hwnd, &ps);
        return 0;
    }
    default:
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
}

bool key_is_down(int key)
{
    if (!_active) return false;
    return static_cast<unsigned short>(GetKeyState(key)) >> 15;
}

struct Wall
{
    int x1, y1;
    int x2, y2;
};

// координаты упорядочены следующим образом:
//   если x1 = x2, то y1 < y2
//   если y1 = y2, то x1 < x2
// это используется в функции obj_pos_is_valid (см. ниже)
const Wall _walls[] =
{
    {40, 40, 100, 40},
    {100, 40, 100, 70},
    {100, 70, 130, 70},
    {130, 70, 130, 100},
    {100, 100, 100, 160},
    {70, 70, 70, 130},
    {40, 130, 70, 130},
    {70, 160, 100, 160},
    {70, 160, 70, 220},
    {100, 190, 100, 220},
    {130, 160, 130, 340},
    {70, 250, 130, 250},
    {100, 130, 160, 130},
    {160, 40, 160, 130},
    {70, 280, 100, 280},
    {70, 280, 70, 340},
    {70, 310, 250, 310},
    {40, 40, 40, 370},
    {100, 340, 100, 370},
    {130, 340, 160, 340},
    {190, 310, 190, 370},
    {40, 370, 190, 370},
    {160, 130, 160, 210},
    {130, 250, 190, 250},
    {160, 100, 190, 100},
    {190, 160, 190, 250},
    {190, 160, 220, 160},
    {190, 130, 280, 130},
    {220, 70, 220, 130},
    {190, 70, 220, 70},
    {130, 40, 340, 40},
    {250, 40, 250, 100},
    {280, 70, 280, 130},
    {280, 70, 310, 70},
    {310, 70, 310, 160},
    {340, 40, 340, 370},
    {310, 190, 340, 190},
    {220, 370, 340, 370},
    {220, 190, 220, 280},
    {160, 280, 280, 280},
    {250, 130, 250, 250},
    {250, 220, 340, 220},
    {280, 160, 280, 220},
    {250, 250, 310, 250},
    {280, 280, 280, 340},
    {220, 340, 280, 340},
    {220, 340, 220, 370},
    {280, 310, 310, 310},
    {310, 280, 310, 340},
};

// работает только для массивов, для указателей даст неверный результат
#define LEN(array) static_cast<int>(sizeof(array) / sizeof(array[0]))

// вызывается регулярно с интервалом _update_interval
void update()
{
    bool vis_change = false;

    // прошли лабиринт?
    if(_obj_pos_y > 370)
    {
        KillTimer(_window_han,1);
        MessageBoxW(NULL,L"Maze passed.\r\nCongratulations!",L"",MB_OK);
    }

    int dir_x = 0;
    if (key_is_down(VK_LEFT)) dir_x--;
    if (key_is_down(VK_RIGHT)) dir_x++;

    int dir_y = 0;
    if (key_is_down(VK_DOWN)) dir_y++;
    if (key_is_down(VK_UP)) dir_y--;

    if ((dir_x != 0) || (dir_y != 0))
    {
        for (int i = 0; i < _obj_speed; i++)
        {
            int new_obj_pos_x = _obj_pos_x + dir_x;
            int new_obj_pos_y = _obj_pos_y + dir_y;
            if (obj_pos_is_valid(new_obj_pos_x, new_obj_pos_y))
            {
                _obj_pos_x = new_obj_pos_x;
                _obj_pos_y = new_obj_pos_y;
                vis_change = true;
            }
            else
            {
                break;
            }
        }
    }

    if (vis_change)
    {
        request_paint();
    }
}

inline int squ(int n)
{
    return n * n;
}

inline int clamp(int n, int min, int max)
{
    assert(min <= max);
    if (n < min) return min;
    if (n > max) return max;
    return n;
}

bool obj_pos_is_valid(int obj_pos_x, int obj_pos_y)
{
    // обойти лабиринт справа и слева не получится
    if(obj_pos_x < 50 || obj_pos_x > 330 || obj_pos_y < 10) return false;

    // объект не должен проходить сквозь стены
    for (int i = 0; i < LEN(_walls); i++)
    {
        const Wall* w = &_walls[i];
        int x1 = w->x1;
        int y1 = w->y1;
        int x2 = w->x2;
        int y2 = w->y2;
        int closest_point_x, closest_point_y;
        if (x1 == x2)
        {
            assert(y1 < y2);
            closest_point_x = x1;
            closest_point_y = clamp(obj_pos_y, y1, y2);
        }
        else
        {
            assert(y1 == y2);
            assert(x1 < x2);
            closest_point_x = clamp(obj_pos_x, x1, x2);
            closest_point_y = y1;
        }
        if (squ(obj_pos_x - closest_point_x) + squ(obj_pos_y - closest_point_y) < squ(_obj_radius)) return false;
    }
    return true;
}

void paint_maze()
{
    assert(_gdi_context != NULL);

    // рисуем фон
    RECT r = {0, 0, _window_client_width, _window_client_height};
    FillRect(_gdi_context, &r, static_cast<HBRUSH>(GetStockObject(GRAY_BRUSH)));

    // рисуем стены
    SelectObject(_gdi_context, GetStockObject(WHITE_PEN));
    for (int i = 0; i < LEN(_walls); i++)
    {
        const Wall* w = &_walls[i];
        MoveToEx(_gdi_context, w->x1, w->y1, NULL);
        LineTo(_gdi_context, w->x2, w->y2);
    }

    // рисуем объект
    SelectObject(_gdi_context, GetStockObject(WHITE_BRUSH));
    SelectObject(_gdi_context, GetStockObject(NULL_PEN));
    Ellipse(_gdi_context, _obj_pos_x - _obj_radius, _obj_pos_y - _obj_radius, _obj_pos_x + _obj_radius, _obj_pos_y + _obj_radius);
}


-------------- Clean: Debug in labirint (compiler: GNU GCC Compiler)---------------

Cleaned "labirint - Debug"

-------------- Build: Debug in labirint (compiler: GNU GCC Compiler)---------------

mingw32-g++.exe -Wall -g -march=core2 -std=c++0x -finput-charset=WINDOWS-1251 -msse4 -c Y:\Codeblocks\labirint\main.cpp -o obj\Debug\main.o
mingw32-g++.exe -o bin\Debug\labirint.exe obj\Debug\main.o -static-libgcc -static-libstdc++ -lgdi32 -luser32 -lkernel32 -lcomctl32
Output size is 65.21 KB
Process terminated with status 0 (0 minutes, 0 seconds)
0 errors, 0 warnings (0 minutes, 0 seconds)
больше хрустальный шар ни чего не подсказывает...
...
Рейтинг: 0 / 0
15.03.2013, 07:02
    #38184960
kot07
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Движение по лабиринту
m_Slaа так?
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
#include <assert.h>
#define NOMINMAX
#include <windows.h>

bool _running = false;
bool _active = false;

int _obj_pos_x = 115;
int _obj_pos_y = 40;
const int _obj_radius = 10;
const int _obj_speed = 2;

bool obj_pos_is_valid(int obj_pos_x, int obj_pos_y);
void init_window();
void term_window();

int main()
{
    init_window();

    _running = true;
    // главный цикл
    while (_running)
    {
        MSG m;
        GetMessage(&m, /*hWnd:*/NULL, /*wMsgFilterMin:*/0, /*wMsgFilterMax:*/0);
        TranslateMessage(&m);
        DispatchMessage(&m);
    }

    term_window();

    return 0;
}

const char* const _window_class_name = "maze";
ATOM _window_class_id = 0;
HWND _window_han = NULL;
// размеры клиентской области окна (client area)
int _window_client_width = -1;
int _window_client_height = -1;

LRESULT CALLBACK window_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

void init_window()
{
    HINSTANCE exe_han = GetModuleHandle(NULL);

    // регистрируем оконный класс
    assert(_window_class_id == 0);
    WNDCLASSEX wc_params;
    wc_params.cbSize = sizeof(WNDCLASSEX);
    wc_params.style = 0;
    wc_params.lpfnWndProc = &window_proc;
    wc_params.cbClsExtra = 0;
    wc_params.cbWndExtra = 0;
    wc_params.hInstance = exe_han;
    wc_params.hIcon = NULL;
    wc_params.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc_params.hbrBackground = NULL; // фон будем рисовать сами
    wc_params.lpszMenuName = NULL;
    wc_params.lpszClassName = _window_class_name;
    wc_params.hIconSm = NULL;
    _window_class_id = RegisterClassEx(&wc_params);

    // создаём окно
    assert(_window_han == NULL);
    _window_han = CreateWindowEx(
                      /*dwExStyle:*/0,
                      /*lpClassName:*/_window_class_name,
                      /*lpWindowName:*/"Maze", // заголовок окна
                      /*dwStyle:*/WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                      /*x:*/CW_USEDEFAULT,
                      /*y:*/CW_USEDEFAULT,
                      /*nWidth:*/CW_USEDEFAULT,
                      /*nHeight:*/CW_USEDEFAULT,
                      /*hWndParent:*/NULL,
                      /*hMenu:*/NULL,
                      /*hInstance:*/exe_han,
                      /*lpParam:*/NULL
                  );
}

void term_window()
{
    if (_window_han != NULL)
    {
        DestroyWindow(_window_han);
        _window_han = NULL;
    }

    if (_window_class_id != 0)
    {
        HINSTANCE exe_han = GetModuleHandle(NULL);
        UnregisterClass(_window_class_name, exe_han);
        _window_class_id = 0;
    }
}

void request_paint()
{
    assert(_window_han != NULL);
    // помечаем всю клиентскую область окна как требующую перерисовки
    InvalidateRect(_window_han, /*lpRect:*/NULL, /*bErase:*/false);
    // в ближайшее время система пришлёт нашему окну сообщение WM_PAINT
}

bool _double_buffered = true;
HDC _gdi_context = NULL;

void update();
void paint_maze();

// оконная процедура (указывается при регистрации оконного класса)
LRESULT CALLBACK window_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_CREATE:
        SetTimer(hwnd, 1, 20, NULL);
        return 0;
    case WM_CLOSE:
        // завершаем главный цикл
        KillTimer(hwnd, 1);
        _running = false;
        return 0;
    case WM_SETFOCUS:
        _active = true;
        return 0;
    case WM_KILLFOCUS:
        _active = false;
        return 0;
    case WM_SIZE:
        _window_client_width = LOWORD(lParam);
        _window_client_height = HIWORD(lParam);
        return 0;
    case WM_TIMER: // посылается таймером см. WM_CREATE
        update();
        return 0;
    case WM_ERASEBKGND:
        // здесь ничего не делаем, фон рисуется в функции paint_maze
        return false; // не нарисовали фон
    case WM_PAINT:
    {
        PAINTSTRUCT ps;
        BeginPaint(hwnd, &ps);
        if (_double_buffered)
        {
            int x = ps.rcPaint.left;
            int y = ps.rcPaint.top;
            int w = ps.rcPaint.right - ps.rcPaint.left;
            int h = ps.rcPaint.bottom - ps.rcPaint.top;
            if ((w > 0) && (h > 0))
            {
                // рисуем лабиринт в back buffer
                HBITMAP back_buf = CreateCompatibleBitmap(ps.hdc, w, h);
                assert(_gdi_context == NULL);
                _gdi_context = CreateCompatibleDC(ps.hdc);
                SelectObject(_gdi_context, back_buf);
                SetViewportOrgEx(_gdi_context, -x, -y, NULL);
                paint_maze();
                RECT xy={50,400,150,450};
                wchar_t text[255];
                wsprintfW(text,L"x=%d, y=%d",_obj_pos_x,_obj_pos_y);
                DrawTextW(_gdi_context, text, -1, &xy, DT_LEFT);

                // копируем содержимое back buffer-а в окно
                BitBlt(ps.hdc, x, y, w, h, _gdi_context, x, y, SRCCOPY);

                DeleteDC(_gdi_context);
                _gdi_context = NULL;
                DeleteObject(back_buf);
            }
        }
        else
        {
            // рисуем лабиринт прямо в окно
            assert(_gdi_context == NULL);
            _gdi_context = ps.hdc;
            paint_maze();
            _gdi_context = NULL;
        }
        EndPaint(hwnd, &ps);
        return 0;
    }
    default:
        return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }
}

bool key_is_down(int key)
{
    if (!_active) return false;
    return static_cast<unsigned short>(GetKeyState(key)) >> 15;
}

struct Wall
{
    int x1, y1;
    int x2, y2;
};

// координаты упорядочены следующим образом:
//   если x1 = x2, то y1 < y2
//   если y1 = y2, то x1 < x2
// это используется в функции obj_pos_is_valid (см. ниже)
const Wall _walls[] =
{
    {40, 40, 100, 40},
    {100, 40, 100, 70},
    {100, 70, 130, 70},
    {130, 70, 130, 100},
    {100, 100, 100, 160},
    {70, 70, 70, 130},
    {40, 130, 70, 130},
    {70, 160, 100, 160},
    {70, 160, 70, 220},
    {100, 190, 100, 220},
    {130, 160, 130, 340},
    {70, 250, 130, 250},
    {100, 130, 160, 130},
    {160, 40, 160, 130},
    {70, 280, 100, 280},
    {70, 280, 70, 340},
    {70, 310, 250, 310},
    {40, 40, 40, 370},
    {100, 340, 100, 370},
    {130, 340, 160, 340},
    {190, 310, 190, 370},
    {40, 370, 190, 370},
    {160, 130, 160, 210},
    {130, 250, 190, 250},
    {160, 100, 190, 100},
    {190, 160, 190, 250},
    {190, 160, 220, 160},
    {190, 130, 280, 130},
    {220, 70, 220, 130},
    {190, 70, 220, 70},
    {130, 40, 340, 40},
    {250, 40, 250, 100},
    {280, 70, 280, 130},
    {280, 70, 310, 70},
    {310, 70, 310, 160},
    {340, 40, 340, 370},
    {310, 190, 340, 190},
    {220, 370, 340, 370},
    {220, 190, 220, 280},
    {160, 280, 280, 280},
    {250, 130, 250, 250},
    {250, 220, 340, 220},
    {280, 160, 280, 220},
    {250, 250, 310, 250},
    {280, 280, 280, 340},
    {220, 340, 280, 340},
    {220, 340, 220, 370},
    {280, 310, 310, 310},
    {310, 280, 310, 340},
};

// работает только для массивов, для указателей даст неверный результат
#define LEN(array) static_cast<int>(sizeof(array) / sizeof(array[0]))

// вызывается регулярно с интервалом _update_interval
void update()
{
    bool vis_change = false;

    // прошли лабиринт?
    if(_obj_pos_y > 370)
    {
        KillTimer(_window_han,1);
        MessageBoxW(NULL,L"Maze passed.\r\nCongratulations!",L"",MB_OK);
    }

    int dir_x = 0;
    if (key_is_down(VK_LEFT)) dir_x--;
    if (key_is_down(VK_RIGHT)) dir_x++;

    int dir_y = 0;
    if (key_is_down(VK_DOWN)) dir_y++;
    if (key_is_down(VK_UP)) dir_y--;

    if ((dir_x != 0) || (dir_y != 0))
    {
        for (int i = 0; i < _obj_speed; i++)
        {
            int new_obj_pos_x = _obj_pos_x + dir_x;
            int new_obj_pos_y = _obj_pos_y + dir_y;
            if (obj_pos_is_valid(new_obj_pos_x, new_obj_pos_y))
            {
                _obj_pos_x = new_obj_pos_x;
                _obj_pos_y = new_obj_pos_y;
                vis_change = true;
            }
            else
            {
                break;
            }
        }
    }

    if (vis_change)
    {
        request_paint();
    }
}

inline int squ(int n)
{
    return n * n;
}

inline int clamp(int n, int min, int max)
{
    assert(min <= max);
    if (n < min) return min;
    if (n > max) return max;
    return n;
}

bool obj_pos_is_valid(int obj_pos_x, int obj_pos_y)
{
    // обойти лабиринт справа и слева не получится
    if(obj_pos_x < 50 || obj_pos_x > 330 || obj_pos_y < 10) return false;

    // объект не должен проходить сквозь стены
    for (int i = 0; i < LEN(_walls); i++)
    {
        const Wall* w = &_walls[i];
        int x1 = w->x1;
        int y1 = w->y1;
        int x2 = w->x2;
        int y2 = w->y2;
        int closest_point_x, closest_point_y;
        if (x1 == x2)
        {
            assert(y1 < y2);
            closest_point_x = x1;
            closest_point_y = clamp(obj_pos_y, y1, y2);
        }
        else
        {
            assert(y1 == y2);
            assert(x1 < x2);
            closest_point_x = clamp(obj_pos_x, x1, x2);
            closest_point_y = y1;
        }
        if (squ(obj_pos_x - closest_point_x) + squ(obj_pos_y - closest_point_y) < squ(_obj_radius)) return false;
    }
    return true;
}

void paint_maze()
{
    assert(_gdi_context != NULL);

    // рисуем фон
    RECT r = {0, 0, _window_client_width, _window_client_height};
    FillRect(_gdi_context, &r, static_cast<HBRUSH>(GetStockObject(GRAY_BRUSH)));

    // рисуем стены
    SelectObject(_gdi_context, GetStockObject(WHITE_PEN));
    for (int i = 0; i < LEN(_walls); i++)
    {
        const Wall* w = &_walls[i];
        MoveToEx(_gdi_context, w->x1, w->y1, NULL);
        LineTo(_gdi_context, w->x2, w->y2);
    }

    // рисуем объект
    SelectObject(_gdi_context, GetStockObject(WHITE_BRUSH));
    SelectObject(_gdi_context, GetStockObject(NULL_PEN));
    Ellipse(_gdi_context, _obj_pos_x - _obj_radius, _obj_pos_y - _obj_radius, _obj_pos_x + _obj_radius, _obj_pos_y + _obj_radius);
}


-------------- Clean: Debug in labirint (compiler: GNU GCC Compiler)---------------

Cleaned "labirint - Debug"

-------------- Build: Debug in labirint (compiler: GNU GCC Compiler)---------------

mingw32-g++.exe -Wall -g -march=core2 -std=c++0x -finput-charset=WINDOWS-1251 -msse4 -c Y:\Codeblocks\labirint\main.cpp -o obj\Debug\main.o
mingw32-g++.exe -o bin\Debug\labirint.exe obj\Debug\main.o -static-libgcc -static-libstdc++ -lgdi32 -luser32 -lkernel32 -lcomctl32
Output size is 65.21 KB
Process terminated with status 0 (0 minutes, 0 seconds)
0 errors, 0 warnings (0 minutes, 0 seconds)
больше хрустальный шар ни чего не подсказывает...
а так все работает, спасибо
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Движение по лабиринту / 25 сообщений из 28, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]