DWORD dwThreadId=1;
DWORD WINAPI Timer(LPVOID lpCOM) // Thread Timer
{
while(tim)
{
Sleep(1000);
Draw(); // функция отрисовки
}
return 0;
}
int main()
{
printf("Press SPACE to start\n");
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(400, 400);
glutInitWindowPosition(200, 200);
glutCreateWindow("Snake");
glutKeyboardFunc(keyPress);
Initialize();
glutDisplayFunc(Draw);
glutMainLoop();
return 0;
}
OpenGL, Поток с таймером для анимации.
В чём проблема:
Надо сделать ежесекундное обновление картинки, функция Draw() работает 100% - ставил cuot внутрь для проверки, но картинка не обновляется.
Картинка обновляется если Draw запихнуть в keyPress() событие или же когда я изменяю размер окна (срабатывает glutDisplayFunc) .
Помогите советом я зашел в тупик =(
Код:
Что за функция Draw()?Может статься,что надо вызвать функцию перерисовки.Либо самого OpenGL,либоWindows(для окна)
SetTimer(). А функцию Draw() напишите все-таки.
Присоединяюсь к @pixo $oft плюс еще одно замечание: если хотите сделать таймер, это лучше делать не через CreateThread(), а через
но всё же хочу по людски
Треды я использовал потому что у меня консольное преложение и мне так легче будет его перенести на линукс
а Drow() отрисовует сцену, рисует змейку и ни в чём не виноват :)
Код:
void Draw()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.6, 0.6, 0.9);
glBegin(GL_LINES);
for(unsigned char i=1;i<=20;i++)
{
glVertex3f(0.05*i, 1.0, 0.0);
glVertex3f(0.05*i, 0.0, 0.0);
glVertex3f(0.0, 0.05*i, 0.0);
glVertex3f(1.0, 0.05*i, 0.0);
};
glEnd();
...
тоже самое только со змейкой
...
}
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.6, 0.6, 0.9);
glBegin(GL_LINES);
for(unsigned char i=1;i<=20;i++)
{
glVertex3f(0.05*i, 1.0, 0.0);
glVertex3f(0.05*i, 0.0, 0.0);
glVertex3f(0.0, 0.05*i, 0.0);
glVertex3f(1.0, 0.05*i, 0.0);
};
glEnd();
...
тоже самое только со змейкой
...
}
как заставить glut или окно(лучше глут) перерисовывать сцену через таймер, а не через события
Раз хочеш перенести потом и на линукс то почемубы не использовать Qt? В нём это просто делается: по QTimer'у вызывается updateGL и всё. Есть в Qt и готовые примеры по опенгл.
Придерживаюсь теории: сперва чтобы начинать что то учить новое - надо хорошо знать старое...
Спасибо всем за помощь - разобрался сам. Игру написал работает на ура)) использовал только С++ и опенГЛ... скомпилировал в VS .NET вес ехе 46кб + glut dll 86кб.
Код:
while(tim)
{
Sleep(1000);
Draw(); // функция отрисовки
}
{
Sleep(1000);
Draw(); // функция отрисовки
}
Надо бы писать так:
Код:
while(tim)
{
Sleep(1000);
glutPostRedisplay(); /* glut скажет операционной системе, что окно хочет
перерисоваться, затем ОС дождется удобного момента
и вызовет Draw (т.к Draw указывалось в параметре glutDisplayFunc() ). */
}
{
Sleep(1000);
glutPostRedisplay(); /* glut скажет операционной системе, что окно хочет
перерисоваться, затем ОС дождется удобного момента
и вызовет Draw (т.к Draw указывалось в параметре glutDisplayFunc() ). */
}
А еще лучше так:
Код:
void timerF() { // сработал таймер glut
glutTimerFunc(30, timerF, 0); // переустановить таймер
glutPostRedisplay(); // перерисовать
}
int main() {
...
glutDisplayFunc(Draw);
glutTimerFunc(30, timerF, 0); // включить таймер на 30мс
glutMainLoop();
}
glutTimerFunc(30, timerF, 0); // переустановить таймер
glutPostRedisplay(); // перерисовать
}
int main() {
...
glutDisplayFunc(Draw);
glutTimerFunc(30, timerF, 0); // включить таймер на 30мс
glutMainLoop();
}
У меня возник новый вопрос :
змейку сделал динамическим списком и просто переставляю с конца на перёд.
но вот с фруктом проблема: иногда может подвисать когда rand_apple() кинет фрукт на змею, просто идет многочленный перебор змеи как бы это исправить
Код:
typedef struct lst //динам змейка
{
char x;
char y;
lst *next;
} snake;
bool check_apple() //проверка
{
snake *temp = p1;
while(temp!=NULL)
{
if((temp->x==apple_x) && (temp->y==apple_y)) return 0;
temp = temp->next;
};
return 1;
}
void rand_apple()
{
do {
srand(time(0));
apple_x = rand() % 19;
apple_y = rand() % 19;
} while(!check_apple()); //проверка, не на змее яблоко ...
}
{
char x;
char y;
lst *next;
} snake;
bool check_apple() //проверка
{
snake *temp = p1;
while(temp!=NULL)
{
if((temp->x==apple_x) && (temp->y==apple_y)) return 0;
temp = temp->next;
};
return 1;
}
void rand_apple()
{
do {
srand(time(0));
apple_x = rand() % 19;
apple_y = rand() % 19;
} while(!check_apple()); //проверка, не на змее яблоко ...
}
Когда это делается в цикле, то при попадании яблока на змею новое значение выдастся лишь по истечении секунды - вот и зависание.
Минус здесь только в том, что если на поле останется последняя свободная от змейки клетка, то случайный перебор может работать долго. ;)
Вариант 2 (извращенный): помимо змейки таким же способом хранить свободные клетки и, если свободных осталось мало, случайным образом определять не координаты, а номер в последовательности свободных.
P.S srand нужно писать только один раз в начале программы. Иначе, если rand_apple() вызвать дважды в секунду, time() выдаст одно и то же время, srand задаст одну и ту же последовательность случайных чисел и "случайные" координаты в обоих случаях будут одинаковы. ( ну вот, koodeer меня опередил :( )
P*t* (2) Идея хорошая спс...