Страницы

Поиск по вопросам

Показаны сообщения с ярлыком sdl. Показать все сообщения
Показаны сообщения с ярлыком sdl. Показать все сообщения

среда, 5 февраля 2020 г.

Самописаная игра постепенно смачно отжирает все ОЗУ

#cpp #sdl


Помогите плиз, этот код после запуска постепенно отжирает все ОЗУ.

Что может быть не так?

        #include "stdafx.h"
        #include 
        #include 
        #include 
        #include 

      int state = 0;
      bool showToBeDone = false;

      void action(int i) {
        if (i == 0) {
            state = 3;
        }
        else if (i == 1) {
            showToBeDone = true;
        }
        else {
            state = 4;
        }
    }
    bool XYInRect(const SDL_Rect& rect, int x, int y)
    {
        return ((x >= rect.x && x <= rect.x + rect.w) && (y >= rect.y && y <= rect.y
+ rect.h));
    }
    int main(int argc, char *argv[])
    {
        SDL_Rect prect;
        std::string input = "";
        const char* username = "Pavel";
        prect.x = 300;
        prect.y = 50;

        bool isRunning = true;
        SDL_Init(SDL_INIT_VIDEO);
        TTF_Init();
        int active = 0;

        SDL_Window* window = SDL_CreateWindow("Beeries 3", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WINDOW_SHOWN);
        SDL_Surface* screen = SDL_GetWindowSurface(window);

        while (isRunning == true) {
            SDL_FillRect(screen, NULL, 0x000000);
            /*if (state == 0) {
            SDL_Surface* hello = SDL_LoadBMP("startup.bmp");
            SDL_BlitSurface(hello, NULL, screen, NULL);
            SDL_UpdateWindowSurface(window);
            SDL_Delay(1000);
            SDL_FreeSurface(hello);
            hello = NULL;
            state = 3;
            }
            else if (state == 3) {*/
            SDL_Surface* fon = SDL_LoadBMP("fon.bmp");

            SDL_BlitSurface(fon, NULL, screen, NULL);

            int size = 0;
            SDL_Surface* pivo = NULL;

            TTF_Font* Sans = TTF_OpenFont("Roboto-Light.ttf", 24);
            SDL_Color wht = { 0,0,0,0 };


            SDL_Rect usernameRect;
            SDL_Surface* usernamed = NULL;
            pivo = SDL_LoadBMP("pivo.bmp");
            // usernamed = TTF_RenderUTF8_Solid(Sans, username, wht);



            usernameRect.x = prect.x;
            usernameRect.y = prect.y + 150;

            SDL_Surface* chat = SDL_LoadBMP("chat.bmp");
            SDL_Surface* txt = NULL;
            SDL_Rect chatRect;
            chatRect.x = 50;
            chatRect.y = 500;

            SDL_Rect msgRect;
            msgRect.x = 70;
            msgRect.y = 550;
            SDL_BlitSurface(chat, NULL, screen, &chatRect);
            const char* etext = input.c_str();
            txt = TTF_RenderText_Solid(Sans, etext, wht);
            SDL_BlitSurface(txt, NULL, screen, &msgRect);
            SDL_Event e;

            while (SDL_PollEvent(&e)) {
                if (e.type == SDL_MOUSEBUTTONDOWN) {
                    int x;
                    int y;

                    SDL_GetMouseState(&x, &y);

                    if (y <= 200) {}
                    else if (XYInRect(chatRect, x, y)) {

                    }
                    else {
                        prect.x = x - 100;
                        prect.y = y - 100;

                        SDL_BlitSurface(pivo, NULL, screen, &prect);
                        SDL_UpdateWindowSurface(window);
                    }
                }
                else if (e.type == SDL_KEYDOWN) {
                    if (e.key.keysym.scancode != 21 && e.key.keysym.scancode != 42
&& input.length() < 29) {
                        input += SDL_GetScancodeName(e.key.keysym.scancode);
                        std::cout << input << std::endl;

                    }
                    else if (e.key.keysym.scancode == 42) {
                        input = input.substr(0, input.size() - 1);
                        std::cout << input << std::endl;
                    }
                    else {
                        /* menu here */
                    }
                }
            }



            SDL_BlitSurface(pivo, NULL, screen, &prect);
              SDL_BlitSurface(usernamed, NULL, screen, &usernameRect);
              SDL_UpdateWindowSurface(window);

              /*}
              else {
              isRunning = false;
              }
              */
          }
          SDL_Quit();
          return 0;
      }

    


Ответы

Ответ 1



Не знаю как у вас устроен код, но должно быть хотяб так для начала. SDL_Surface* fon = SDL_LoadBMP("fon.bmp"); SDL_Surface* pivo = SDL_LoadBMP("pivo.bmp"); SDL_Surface* usernamed = TTF_RenderUTF8_Solid(Sans, username, wht); SDL_Surface* chat = SDL_LoadBMP("chat.bmp"); SDL_Surface* txt = NULL; TTF_Font* Sans = TTF_OpenFont("Roboto-Light.ttf", 24); int size = 0; SDL_Color wht = { 0,0,0,0 }; SDL_Rect usernameRect; while (isRunning == true) { SDL_FillRect(screen, NULL, 0x000000); SDL_BlitSurface(fon, NULL, screen, NULL); size = 0; //wht = { 0,0,0,0 }; usernameRect.x = prect.x; usernameRect.y = prect.y + 150; txt = NULL; } Также вам придётся освобождать память (думаю в конце функции main для вашего кода и до SDL_Quit();) при помощи: SDL_FreeSurface(fon); SDL_FreeSurface(pivo); SDL_FreeSurface(usernamed); SDL_FreeSurface(chat); SDL_FreeSurface(txt); TTF_CloseFont(Sans); // и ещё шрифт выгрузить. SDL_Quit(); // выгрузить библиотеку

Ответ 2



Вы не освобождаете ресурсы, которые получаете. К тому-же переопределяя в цикле указатели на ресурсы, которые не освобождены (fon, Sans и др.), Вы теряете возможность их освободить. Смотрите функции SDL_FreeSurface, TTF_CloseFont, SDL_DestroyWindow. И внимательно читайте документацию по библиотеке, которую Вы используете.

четверг, 23 января 2020 г.

Как прикрепить патч для dll к проекту?

#sdl #opengl #cpp #dll


Я написал приложение на SDL + OPENGL + C++ в CodeBlocks. Обнаружил, что при запуске
исполняемого файла, скомпилированного в релизе (при запуске в релизе в самой среде
всё отлично работает) приложение некоторые .png файлы не загружает (а именно png-24)
и выдаёт в файл для ошибок (stderr) "libpng warning: Interlace handling should be turned
on when using png_ read_ image". Как выяснилось, sdl_ image использует такую libpng(а
именно libpng15-15.dll, другие я пробовал, sdl_image вроде требует именно эту либу),
в которой функция png_read_image имеет ошибку. Я долго искал решение (png-24 нужны),
качал вроде бы более новые версии libpng, но всё тщетно. Нашёл патч, который должен
фиксить эту ошибку:
--- libpng-1.5.0/pngread.c.ark  2011-01-14 12:27:23.440018507 +0100
+++ libpng-1.5.0/pngread.c  2011-01-14 12:28:02.866685173 +0100
@@ -841,7 +841,7 @@ png_read_image(png_structp png_ptr, png_
    }
    else
    {
-      if (!(png_ptr->transformations & PNG_INTERLACE))
+      if (png_ptr->interlaced && !(png_ptr->transformations & PNG_INTERLACE))
   {
      /* Caller called png_start_read_image or png_read_update_info without
       * first turning on the PNG_INTERLACE transform.  We can fix this here,

но не пойму? как его прицепить к  проекту. Скомпилировать свою libpng из исходников
пока не получается (очень не хочется этим заниматься). Помогите пожалуйста!    


Ответы

Ответ 1



Вам придётся скомпилировать libpng. Патч предназначен для исходников, к исходникам его и надо применять. Вы не сможете так просто применить патч исходников для бинарника. В качестве ненадёжной альтернативы, можно попробовать дизассемблировать код libpng, найти нужную функцию, и применить патч вручную. Однако, это имеет право не сработать -- например, если оптимизатор заинлайнил кое-где вызов этой функции. Короче говоря, легче скомпилировать. Кстати, может быть, легче будет уговорить sdl_image использовать другую версию libpng?

Ответ 2



Итак, нашёлся ответ. Собственно я нашёл решение только по другим странностям, когда релиз и дебаг версии начали работать совсем не так, как скомпилированные .ехе. начали вылетать ошибки на простейших функциях opengl и сам .ехе вариант очень тормозил. Оказывается я в начале сунул какую-то кривую версию библиотеки opengl в папку и компилятор работал с нормальной, а вот ехе с кривой.

воскресенье, 5 января 2020 г.

Формула полета пули в 2d игре

#c #разработка_игр #sdl


Пишу небольшой 2D шутер. Возникла проблема с просчетом траектории полета пули. если
в кратце: персонаж, который стреляет находится в центре экрана ( вид сверху), нам известен
угол, на который повернут персонаж, начальная позиция пули так же центр экрана соответственно.
Вот как я это пытался сделать:

phy->ownbullets[i].cX += cos(da) * .5 ;
phy->ownbullets[i].cY += sin(da) * .5 ;


где .5 - скорость полета, da - угол, но все равно траектория хаотична. В чем может
быть проблема?

Запись экрана - http://rgho.st/6HkZk2Tpy
    


Ответы

Ответ 1



Функции sin и cos принимают значения в радианах. Если значения угла в градусах, то необходимо перевести их в радианы (умножить на число Пи и разделить на 180 градусов): const double pi = 3.14159265358979323846; phy->ownbullets[i].cX += cos(da * pi / 180) * .5 ; phy->ownbullets[i].cY += sin(da * pi / 180) * .5 ;

понедельник, 8 апреля 2019 г.

Самописаная игра постепенно смачно отжирает все ОЗУ

Помогите плиз, этот код после запуска постепенно отжирает все ОЗУ.
Что может быть не так?
#include "stdafx.h" #include #include #include #include
int state = 0; bool showToBeDone = false;
void action(int i) { if (i == 0) { state = 3; } else if (i == 1) { showToBeDone = true; } else { state = 4; } } bool XYInRect(const SDL_Rect& rect, int x, int y) { return ((x >= rect.x && x <= rect.x + rect.w) && (y >= rect.y && y <= rect.y + rect.h)); } int main(int argc, char *argv[]) { SDL_Rect prect; std::string input = ""; const char* username = "Pavel"; prect.x = 300; prect.y = 50;
bool isRunning = true; SDL_Init(SDL_INIT_VIDEO); TTF_Init(); int active = 0;
SDL_Window* window = SDL_CreateWindow("Beeries 3", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WINDOW_SHOWN); SDL_Surface* screen = SDL_GetWindowSurface(window);
while (isRunning == true) { SDL_FillRect(screen, NULL, 0x000000); /*if (state == 0) { SDL_Surface* hello = SDL_LoadBMP("startup.bmp"); SDL_BlitSurface(hello, NULL, screen, NULL); SDL_UpdateWindowSurface(window); SDL_Delay(1000); SDL_FreeSurface(hello); hello = NULL; state = 3; } else if (state == 3) {*/ SDL_Surface* fon = SDL_LoadBMP("fon.bmp");
SDL_BlitSurface(fon, NULL, screen, NULL);
int size = 0; SDL_Surface* pivo = NULL;
TTF_Font* Sans = TTF_OpenFont("Roboto-Light.ttf", 24); SDL_Color wht = { 0,0,0,0 };
SDL_Rect usernameRect; SDL_Surface* usernamed = NULL; pivo = SDL_LoadBMP("pivo.bmp"); // usernamed = TTF_RenderUTF8_Solid(Sans, username, wht);

usernameRect.x = prect.x; usernameRect.y = prect.y + 150;
SDL_Surface* chat = SDL_LoadBMP("chat.bmp"); SDL_Surface* txt = NULL; SDL_Rect chatRect; chatRect.x = 50; chatRect.y = 500;
SDL_Rect msgRect; msgRect.x = 70; msgRect.y = 550; SDL_BlitSurface(chat, NULL, screen, &chatRect); const char* etext = input.c_str(); txt = TTF_RenderText_Solid(Sans, etext, wht); SDL_BlitSurface(txt, NULL, screen, &msgRect); SDL_Event e;
while (SDL_PollEvent(&e)) { if (e.type == SDL_MOUSEBUTTONDOWN) { int x; int y;
SDL_GetMouseState(&x, &y);
if (y <= 200) {} else if (XYInRect(chatRect, x, y)) {
} else { prect.x = x - 100; prect.y = y - 100;
SDL_BlitSurface(pivo, NULL, screen, &prect); SDL_UpdateWindowSurface(window); } } else if (e.type == SDL_KEYDOWN) { if (e.key.keysym.scancode != 21 && e.key.keysym.scancode != 42 && input.length() < 29) { input += SDL_GetScancodeName(e.key.keysym.scancode); std::cout << input << std::endl;
} else if (e.key.keysym.scancode == 42) { input = input.substr(0, input.size() - 1); std::cout << input << std::endl; } else { /* menu here */ } } }

SDL_BlitSurface(pivo, NULL, screen, &prect); SDL_BlitSurface(usernamed, NULL, screen, &usernameRect); SDL_UpdateWindowSurface(window);
/*} else { isRunning = false; } */ } SDL_Quit(); return 0; }


Ответ

Не знаю как у вас устроен код, но должно быть хотяб так для начала.
SDL_Surface* fon = SDL_LoadBMP("fon.bmp"); SDL_Surface* pivo = SDL_LoadBMP("pivo.bmp"); SDL_Surface* usernamed = TTF_RenderUTF8_Solid(Sans, username, wht); SDL_Surface* chat = SDL_LoadBMP("chat.bmp"); SDL_Surface* txt = NULL; TTF_Font* Sans = TTF_OpenFont("Roboto-Light.ttf", 24); int size = 0; SDL_Color wht = { 0,0,0,0 }; SDL_Rect usernameRect; while (isRunning == true) { SDL_FillRect(screen, NULL, 0x000000); SDL_BlitSurface(fon, NULL, screen, NULL); size = 0; //wht = { 0,0,0,0 }; usernameRect.x = prect.x; usernameRect.y = prect.y + 150; txt = NULL; }
Также вам придётся освобождать память (думаю в конце функции main для вашего кода и до SDL_Quit();) при помощи:
SDL_FreeSurface(fon); SDL_FreeSurface(pivo); SDL_FreeSurface(usernamed); SDL_FreeSurface(chat); SDL_FreeSurface(txt); TTF_CloseFont(Sans); // и ещё шрифт выгрузить. SDL_Quit(); // выгрузить библиотеку

суббота, 16 марта 2019 г.

Как прикрепить патч для dll к проекту?

Я написал приложение на SDL + OPENGL + C++ в CodeBlocks. Обнаружил, что при запуске исполняемого файла, скомпилированного в релизе (при запуске в релизе в самой среде всё отлично работает) приложение некоторые .png файлы не загружает (а именно png-24) и выдаёт в файл для ошибок (stderr) "libpng warning: Interlace handling should be turned on when using png_ read_ image". Как выяснилось, sdl_ image использует такую libpng(а именно libpng15-15.dll, другие я пробовал, sdl_image вроде требует именно эту либу), в которой функция png_read_image имеет ошибку. Я долго искал решение (png-24 нужны), качал вроде бы более новые версии libpng, но всё тщетно. Нашёл патч, который должен фиксить эту ошибку: --- libpng-1.5.0/pngread.c.ark 2011-01-14 12:27:23.440018507 +0100 +++ libpng-1.5.0/pngread.c 2011-01-14 12:28:02.866685173 +0100 @@ -841,7 +841,7 @@ png_read_image(png_structp png_ptr, png_ } else { - if (!(png_ptr->transformations & PNG_INTERLACE)) + if (png_ptr->interlaced && !(png_ptr->transformations & PNG_INTERLACE)) { /* Caller called png_start_read_image or png_read_update_info without * first turning on the PNG_INTERLACE transform. We can fix this here, но не пойму? как его прицепить к проекту. Скомпилировать свою libpng из исходников пока не получается (очень не хочется этим заниматься). Помогите пожалуйста!


Ответ

Итак, нашёлся ответ. Собственно я нашёл решение только по другим странностям, когда релиз и дебаг версии начали работать совсем не так, как скомпилированные .ехе. начали вылетать ошибки на простейших функциях opengl и сам .ехе вариант очень тормозил. Оказывается я в начале сунул какую-то кривую версию библиотеки opengl в папку и компилятор работал с нормальной, а вот ехе с кривой.

вторник, 5 февраля 2019 г.

Формула полета пули в 2d игре

Пишу небольшой 2D шутер. Возникла проблема с просчетом траектории полета пули. если в кратце: персонаж, который стреляет находится в центре экрана ( вид сверху), нам известен угол, на который повернут персонаж, начальная позиция пули так же центр экрана соответственно. Вот как я это пытался сделать:
phy->ownbullets[i].cX += cos(da) * .5 ; phy->ownbullets[i].cY += sin(da) * .5 ;
где .5 - скорость полета, da - угол, но все равно траектория хаотична. В чем может быть проблема?
Запись экрана - http://rgho.st/6HkZk2Tpy


Ответ

Функции sin и cos принимают значения в радианах. Если значения угла в градусах, то необходимо перевести их в радианы (умножить на число Пи и разделить на 180 градусов):
const double pi = 3.14159265358979323846; phy->ownbullets[i].cX += cos(da * pi / 180) * .5 ; phy->ownbullets[i].cY += sin(da * pi / 180) * .5 ;