2014-01-12 11 views
1

Я пытаюсь создать свою первую программу в SDL 1.2, чтобы познакомиться с SDL. У меня болит голова, пытаясь понять, почему моя программа немедленно закрывается.Программа немедленно закрывается в SDL

Связано ли это с тем, как я его компилирую?

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

Guy.h:

#ifndef GUY_H 
#define GUY_H 

class Guy{ 
    public: 
     Guy(int, int); 
     void move(); 
     void adjustVelocity(int, int); 
     int getX(); 
     int getY(); 
     int getXVel(); 
     int getYVel(); 
    private: 
     int xPos, yPos, xVel, yVel; 
}; 
#endif 

Guy.cpp:

#include "Guy.h" 

Guy::Guy(int x, int y){ 
    xPos = x; 
    yPos = y; 
} 
void Guy::move(){ 
    xPos += xVel; 
    yPos += yVel; 
} 
void Guy::adjustVelocity(int x, int y){ 
    xVel += x; 
    yVel += y; 
} 
int Guy::getX(){ 
    return xPos; 
} 
int Guy::getY(){ 
     return yPos; 
} 
int Guy::getXVel(){ 
    return xVel; 
} 
int Guy::getYVel(){ 
    return yVel; 
} 

main.cpp:

#include "SDL/SDL.h" 
#include "SDL/SDL_image.h" 
#include "Guy.h" 
#include <string> 
#include <iostream> 

bool init(); 
bool loadAllFiles(); 
void paintScreen(); 
void update(); 
bool handle(); 
void cleanUp(); 

void addSurface(int, int, SDL_Surface*, SDL_Surface*, SDL_Rect* clip = NULL); 
SDL_Surface* loadFile(std::string); 
SDL_Surface* Screen; 
SDL_Surface* BackgroundIMG; 
SDL_Surface* GuyIMG; 
Guy* Hunter; 


int main(int argc, char* args[]){ 
    std::cout << "Why won't it even cout this?? :(" << endl; 
    if(!init()){ 
     return 1; 
    } 
    if(!loadAllFiles()){ 
     return 2; 
    } 
    Hunter = new Guy(0,0); 
    paintScreen(); 
    while(handle()){ 
     update(); 
    } 

    cleanUp(); 
    return 0; 

    SDL_Init(SDL_INIT_EVERYTHING); 
    Screen = SDL_SetDisplayMode(640, 480, 32, SDL_SWSURFACE); 
    SDL_Flip(Screen); 
    SDL_Delay(1000); 
} 

bool init(){ 
    if(SDL_Init(SDL_INIT_EVERYTHING)==-1){ 
     return false; 
    } 
    Screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE); 
    if(Screen==NULL){ 
     return false; 
    } 
    SDL_WM_SetCaption("First SDL Test On Own", NULL); 
    return true; 
} 

bool loadAllFiles(){ 
    BackgroundIMG = loadFile("Background.png"); 
    GuyIMG = loadFile("Guy.png"); 
    if(BackgroundIMG==NULL || GuyIMG==NULL){ 
     return false; 
    } 
    else{ 
     return true; 
    } 
} 

void paintScreen(){ 
    addSurface(0, 0, BackgroundIMG, Screen); 
    addSurface(Hunter->getX(), Hunter->getY(), GuyIMG, Screen); 
    SDL_Flip(Screen); 
} 

void update(){ 
    Hunter->move(); 
    addSurface(Hunter->getX(), Hunter->getY(), GuyIMG, Screen); 
    SDL_Flip(Screen); 
} 

bool handle(){ 
    SDL_Event event; 
    while(SDL_PollEvent(&event)){ 
     if(event.type==SDL_QUIT){ 
      return false; 
     } 
     else if(event.type==SDL_KEYDOWN){ 
      switch(event.key.keysym.sym){ 
       case SDLK_UP: 
        Hunter->adjustVelocity(0, -1); 
        break; 
       case SDLK_DOWN: 
        Hunter->adjustVelocity(0, 1); 
        break; 
       case SDLK_RIGHT: 
        Hunter->adjustVelocity(1, 0); 
        break; 
       case SDLK_LEFT: 
        Hunter->adjustVelocity(-1, 0); 
        break; 
      } 
     } 
    } 
    return true; 
} 

void cleanUp(){ 
    SDL_FreeSurface(GuyIMG); 
    SDL_FreeSurface(BackgroundIMG); 
    SDL_Quit(); 
    delete Hunter; 
} 



void addSurface(int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip){ 
    SDL_Rect offset; 
    offset.x = x; 
    offset.y = y; 
    SDL_BlitSurface(source, clip, destination, &offset); 
} 

SDL_Surface* loadFile(std::string s){ 
    SDL_Surface* surface = IMG_Load(s.c_str()); 
    if(surface==NULL){ 
     return NULL; 
    } 
    else{ 
     SDL_Surface* opsurface = SDL_DisplayFormat(surface); 
     SDL_FreeSurface(surface); 
     return opsurface; 
    } 
} 

Мой Makefile:

all: main.o 
     g++ -o run main.o Guy.o -lSDL -lSDL_image 
main.o: Guy.o 
     g++ -c main.cpp 
Guy.o: 
     g++ -c Guy.cpp 

Всякий раз, когда я скомпилирую его с этим make-файлом, я не получаю ошибок.

+1

Это консольное приложение в оконной системе? Много раз консольные приложения заканчиваются, и оконная система немедленно закрывает окно. –

+0

Да, я собираю его в терминале, но у меня есть рабочий стол XFCE. Я экспериментировал с этим, и я думаю, что проблема в том, что make-файл по какой-то причине не обновлял файлы .o. Поэтому он запускал старую версию программы. Это объясняет, почему cout не будет работать. –

+0

Обновление: При экспериментировании я узнал, что если я не проверю, есть ли Экран == NULL, в bool init() экран не исчезнет сразу. –

ответ

0

Ваша программа немедленно закрывается, потому что вы используете SDL_PollEvent(&event). Эта функция вернет false, если нет события для обработки, которое в вашем случае происходит при запуске программы. Если пользователь должен предоставить входные данные окна, факт, что нет события для обработки, является правилом, а не исключением.

У вас есть 2 варианта:

  1. Переключение в SDL_WaitEvent. Это действительно похоже на SDL_PollEvent, но разница в том, что это блокирующий вызов. Преимущество состоит в том, чтобы быть простым для получения поведения, которое вы ожидаете от своего приложения.
  2. Оставайтесь с SDL_PollEvent и добавьте механизм, чтобы отложить выполнение, когда нет события для обработки. Обычно люди используют SDL_Delay с задержкой 0 или 10. Преимущество в том, что вы контролируете, что делает приложение, когда нет событий.

Пример сценария цикла процесса.

SDL_Event event; 
bool stop = false; 
while(!stop){ 
    bool got_event = SDL_PollEvent(&event) > 0; 
    if(got_event){ 
     stop = processEvent(event); 
    } 
    else { 
     if(backGroundWorkTodo()){ 
      doBackGroundWork(); 
     } 
     else{ 
      //may defer execution 
      SDL_Delay(0); 
     } 
    } 
} 
+0

Большое вам спасибо! У меня есть еще один вопрос ... Можно ли принимать постоянный ввод в SDL? Как будто я удерживал клавишу со стрелкой, будет ли она продолжать реагировать? Прямо сейчас, если я удерживаю клавишу со стрелкой, SDL распознает только одно: не то, что я держу его. –

+0

Да, вы можете распознать это с внутренним состоянием ключа.Когда событие SDL_KEYDOWN, это означает, что ключ удерживается до получения SDL_KEYUP. – UmNyobe