Linux mint 在运行 SDL2 程序时冻结

Linux mint 在运行 SDL2 程序时冻结

在我开发的过去几个 SDL2 程序中,似乎出现了最奇怪的错误;每当我运行该程序时(经过任意时间后),Linux mint 就会冻结。我无法移动鼠标或对计算机进行任何操作。此时我唯一的选择就是按下电源按钮直到它关闭。我正在使用库 SDL2 和 SDL2_ttf。我假设这是某种类型的图形驱动程序问题(因为我过去遇到过驱动程序问题),所以我将图形驱动程序更新为 xserver-xorg-video-nouveau(开源)。这解决了我之前的图形驱动程序问题。

我的内核版本是 5.8.10。我的 GPU 是 GEforce GT 710。我的电脑是 dell-inspiron 560

如果您需要更多信息,请告诉我!

附言:考虑到错误在多个程序中的一致性,我严重怀疑这是一个代码问题,但如果您有其他想法,请告诉我。

提前感谢您的帮助!

编辑:根据要求,这是我的代码。(我正在尝试制作 2048 ai,但目前游戏尚未完成)

主程序

#include "board.h"
#include <time.h>

int main(int argc, char* argv[]) {
    srand(time(NULL));

    SDL_Init(SDL_INIT_EVERYTHING);
    TTF_Init();

    SDL_Window* window = SDL_CreateWindow("template", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 276, 276, SDL_WINDOW_RESIZABLE);
    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0);

    SDL_RenderSetLogicalSize(renderer, 276, 276);

    board b(renderer);
    direction dir;

    bool isFullscreen = false;
    bool running = true;

    Uint64 now = SDL_GetPerformanceCounter();
    Uint64 last = 0;

    double dt = 0;

    while (running) {
        last = now;
        now = SDL_GetPerformanceCounter();
        dt = ((now - last)/(double)SDL_GetPerformanceFrequency());

        dir = none;

        SDL_Event event;
        while (SDL_PollEvent(&event)) {
            switch (event.type) {
            case SDL_QUIT:
                running = false;
                break;
            case SDL_KEYDOWN:
                switch (event.key.keysym.sym) {
                case SDLK_ESCAPE:
                    running = false;
                    break;
                case SDLK_F11:
                    if (!isFullscreen) SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
                    else SDL_SetWindowFullscreen(window, NULL);
                    isFullscreen = !isFullscreen;
                    break;
                case SDLK_RIGHT:
                    dir = right;
                    break;
                case SDLK_LEFT:
                    dir = left;
                    break;
                case SDLK_UP:
                    dir = up;
                    break;
                case SDLK_DOWN:
                    dir = down;
                    break;
                }
                break;
            }
        }

        b.update(dir);

        SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
        SDL_RenderClear(renderer);

        b.draw();

        SDL_RenderPresent(renderer);
    }

    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    TTF_Quit();
    SDL_Quit();
}

#include <stdlib.h>
#include "texture.h"
#include "rect.h"

class block{
public:
    block(){
        value = 2 * (rand() % 2 + 1);
        switch(value){
        case 2:
            color = {238, 228, 218, 255};
            break;
        case 4:
            color = {237, 224, 200, 255};
            break;
        }
    }
    block(const block &b){
        value = b.value;
        switch(value){
        case 2:
            color = {238, 228, 218, 255};
            break;
        case 4:
            color = {237, 224, 200, 255};
            break;
        case 8:
            color = {242, 177, 121, 255};
            break;
        case 16:
            color = {245, 149, 99, 255};
            break;
        case 32:
            color = {246, 124, 95, 255};
            break;
        case 64:
            color = {246, 94, 59, 255};
            break;
        case 128:
            color = {237, 207, 114, 255};
            break;
        case 256:
            color = {237, 204, 97, 255};
            break;
        case 512:
            color = {237, 200, 80, 255};
            break;
        case 1024:
            color = {237, 197, 63, 255};
            break;
        case 2048:
            color = {237, 194, 46, 255};
            break;
        }
    }
    block operator=(const block &b2){
        value = b2.value;
        switch(value){
        case 2:
            color = {238, 228, 218, 255};
            break;
        case 4:
            color = {237, 224, 200, 255};
            break;
        case 8:
            color = {242, 177, 121, 255};
            break;
        case 16:
            color = {245, 149, 99, 255};
            break;
        case 32:
            color = {246, 124, 95, 255};
            break;
        case 64:
            color = {246, 94, 59, 255};
            break;
        case 128:
            color = {237, 207, 114, 255};
            break;
        case 256:
            color = {237, 204, 97, 255};
            break;
        case 512:
            color = {237, 200, 80, 255};
            break;
        case 1024:
            color = {237, 197, 63, 255};
            break;
        case 2048:
            color = {237, 194, 46, 255};
            break;
        }
        return *this;
    }
    bool operator==(const block &b2){
        return (b2.value == value);
    }
    bool operator!=(const block &b2){
        return (b2.value != value);
    }
    void setVal(int val){
        value = val;
        switch(value){
        case 2:
            color = {238, 228, 218, 255};
            break;
        case 4:
            color = {237, 224, 200, 255};
            break;
        case 8:
            color = {242, 177, 121, 255};
            break;
        case 16:
            color = {245, 149, 99, 255};
            break;
        case 32:
            color = {246, 124, 95, 255};
            break;
        case 64:
            color = {246, 94, 59, 255};
            break;
        case 128:
            color = {237, 207, 114, 255};
            break;
        case 256:
            color = {237, 204, 97, 255};
            break;
        case 512:
            color = {237, 200, 80, 255};
            break;
        case 1024:
            color = {237, 197, 63, 255};
            break;
        case 2048:
            color = {237, 194, 46, 255};
            break;
        }
    }
    int getVal(){ return value; }
    SDL_Color getCol(){ return color; }
private:
    SDL_Color color;
    int value;
};

董事会

#pragma once
#include "block.h"
#include "direction.h"
#include <vector>

class board{
public:
    board(SDL_Renderer* renderer){
        rend = renderer;
        blocks = {
            {NULL, NULL, NULL, NULL},
            {NULL, NULL, NULL, NULL},
            {NULL, NULL, NULL, NULL},
            {NULL, NULL, NULL, NULL},
        };
        vec2 pos1(rand() % 4, rand() % 4);
        blocks[pos1.y][pos1.x] = new block();
        vec2 pos2(rand() % 4, rand() % 4);
        while(pos1 == pos2) { pos2 = vec2(rand() % 4, rand() % 4); }
        blocks[pos2.y][pos2.x] = new block();
    }
    void update(direction d){
        vec2 strt, end, dir;
        if(d == up || d == left){
            strt = vec2(0, 0);
            end = vec2(4, 4);
            dir = vec2(1, 1);
        }
        else if(d == down){
            strt = vec2(0, 3);
            end = vec2(4, -1);
            dir = vec2(1, -1);
        }
        else if(d == right){
            strt = vec2(3, 0);
            end = vec2(-1, 4);
            dir = vec2(-1, 1);
        }
        else return;

        for(int y = strt.y; y != end.y; y += dir.y){
            for(int x = strt.x; x != end.x; x += dir.x){
                if(blocks[y][x]) moveBlock(x, y, d);
            }
        }
        vec2 newPos(rand() % 4, rand() % 4);
        while(blocks[newPos.y][newPos.x]){ newPos = vec2(rand() % 4, rand() % 4); }
        blocks[newPos.y][newPos.x] = new block();
    }
    void draw(){
        SDL_Rect background = {0, 0, 276, 276};
        SDL_SetRenderDrawColor(rend, 73, 68, 63, 255);
        SDL_RenderFillRect(rend, &background);
        for(int y = 0; y < blocks.size(); y++){
            for(int x = 0; x < blocks[y].size(); x++){
                SDL_Rect r = {x * 64 + 4 * (x+1), y * 64 + 4 * (y + 1), 64, 64};
                SDL_Color col;
                text t(50, rend);
                if(blocks[y][x]){
                    t.updateText(std::to_string(blocks[y][x]->getVal()), 50);
                    col = blocks[y][x]->getCol();
                }
                else{
                    col = {80, 76, 71, 255};
                }
                SDL_SetRenderDrawColor(rend, col.r, col.g, col.b, col.a);
                SDL_RenderFillRect(rend, &r);
                t.draw(r.x + 32 - t.getWidth() / 2, r.y + 32 - t.getHeight() / 2);
            }
        }
    }
private:
    std::vector<std::vector<block*>> blocks;
    SDL_Renderer* rend;
    void moveBlock(int x, int y, direction d){
        int dir;
        bool canMove;
        do{
            if(d == left || d == right){
                if(d == left) dir = -1;
                else dir = 1;

                try{
                    bool blockIsNull;
                    bool isSameValue;
                    if(blocks.at(y).at(x + dir)){
                        blockIsNull = false;
                        isSameValue = blocks.at(y).at(x + dir)->getVal() == blocks.at(y).at(x)->getVal();
                    }
                    else{
                        blockIsNull = true;
                        isSameValue = false;
                    }
                    if(blockIsNull || isSameValue){
                        block* b = blocks[y][x];
                        if(isSameValue) if(blocks[y][x + dir]->getVal() == b->getVal()) b->setVal(b->getVal() * 2);
                        blocks[y][x] = NULL;
                        blocks[y][x + dir] = b;

                        x += dir;

                        try{
                            if(blocks.at(y).at(x + dir)){
                                canMove = !blocks.at(y).at(x + dir) || blocks.at(y).at(x + dir)->getVal() == blocks.at(y).at(x)->getVal();
                            }
                            else{
                                canMove = !blocks.at(y).at(x + dir);
                            }
                        }
                        catch(const std::out_of_range& e){
                            canMove = false;
                        }
                    }
                }
                catch(const std::out_of_range& e){
                   canMove = false;
                }
            }
            else if(d == up || d == down){
                if(d == up) dir = -1;
                else dir = 1;

                try{
                    bool blockIsNull;
                    bool isSameValue;
                    if(blocks.at(y + dir).at(x)){
                        blockIsNull = false;
                        isSameValue = blocks.at(y + dir).at(x)->getVal() == blocks.at(y).at(x)->getVal();
                    }
                    else{
                        blockIsNull = true;
                        isSameValue = false;
                    }
                    if(blockIsNull || isSameValue){
                        block* b = blocks[y][x];
                        if(isSameValue) if(blocks[y + dir][x]->getVal() == b->getVal()) b->setVal(b->getVal() * 2);
                        blocks[y][x] = NULL;
                        blocks[y + dir][x] = b;

                        y += dir;

                        try{
                            if(blocks.at(y).at(x + dir)){
                                canMove = !blocks.at(y + dir).at(x) || blocks.at(y+ dir).at(x )->getVal() == blocks.at(y).at(x)->getVal();
                            }
                            else{
                                canMove = !blocks.at(y + dir).at(x);
                            }
                        }
                        catch(const std::out_of_range& e){
                            canMove = false;
                        }
                    }
                }
                catch(const std::out_of_range& e){
                   canMove = false;
                }
            }
            else canMove = false;
        }while(canMove);
    }
};

方向.h

enum direction{
    left,
    right,
    up,
    down,
    none
};

矩形

#pragma once
#include "vec2.h"
#include <vector>

class rect{
public:
  rect(){
    min = vec2();
    max = vec2();
    w = h = 0;
  }
  rect(double x, double y, double width, double height){
    min = vec2(x, y);
    max = vec2(x + width, y + height);
    w = width;
    h = height;
  }
  void updatePos(vec2 pos){
    min = pos;
    max = pos + vec2(w, h);
  }
  double getWidth(){
    return w;
  }
  double getHeight(){
    return h;
  }
  vec2 getPos(){
    return min;
  }
  rect operator+(vec2 t){
    rect temp = *this;
    temp.updatePos(temp.min + t);
    return temp;
  }
  rect operator-(vec2 t){
    rect temp = *this;
    temp.updatePos(temp.min - t);
    return temp;
  }
private:
  vec2 min;
  vec2 max;
  double w;
  double h;
  friend bool rectVrect(rect r1, rect r2);
  friend bool rectVpt(rect r, vec2 pt);
  friend void drawRect(SDL_Renderer* renderer, rect r);
};

bool rectVpt(rect r, vec2 pt){
  return (pt.x < r.max.x && pt.x > r.min.x && pt.y < r.max.y && pt.y > r.min.y);
}

bool rectVrect(rect r1, rect r2){
  if(r1.max.x < r2.min.x || r1.min.x > r2.max.x) return false;
  if(r1.max.y < r2.min.y || r1.min.y > r2.max.y) return false;
  return true;
}

void drawRect(SDL_Renderer* renderer, rect r){
  SDL_Rect rect = {(int)r.min.x, (int)r.min.y, (int)r.w, (int)r.h};
  SDL_RenderFillRect(renderer, &rect);
}

纹理.h

#pragma once
#include <SDL.h>
#include <SDL2/SDL_ttf.h>
#include <iostream>
#include <string>
#include "arial.h"

class text{
public:
  text(int fontSize, SDL_Renderer* rend){
    t = "";
    f = TTF_OpenFont("assets/arial.ttf", fontSize);
    renderer = rend;
    c =  {0, 0, 0};
    textre = NULL;
    w = h = 0;
    destRct.h = h;
    destRct.w = w;
  }
  text(std::string txt, int fontSize, SDL_Renderer* rend){
    t = txt;
    SDL_RWops* fontRW = SDL_RWFromConstMem(arial, 1036584);
    f = TTF_OpenFontRW(fontRW, 0, fontSize);
    renderer = rend;
    c =  {0, 0, 0};
    SDL_Surface* surf = TTF_RenderText_Solid(f, txt.c_str(), c);
    textre = SDL_CreateTextureFromSurface(renderer, surf);
    SDL_QueryTexture(textre, NULL, NULL, &w, &h);
    destRct.h = h;
    destRct.w = w;
    SDL_FreeSurface(surf);
  }
  void draw(int x, int y){
    destRct.x = x;
    destRct.y = y;
    if(textre) SDL_RenderCopyEx(renderer, textre, NULL, &destRct, 0, NULL, SDL_FLIP_NONE);
  }
  void clean(){
    t.clear();
    if(textre) SDL_DestroyTexture(textre);
    destRct.h = destRct.w = 0;
  }
  void updateText(std::string txt, int fontSize){
    TTF_CloseFont(f);
    SDL_RWops* fontRW = SDL_RWFromConstMem(arial, 1036584);
    f = TTF_OpenFontRW(fontRW, 0, fontSize);
    if(textre) SDL_DestroyTexture(textre);
    t = txt;
    SDL_Surface* surf = TTF_RenderText_Solid(f, txt.c_str(), c);
    textre = SDL_CreateTextureFromSurface(renderer, surf);
    SDL_QueryTexture(textre, NULL, NULL, &w, &h);
    destRct.h = h;
    destRct.w = w;
  }
  int getWidth(){ return w; }
  int getHeight(){ return h; }
  SDL_Renderer* getRenderer(){ return renderer; }
  ~text(){
    SDL_DestroyTexture(textre);
  }
private:
  std::string t;
  SDL_Renderer* renderer;
  SDL_Texture* textre;
  SDL_Color c;
  TTF_Font* f;
  SDL_Rect destRct;
  int w, h;
};

vec2.h

#pragma once
#include <SDL.h>

class vec2{
public:
    vec2(){
        x = 0;
        y = 0;
    }
    vec2(double X, double Y){
        x = X;
        y = Y;
    }
  SDL_Point getSDLpoint(){
    SDL_Point p;
    p.x = x;
    p.y = y;
    return p;
  }
    double x;
    double y;
    vec2 operator+(vec2 v){
        return vec2(x+v.x, y+v.y);
    }
    vec2 operator-(vec2 v){
        return vec2(x-v.x, y-v.y);
    }
    vec2 operator*(vec2 v){
        return vec2(x*v.x, y*v.y);
    }
    vec2 operator*(double v){
        return vec2(x*v, y*v);
    }
  vec2 operator/(vec2 v){
        return vec2(x/v.x, y/v.y);
    }
  vec2 operator/(double v){
        return vec2(x/v, y/v);
    }
    vec2 operator+=(vec2 v){
        x += v.x;
        y += v.y;
        return *this;
    }
    vec2 operator-=(vec2 v){
        x -= v.x;
        y -= v.y;
        return *this;
    }
    vec2 operator*=(vec2 v){
        x *= v.x;
        y *= v.y;
        return *this;
    }
    vec2 operator*=(double v){
        x *= v;
        y *= v;
        return *this;
    }
  vec2 operator/=(vec2 v){
        x /= v.x;
        y /= v.y;
        return *this;
    }
  vec2 operator/=(double v){
    x /= v;
    y /= v;
    return *this;
  }
  bool operator==(vec2 v){
      return (v.x == x && v.y == y);
  }
  bool operator!=(vec2 v){
      return (v.x != x || v.y != y);
  }
};

相关内容