1
Général / Probleme intersection / list.erase
« le: Mars 08, 2017, 04:25:46 pm »
Bonjour
Pour apprendre à utiliser la SFML, je suis entrain de réaliser un shoot em up trés simple mais j'ai un léger probleme.
Lorsque je touche le premier bloc ( je peux toucher les autres sans probleme ) , la fonction erase se déclenche et au lieu de supprimer le bloc, elle change les coordonnées x de tout mes blocs ce qui cause la fin de la partie.
Ce probleme n'arrive que lors du lancement de l'appli. Si je relance une partie sans fermer l'appli tout se passe correctement.
PS : je sais que le code est très salle et que ce n'est surement pas les bonnes techniques, ce sont juste des essais
Pour apprendre à utiliser la SFML, je suis entrain de réaliser un shoot em up trés simple mais j'ai un léger probleme.
Lorsque je touche le premier bloc ( je peux toucher les autres sans probleme ) , la fonction erase se déclenche et au lieu de supprimer le bloc, elle change les coordonnées x de tout mes blocs ce qui cause la fin de la partie.
Ce probleme n'arrive que lors du lancement de l'appli. Si je relance une partie sans fermer l'appli tout se passe correctement.
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include "iostream"
#include <list>
#include <time.h>
using namespace sf;
using namespace std;
const int width = 1600;
const int height = 900;
const int shipRad = 3;
const int shipSize = 30;
const int INTRO=1;
const int JEU=2;
const int FIN=3;
bool intersects (const RectangleShape & rect1,const RectangleShape & rect2)
{
FloatRect r1=rect1.getGlobalBounds();
FloatRect r2=rect2.getGlobalBounds();
return r1.intersects (r2);
}
int fRand(int fMin, int fMax)
{
int f = (int)rand();
f=f%fMax;
return f;
}
int main()
{
int gameState = INTRO;
int score;
char* scoreStr;
srand(time(NULL));
Clock clock;
Clock blocClock;
Clock moveClock;
Time time, blocTime, moveTime;
double speed;
VideoMode videoMode(width, height);
RenderWindow window(videoMode,"TOAST");
CircleShape ship(shipSize,shipRad);
ship.setPosition(300,200);
ship.setFillColor(Color::Blue);
ship.rotate(90);
list<RectangleShape> laser,bloc;
Font font;
font.loadFromFile("OutrunFutureBold.otf");
Text intro;
intro.setString("SPACE SHOOTER !!!\n PRESS ENTER TO PLAY");
intro.setFont(font);
intro.setPosition(width/15,height/4);
intro.setCharacterSize(100);
intro.setColor(Color::White);
Text fin;
fin.setFont(font);
fin.setPosition(width/4,height/4);
fin.setCharacterSize(100);
fin.setColor(Color::White);
Text scoreTxt;
scoreTxt.setFont(font);
scoreTxt.setPosition(10,10);
scoreTxt.setCharacterSize(30);
scoreTxt.setColor(Color::White);
while (window.isOpen())
{
window.clear(Color::Black);
if(gameState==INTRO)
{
window.draw(intro);
Event event;
while (window.pollEvent(event))
{
if ( (event.type == Event::Closed) ||
((event.type == Event::KeyPressed) && (event.key.code==Keyboard::Escape)) )
window.close();
if((event.type == Event::KeyPressed) && (event.key.code==Keyboard::Return))
{
laser.clear();
bloc.clear();
blocClock.restart();
score = 0;
gameState=JEU;
}
}
}
if(gameState==JEU){
Event event;
while (window.pollEvent(event))
{
if ( (event.type == Event::Closed) ||
((event.type == Event::KeyPressed) && (event.key.code==Keyboard::Escape)) )
{
window.close();
}
if((event.type == Event::KeyPressed) && (event.key.code==Keyboard::Space)){
time = clock.getElapsedTime();
if(time.asSeconds()>0.25){
clock.restart();
RectangleShape shoot;
shoot.setSize(Vector2f(50,2));
shoot.setFillColor(Color::Red);
shoot.setPosition(ship.getPosition().x,ship.getPosition().y+30);
laser.push_front (shoot);
}
}
}
moveTime = moveClock.getElapsedTime();
moveClock.restart();
speed = moveTime.asSeconds();
sprintf(scoreStr, "%d", score);
scoreTxt.setString(scoreStr);
window.draw(scoreTxt);
if(Keyboard::isKeyPressed(Keyboard::Up) && ship.getPosition().y>0)
{
ship.move(0,-500*speed);
}
if(Keyboard::isKeyPressed(Keyboard::Down) && ship.getPosition().y<height-(shipSize*2))
{
ship.move(0,500*speed);
}
if(Keyboard::isKeyPressed(Keyboard::Left) && ship.getPosition().x>shipSize*2)
{
ship.move(-500*speed,0);
}
if(Keyboard::isKeyPressed(Keyboard::Right) && ship.getPosition().x<width/4)
{
ship.move(500*speed,0);
}
blocTime = blocClock.getElapsedTime();
if(blocTime.asSeconds()>1)
{
blocClock.restart();
double y = fRand(0,height-50);
printf("%f\n",y);
RectangleShape b;
b.setSize(Vector2f(40,40));
b.setFillColor(Color::Green);
b.setPosition(width,y);
bloc.push_front (b);
}
window.draw(ship);
for (list<RectangleShape>::iterator it=laser.begin(); it!=laser.end(); ++it)
{
window.draw(*it);
}
for (list<RectangleShape>::iterator it=laser.begin(); it!=laser.end(); ++it)
{
it->move(800*speed,0);
}
for (list<RectangleShape>::iterator itBloc=bloc.begin(); itBloc!=bloc.end(); ++itBloc)
{
window.draw(*itBloc);
}
for (list<RectangleShape>::iterator it=bloc.begin(); it!=bloc.end(); ++it)
{
it->move(-350*speed,0);
if(it->getPosition().x<0 ){
gameState=FIN;
}
}
for (list<RectangleShape>::iterator it=laser.begin(); it!=laser.end(); ++it)
{
for (list<RectangleShape>::iterator itBloc=bloc.begin(); itBloc!=bloc.end(); ++itBloc)
{
if(intersects(*itBloc,*it))
{
it = laser.erase(it);
itBloc = bloc.erase(itBloc); //Ligne du probleme
score++;
}
}
}
}
if(gameState==FIN)
{
Event event;
while (window.pollEvent(event))
{
if ( (event.type == Event::Closed) ||
((event.type == Event::KeyPressed) && (event.key.code==Keyboard::Escape)) )
window.close();
if((event.type == Event::KeyPressed) && (event.key.code==Keyboard::Return))
{
blocClock.restart();
gameState=INTRO;
}
}
sprintf(scoreStr, "%d", score);
fin.setString("GAME OVER\nSCORE : " + string(scoreStr));
window.draw(fin);
}
window.display();
}
return EXIT_SUCCESS;
}
#include <SFML/Audio.hpp>
#include "iostream"
#include <list>
#include <time.h>
using namespace sf;
using namespace std;
const int width = 1600;
const int height = 900;
const int shipRad = 3;
const int shipSize = 30;
const int INTRO=1;
const int JEU=2;
const int FIN=3;
bool intersects (const RectangleShape & rect1,const RectangleShape & rect2)
{
FloatRect r1=rect1.getGlobalBounds();
FloatRect r2=rect2.getGlobalBounds();
return r1.intersects (r2);
}
int fRand(int fMin, int fMax)
{
int f = (int)rand();
f=f%fMax;
return f;
}
int main()
{
int gameState = INTRO;
int score;
char* scoreStr;
srand(time(NULL));
Clock clock;
Clock blocClock;
Clock moveClock;
Time time, blocTime, moveTime;
double speed;
VideoMode videoMode(width, height);
RenderWindow window(videoMode,"TOAST");
CircleShape ship(shipSize,shipRad);
ship.setPosition(300,200);
ship.setFillColor(Color::Blue);
ship.rotate(90);
list<RectangleShape> laser,bloc;
Font font;
font.loadFromFile("OutrunFutureBold.otf");
Text intro;
intro.setString("SPACE SHOOTER !!!\n PRESS ENTER TO PLAY");
intro.setFont(font);
intro.setPosition(width/15,height/4);
intro.setCharacterSize(100);
intro.setColor(Color::White);
Text fin;
fin.setFont(font);
fin.setPosition(width/4,height/4);
fin.setCharacterSize(100);
fin.setColor(Color::White);
Text scoreTxt;
scoreTxt.setFont(font);
scoreTxt.setPosition(10,10);
scoreTxt.setCharacterSize(30);
scoreTxt.setColor(Color::White);
while (window.isOpen())
{
window.clear(Color::Black);
if(gameState==INTRO)
{
window.draw(intro);
Event event;
while (window.pollEvent(event))
{
if ( (event.type == Event::Closed) ||
((event.type == Event::KeyPressed) && (event.key.code==Keyboard::Escape)) )
window.close();
if((event.type == Event::KeyPressed) && (event.key.code==Keyboard::Return))
{
laser.clear();
bloc.clear();
blocClock.restart();
score = 0;
gameState=JEU;
}
}
}
if(gameState==JEU){
Event event;
while (window.pollEvent(event))
{
if ( (event.type == Event::Closed) ||
((event.type == Event::KeyPressed) && (event.key.code==Keyboard::Escape)) )
{
window.close();
}
if((event.type == Event::KeyPressed) && (event.key.code==Keyboard::Space)){
time = clock.getElapsedTime();
if(time.asSeconds()>0.25){
clock.restart();
RectangleShape shoot;
shoot.setSize(Vector2f(50,2));
shoot.setFillColor(Color::Red);
shoot.setPosition(ship.getPosition().x,ship.getPosition().y+30);
laser.push_front (shoot);
}
}
}
moveTime = moveClock.getElapsedTime();
moveClock.restart();
speed = moveTime.asSeconds();
sprintf(scoreStr, "%d", score);
scoreTxt.setString(scoreStr);
window.draw(scoreTxt);
if(Keyboard::isKeyPressed(Keyboard::Up) && ship.getPosition().y>0)
{
ship.move(0,-500*speed);
}
if(Keyboard::isKeyPressed(Keyboard::Down) && ship.getPosition().y<height-(shipSize*2))
{
ship.move(0,500*speed);
}
if(Keyboard::isKeyPressed(Keyboard::Left) && ship.getPosition().x>shipSize*2)
{
ship.move(-500*speed,0);
}
if(Keyboard::isKeyPressed(Keyboard::Right) && ship.getPosition().x<width/4)
{
ship.move(500*speed,0);
}
blocTime = blocClock.getElapsedTime();
if(blocTime.asSeconds()>1)
{
blocClock.restart();
double y = fRand(0,height-50);
printf("%f\n",y);
RectangleShape b;
b.setSize(Vector2f(40,40));
b.setFillColor(Color::Green);
b.setPosition(width,y);
bloc.push_front (b);
}
window.draw(ship);
for (list<RectangleShape>::iterator it=laser.begin(); it!=laser.end(); ++it)
{
window.draw(*it);
}
for (list<RectangleShape>::iterator it=laser.begin(); it!=laser.end(); ++it)
{
it->move(800*speed,0);
}
for (list<RectangleShape>::iterator itBloc=bloc.begin(); itBloc!=bloc.end(); ++itBloc)
{
window.draw(*itBloc);
}
for (list<RectangleShape>::iterator it=bloc.begin(); it!=bloc.end(); ++it)
{
it->move(-350*speed,0);
if(it->getPosition().x<0 ){
gameState=FIN;
}
}
for (list<RectangleShape>::iterator it=laser.begin(); it!=laser.end(); ++it)
{
for (list<RectangleShape>::iterator itBloc=bloc.begin(); itBloc!=bloc.end(); ++itBloc)
{
if(intersects(*itBloc,*it))
{
it = laser.erase(it);
itBloc = bloc.erase(itBloc); //Ligne du probleme
score++;
}
}
}
}
if(gameState==FIN)
{
Event event;
while (window.pollEvent(event))
{
if ( (event.type == Event::Closed) ||
((event.type == Event::KeyPressed) && (event.key.code==Keyboard::Escape)) )
window.close();
if((event.type == Event::KeyPressed) && (event.key.code==Keyboard::Return))
{
blocClock.restart();
gameState=INTRO;
}
}
sprintf(scoreStr, "%d", score);
fin.setString("GAME OVER\nSCORE : " + string(scoreStr));
window.draw(fin);
}
window.display();
}
return EXIT_SUCCESS;
}
PS : je sais que le code est très salle et que ce n'est surement pas les bonnes techniques, ce sont juste des essais