2017-06-05 18 views
0

我的超简单2D游戏Caventure取决于尽管在根目录中有正确的DLL,但Windows可执行文件无法启动

编译时,目录看起来象

Caventure.exe 
libfreetype-6.dll 
notomono-regular.ttf 
SDL2.dll 
SDL2_ttf.dll 
zlib1.dll 

我使用Microsoft Visual Studio 2015年,我一直在关注Lazy Foo's tutorials on building with Windows甚至以下的步骤后,这是行不通的。以下是我所做的:

  1. 将编译器链接到x64中的包含和库目录。
  2. 链接库。
  3. 将库复制到C:\Windows\SysWOW64
  4. 包括<Windows.h>
  5. 使用的兼容模式。
  6. 在Visual Studio IDE中对其进行测试,包括使用调试器。

当我打开它时,它立即关闭,它不会返回任何错误。

这里的主源文件:

#include <stdio.h> 
#include <stdexcept> 
#include <Windows.h> 
#include <SDL.h> 
#include <SDL_ttf.h> 

#include "TextMenu.h" 
#include "TextBox.h" 

#include "Graphics.h" 
#include "Event.h" 

// Screen dimensions, constants 
#define SCREEN_WIDTH 800 
#define SCREEN_HEIGHT 600 
// 600 for ground, 280 for output, 20 for input 

Graphics Global; 
Event Loop; 

void Init(Graphics& Global) 
{ 
    if (SDL_Init(SDL_INIT_VIDEO) > 0) 
    { 
     throw(::std::runtime_error("SDL failed to initialise! ERROR: ")); 
    } 
    Global.Window = SDL_CreateWindow("Caventure", 
     SDL_WINDOWPOS_UNDEFINED, 
     SDL_WINDOWPOS_UNDEFINED, 
     SCREEN_WIDTH, 
     SCREEN_HEIGHT, 
     SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE); 
    if (Global.Window == NULL) 
    { 
     throw(::std::runtime_error("Window failed to initialise! ERROR: ")); 
    } 
    Global.ScreenSurface = SDL_GetWindowSurface(Global.Window); 
    if (Global.ScreenSurface == NULL) 
    { 
     throw(::std::runtime_error("Surface failed to initialise! ERROR: ")); 
    } 
    Global.Renderer = SDL_CreateRenderer(Global.Window, -1, 0); 
    if (Global.Renderer == NULL) 
    { 
     throw(::std::runtime_error("Renderer could not be initialised! ERROR: ")); 
    } 
    if (TTF_Init() > 0) 
    { 
     throw(::std::runtime_error("TTF could not be initialised! ERROR: ")); 
    } 
} 

void UpdateMedia(Graphics& Global) 
{ 
    SDL_GetWindowSize(Global.Window, &Global.width, &Global.height); 

    // Set geomtry dimensions, apart from rcTextInput. 
    Global.rcGround = { 0, 0, Global.width, (Global.height/3) * 2 }; 
    Global.rcTextOutput = { 0, (Global.height/3) * 2, Global.width, Global.height - 40 }; 
    Global.rcTextOutputGrd = { 0, (Global.height/3) * 2, Global.width, Global.height - 40 }; 

    Global.SpriteDefaultX = Global.width/2; 
    Global.SpriteDefaultY = Global.height/2; 
}; 

void LoadMedia(Graphics& Global) 
{ 
    UpdateMedia(Global); 

    Global.rcSprite = { Global.SpriteDefaultX, Global.SpriteDefaultY, 4, 4 }; 

    Global.Font = TTF_OpenFont("src/graphics/resources/notomono-regular.ttf", 14); 
    if (Global.Font == NULL) 
    { 
     throw(::std::runtime_error("Font failed to load! ERROR: ")); 
    } 

    SDL_SetTextInputRect(&Global.rcTextInput); 
} 

void InputLoop(Graphics& Global, Event& Loop) 
{ 
    if (Loop.event.type == SDL_QUIT) 
    { 
     Loop.bQuit = true; 
    } 
    else if (Loop.event.type == SDL_KEYDOWN) 
    { 
     // Sprite movement 
     switch (Loop.event.key.keysym.sym) 
     { 
     case SDLK_UP: 
      Global.rcSprite.y -= 5; 
      break; 

     case SDLK_DOWN: 
      Global.rcSprite.y += 5; 
      break; 

     case SDLK_LEFT: 
      Global.rcSprite.x -= 5; 
      break; 

     case SDLK_RIGHT: 
      Global.rcSprite.x += 5; 
      break; 
     } 

     // Backspace handler 
     if (Loop.event.key.keysym.sym == SDLK_BACKSPACE && Loop.InputText.length() > 0) 
     { 
      Loop.InputText.pop_back(); 
      if (Loop.InputText.length() == 0) 
      { 
       Loop.InputText = " "; 
      } 
     } 

     // Creates new line of text 
     else if (Loop.event.key.keysym.sym == SDLK_RETURN && Loop.InputText.length() != 0 && Loop.InputText != " ") 
     { 
      Global.Menu.NewBox(Loop.InputText); 
      Loop.bRenderText = true; 
      Loop.InputText = " "; 
     } 
    } 
    else if (Loop.event.type == SDL_TEXTINPUT) 
    { 
     Loop.InputText += Loop.event.text.text; 
    } 
} 

void RenderLoop(Graphics& Global, Event& Loop) 
{ 
    UpdateMedia(Global); 

    // Renders sprite movement 
    if (Global.rcSprite.x < 0 || Global.rcSprite.y < 0 || Global.rcSprite.y > Global.rcGround.h || Global.rcSprite.x > Global.rcGround.w) 
    { 
     Global.rcSprite.x = Global.SpriteDefaultX; 
     Global.rcSprite.y = Global.SpriteDefaultY; 
    } 

    // Sets background to black 
    SDL_SetRenderDrawColor(Global.Renderer, 0x00, 0x00, 0x00, 0x00); 
    SDL_RenderClear(Global.Renderer); 

    // Renders background of sprite to black 
    SDL_RenderFillRect(Global.Renderer, &Global.rcGround); 
    SDL_BlitSurface(Global.CurrentSurface, NULL, Global.ScreenSurface, &Global.rcGround); 

    // Renders background of text box to grey 
    SDL_SetRenderDrawColor(Global.Renderer, 0x40, 0x40, 0x40, 0x40); 
    SDL_RenderFillRect(Global.Renderer, &Global.rcTextOutputGrd); 
    SDL_BlitSurface(Global.CurrentSurface, NULL, Global.ScreenSurface, &Global.rcTextOutputGrd); 

    SDL_SetRenderDrawColor(Global.Renderer, 0x00, 0x00, 0x00, 0x00); 
    // Renders text input 
    Global.TextInput.Render(Global.Renderer, Global.Font, Loop.InputText.c_str(), Global.TextColor); 
    Global.rcTextInput = { 0, Global.height - 20, Global.TextInput.GetWidth(), Global.TextInput.GetHeight() }; 
    SDL_RenderCopy(Global.Renderer, Global.TextInput.GetTexture(), NULL, &Global.rcTextInput); 

    // Renders text output 
    if (Loop.bRenderText) 
    { 
     Global.Menu.Update(Global.Renderer, Global.Font, Global.TextColor, Global.rcTextOutput); 
    } 
    SDL_RenderSetClipRect(Global.Renderer, NULL); 

    // Renders text box background edges white 
    SDL_SetRenderDrawColor(Global.Renderer, 0xFF, 0xFF, 0xFF, 0xFF); 
    SDL_RenderDrawLine(Global.Renderer, 0, (Global.height/3) * 2, Global.width, (Global.height/3) * 2); 
    SDL_RenderDrawLine(Global.Renderer, 0, Global.height - 20, Global.width, Global.height - 20); 

    // Renders sprite 
    SDL_RenderFillRect(Global.Renderer, &Global.rcSprite); 
    SDL_BlitSurface(Global.CurrentSurface, NULL, Global.ScreenSurface, &Global.rcSprite); 

    // Presents render 
    SDL_RenderPresent(Global.Renderer); 
} 

void Quit(Graphics& Global) 
{ 
    // Deallocate memory 
    SDL_DestroyWindow(Global.Window); 
    SDL_DestroyRenderer(Global.Renderer); 
    TTF_CloseFont(Global.Font); 
    Global.Window = NULL; 
    Global.Renderer = NULL; 
    Global.Font = NULL; 

    // Quit SDL subsystems 
    TTF_Quit(); 
    SDL_Quit(); 
} 

int main(int argc, char *argv[]) 
{ 
    try 
    { 
     Init(Global); 
     LoadMedia(Global); 
     SDL_StartTextInput(); 
     while (!Loop.bQuit) 
     { 
      while (SDL_PollEvent(&Loop.event) != 0) 
      { 
       InputLoop(Global, Loop); 
       RenderLoop(Global, Loop); 
      } 
     } 
     SDL_StopTextInput(); 
    } 
    catch (std::runtime_error const& msg) 
    { 
     printf("%s", msg.what()); 
     if (SDL_GetError() != NULL) 
     { 
      printf("%s", SDL_GetError()); 
     } 
     else if (TTF_GetError() != NULL) 
     { 
      printf("%s", TTF_GetError()); 
     } 
     else 
     { 
      printf("%s", "NULL"); 
     } 
     Quit(Global); 
     return EXIT_FAILURE; 
    } 
    Quit(Global); 
    return EXIT_SUCCESS; 
} 
+0

从您提供的信息中,很难有人提出正确的解决方案。在调试模式下构建应用程序并启动调试器(F10)。 – ZDF

+0

@ZDF它在调试器中完美工作,我忘记了那些信息。我会编辑我的问题。 –

+0

看看[这](https://stackoverflow.com/questions/41044723/vc-2015-u3-assert-crashes-the-application)适合你的情况。 – ZDF

回答

1

我在每次成功初始化后都插入SDL_Log()以查找错误。我用来监视日志。

原来

Global.Font = TTF_OpenFont("src/graphics/resources/notomono-regular.ttf", 14); 

是错误的。

用简单

Global.Font = TTF_OpenFont("notomono-regular.ttf", 14); 

更换它改正的错误。

+1

记录是一种奇妙的方法。鉴于这个答案帮助你找到了问题,并且另外描述了真正的问题(作为字体路径问题),我建议将这个答案标记为已接受的答案。 (即使你问了这个问题)。 – Arafangion

1

四点建议:

  1. 查看Windows事件日志。
  2. 在调试器中运行它。
  3. 从Windows命令行启动它。
  4. 添加日志记录。
+0

事件查看器中没有任何内容,使用GDB只返回代码01,并且使用命令行根本不返回任何内容。 –

+1

@PradanaAumars:然后,我建议下移到下一个建议......顺便说一句,退出代码没有显示在命令行中;我会建议https://stackoverflow.com/a/334890/52273获取退出代码。 – Arafangion

1

当错误发生时,程序

  1. 一条消息打印到控制台,但没有控制台,因此,该消息是条死胡同,然后

  2. 立即退出,这样即使如果有控制台,它会在一瞬间消失。

如果您想从GUI Windows程序实际报告错误,您必须等待足够长的时间才能看到错误。借助SDL,SDL_ShowSimpleMessageBox是做这件事的好选择。

+0

为了告诉我关于['SDL_ShowSimpleMessageBox()'](https://wiki.libsdl.org/SDL_ShowSimpleMessageBox)的荣誉,我将使用它。 –

相关问题