c++ - 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
}
}
解决方案
[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" :)
推荐阅读
- printing - 打印预览中CKeditor中缺少背景颜色
- pandas - 熊猫子图上的多个图
- html - 如何修复图像下推文本?
- mysql - MYSQL 从同一个表中选择并连接多个 where AND 子句
- javascript - 十进制-二进制 (JavaScript) 项目
- python - Python网页抓取多个页面只有一个静态链接
- java - JAVA中的MySQL表名注入
- python - 两个通配符之间的python正则表达式匹配
- html - 第三方托管网站图片未在 IE11 上显示且行为随机
- asp.net-mvc - 将对象的持久集合添加到 .NET Core 中的另一个对象