首页 > 解决方案 > Exe打开一个窗口但窗口卡住然后崩溃

问题描述

我有一个打开窗口但窗口无法显示的 exe。相反,它会卡住然后崩溃。

似乎没有任何问题,但它不起作用。我还在线程上使用了分离并使用互斥锁保护了执行。错误是否在 for 循环之一上?

我可以肯定的是,它不会达到window.display()一次。

执行也到达sf::RenderWindow window( ...语句。

#include "pch.h"

class enemy { //basic enemy entity with constructor that gives it a radom position on the view
public:
    sf::CircleShape body; int ID;// basic values

    void isHit(sf::Vector2f mp);// checks if the enemy has got hit and if so destructs when the class

    enemy(); // this class won't have enoughter consturction
    ~enemy();// arranges enemyList

};

bool amno = 1; int enemyCount = 0; enemy** enemyList; void newEnemy();// allocates new enemy

std::mutex enemyCountMutex; void spawnEnemy();// simple function for one simple enemy spawn thread

int main()
{

    sf::CircleShape player(9.f, 8); std::chrono::high_resolution_clock gameClock;
    sf::RenderWindow window(sf::VideoMode(800, 600), "BasicShooterGame_V_0_0_6", sf::Style::Close | sf::Style::Titlebar);// game window

我的意思是这个大括号之间的错误必须在这里之后

    player.setOutlineThickness(5.f); player.setOutlineColor(sf::Color(200, 160, 0)); player.setFillColor(sf::Color(0, 0, 0, 0)); player.setOrigin(9.f, 9.f);
    std::thread enemySpawnThread(spawnEnemy); enemySpawnThread.detach();
    sf::Event event; while (window.isOpen())// allocating event handling class and making the gameLoop

    {

        while (window.pollEvent(event))// event loop
        {

            if (event.type == sf::Event::Closed) { return 0; }

        }

        player.setPosition(static_cast<sf::Vector2f>(sf::Mouse::getPosition(window)));// setting the aim position

        enemyCountMutex.lock();

        if (sf::Mouse::isButtonPressed(sf::Mouse::Left)) {// checking if succesfully button pressed
            srand((unsigned long)gameClock.now);
            if (amno) {
                for (int l = 0; l < enemyCount; l++) {
                    enemyList[l]->isHit(static_cast<sf::Vector2f>(sf::Mouse::getPosition()));
                }
            }
            amno = false;
        }
        else { amno = true; }// for disabling holding ability

        window.clear(sf::Color(160, 160, 160));//  clearing window
        if (enemyCount) {
            for (int l = 0; l < enemyCount; l++) {//   loop for drawing enemies
                window.draw(enemyList[l]->body);
            } window.draw(player); window.display();// draving player at last makes it shown on top displaying
        }

        enemyCountMutex.unlock();
    }

    std::cin >> amno;
}

enemy::enemy() {// just initializes enemy values   // basicly making the bodi's appearance
    body.setRadius(30.f); body.setFillColor(sf::Color(255, 96, 0)); body.setOrigin(30.f, 30.f); body.setPointCount(50); ID = enemyCount;
    ID = enemyCount; enemyCount++;// requared for handling the enemyList
    body.setPosition(static_cast<float>(rand()), static_cast<float>(rand()));
}

void enemy::isHit(sf::Vector2f mp) {//           enemy is a circle that way calculation is complicated
    sf::Vector2f cp = mp - body.getPosition();// calculating mouse's position referenced to enemi's position
    if (900 > cp.x * cp.x + cp.y * cp.y) {//     basic cordination system circle formula
        delete this; //                          this will call the destructor and the destructor will be arranging the list
    }//                                          I am not adding anythink more than that on this version
}

enemy::~enemy() {//                               enemyList is just a pointer list so there is nothing hard
    for (int l = ID; l < enemyCount - 1; l++) {// just filling the empty space with next one until the last one
        enemyList[l] = enemyList[l + 1];//        basic moving
    }enemyCount--;//                              lastly decreasing enemy existing enemy count
}

void newEnemy() {// steps of allocating a new enemy :       1 allocate a bigger pointer array 
    enemyCountMutex.lock();
    enemyCount++; enemy** ram = new enemy * [enemyCount];// 2 make the array contains the older array
    for (int l = 0; l < enemyCount - 1; l++) {//            \ while doing it setting other pointers to null is important
        ram[l] = enemyList[l]; enemyList[l] = NULL;//       3 finally allocate new enemy and delete the older unnecessary array
    } ram[enemyCount] = new enemy; delete[] enemyList;//    4 and at last just set the ID and use new array
    ram[enemyCount]->ID = enemyCount - 1; enemyList = ram; enemyCountMutex.unlock();
}

void spawnEnemy() {//                                  just calls newEnemy function
    float mult = 0.99f, ampl = 10.f;//  basicly for sppeding up enemy spawn
    while (true) {
        newEnemy();//                                                   spawning new enemy
        sf::sleep(sf::seconds(ampl));// waiting spawn time
        ampl *= mult;//                                                 speeding up
    }
}

标签: c++windowexesfml

解决方案


[off-topic] do you pay per line used? Why do you place multiple statements on the same line?

In newEnemy() you allocate an array:

enemy** ram = new enemy *[enemyCount];

and a couple of lines down you write out-of-bounds:

ram[enemyCount] = new enemy;

Your code ran for awhile, then threw an exception.

After fixing that one, still getting an exception. Looks like you increment enemyCount one too many times: in newEnemy() and in enemy::enemy().

Removing enemyCount++; from enemy::enemy() fixed the access violation exception. I can see the game, not sure what else is wrong :)

UPDATE:

Found two more issues: Enemies were created off-screen; fixed with

body.setPosition(static_cast<float>(rand()%800), static_cast<float>(rand()%600));

You are mixing screen coordinates returned from sf::Mouse::getPosition() with you game coordinates.

Also, don't srand() in a middle of the game, one time is enough. It won't get "more random" :)


推荐阅读