Форум программистов, компьютерный форум CyberForum.ru

Как написать свой таймер? - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 11, средняя оценка - 4.64
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
06.01.2014, 00:14     Как написать свой таймер? #1
Чтобы функция выполнялась скажем каждые 200 миллисекунд. Сейчас WM_TIMER делает это, но он не подходит. Искал по многим запросам в гугле и не смог найти простого примера.
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,919
Записей в блоге: 2
Завершенные тесты: 1
06.01.2014, 00:32     Как написать свой таймер? #2
Цитата Сообщение от mzarb Посмотреть сообщение
Сейчас WM_TIMER делает это, но он не подходит.
Почему?
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
06.01.2014, 00:39  [ТС]     Как написать свой таймер? #3
Croessmah, мне так сказали
Nikcharn
 Аватар для Nikcharn
71 / 53 / 3
Регистрация: 31.07.2009
Сообщений: 149
06.01.2014, 01:45     Как написать свой таймер? #4
Цитата Сообщение от mzarb Посмотреть сообщение
мне так сказали
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <ctime> 
using namespace std;
void how2timer(int ms) {
    int CLOCKS_PER_MSEC = CLOCKS_PER_SEC / 1000; 
    clock_t end_time = clock() + ms * CLOCKS_PER_MSEC ;
    while (clock() < end_time) {}
    cout << "Время вышло!!!\n";
}
int main (){
    how2timer(5000);  // 5 секунд
    return 0;
}
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
06.01.2014, 02:23  [ТС]     Как написать свой таймер? #5
Nikcharn, ок, а куда это дело вставлять, в WM_CREATE сойдет?
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11845 / 6824 / 771
Регистрация: 27.09.2012
Сообщений: 16,919
Записей в блоге: 2
Завершенные тесты: 1
06.01.2014, 02:31     Как написать свой таймер? #6
Цитата Сообщение от mzarb Посмотреть сообщение
а куда это дело вставлять
для начала в голову. Смысл вставлять то, что не понимаете?
Nikcharn
 Аватар для Nikcharn
71 / 53 / 3
Регистрация: 31.07.2009
Сообщений: 149
06.01.2014, 02:34     Как написать свой таймер? #7
Цитата Сообщение от mzarb Посмотреть сообщение
ок, а куда это дело вставлять, в WM_CREATE сойдет?
А можете полнее озвучить вашу задачу?
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
06.01.2014, 02:50  [ТС]     Как написать свой таймер? #8
Nikcharn,
C++
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
#include "windows.h"
#include <deque>
#include <algorithm>
#include <iostream>
#include <time.h>
 
const int cellCountX = 60;
const int cellCountY = 40;
const int cellSize   = 10;
 
const int windowWidth  = cellSize * cellCountX+7;
const int windowHeight = cellSize * cellCountY+29;
const int clientWidth  = cellSize * cellCountX;
const int clientHeight = cellSize * cellCountY;
 
int snakeSize  = 6;
int snakeLives = 4;
struct snake{
  int x;
  int y;
};
 
std::deque<snake> snakePos;
std::deque<snake> lifePos;
std::deque<snake> foodPos;
 
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
 
int WINAPI WinMain(HINSTANCE h,HINSTANCE hprevinstance,LPSTR lpcmdline,int ncmdshow){
  WNDCLASSEX wc;
  HWND hwnd;
  MSG msg;
 
  ZeroMemory(&msg,sizeof(MSG));
  wc.cbSize=sizeof(wc);
  wc.style=CS_OWNDC|CS_HREDRAW|CS_VREDRAW;
  wc.lpfnWndProc=WndProc;
  wc.cbClsExtra=0;
  wc.cbWndExtra=0;
  wc.hInstance=h;
  wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);
  wc.hCursor=LoadCursor(h,IDC_ARROW);
  wc.hbrBackground=(HBRUSH)GetStockObject(GRAY_BRUSH);
  wc.lpszMenuName=NULL;
  wc.lpszClassName="main";
  wc.hIconSm=LoadIcon(NULL,IDI_APPLICATION);
  if(!RegisterClassEx(&wc)) return 0;
 
  if(!(hwnd=CreateWindowEx(NULL,"main","Snake",WS_OVERLAPPEDWINDOW^WS_MAXIMIZEBOX^WS_THICKFRAME|WS_VISIBLE,(GetSystemMetrics(SM_CXSCREEN) - windowWidth) / 2, (GetSystemMetrics(SM_CYSCREEN) - windowHeight-300) / 2,windowWidth,windowHeight,NULL,NULL,h,NULL))) return 0;
  ShowWindow(hwnd,SW_SHOWDEFAULT);
  UpdateWindow(hwnd);
 
  while(msg.message != WM_QUIT){
    if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)){
      TranslateMessage(&msg);
      DispatchMessage(&msg);
    }
  }
  return msg.wParam;
}
 
snake GenFoodPos() {
  int foodPosX;
  int foodPosY;
  snake foodPosTemp;
  srand(clock());
  foodPosX = rand() % cellCountX;
  foodPosY = rand() % cellCountY;
  foodPosTemp.x = foodPosX*cellSize;
  foodPosTemp.y = foodPosY*cellSize;
  return foodPosTemp;
}
 
bool CheckFoodPos(snake foodPos){
  for(std::deque<snake>::iterator it = snakePos.begin(); it!=snakePos.end();++it){
    if(foodPos.x == it->x && foodPos.y == it->y){
      return FALSE;
    }
  }
  return TRUE;
}
 
void SetFoodPos(){
  snake newFoodTemp;
  bool badFoodPos;
  do
  {
    newFoodTemp = GenFoodPos();
    badFoodPos = CheckFoodPos(newFoodTemp);
  } while(!badFoodPos);
  foodPos.push_front(newFoodTemp);
  if(foodPos.size() > 1) foodPos.pop_back();
}
 
bool CheckGettingFood(){
  if(snakePos.front().x == foodPos.front().x && snakePos.front().y == foodPos.front().y){
    SetFoodPos();
    return TRUE;
  }
  return FALSE;
}
 
void OriginSnakePos() {
  for(int i=0; i < snakeSize; i++){
    snake snakePosTemp ={cellSize * ((cellCountX/2)+i),  cellSize * (cellCountY/2)};
    snakePos.push_back(snakePosTemp);
  }
}
 
snake GenLifePos() {
  int lifePosX;
  int lifePosY;
  snake lifePosTemp;
  srand(clock());
  lifePosX = rand() % cellCountX;
  lifePosY = rand() % cellCountY;
  lifePosTemp.x = lifePosX*cellSize;
  lifePosTemp.y = lifePosY*cellSize;
  return lifePosTemp;
}
 
bool CheckLifePos(snake lifePos){
  for(std::deque<snake>::iterator it = snakePos.begin(); it!=snakePos.end();++it){
    if(lifePos.x == it->x && lifePos.y == it->y){
      return FALSE;
    }
  }
  if(lifePos.x == foodPos.front().x && lifePos.y == foodPos.front().y){
    return FALSE;
  }
  return TRUE;
}
 
void SetLifePos(){
  snake newLifeTemp;
  bool badLifePos;
  do
  {
    newLifeTemp = GenLifePos();
    badLifePos = CheckLifePos(newLifeTemp);
  } while(!badLifePos);
  lifePos.push_front(newLifeTemp);
  if(lifePos.size() > 1) lifePos.pop_back();
}
 
bool CheckGettingLife(){
  if(snakePos.front().x == lifePos.front().x && snakePos.front().y == lifePos.front().y){
    SetLifePos();
    ++snakeLives;
    return TRUE;
  }
  return FALSE;
}
 
bool CheckWrongMove(){
  for(std::deque<snake>::iterator it = snakePos.begin()+4; it!=snakePos.end();++it){
    //Проверка на касение головы с хвостом
    if(snakePos.front().x == it->x && snakePos.front().y == it->y){
      return TRUE;
    }
  }
  //Проверка на касание головы со стенами
  if(snakePos.front().x <= -1 || snakePos.front().x >= clientWidth
    || snakePos.front().y >= clientHeight || snakePos.front().y <= -1) {
      return TRUE;
  }
  return FALSE;
}
 
void SnakeMove(int keyPressed, HWND hwnd){
  if(!snakeLives) snakeLives = 4;
  snakePos.push_front(snakePos.front());
  switch(keyPressed){
  case VK_LEFT:
    snakePos.front().x -= cellSize;
    break;
  case VK_UP:
    snakePos.front().y -= cellSize;
    break;
  case VK_RIGHT:
    snakePos.front().x += cellSize;
    break;
  case VK_DOWN:
    snakePos.front().y += cellSize;
    break;
  }
  if(!CheckGettingFood()) snakePos.pop_back();
  if(CheckWrongMove()){
    snakePos.erase(snakePos.begin(),snakePos.end());
    OriginSnakePos();
    --snakeLives;
  }
  InvalidateRect(hwnd, NULL, TRUE);
}
 
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
  HDC hdc;
  PAINTSTRUCT ps;
  HPEN redPen;
  HPEN greenPen;
  HBRUSH hBrush;
  static HWND hwndB;
  static int keyPressed;
  static int keyPrvPres;
  switch (message){
 
  case WM_CREATE:
    keyPressed = VK_LEFT;
    keyPrvPres = VK_LEFT;
    OriginSnakePos();
    SetFoodPos();
    SetTimer(hwnd, 1, 300, NULL);
 
    return 0;
 
  case WM_KEYDOWN:
    switch(wParam){
    case VK_UP:
      if(keyPrvPres != VK_DOWN) keyPressed = VK_UP;
      break;
    case VK_DOWN:
      if(keyPrvPres != VK_UP) keyPressed = VK_DOWN;
      break;
    case VK_LEFT:
      if(keyPrvPres != VK_RIGHT) keyPressed = VK_LEFT;
      break;
    case VK_RIGHT:
      if(keyPrvPres != VK_LEFT) keyPressed = VK_RIGHT;
      break;
    }
    return 0;
 
  case WM_TIMER:
    SnakeMove(keyPressed, hwnd);
    keyPrvPres = keyPressed;
    return 0;
 
  case WM_PAINT:
    hdc = BeginPaint(hwnd, &ps);
    greenPen = CreatePen(PS_SOLID,1,RGB(0,255,0));
    hBrush = CreateSolidBrush(RGB(0,255,0));
    redPen = CreatePen(PS_SOLID,1,RGB(255,0,0));
    SelectObject(hdc, greenPen);
    if(snakeLives){ 
      //Отрисовка змеи
      for(std::deque<snake>::iterator it = snakePos.begin(); it!=snakePos.end(); ++it){
        Rectangle(hdc, it->x+cellSize, it->y+cellSize, it->x, it->y);
      }
 
      //Отрисовка еды
      SelectObject(hdc, redPen);
      Rectangle(hdc, foodPos.back().x+cellSize, foodPos.back().y+cellSize, foodPos.back().x, foodPos.back().y);
      SelectObject(hdc, greenPen);
      //Отрисовка поля
      for(int i=0;i<=clientWidth;i+=cellSize){
        MoveToEx(hdc,i,0,NULL);
        LineTo(hdc,i,clientHeight);
      }
      for(int j=0;j<=clientHeight;j+=cellSize){
        MoveToEx(hdc,0,j,NULL);
        LineTo(hdc,clientWidth,j);
      }
    }
    else {
      KillTimer(hwnd, 1);
      if(MessageBox(hwnd, "\nPress 'OK' to play again", "Game Over", MB_OK|MB_APPLMODAL) == IDOK)
        SetTimer(hwnd, 1, 300, NULL);
    }
    EndPaint(hwnd, &ps);
    return 0;
 
  case WM_DESTROY:
    KillTimer(hwnd, 1);
    PostQuitMessage(0);
    return 0;
  }
  return DefWindowProc(hwnd, message, wParam, lParam);
}
Вот в этом коде заменить WM_TIMER на ваш код. Пробовал не получается.
Nikcharn
 Аватар для Nikcharn
71 / 53 / 3
Регистрация: 31.07.2009
Сообщений: 149
06.01.2014, 13:39     Как написать свой таймер? #9
Цитата Сообщение от mzarb Посмотреть сообщение
Вот в этом коде заменить WM_TIMER на ваш код. Пробовал не получается.
Эм, логично. В начале внимательно посмотрите на мою функцию и поймите что она делает.
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
06.01.2014, 15:05  [ТС]     Как написать свой таймер? #10
Nikcharn, и что же она делает?
FraidZZ
Модератор
 Аватар для FraidZZ
3879 / 1505 / 227
Регистрация: 06.01.2013
Сообщений: 4,029
Завершенные тесты: 1
06.01.2014, 15:09     Как написать свой таймер? #11
mzarb, после вызова происходит задержка на указанное число мс
Nikcharn
 Аватар для Nikcharn
71 / 53 / 3
Регистрация: 31.07.2009
Сообщений: 149
06.01.2014, 15:11     Как написать свой таймер? #12
Цитата Сообщение от mzarb Посмотреть сообщение
Nikcharn, и что же она делает?
Эта функция, через заданное время, например при входных данных 5000 (5 сек), выводит на экран, что время вышло и можно делать следующее действие. Вам же нужно доработать ее. Вместо того чтобы она писала текст, например, вам нужно поставить то действие какое Вы хотите, типа выполнение функции и т.д..
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
06.01.2014, 15:22     Как написать свой таймер? #13
mzarb, вы так и не объяснили: чем не устраивает WM_TIMER?
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
06.01.2014, 15:54  [ТС]     Как написать свой таймер? #14
alsav22, я же не задавал вопрос о том, что лучше.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
06.01.2014, 15:57     Как написать свой таймер? #15
Цитата Сообщение от mzarb Посмотреть сообщение
я же не задавал вопрос о том, что лучше.
И что? Я к тому, что код Nikcharn, совсем не годится для вашего кода.
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
06.01.2014, 16:19  [ТС]     Как написать свой таймер? #16
alsav22, я не могу сейчас объяснить толком зачем, потому что хочу менять структуру дальше, а WM_TIMER в неё не вписывается. По этому мне нужен любой таймер, только чтобы он не был связан с WM_TIMER и был по возможности не сильно большой. Ну в играх же какие-то таймеры используют? Мне нужен примерно такой же, только меня не интересует его точность, а просто чтобы был не такой как у меня сейчас, а в виде функции.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
06.01.2014, 16:43     Как написать свой таймер? #17
Цитата Сообщение от mzarb Посмотреть сообщение
Ну в играх же какие-то таймеры используют?
Используют. Используют те, которые предоставляет библиотека, с помощью которой игра пишется. У вас код использует WinAPI, значит и таймер нужен такой же (WM_TIMER).
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
06.01.2014, 18:40  [ТС]     Как написать свой таймер? #18
alsav22, ясно

Добавлено через 1 час 26 минут
кстати, а толку копипастить? ссылка
Какой смысл на этом форуме себе репутацию клепать? Вон сегодня один школер уже доказал это, когда мне -218 влепил в репу.
Nikcharn
 Аватар для Nikcharn
71 / 53 / 3
Регистрация: 31.07.2009
Сообщений: 149
06.01.2014, 18:40     Как написать свой таймер? #19
Цитата Сообщение от alsav22 Посмотреть сообщение
У вас код использует WinAPI, значит и таймер нужен такой же (WM_TIMER).
Это удобнее просто, но если человек хочет написать свой таймер, кто ему мешает? Это же не для бизнес продукта делается, а для обучения.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.01.2014, 18:43     Как написать свой таймер?
Еще ссылки по теме:

Написать свой манипулятор C++
как сделать таймер? C++
C++ Написать функцию, сдвигающую влево свой аргумент

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
mzarb
-211 / 7 / 1
Регистрация: 14.01.2013
Сообщений: 141
06.01.2014, 18:43  [ТС]     Как написать свой таймер? #20
Nikcharn, +
Эта змейка даже не для вуза. Я мог бы сделать весь функционал за пол часа, но там бы было много быдлокода и костылей, а так хочу что-то более мне нормально сделать и как вы отметили, научится на этом.
Yandex
Объявления
06.01.2014, 18:43     Как написать свой таймер?
Ответ Создать тему
Опции темы

Текущее время: 15:19. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru