I'm trying to make a ship shoot every time the space key is press but the thing is that the pressing of the key is detect randomly.
The game class is the one that manage the differents screens of the game and the PlayScene class is the one that manage the behavior of the different entities. the problem is in the ProcessEvent() function.
here's the code:
Game.h
/***
* Clase para manejar un bucle de juego con distintas escenas
*/
class Game {
public:
/// comenzar el bucle de juego
void run();
/// cambiar la escena actual por otra
void switchScene(BaseScene *scene);
/// obtener la instancia de juego (singleton)
static Game &getInstance();
/// crear un juego especificando el modo de video y la escena inicial
static Game &create(const sf::VideoMode &videoMode, BaseScene *scene, const string &name = "");
private:
sf::RenderWindow window;
BaseScene *currentScene, *nextScene;
sf::Clock clock;
void processEvents();
void update();
void draw();
static Game *instance;
Game();
};
#endif
Game.cpp
Game *Game::instance = nullptr;
Game::Game(){}
Game &Game::create(const sf::VideoMode &videoMode, BaseScene *scene, const string &name){
if(instance){
cerr<<"ERROR: can't call create(), game already running."<<endl;
}else{
Game & g = getInstance();
g.window.create(videoMode, name, sf::Style::Close);
g.nextScene = nullptr;
g.currentScene = scene;
g.window.setFramerateLimit(60);
g.clock.restart();
}
return getInstance();
}
Game &Game::getInstance(){
if(!instance){
instance = new Game();
}
return *instance;
}
void Game::run(){
while(window.isOpen() && currentScene != nullptr) {
sf::Event e;
while(window.pollEvent(e)){
if(e.type == sf::Event::Closed){
window.close();
}
}
update();
processEvents();
draw();
if(nextScene != nullptr){
delete currentScene;
currentScene = nextScene;
nextScene = nullptr;
}
}
}
void Game::update(){
currentScene->update(clock.getElapsedTime().asSeconds());
clock.restart();
}
void Game::processEvents(){
currentScene->processEvent(window);
}
void Game::draw(){
window.clear(sf::Color(0,0,0,255));
currentScene->draw(window);
window.display();
}
void Game::switchScene(BaseScene *scene){
nextScene = scene;
}
BaseScene.h
class BaseScene {
public:
/// constructor
BaseScene();
/// función que será invocada para actualizar la escena
virtual void update(float elapsed);
virtual void processEvent(sf::RenderWindow &w);
/// función que será invocada para dibujar la escena
virtual void draw(sf::RenderWindow &w);
/// agrega un nuevo actor a la escena
void add(Entity *e);
/// eliminar un actor de la escena
void remove(Entity *e);
private:
vector<Entity *> entities;
vector<Entity *> to_delete;
};
#endif
BaseScene
BaseScene::BaseScene() {
}
void BaseScene::update(float elapsed) {
for(auto e: entities){
e->update(elapsed);
}
// elimina actores
for(auto d: to_delete){
auto it = find(entities.begin(), entities.end(), d);
if(it != entities.end()){
entities.erase(it);
}
}
to_delete.clear();
}
void BaseScene::processEvent(sf::RenderWindow &w){
}
void BaseScene::draw(sf::RenderWindow &w){
for(auto e: entities){
e->draw(w);
}
}
void BaseScene::add(Entity *e){
entities.push_back(e);
}
void BaseScene::remove(Entity *e){
to_delete.push_back(e);
}
PlayScene.h
class PlayScene : public BaseScene {
private:
ScrollingBackground background;
Player player;
std::vector<Enemy> enemies;
std::vector<Bullet> bullets;
public:
PlayScene();
void update (float elapsed);
void processEvent(sf::RenderWindow &w);
void draw (sf::RenderWindow & w);
};
PlayScene.cpp
PlayScene::PlayScene() {
for (int i=0; i<5; i++){
Enemy *enemy = new Enemy();
enemies.push_back(*enemy);
}
}
void PlayScene::processEvent(sf::RenderWindow &w){
sf::Event event;
while(w.pollEvent(event)){
if (event.type == sf::Event::KeyPressed){
if (event.key.code == sf::Keyboard::Space){
Bullet *bullet = new Bullet(player.getPosition().x, player.getPosition().y);
bullet->setRotation(-90);
bullet->setSpeed();
bullets.push_back(*bullet);
}
}
}
}
void PlayScene::update (float elapsed) {
BaseScene::update(elapsed);
background.update(elapsed);
player.update(elapsed);
for (size_t i=0; i<enemies.size(); i++){
enemies[i].update(elapsed);
if (enemies[i].fireEvent(elapsed)){
Bullet *bullet = new Bullet(enemies[i].getPosition().x-25, enemies[i].getPosition().y-34);
bullets.push_back(*bullet);
}
}
for (size_t i=0; i<bullets.size(); i++){
bullets[i].update(elapsed);
if (bullets[i].getPosition().y >480+5){
bullets.erase(bullets.begin() + i);
}
if (bullets[i].getBounds().intersects(player.getBounds())){
player.getHit();
bullets.erase(bullets.begin()+i);
}
}
}
void PlayScene::draw (sf::RenderWindow & w) {
BaseScene::draw(w);
background.draw(w);
player.draw(w);
for (size_t i=0; i<bullets.size(); i++){
bullets[i].draw(w);
}
for (size_t i=0; i<enemies.size(); i++){
enemies[i].draw(w);
}
}