[英]SFML - program crashes when trying to draw sprite from vector
我正在編寫這個相對簡單的程序,當按下空格鍵時,可以從移動的角色發射小彈丸。
程序編譯無誤(在代碼塊中),並運行到按下空格鍵為止。 該程序沒有啟動彈丸,而是立即崩潰。
我認為我已經能夠將墜機事件隔離到將彈丸繪制到屏幕的那條線上(第83頁)。 我只是在前后的行上使用了cout語句,而第二條語句沒有顯示。
for (int ii = 0; ii < inMotion.size(); ii++)
{
window.draw(inMotion[ii].bulletSprite);
}
我認為解決此問題將需要我的所有代碼,因此我已發布了所有代碼。
#include <iostream>
#include <SFML/Graphics.hpp>
#include <string.h>
#include <math.h>
#include <vector>
using namespace std;
class Projectile
{
public:
Projectile(int, string);
void moveBullet();
sf::Sprite bulletSprite;
private:
sf::Texture bulletTexture;
int speed;
string bulletTextureString;
};
Projectile::Projectile(int s, string t)
{
speed = s;
bulletTextureString = t;
if(!bulletTexture.loadFromFile((bulletTextureString).c_str()))
{
cout << "error";
}
bulletSprite.setTexture(bulletTexture);
}
void Projectile::moveBullet()
{
bulletSprite.move(speed, 0);
}
class thePlayer
{
public:
void Fire(sf::Time);
void Walk();
void Draw(sf::RenderWindow&);
void Create(string);
sf::Time lastShot;
private:
vector<Projectile> inMotion;
sf::Texture playerTexture;
sf::Sprite playerSprite;
string playerTextureString;
int moveSpeed = 5;
};
void thePlayer::Create(string s)
{
playerTextureString = s;
if(!playerTexture.loadFromFile((playerTextureString).c_str()))
{
cout << "error";
}
playerSprite.setTexture(playerTexture);
}
void thePlayer::Fire(sf::Time time)
{
sf::Time shotDelay = sf::milliseconds(100);
if(time - lastShot >= shotDelay)
{
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
{
Projectile bullet(15, "fireball.png");
bullet.bulletSprite.setPosition(playerSprite.getPosition());
inMotion.push_back(bullet);
}
}
for(int ii = 0; ii < inMotion.size(); ii++)
{
inMotion[ii].moveBullet();
}
}
void thePlayer::Draw(sf::RenderWindow& window)
{
for (int ii = 0; ii < inMotion.size(); ii++)
{
window.draw(inMotion[ii].bulletSprite);
}
window.draw(playerSprite);
}
void thePlayer::Walk()//awsd standart movement
{
int x = 0;
int y = 0;
if(sf::Keyboard::isKeyPressed(sf::Keyboard::A))
{
x-= moveSpeed;
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::D))
{
x+= moveSpeed;
}
if(sf::Keyboard::isKeyPressed(sf::Keyboard::W))
{
y-= moveSpeed;
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::S))
{
y+= moveSpeed;
}
playerSprite.move(x, y);
}
class Game
{
public:
void Update(sf::RenderWindow&, sf::Time);
void Start(sf::Time);
sf::Clock clock;
thePlayer player;
private:
};
void Game::Start(sf::Time time)
{
player.Create("block.png");
player.lastShot = time;
}
void Game::Update(sf::RenderWindow& window, sf::Time time)
{
player.Fire(time);
player.Walk();
player.Draw(window);
}
int main()
{
sf::RenderWindow window(sf::VideoMode(1000, 1000), "Menu");
window.setFramerateLimit(60);
Game theGame;
sf::Clock clock;
sf::Time startTime = clock.restart();
theGame.Start(startTime);
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
}
window.clear(sf::Color::White);
sf::Time elapsed = clock.getElapsedTime();
theGame.Update(window, elapsed);
window.display();
}
return 0;
}
非常感謝幫忙。
編輯:我嘗試使用調試器,但什么都找不到。 鏈接到一篇有關代碼塊調試的好文章的鏈接將非常有用。
我自己解決了。 我發現必須通過指針引用Bullet類,並確保紋理也是公共的。 我也錯誤地使用了構造函數,並且擺脫了這些構造函數。
我的大概解決方案是...
void thePlayer::Fire(sf::Time time)
{
sf::Time shotDelay = sf::milliseconds(100);
if(time - lastShot >= shotDelay)
{
if(sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
{
Projectile *bullet = new Bullet;
bullet->bulletSprite.setPosition(playerSprite.getPosition());
inMotion.push_back(bullet);
}
}
for(int ii = 0; ii < inMotion.size(); ii++)
{
inMotion[ii]->moveBullet();
}
還必須在類中更改向量聲明
//...
vector<Bullet*> Bullets;
//...
再次感謝那些試圖回答的人。
好吧,您編寫的游戲代碼非常錯誤!
我的建議:
您應該創建一個球員和一個子彈班,
每個類分別作為渲染方法和更新方法-更新方法具有dt(到最后一幀為止的經過時間)參數,
播放器類具有“移動”和“觸發”方法,
在游戲循環中,您首先要讀取輸入(並在需要時調用move或fire方法),更新所有對象(玩家和項目符號的位置)並繪制所有內容,
move方法應使玩家具有速度,
射擊方法應以速度制造子彈,
更新方法應計算新位置(具有速度和dt),
玩家和子彈可能來自基礎游戲元素類(女巫計算位置,碰撞等)。
您必須重置時鍾:
sf::Time elapsed = clock.restart();
而且,您應該只加載一次射彈的紋理,並在Projectile類的所有實例中使用它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.