Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Создание потока в консольном приложении 
:(
    Опции темы
4epT
Дата 21.12.2010, 15:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Добрый день! Я делаю на С++ в консоли простую игрушку ... нужно сделать так что бы 2 человека могли управлять своими человечками (перемещаясь по матрице). Для каждого отведены отдельные клавиши.

Дайте пожалуйста пример когда или название функции с ее сигнатурой как это правильно делается)

спасибо!
PM MAIL   Вверх
KaraKum
Дата 21.12.2010, 17:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: 1
Всего: 1



Если "Windows", то CreateThread() :
Код

DWORD Function(LPVOID parameter)
{
     printf("Hello, thread!\n");
}
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)Function, NULL, NULL, NULL);


Если Linux, то pthread_create():
Код

void Function(void* parameter)
{
     printf("Hello, thread!\n");
}
pthread_create(new pthread_t, NULL, Function, NULL);


Это сообщение отредактировал(а) KaraKum - 21.12.2010, 17:17
PM MAIL WWW   Вверх
4epT
Дата 21.12.2010, 17:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Цитата(KaraKum @ 21.12.2010,  17:14)
Если "Windows", то CreateThread() :
Код

DWORK Function(LPVOID parameter)
{
     printf("Hello, world's thread!\n");
}
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)Function, NULL, NULL, NULL);

да, под винду ..

Спасибо ) попробую))

А как закрыть поток ?))
PM MAIL   Вверх
KaraKum
Дата 21.12.2010, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: 1
Всего: 1



А пользователи нажимают кнопки на одном компьютере?
PM MAIL WWW   Вверх
4epT
Дата 21.12.2010, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Цитата(KaraKum @ 21.12.2010,  17:18)
А пользователи нажимают кнопки на одном компьютере?

да. С этим могут быть проблемы?
PM MAIL   Вверх
KaraKum
Дата 21.12.2010, 17:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: 1
Всего: 1



Цитата(4epT @ 21.12.2010,  18:18)
Цитата(KaraKum @ 21.12.2010,  17:18)
А пользователи нажимают кнопки на одном компьютере?

да. С этим могут быть проблемы?

Если создание потоков связано с вводом пользователей, то не обязательно создавать потоки.
С наличием в программе потоков (то есть не только основной функции main()) могут быть проблемы из-за параллельного использования одной и той же памяти (данных).
Лучше избегать их создания если есть такая возможность, а в данном случае она вроде как есть...

Это сообщение отредактировал(а) KaraKum - 21.12.2010, 17:22
PM MAIL WWW   Вверх
4epT
Дата 21.12.2010, 17:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Ну вот к примеру .... я хочу реализовать змейку ... но что бы одновременно бегало 2 змейки в консоли. Насколько я понимаю, если один пользователь будет очень быстро нажимать на клавиши, то второй просто не сможет двигаться ... или я ошибаюсь?))
PM MAIL   Вверх
KaraKum
Дата 21.12.2010, 17:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: 1
Всего: 1



Второй поток здесь не нужен.
Нажимаем кнопку - двигаем змейку в сторону; для другой змейки другие кнопки.
А залипание клавиш зависит уже от клавиатуры и нажимаемых групп кнопок (некоторые кнопки нельзя нажать больше двух штук, а некоторые можно и сразу 4 если правильно разбросать их по клаве), а будет ли игрок успевать нажимать клавиши зависит уже от его настойчивости и ширины плеч оппонента  smile 
PM MAIL WWW   Вверх
4epT
Дата 21.12.2010, 17:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Цитата(KaraKum @ 21.12.2010,  17:54)
Второй поток здесь не нужен.
Нажимаем кнопку - двигаем змейку в сторону; для другой змейки другие кнопки.
А залипание клавиш зависит уже от клавиатуры и нажимаемых групп кнопок (некоторые кнопки нельзя нажать больше двух штук, а некоторые можно и сразу 4 если правильно разбросать их по клаве), а будет ли игрок успевать нажимать клавиши зависит уже от его настойчивости и ширины плеч оппонента  smile

 smile  посмеялся )))
хорошо, а такой вариант ... я зажимаю кнопку .... и я ловлю нажатие клавиш в бесконечном while при помощи getch(); Тут тоже не нужен второй поток?))))
PM MAIL   Вверх
KaraKum
Дата 21.12.2010, 18:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: 1
Всего: 1



Ой, я невнимательно прочитал в вопросе про консоль.
Хмм... подразумевается использование ASCII-графики?  smile

Добавлено через 59 секунд
Я думаю будет проще создать обычное окно и рисовать в нём посредством GDI.
PM MAIL WWW   Вверх
4epT
Дата 21.12.2010, 18:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Цитата(KaraKum @ 21.12.2010,  18:02)
Ой, я невнимательно прочитал в вопросе про консоль.
Хмм... подразумевается использование ASCII-графики?  smile

Добавлено @ 18:03
Я думаю будет проще создать обычное окно и рисовать в нём посредством GDI.

Я с MFC не знаком ( на с++ с оконным интерфейсом писал только с использованием WinAPI ... а там с GDI сплошные проблемы(

И все же что посоветуешь?) в консоли с потоком?) 
PM MAIL   Вверх
KaraKum
Дата 21.12.2010, 18:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: 1
Всего: 1



GDI относится к WinAPI - то есть должен быть доступен сразу после установки Visual Studio Express Edition (бесплатная которая и скачивается с сайта майрософта).
На консоли - это, конечно, дохлый номер. Идеальный вариант - на OpenGL, но займёт много времени его освоение (недели), а на GDI можно быстро что-нибудь начать делать.
PM MAIL WWW   Вверх
4epT
Дата 21.12.2010, 18:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Цитата(KaraKum @ 21.12.2010,  18:10)
GDI относится к WinAPI - то есть должен быть доступен сразу после установки Visual Studio Express Edition (бесплатная которая и скачивается с сайта майрософта).
На консоли - это, конечно, дохлый номер. Идеальный вариант - на OpenGL, но займёт много времени его освоение (недели), а на GDI можно быстро что-нибудь начать делать.

Ясно ... ( у меня просто по сути есть 3-4 дня, до защиты курсового .... буду думать)

Спасибо за помощь)
PM MAIL   Вверх
Batbko
Дата 21.12.2010, 18:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 17.12.2010

Репутация: нет
Всего: нет



Кстати WM_KEYDOWN в виндовой консоли никто не отменял smile хотя это и изврат но достучаться до окна не так уж и сложно...
и даже рисовать на нем с помощью GDI  и добавлять элементы управления, мои знания API изрядно проржавели но даже где то на этом форуме я видел алгоритм получения главного окошка процесса,
а дальше дело техники : остаеться только правильно подменить оконную процедуру ;)
Хотя если для курсача и если препод смотрит в исходники то лучше не извращаться 
PM MAIL   Вверх
KaraKum
Дата 21.12.2010, 18:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: 1
Всего: 1



Всё вышеперечисленное можно заменить одной строчкой вызова функции создания нормально виндового окна.
PM MAIL WWW   Вверх
Batbko
Дата 21.12.2010, 19:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 17.12.2010

Репутация: нет
Всего: нет



Ну так человек консоль хочет smile а руками гуи консольное писать да логику потоков i/o хоть для вида дело заковыристое...
Интереснее как препод оное представляет ? чему тож он научить пытаеццо smile
А вот если ограничений на способ реализации нету то лучше GDI а ещё лучше Qt или что нить похожее 
Делал по приколу игрушку "жизнь" ушло пару часов на матчасть пару часов на логику и минут 15 на гуй(На Qt)
PM MAIL   Вверх
KaraKum
Дата 21.12.2010, 21:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: 1
Всего: 1



Цитата(Batbko @  21.12.2010,  20:48 Найти цитируемый пост)
Интереснее как препод оное представляет ?

Преподы у нас нынче пожилые - вот глянет он на такой код сквозь свои окуляры "+8" и сердце схватит...
Поэтому, 4epT,  smile  - пиши на WinAPI с "WinMain" вместо "main" и всем сопудствующим...

Это сообщение отредактировал(а) KaraKum - 21.12.2010, 21:27
PM MAIL WWW   Вверх
boostcoder
Дата 21.12.2010, 21:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



кстати сам микрософт, рекомендует использовать _beginthread()/_beginthreadex() вместо CreateThread smile 
PM WWW   Вверх
KaraKum
Дата 21.12.2010, 21:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: 1
Всего: 1



Непредсказуемый майкрософт...  smile 
PM MAIL WWW   Вверх
4epT
Дата 21.12.2010, 22:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Я попытался сделать все это в консоли .. сделал второй поток, в котором цикл while(true) и gtehc()-ем ловлю нажатые клавиши ... все работает но тормозит жутко (((

так и должно быть?) или я где то набочил?

Добавлено через 9 минут и 41 секунду
На WinAPI будут проблемы с GDI ... вообще мне нужно сделать бомбермена =) а там ставить бомбы взрыв на n пикселей по краям, как это отлавливать через GDI ? 
PM MAIL   Вверх
4epT
Дата 21.12.2010, 22:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



есть еще один вариант) на WinAPI но без GDI ....

сделаю Label на всю область экрана ... и буду в него печатать матрицу (игровое поле) ... все нажатые клавиши будут изменять поле и все ...

Просто по сути, для этого курсового мы должны использовать обычные знания ООП, то есть на данные момент мы не знаем ни потоков ни WinAPI ничего)
PM MAIL   Вверх
Batbko
Дата 21.12.2010, 23:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 17.12.2010

Репутация: нет
Всего: нет



Bomberman говоришь... ООП!?smile
Если логика готова, то нарисовать её чем угодно большого труда не составит smile
Если будешь делать не консольно приложение, то для обработки клавиатуры достаточно ловить WM_KEYDOWN в оконной процедуре - никаких потоков не надо IMHO.

Но если имеешь шустрый инет и желание разок разобраться а потом без особого труда использовать
то сходи например сюда это - тулкит от нокии.
ООП и примеров, в том числе и рисования там хоть отбавляй. Притом каждый пример подробно разжеван и задокументирован. И ты можешь забыть про оконные процедуры и прочие неприятные вещи.

P.S. Слегка погуглив по запросу  можно поглядеть на пару-другую реализаций этого самого бомбермена на qt:)
PM MAIL   Вверх
4epT
Дата 21.12.2010, 23:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Составить логику проблем не будет) в этом я уверен ... а вот насчет WM_KEYDOWN можно примерчик?) именно для консоли ... Qt нету времени учить) курсовым занимаюсь вечером после работы)
PM MAIL   Вверх
Batbko
Дата 22.12.2010, 00:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 40
Регистрация: 17.12.2010

Репутация: нет
Всего: нет



Заполучить нового адепта не удалось  smile  smile


как получить хэндл окошка консольного спросишь на форуме 
а после надо поступать примерно так(поправьте кто нибудь если что):
Код



static WNDPROC s_oldWndProc;

LRESULT CALLBACK KeyEventFilter(

    HWND hwnd,    // handle of window
    UINT uMsg,    // message identifier
    WPARAM wParam,    // first message parameter
    LPARAM lParam    // second message parameter
   )
{
switch(msg)
{
   case WM_KEYDOWN:
   switch(lParam)
{
   case VK_одна_из_обрабатываемых_клавиш:
   обработчик_нажатия_заданой_клавиши();
   return true;
   case VK_ещё_одна:
   обработчик_нажатия_другой_клавиши();
   return true;
   ....
   default:
s_oldWndProc(hwnd,uMsg,wParam,lParam);
   
}

   break;
   default:
s_oldWndProc(hwnd,uMsg,wParam,lParam);
}

}

void main()
{
...
HWND h_console=хендл_консольного_окошка();

s_oldWndProc=(WNDPROC)GetWindowLong(
  h_console,
  GWL_WNDPROC
);

SetWindowLong(
h_console;
  GWL_WNDPROC,
(LONG)(&KeyEventFilter)
);
...
}


как то так, хотя повторюсь мои знания winAPI исрядно попорчены отсутствием практики

P.S. Хотя выучить Qt поглазев на пару примеров в разы проще IMHO.

Это сообщение отредактировал(а) Batbko - 22.12.2010, 00:14
PM MAIL   Вверх
4epT
Дата 22.12.2010, 00:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Цитата(Batbko @ 22.12.2010,  00:07)
Заполучить нового адепта не удалось  smile  smile


как получить хэндл окошка консольного спросишь на форуме 
а после надо поступать примерно так(поправьте кто нибудь если что):
Код



static WNDPROC s_oldWndProc;

LRESULT CALLBACK KeyEventFilter(

    HWND hwnd,    // handle of window
    UINT uMsg,    // message identifier
    WPARAM wParam,    // first message parameter
    LPARAM lParam    // second message parameter
   )
{
switch(msg)
{
   case WM_KEYDOWN:
   switch(lParam)
{
   case VK_одна_из_обрабатываемых_клавиш:
   обработчик_нажатия_заданой_клавиши();
   return true;
   case VK_ещё_одна:
   обработчик_нажатия_другой_клавиши();
   return true;
   ....
   default:
s_oldWndProc(hwnd,uMsg,wParam,lParam);
   
}

   break;
   default:
s_oldWndProc(hwnd,uMsg,wParam,lParam);
}

}

void main()
{
...
HWND h_console=хендл_консольного_окошка();

s_oldWndProc=(WNDPROC)GetWindowLong(
  h_console,
  GWL_WNDPROC
);

SetWindowLong(
h_console;
  GWL_WNDPROC,
(LONG)(&KeyEventFilter)
);
...
}


как то так, хотя повторюсь мои знания winAPI исрядно попорчены отсутствием практики

P.S. Хотя выучить Qt поглазев на пару примеров в разы проще IMHO.

если честно я все равно не понимаю как это мне поможет сделать программу без потока (( они ведь должны как то одновременно ходить ... с компьютером наверное будет легче сделать?)
PM MAIL   Вверх
4epT
Дата 22.12.2010, 00:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Кто нибудь может объяснить почему так происходит ? отлавливаю нажатие клавиши "<-" и аналог "a"

Для стрелочки все реагирует быстро ... для буквы "а" большая задержка, мало того не всегда срабатывает. ког аналагичен, за исключением что там разные игроки дергаются. вот код:

Функция шага:
b - это бомбермен ...
Код

DWORD WINAPI _step(LPVOID data)
{
    EnterCriticalSection( &criticalSection );

    _TData *tdata = (_TData*) data;

    tdata->b->step(tdata->dir , *field);
    SetWindowText(tdata->mainHwnd , field->toString().c_str() );

    LeaveCriticalSection( &criticalSection );

    return 1;
}


вот так я создаю поток при каждом нажатии клавиш:

Код

case 39://шаг вправо первым бомберменом
{

    _TData tdata;
    tdata.dir = RIGHT;
    tdata.mainHwnd = print;
    tdata.b= p1;

    HANDLE hThread = ::CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)_step, &tdata, NULL, NULL);
    WaitForSingleObject(hThread, 1);
    CloseHandle(hThread);
    break;
}

case 68://шаг вправо вторым Бомберменом
{
    _TData tdata;
    tdata.dir = RIGHT;
    tdata.mainHwnd = print;
    tdata.b= p2;
    HANDLE hThread = ::CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)_step, &tdata, NULL, NULL);
    WaitForSingleObject(hThread, 1);
    CloseHandle(hThread);
    break;
}

PM MAIL   Вверх
KaraKum
Дата 22.12.2010, 01:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: 1
Всего: 1



Не всматриваясь в реализацию всей игры сразу можно сказать что на месте создания поток и дожидания пока они завершатся можно просто вызвать сами функции потоков:
Код

case 39://шаг вправо первым бомберменом
{
    _TData tdata;
    tdata.dir = RIGHT;
    tdata.mainHwnd = print;
    tdata.b= p1;
    /*HANDLE hThread = ::CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)_step, &tdata, NULL, NULL);
    WaitForSingleObject(hThread, 1);
    CloseHandle(hThread);*/
    _step(NULL);
    break;
}
case 68://шаг вправо вторым Бомберменом
{
    _TData tdata;
    tdata.dir = RIGHT;
    tdata.mainHwnd = print;
    tdata.b= p2;
    /*HANDLE hThread = ::CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)_step, &tdata, NULL, NULL);
    WaitForSingleObject(hThread, 1);
    CloseHandle(hThread);*/
    _step(NULL);
    break;
}


Добавлено @ 01:04
Все игры (в том числе AAA шутеры, MMORPG (WOW, LineageII)) являются, в принципе, однопоточными - только лишь часть, отвечающая за соединение, может быть отведена в отдельный поток, но и то лишь из-за принципа организации сетевого соединения. И змейку или бомбермена тоже можно реализовать довольствуясь лишь одним потоком  smile

Добавлено через 8 минут и 55 секунд
Если смотреть на любую игры с-высока, то её можно представить так:
- каждые сколько-то миллисекунд (20-30 раз в секунду) заново рисуется весь экран в зависимости от текущего состояния данных игры
- перед каждой отрисовкой игровые объекты меняют своё состояние в зависимости от текущего состояния и введённых в игру данных (полученных данных по сети или просто нажатых клавиш на клавиатуре)
Ввод данных в игру (клавиши клавиатуры) уже, в принципе, могут игру не "волновать" - логично даже создать массив текуще нажатых клавиш и устанавливать в "true" те клавиши, которые сейчас нажаты, а игровые объекты будут этот массив считывать.
В этой системе просто нет работы для какого-либо второго потока - нечем ему тут заняться.

Это сообщение отредактировал(а) KaraKum - 22.12.2010, 01:05
PM MAIL WWW   Вверх
4epT
Дата 22.12.2010, 01:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Цитата(KaraKum @ 22.12.2010,  01:01)
Не всматриваясь в реализацию всей игры сразу можно сказать что на месте создания поток и дожидания пока они завершатся можно просто вызвать сами функции потоков:
Код

case 39://шаг вправо первым бомберменом
{
    _TData tdata;
    tdata.dir = RIGHT;
    tdata.mainHwnd = print;
    tdata.b= p1;
    /*HANDLE hThread = ::CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)_step, &tdata, NULL, NULL);
    WaitForSingleObject(hThread, 1);
    CloseHandle(hThread);*/
    _step(NULL);
    break;
}
case 68://шаг вправо вторым Бомберменом
{
    _TData tdata;
    tdata.dir = RIGHT;
    tdata.mainHwnd = print;
    tdata.b= p2;
    /*HANDLE hThread = ::CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)_step, &tdata, NULL, NULL);
    WaitForSingleObject(hThread, 1);
    CloseHandle(hThread);*/
    _step(NULL);
    break;
}


Добавлено @ 01:04
Все игры (в том числе AAA шутеры, MMORPG (WOW, LineageII)) являются, в принципе, однопоточными - только лишь часть, отвечающая за соединение, может быть отведена в отдельный поток, но и то лишь из-за принципа организации сетевого соединения. И змейку или бомбермена тоже можно реализовать довольствуясь лишь одним потоком  smile

переделал без потоков))) работать стало значительно лучше)) хоть и не идеально)

ну а бомбы уже нужно создавать в потоках ? они ведь должны взрываться через какое то время ... к примеру я ставлю бомбу, создаю для нее поток, в потоке делаю Sleep на время n и взрываю ее ..

правильно? или так же самое можно без потока обойтись ?)
PM MAIL   Вверх
KaraKum
Дата 22.12.2010, 01:15 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: 1
Всего: 1



В случае со змейкой это так (не попню именование тамошних команд):
- создать массив допустим такой: bool keys[100500];
- по WM_KEYDOWN:
      keys[PUSHED_KEY_CODE] = true;
- по WM_KEYUP:
      keys[RELEASED_KEY_CODE] = false;
- по моменту обновления всех объектах (у нас только одинокая змея):
      snake->LIVE!()
      {
             if(keys[CROWL_FORWARD])
             {
                    //двигаем змейку на пиксель вперёд (ну или какая у неё там скорость передвижения)...
             }
             else if(keys[TURN_RIGHT])
             {
                    //поворачиваемся вправо...
             }
             else if...
      }
- очищаем экран и рисуем всё заново в зависимости от текущего положения змейки...

Добавлено через 1 минуту и 29 секунд
Цитата(4epT @  22.12.2010,  02:10 Найти цитируемый пост)
ну а бомбы уже нужно создавать в потоках ? они ведь должны взрываться через какое то время ... к примеру я ставлю бомбу, создаю для нее поток, в потоке делаю Sleep на время n и взрываю ее ..

Здесь тоже самое что прежде - игру нужно обновлять какое-то количество раз в секунду. sleep() использовать в играх нельзя.
PM MAIL WWW   Вверх
4epT
Дата 22.12.2010, 01:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Цитата(KaraKum @ 22.12.2010,  01:15)
Здесь тоже самое что прежде - игру нужно обновлять какое-то количество раз в секунду. sleep() использовать в играх нельзя.

то есть запомнить время когда она была установлена и при обновлении игрового поля проверять вышло ли время?
PM MAIL   Вверх
KaraKum
Дата 22.12.2010, 01:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: 1
Всего: 1



Да, именно так.
PM MAIL WWW   Вверх
4epT
Дата 22.12.2010, 01:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Цитата(KaraKum @ 22.12.2010,  01:20)
Да, именно так.

спасибо большое) завтра буду пробовать!!)) еще отпишусь)
PM MAIL   Вверх
KaraKum
Дата 22.12.2010, 01:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: 1
Всего: 1



До завтра  smile 
PM MAIL WWW   Вверх
Леопольд
Дата 22.12.2010, 12:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



4epT, по мне, луче воспользоваться кросплатформенной библиотекой. Например Boost.Thread.

В С++0X планируется поддержка многопоточности. Если программа пишется для себя то можно написать на нём.
Компилировать можно VS2010 EE и g++4.5. Возможно есть ещё какие-то free компиляторы.


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
KaraKum
Дата 22.12.2010, 12:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: 1
Всего: 1



Цитата(Леопольд @  22.12.2010,  13:41 Найти цитируемый пост)
воспользоваться кросплатформенной библиотекой. Например Boost.Thread.

Мы, вроде как, решили не создавать потоков   smile 
PM MAIL WWW   Вверх
4epT
Дата 22.12.2010, 13:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Снова здравствуйте!)

Спасибо большое за совет, но буду писать без потоков)

Написал что бы ставились бомбы ... все ок) только они не взрываются ( где то теряются.

Я в игровом поле сделал массив Бомб. Бомбы экземляры классов.

Смотрел через отладчик .. добавляется нормально, а вот уже при проверке на взрыв размер массива равен 0  smile

Вот очередь вызова функций =)

Код

Bomb b;
p1->setBomb(*field , b);
SetWindowText(print , field->toString().c_str() );
break;


Код

Position p(x , y);
if( field.isFree( p ) )
{
    field.set(p , 5);//5 - означает что тут бомба
    GetLocalTime(&bomb.installTime);
    bomb.setX(p.getX());
    bomb.setY(p.getY());
    field.addBomb(bomb);//добавление бомбы в массив
}
 

Код

void Field::addBomb(Bomb b)
{
Bomb *b2 = new Bomb(b.getTime() , b.getRadius());
b2->setX(b.getX());
b2->setY(b.getY());
b2->installTime = b.installTime;
this->lst[this->currentSizeLst] = *b2;
this->currentSizeLst++;//текущий размер массива, массив lst динамический
}


Код

if( !this->isBum(i , j) ) // Вызов проверки на взрыв
                


Код

bool Field::isBum(int x , int y)
{
    SYSTEMTIME curTime;
    GetLocalTime(&curTime);

    for(int i = 0; i < this->currentSizeLst; i++)//тут уже размер равен 0 ... 
    {


Такое ощущение что где то теряю игровое поле (( и при вызове isBum уже просто напросто копия игрового поля.

Есть какие нибудь идеи ?)) Опыта программирования на С++ мало, так что скорей всего где то напорол с указателями ...
PM MAIL   Вверх
KaraKum
Дата 22.12.2010, 13:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: 1
Всего: 1



Кстати, по поводу отрисовки изображения:
На данный момент я не знаю какими методами ты рисуешь изображение, но GDI всё-таки очень простая и удобная вещь (было реализовано специально чтобы можно было что-то быстро и просто нарисовать без использования horse-power OpenGL или DirectX). Например змейку можно было бы нарисовать примерно вот так (опять не помню точные имена функций):
Код

//стираем (рисуем поверх) всё что было нарисовано в предыдущем цикле:
gdi->fill(0xffffff); //или можно нарисовать просто белый квадрат поверх того что уже есть размером с весь экран
//рисуем змею в виде прямоугольника:
gdi->drawRect(10, 10, 200, 20);
//рисуем мышей, за которыми наша змея ползает:
for(int i = 0; i < mices.size(); i++)
{
     gdi->drawRect(mices[i].x, mices[i].y, mices[i].x + MOUSE_WIDTH, mices[i].y + MOUSE_HEIGHT);
}

Я почти уверен что этот метод проще чем то как ты отрисовываешь изображение сейчас. И проще, и правильнее.

Добавлено @ 13:28
Цитата(4epT @ 22.12.2010,  14:12)
Код

Position p(x , y);
if( field.isFree( p ) )
{
    field.set(p , 5);//5 - означает что тут бомба
    GetLocalTime(&bomb.installTime);
    bomb.setX(p.getX());
    bomb.setY(p.getY());
    field.addBomb(bomb);//добавление бомбы в массив
}
 

Код

void Field::addBomb(Bomb b)
{
Bomb *b2 = new Bomb(b.getTime() , b.getRadius());
b2->setX(b.getX());
b2->setY(b.getY());
b2->installTime = b.installTime;
this->lst[this->currentSizeLst] = *b2;
this->currentSizeLst++;//текущий размер массива, массив lst динамический
}

Ошибка здесь.

Нужно определить конструктор копирования, который будет копировать время создания бомбы и в функцию передавать бомбу сразу по указателю или по ссылке - но это уже красивость - ошибка не тут  smile 

Я не знаю что ты имеешь в виду под динамическим массивом, но С++ по своей натуре не позволяет осуществлять произвольный доступ к элементам массива.
Например если создать массив
Код

int array[2];

то нельзя обратиться, например, к третьему элементу:
Код

//ошибка - программа либо вылетет на этом месте, либо в дальнейшем этот несуществующий третий элемент перезапишется каким-нибудь другим значением.
array[2] = 100500;


Добавлено @ 13:33
Тебе нужно использовать STL-контейнер и лучше хранить бомбы по указателям (так проще и логичнее):
Код


#include <vector>

std::vector<Bomb*> bombs;

void Field::addBomb(Bomb b)
{
Bomb *b2 = new Bomb(b.getTime() , b.getRadius());
b2->setX(b.getX());
b2->setY(b.getY());
b2->installTime = b.installTime;
/*this->lst[this->currentSizeLst] = *b2;
this->currentSizeLst++;//текущий размер массива, массив lst динамический*/
bombs.push_back(b2);
}

//потом по бомбам можно пройтись вот так:
void ForEachBomb()
{
    for(int i = 0; i < bombs.size(); i++)
   {
        Bomb* bomb = bombs[i];
        //взрывай бомбу если пришла пора (ну или кто-нибудь рядом пробегает - мир суров)...
   }
}


Это сообщение отредактировал(а) KaraKum - 22.12.2010, 13:33
PM MAIL WWW   Вверх
4epT
Дата 22.12.2010, 13:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Отрисовку через GDI сделаю если буду влаживаться в сроки)

STL-контейнера я думал, но почему то не решился его использовать =)

Под динамическим я понимаю вот это:
Код

Bomb *lst  = new Bomb[100];
int maxSizeLst = 100;
int currentSizeLst = 0;


Перегрузку конструктора копирования сделаю) но это ведь не решает почему размер массива обнуляется (
А кстати ... я юзаю для времени вот это SYSTEMTIME, нормально?)



PM MAIL   Вверх
KaraKum
Дата 22.12.2010, 14:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: 1
Всего: 1



Эмм, а что именно обнуляется? Время установки бомбы?
PM MAIL WWW   Вверх
4epT
Дата 22.12.2010, 14:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Цитата(KaraKum @ 22.12.2010,  14:02)
Эмм, а что именно обнуляется? Время установки бомбы?

Нет, их кол-во ... 

я при создании бомбы, то есть при методе addBomb увеличиваю текущий размер на 1

Код

this->lst[this->currentSizeLst] = *b2;
this->currentSizeLst++;


а уже при проверке на взрыв бомб я не могу узнать сколько у меня их там ... так как размер равен 0 =( я это вижу через отладчик ...
PM MAIL   Вверх
KaraKum
Дата 22.12.2010, 15:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: 1
Всего: 1



Тогда показывай код использования этого объекта "this", где переменная currentSizeLst и объявлена.
И используй std::vector или std::list, а не "new Bomb[100]".
PM MAIL WWW   Вверх
4epT
Дата 22.12.2010, 15:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Цитата(KaraKum @ 22.12.2010,  15:18)
Тогда показывай код использования этого объекта "this", где переменная currentSizeLst и объявлена.
И используй std::vector или std::list, а не "new Bomb[100]".

А какой код показать? могу показать сигнатуры всех методов этого "this" ... то есть *.h файл =)
PM MAIL   Вверх
KaraKum
Дата 22.12.2010, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: 1
Всего: 1



Код в студию!
PM MAIL WWW   Вверх
4epT
Дата 22.12.2010, 15:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Цитата(KaraKum @ 22.12.2010,  15:26)
Код в студию!

скину только вечером =( как с работы вернусь
PM MAIL   Вверх
4epT
Дата 22.12.2010, 23:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Вот собственно код:

Код

#pragma once
#include "Position.h"
#include <string>
#include "Bomb.h"

using namespace std;

class Field
{
private:
    int **field;
    int width;
    int height;
    Bomb *lst;
    int currentSizeLst;
    int maxSizeLst;
public:
    Field(int height, int width);
    void loadMap();
    bool isBum(int x, int y);
    void print();
    bool isFree(Position pos);
    void installUpdates(Position old, Position _new, int symbol);
    void setPlayerPosition(Position pos, int value);
    void set(Position pos, int symbol);
    int getWidth();
    int getHeight();
    void addBomb(Bomb b);
    wstring toString();
    ~Field();
};


Это Field.h
PM MAIL   Вверх
KaraKum
Дата 22.12.2010, 23:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: 1
Всего: 1



cpp-файл тоже нужен - непонятно что такое "int **field"
PM MAIL WWW   Вверх
4epT
Дата 22.12.2010, 23:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Цитата(KaraKum @ 22.12.2010,  23:23)
cpp-файл тоже нужен - непонятно что такое "int **field"

тут многовато (

Код

#include "Field.h"

#include <iostream>

using namespace std;

//=======================================================================================//
//                                Marks                                                     //
//=======================================================================================//

// 0 - * - Стена
// 1 -   - Пусто
// 2 - ^ - Игрок
// 3 - @ - Противник
// 4 - $ - Бонус
// 5 - # - Бомба


//=======================================================================================//

Field::Field(int height, int width)
{
    this->width = width;
    this->height = height;

    this->field = new int*[this->width];

    for(int i = 0; i < this->width; i++)
    {
        this->field[i] = new int[this->height];
    }

    this->loadMap();

    this->lst = new Bomb[100];
    this->currentSizeLst = 0;
    this->maxSizeLst = 100;
}


void Field::loadMap()
{
    for(int i = 0; i < this->width; i++)
    {
        for(int j = 0; j < this->height; j++)
        {
            if( i == 0 || j == 0 || i == this->width - 1 || j == this->height - 1)
            {
                this->field[i][j] = 0;
            }
            else
            {
                this->field[i][j] = 1;
            }

        }
    }
}

void Field::print()
{
    for(int i = 0; i < this->width; i++)
    {
        for(int j = 0; j < this->height; j++)
        {
            if( this->field[i][j] == 0 )
            {
                cout<<"*";
            }
            else if( this->field[i][j] == 2 )
            {
                cout<<"^";
            }
            else if( this->field[i][j] == 1 )
            {
                cout<<" ";
            }
            else if( this->field[i][j] == 3 )
            {
                cout<<"@";
            }
            else if( this->field[i][j] == 5 )
            {
                cout<<"#";
            }
        }
        cout<<endl;
    }
}

bool Field::isBum(int x , int y)
{
    SYSTEMTIME curTime;
    GetLocalTime(&curTime);

    for(int i = 0; i < this->currentSizeLst; i++)
    {
        if( this->lst[i].getX() == x && this->lst[i].getY() == y )
        {
            int sek = 59 - this->lst[i].getTime();

            if( curTime.wSecond < sek && curTime.wSecond < this->lst[i].bumTime.wSecond + this->lst[i].getTime() )
            {
                this->field[x][y] = 0;
                return true;
            }
            else
            {
                return false;
            }
        }
    }

    return false;
}

wstring Field::toString()
{
    wstring str;
    wchar_t buff[8];
    for(int i = 0; i < this->width; i++)
    {
        for(int j = 0; j < this->height; j++)
        {
            if( this->field[i][j] == 0 )
            {
                str.append(L"|");
            }
            else if( this->field[i][j] == 2 )
            {
                str.append(L"1");
            }
            else if( this->field[i][j] == 1 )
            {
                str.append(L" ");
            }
            else if( this->field[i][j] == 3 )
            {
                str.append(L"@");
            }
            else if( this->field[i][j] == 5 )
            {
                if( !this->isBum(i , j) )
                {
                    str.append(L"#");
                }
                else
                {
                    if( this->field[i][j] == 0 )
                    {
                        str.append(L"|");
                    }
                }
            }
        }
        str.append(L"\r\n");
    }

    return str;

}

void Field::addBomb(Bomb b)
{
    Bomb *b2 = new Bomb(b.getTime() , b.getRadius());
    b2->setX(b.getX());
    b2->setY(b.getY());
    b2->installTime = b.installTime;
    this->lst[this->currentSizeLst] = *b2;
    this->currentSizeLst++;
}

bool Field::isFree(Position pos)
{
    if(pos.getX() < 0 || pos.getX() >= this->width)
    {
        return false;
    }
    if(pos.getY() < 0 || pos.getY() >= this->height)
    {
        return false;
    }

    if( this->field[pos.getX()][pos.getY()] == 1 || this->field[pos.getX()][pos.getY()] == 4 )
    {
        return true;
    }

    return false;
}

void Field::installUpdates(Position old, Position _new, int symbol)
{
    this->field[old.getX()][old.getY()] = 1;
    this->field[_new.getX()][_new.getY()] = symbol;
}

void Field::setPlayerPosition(Position pos, int value)
{
    if( isFree(pos) )
    {
        this->field[pos.getX()][pos.getY()] = 2;
    }
}

void Field::set(Position pos, int symbol)
{
    if( isFree(pos) )
    {
        this->field[pos.getX()][pos.getY()] = symbol;
    }
}

int Field::getWidth()
{
    return this->width;
}

int Field::getHeight()
{
    return this->height;
}

Field::~Field()
{
}


PM MAIL   Вверх
Леопольд
Дата 23.12.2010, 12:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(KaraKum @  22.12.2010,  12:55 Найти цитируемый пост)
Мы, вроде как, решили не создавать потоков
GUI и чем рисовать я бы тоже взял кросплатформенное... smile
Qt4, Ogre3D и т.д. и т.п.


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
4epT
Дата 25.12.2010, 11:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



KaraKum, привет) Я начал отрисовывать через GDI+ ... я сделал метод который просто выводит на экран матрицу в красивом виде ... перерисовка происходит каждый раз когда кто то двигается или ставит бомбу и экран блымает (то есть перерисовка происходит не достаточно быстро) - этого как то можно избежать?

Насколько я понимаю можно обновлять не все игровое поле а только его часть, но вот как за этим уследить?)
PM MAIL   Вверх
KaraKum
Дата 25.12.2010, 16:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: 1
Всего: 1



Привет  smile 
Тормозить не должно даже если перерисовывать весь экран 30 раз в секунду (ну, если у тебя комп на биполярных транзисторах  smile )
Проблема, видимо, в чём-то другом. Выложи сюда код функции отрисовки - она, наверное, небольшая...
А тормозит как именно?: экран прорисовывается медленно сверху-вниз (как при рендеринге 3D-сцен в соответствующих редакторах) или экран отрисовывается моментально, но с задержкой по времени?
PM MAIL WWW   Вверх
4epT
Дата 25.12.2010, 18:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Цитата(KaraKum @ 25.12.2010,  16:47)
Привет  smile 
Тормозить не должно даже если перерисовывать весь экран 30 раз в секунду (ну, если у тебя комп на биполярных транзисторах  smile )
Проблема, видимо, в чём-то другом. Выложи сюда код функции отрисовки - она, наверное, небольшая...
А тормозит как именно?: экран прорисовывается медленно сверху-вниз (как при рендеринге 3D-сцен в соответствующих редакторах) или экран отрисовывается моментально, но с задержкой по времени?

скорее всего как при рендеринге 3D-сцен в соответствующих редакторах =))) но довольна таки быстро ... ну то есть та область перерисовывает блымает (это когда зажмешь кнопку и непрерывно перемещаешь бомбермена в сторону).

Вот код отрисовки:

Код

Graphics gr(aDc);
    
int step = 20;
int x = 0;
int y = 0;
....

for( int i = 0; i < field->getHeight(); i++ )
{
    for( int j = 0; j < field->getWidth(); j++ )
    {
        if( field->getField()[i][j] == 0 )
        {
            gr.DrawRectangle(penBlack , x , y , step , step);
            gr.FillRectangle(&brushBlack , x , y , step , step);
        }
        else if( field->getField()[i][j] == 2 )
        {
            gr.DrawRectangle(penBlue , x , y , step , step);
            gr.FillRectangle(&brushBlue , x , y , step , step);
        }
        else if( field->getField()[i][j] == 1 )
        {
            gr.DrawRectangle(penBackColor , x , y , step , step);
            gr.FillRectangle(&brushBackColor , x , y , step , step);
        }
        else if( field->getField()[i][j] == 3 )
        {
            gr.DrawRectangle(penGreen , x , y , step , step);
            gr.FillRectangle(&brushGreen , x , y , step , step);
        }
        else if( field->getField()[i][j] == 5 )
        {
            gr.DrawRectangle(penBackColor , x , y , step , step);
            gr.FillRectangle(&brushBackColor , x , y , step , step);
            gr.FillEllipse(&brushBlack , x , y , step - 5 , step - 5);
            gr.DrawLine(penBlack, x + (step - 5) / 2 , y + (step - 5) / 2 , x + (step - 5) / 2 , y - 5);  
        }
        else if( field->getField()[i][j] == 6 )
        {
            gr.DrawRectangle(penRed , x , y , step , step);
            gr.FillRectangle(&brushRed , x , y , step , step);
        }
        else if( field->getField()[i][j] == 4 )
        {
            RectF layoutRect(x + 2, y - 2, step, step);
            gr.DrawRectangle(penBackColor , x , y , step , step);
            gr.FillRectangle(&brushBackColor , x , y , step , step);
            gr.FillEllipse(&brushYellow , x , y , step , step);
            gr.DrawString ( L"$" , 22 ,  &myFont , layoutRect , &format, &brushGreen );
        }
            y += step;
    }
    y = 0;
    x += step;
}


при каком либо движении делаю UpdateMainWindow()

Код

void UpdateMainWindow ( )
{
    RECT r = { 0 };
    ::GetClientRect ( mainWindow, &r );
    ::InvalidateRect ( mainWindow, &r, TRUE );
    ::UpdateWindow ( mainWindow );
}


в WM_PAINT:

Код

case WM_PAINT:
    {
        PAINTSTRUCT ps = { 0 };
        HDC dc = ::BeginPaint (mainWindow, &ps);
        drawRect(dc);
        ::EndPaint(mainWindow, &ps);
        break;
    }


drawRect - это функция рисования =)
PM MAIL   Вверх
KaraKum
Дата 25.12.2010, 18:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: 1
Всего: 1



Аа, я понял. Скорее всего причина в следующем: в твоём случае, вероятно, экран перерисовывается при каждом событии нажатия клавиши, а это может происходить очень часто. Про WM_KEYDOWN не могу ничего сказать, но, вот, например, в SDL сообщения нажатии могут происходить по 500-1000 раз в секунду, что, конечно, тяжелова-то.
Если WM_KEYDOWN действительно приходят очень часто, то тебе нужно при нажатии клавиш лишь изменять какое-то внутреннее состояние игры и не перересовывать всё заново каждом этом случае, а отрисовкой заниматься только по таймеру (где-то 30 раз в секунду), ну и по WM_PAINT тоже (это событие приходит когда сворачивают-разворачивают окно, поэтому если есть таймер, генерирующий события 30 раз в секунду, то можно довольствоваться только им).

Для отладки можно измерить сколько занимает времени одна отрисовка:
Код

#include "timing.h"

Timer timer;
timer.getElapsedTime();

PAINTSTRUCT ps = { 0 };
HDC dc = ::BeginPaint (mainWindow, &ps);
drawRect(dc);
::EndPaint(mainWindow, &ps);

printf("drawing consumed %.6f seconds.\n", timer.getElapsedTime());


Это сообщение отредактировал(а) KaraKum - 25.12.2010, 18:48

Присоединённый файл ( Кол-во скачиваний: 2 )
Присоединённый файл  timing.rar 1,16 Kb
PM MAIL WWW   Вверх
4epT
Дата 26.12.2010, 00:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Ну так даже если WM_KEYDOWN срабатывает очень часто, у меня ведь каждая клавишу фильтруется ... и по идеи оно вызывается 1 раз при нажатии клавиши
PM MAIL   Вверх
KaraKum
Дата 26.12.2010, 01:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: 1
Всего: 1



Хмм... тогда сложно что-либо сказать.
Нужно, значит, сделать замер времени, чтобы сократить число подозреваемых  smile 
PM MAIL WWW   Вверх
4epT
Дата 26.12.2010, 01:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Цитата(KaraKum @ 26.12.2010,  01:03)
Хмм... тогда сложно что-либо сказать.
Нужно, значит, сделать замер времени, чтобы сократить число подозреваемых  smile

ну pringf выводит в консоль .... а у меня оконное приложение) как посмотреть то что он вывел?)
PM MAIL   Вверх
KaraKum
Дата 26.12.2010, 01:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: 1
Всего: 1



В файл:
Код

FILE* file = fopen("log.txt", "w");
fprintf(file, "Hello, file system!", ...);

PM MAIL WWW   Вверх
4epT
Дата 26.12.2010, 02:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Цитата(KaraKum @ 26.12.2010,  01:29)
В файл:
Код

FILE* file = fopen("log.txt", "w");
fprintf(file, "Hello, file system!", ...);

ок) сделаю тест напишу)
PM MAIL   Вверх
KaraKum
Дата 26.12.2010, 02:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

Репутация: 1
Всего: 1



ждёмс....  smile 
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1146 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.