LINUX.ORG.RU

Не работают события в SDL2

 


0

1

Всем привет! Я написал код:

#include «SDL2/SDL.h» #include

using namespace std;

// Размеры окна. const int Window_width= 640; const int Window_height= 480;

SDL_Event event; // Создаем структуру событий. bool running= true; // Работает ли приложение.

int main(int argc, char **argv) {

// Инициализируем все модули SDL (видео, аудио и т. д.).

if (SDL_Init(SDL_INIT_EVERYTHING) != 0) // if (SDL_Init(SDL_INIT_EVENTS) != 0) return 1;

SDL_Surface* screen_surface = NULL; SDL_Window* window = NULL;

// создаем окно.

window= SDL_CreateWindow(«Hello, SDL 2!»,SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, Window_width, Window_height, SDL_WINDOW_SHOWN);

if (window == NULL) return 1;

while (running) // Пока работает. {

// Цикл обработки событий. while (SDL_PollEvent(&event) ) {

if (event.type == SDL_QUIT)
    {
        running = false;
    }

    if (event.type == SDL_KEYDOWN)
    {
        running = false;
    }

    if (event.type == SDL_MOUSEBUTTONDOWN)
    {
        running = false;
    }
}

} // Конец while (running)

} // Конец main()

Компилирую так: g++ /home/grec/D/progi/3D_Modeling.cpp -o 3D_Modeling.compl -lSDL $(sdl2-config –cflags –libs)

События не работают. Код частично не мой. Как я понял при нажатии любой клавиши выход их цикла и из программы (автор сделал это для теста событий). Почему не работают события? Библиотека хорошая вроде, но такого я ни как не ждал.


Условие в цикле while проверяется только когда выполнение доходит до строчки, где цикл начинается.

Помнится, где-то встречал замечание о том, что достаточно много студентов считает, если написать while (running) {, то компьютер как бы подписывается на изменения переменной running, и её сброс в false сразу же прерывает цикл. Очевидно, это не так. Но это очевидно далеко не всем.

i-rinat ★★★★★
()

Суть в том, что при одновременной линковке библиотеки SDL1, которую ты линкуешь директивой -lSDL и SDL2, которую ты линкуешь директивой $(sdl2-config --libs), у тебя получается неопределённое поведение. Оно даёт слинковать, потому что некоторые сущности и функции в этих библиотеках просто одинаковые и конфликтов с точки зрения компилятора нет: какой-нибудь SDL_Init() уходит в дебри SDL1, а SDL_CreateWindow() – в SDL2. При этом структуры обоих библиотек в памяти естественно разные, поэтому ничего толком не работает и выглядит странно.

Убери -lSDL из флагов компиляции и этот корявенький пример должен заработать как ты хочешь.

Просто ты намешал всё в кучу:

$ ldd 3D_Modeling.compl | grep SDL
	libSDL-1.2.so.0 => /lib/x86_64-linux-gnu/libSDL-1.2.so.0 (0x00007f7bc4f73000)
	libSDL2-2.0.so.0 => /lib/x86_64-linux-gnu/libSDL2-2.0.so.0 (0x00007f7bc4dd3000)
EXL ★★★★★
()
Последнее исправление: EXL (всего исправлений: 2)
Ответ на: комментарий от i-rinat

Я только вижу что у него скобки закоментированны нахрен, но это потому что код вставлен просто так наверное. Ну и надо через if/else но тут не критично ибо он везде выходит, так что пофиг. Ну running не объявлена ещё.

В упор не вижу что не так -_- Может это мне спать пора?

Я даже скопировал, поправив очевидное.

#include <stdio.h>
#include <SDL2/SDL.h>
#include <stdbool.h>

int main(int argc, char *argv[])
{
     SDL_Init(SDL_INIT_EVERYTHING);
     SDL_CreateWindow("Hello, SDL 2!",SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 100, 100, SDL_WINDOW_SHOWN);
     bool running = true;
     SDL_Event event;
     while (running)
     {
         while ( SDL_PollEvent(&event) ) 
         {

                if(event.type == SDL_QUIT)
                {
                    running = false;
                }

                if (event.type == SDL_KEYDOWN)
                {
                    running = false;
                }

                if (event.type == SDL_MOUSEBUTTONDOWN)
                {
                    running = false;
                }
          }
      }

    return 0;
}

Всё ок же

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 3)
Ответ на: комментарий от LINUX-ORG-RU

У ТС условия являются дочерними к SDL_QUIT. Но это у него ерунда с форматированием, о котором кто-то забыл и выложил в нечитабельном виде, попутно добавив новых ошибок.

lnx4
()
Ответ на: комментарий от LINUX-ORG-RU

Всё окей, оказывается. Я чего-то решил, что цикл while (SDL_PollEvent(&event)) будет бесконечный, что это типа основного цикла программ, которые крутятся, пока программа работает. Типа как GetMessage в Win32, которая вернёт 0 только когда программа должна завершаться.

Надо было спать идти, да.

i-rinat ★★★★★
()
Ответ на: комментарий от EXL

Еше раз спасибо, заработало. Я хочу написать код правильно, я думаю это нормальное желание. Правда времени нет. Сейчас я стал разбираться с обработкой клавиатуры. Сразу скажу что SDL мне по названиям переменных не нравиться. Это так, минус SDL. Выбрал его так как известный и по другим либам инфы нет или на английском. Пока основной код что я писал в первом сообщении. Но я уже написал что хочу правильно и как мне удобно написать код, поэтому этот код вообще в другую концепцию может модифицироваться, SDL это позволяет как я понял. Буду приводить куски кода, весь код в первом моем сообщении. Еще я не силен в с++, хотелось бы на си написать, но я ни знаю на сколько это дольше будет, собственно свой динамический массив в любом случае придеться писать (если все же перейду на си). Можно ли обойтись в си без map, векторов и прочего, что есть в с++, я ни знаю. По этим вопросам тоже нужен совет опытного прогера на си. Сейчас я пытаюсь вынести обработку клавиатуры в функцию (как это сделано на языке js):

case SDL_KEYDOWN: // Нажата клавиша. key(event.key.keysym.sym); break;

void key(int Key) // тут int? {

if (key == SDLK_q) running= false;

}

это то с чего я начал, но после решил поменять концепцию - я считаю правильным такую обработку событий - чтобы произошедшее событие просто лежало в переменной. Для понимания - в объекте (но я против объектов), в массиве или мне кажется лучше в переменной. К примеру переменная Keyword хранит строку «Q», при чем с учетом регистра. После останется только работать с переменной Keyword: if (Keyword == «Q») то что-то делаем.

На что-то подобное я вроде наткнулся, вот код только для работы с клавиатурой (пока с этим кодом работаем, а не то что я скидывал ранее):

// Понятно что окно создали.

Uint8* keyboard;

// Основной цикл. while (running) // Пока работает. {

SDL_PumpEvents(); keyboard= SDL_GetKeyState(NULL); if (key_map[SDLK_Return] ) cout << «Enter pressed» << «\n»;

} // Конец while (running)

Код не дописан, просто компилирую. Возникли ошибки при компиляции:

error: ‘SDL_GetKeyState’ was not declared in this scope; did you mean ‘SDL_GetModState’?

Зачем я ее должен объявлять? Разве она не объявлена в либе SDL? Если объявлять, то где и как?

error: ‘key_map’ was not declared in this scope; did you mean ‘key_t’?

error: ‘SDLK_Return’ was not declared in this scope; did you mean ‘SDLK_RETURN’?

wadic2
() автор топика
Ответ на: комментарий от wadic2

Путь в программирование начинается с базового изучения английского языка и того языка программирования, который ты хочешь использовать. Потому что все актуальные материалы, туториалы и документация публикуется на английском.

А твои ошибки и трудности из-за того, что ты не понимаешь как и что именно нужно делать в этом языке и как нужно использовать библиотеку, находишь какие-то протухшие материалы и пытаешься их использовать не разбираясь.

Зачем я ее должен объявлять? Разве она не объявлена в либе SDL? Если объявлять, то где и как?

Вот опять, откуда-то ты скопировал кусок кода, который предназначен для SDL1, а не SDL2. Функция SDL_GetKeyState() из SDL1, в SDL2 она называется SDL_GetKeyboardState().

В общем, у тебя два пути для достижения какой-то там цели, которую ты себе обозначил.

Первый, долгий, но правильный: сесть за литературу и изучить базовый английский язык, язык программирования C на базовом уровне, язык программирования C++ на базовом уровне, документацию к SDL2 и примеры использования этой библиотеки: https://github.com/libsdl-org/SDL/tree/main/test

Второй, быстрый, не особо правильный: найти где-нибудь на GitHub пример небольшой игры с нужной тебе функциональностью и потихоньку разбираться в том, как оно там всё работает. Например, вот пример использования SDL_GetKeyboardState(): https://github.com/jleipus/dino-jump/blob/master/src/InputHandler.cpp

$ sudo apt install git libsdl2-image-dev libsdl2-ttf-dev
$ git clone https://github.com/jleipus/dino-jump
$ cd dino-jump/
$ make
$ ./platformer

К тому же тут есть актуальные уроки по SDL2: https://lazyfoo.net/tutorials/SDL/ их можно читать с каким-нибудь Google Translate наперевес.

EXL ★★★★★
()
Ответ на: комментарий от EXL

«Путь в программирование начинается с базового изучения английского языка и того языка программирования, который ты хочешь использовать» - я не согласен на счет английского, да, без него в не рускоязычного интернета тяжело. Все дело в том что нет времени. А совет нет времени - значит не делай, ну это не правильный совет. Язык приходиться изучать по ходу. Для того и спрашиваю тут на форуме, чтобы узнать язык, узнать SDL и прочее. Я не мало знаю языков, все учил так. Так что тут нет проблемы, нужно учить. Да и с языком мало проблем. Скорее проблема в выборе языка, то ли си, то ли с++. Я сам не знаю, это как то исходя из обстоятельств решиться. Сперва выбрал с++, просто и-за map. Но сейчас мож и поменяю решение. Много не правильно в с++. А вообще я по максимому глубоко разбираюсь в языках, их устройстве и каким каким должен быть язык. Свой ассемблер немного не дописал. Так что в языках понимаю. SDl тоже на форуме учить приходиться, у меня нет вариантов. Доки на английском читать - это не эффективно (долго и можно не разобраться). Читал и читаю доки. По SDL самый минимум пока читал. Игру посмотрю завтра наверное. Переписал почти весь код:

// Понятно что окно создали.

Uint8* keyboard;

// Основной цикл. while (running) // Пока работает. {

SDL_PumpEvents(); keyboard= SDL_GetKeyboardState(NULL);

// if (keyboard[SDLK_RETURN] ) if (keyboard[SDLK_q] ) { cout << «Enter pressed» << «\n»; running= false; }

} // Конец while (running)

Компилируется, но ни на энтер, ни на «q» не реагирует.

wadic2
() автор топика
Последнее исправление: wadic2 (всего исправлений: 1)
Ответ на: комментарий от wadic2

Хорошо, английский язык для тебя проблема, но думаю для тебя не станет проблемой изучить используемые тут способы разметки сообщений Lorcode или Markdown и перестать насиловать всем глаза?

Jameson ★★★★★
()
Ответ на: комментарий от Jameson

Переписал почти весь код:

// Основной цикл. while (running) // Пока работает. {

SDL_PumpEvents(); keyboard= SDL_GetKeyboardState(NULL);

Ни чего не поменялось. Насилует глаза желание владельцев форума сократить объем диска. Экономят по мелочи, насилует глаза не реально. Терплю.

wadic2
() автор топика
Последнее исправление: wadic2 (всего исправлений: 1)
Ответ на: комментарий от wadic2

Ну ты же понимаешь, да, что разбираться и писать за тебя программу пользователи этого форума не будут?

// g++ test.cpp -lSDL2
// ./a.out

#include <SDL2/SDL.h>

int main(int argc, char *argv[]) {
	SDL_Init(SDL_INIT_EVERYTHING);
	SDL_CreateWindow("A Fucking Window", 300, 300, 300, 300, SDL_WINDOW_SHOWN);
	while ("Catgirls are cute!") {
		SDL_PumpEvents();

		if (SDL_GetKeyboardState(NULL)[SDL_SCANCODE_RETURN])
			break;
		if (SDL_GetKeyboardState(NULL)[SDL_SCANCODE_ESCAPE])
			break;
		if (SDL_GetKeyboardState(NULL)[SDL_SCANCODE_Q])
			break;

		SDL_Delay(16); // ~60 fps.
	}
	return 0;
}
EXL ★★★★★
()
Последнее исправление: EXL (всего исправлений: 3)
Ответ на: комментарий от wadic2

Насилует глаза желание владельцев форума сократить объем диска. Экономят по мелочи, насилует глаза не реально. Терплю.

О как. Вопросов больше не имею, успехов в жизни.

Jameson ★★★★★
()

Есть такое ощущение, что хочешь ты игрушку попробовать написать.

Предлагаю на данном этапе взять SFML. Раньше на том же ютубе на русском примеров было море, не думаю, что что-то здесь критично изменилось.

Во-первых, проще и многое уже реализовано на более высоком уровне. Во-вторых, сразу стартуешь в ООП.

lnx4
()