Bonsoir à tous ! J'ai un petit problème sur un programme que je développe. Je programme un casse_brique. La collision avec le mur, avec les briques et l'affichage sont implémentés. J'ai essayé de gérer la disparition des brick quand elles sont touchées mais il y a quelque chose que je ne comprends pas.
J'ai fais cette fonction qui gère l'update de la balle/des bricks :
le dt_collision, l'id de la brick collisionnée et le type de collision sont donnés par cette fonction :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 void Level::updateBalls(int _dt_min, int _dt_next_collision, TypeOfCollision _typeOfCollision) { for (auto ball : balls_) { if (_dt_min < _dt_next_collision) { Vector position = ball->getPosition(); Vector velocity = ball->getVelocity(); double radius = ball->getRadius(); double px = position.getX(); double py = position.getY(); double vx = velocity.getX(); double vy = velocity.getY(); ball->positionChange(_dt_min); } else { ball->positionChange(_dt_next_collision); if (_typeOfCollision == VERT) ball->velocityPostBrick(true); else ball->velocityPostBrick(false); } } } void Level::updateBricks(int _brickId) { if (_brickId >= 0) { std::cout << "COLLISION"; bricks_.erase(bricks_.begin() + _brickId); } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 std::tuple<int, TypeOfCollision, int> Level::dtCollision() { int dt_min= 10000; TypeOfCollision typeOfCollision_next = VERT; int index_brick_collision = -1; int dt = 10000; TypeOfCollision typeOfCollision = VERT; int index_brick = 0; for (auto ball : balls_) { for (auto brick : bricks_) { this->dtballBrickColllision(*ball, *brick, dt, typeOfCollision); if (dt < dt_min) { dt_min = dt; typeOfCollision_next = typeOfCollision; index_brick_collision = index_brick; } index_brick++; } this->dtballWallColllision(*ball, wall_, dt, typeOfCollision); if (dt < dt_min) { dt_min = dt; typeOfCollision_next = typeOfCollision; index_brick_collision = -1; } } // std::cout << index_brick_collision; auto p = std::make_tuple(dt_min, typeOfCollision_next, index_brick_collision); return p; }
Et la classe level qui gère le set de balles, bricks, le mur est utilisé comme ça dans le main :
si ça peut être utile la fonction loadLevel :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 int main() { int WIDTH_WINDOW = 1600; int HEIGHT_WINDOW = 800; std::vector<Brick*> bricks; Ball ball1 = Ball(0.99, 5, 4, 900, 700, 0.01, 0.03); Brick brick1 = Brick(100, 20, 1, 810, 710); Brick brick2 = Brick(20, 200, 1, 400, 310); Brick brick3 = Brick(20, 150, 1, 220, 110); Brick brick4 = Brick(200, 110, 1, 560, 220); bricks.push_back(&brick1); bricks.push_back(&brick2); bricks.push_back(&brick3); bricks.push_back(&brick4); Level level(1, &ball1, bricks, WIDTH_WINDOW, HEIGHT_WINDOW); level.loadLevel(&window); while (window.isOpen()) { window.clear(sf::Color::Black); auto tuple = level.dtCollision(); auto dt_coll = std::get<0>(tuple); auto typeOfColl = std::get<1>(tuple); auto brickColl = std::get<2>(tuple); std::cout << level.getBricks().size() << "\n"; level.updateBalls(10, dt_coll, typeOfColl); level.loadLevel(&window); window.display(); level.updateBricks(brickColl); level.loadLevel(&window); // level.updateLevel(10, dt_coll, typeOfColl, brickColl); window.display(); sf::Event event; while (window.pollEvent(event)) { if (event.type == sf::Event::Closed) window.close(); } } return 0; }
Et la classe Level :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 void Level::loadLevel(sf::RenderWindow *window) { for (int i = 0; i < nbOfBricks_; i++) { sf::RectangleShape brick1s(sf::Vector2f(bricks_[i]->getWidth(), bricks_[i]->getHeight())); brick1s.setFillColor(sf::Color::Blue); brick1s.setOrigin(bricks_[i]->getWidth()/2, bricks_[i]->getHeight()/2); brick1s.setPosition(bricks_[i]->getPosition().getX(), bricks_[i]->getPosition().getY()); window->draw(brick1s); } for (int i = 0; i < nbOfBalls_; i++) { sf::CircleShape ball1s(balls_[i]->getRadius()); ball1s.setFillColor(sf::Color::Red); ball1s.setOrigin(balls_[i]->getRadius(), balls_[i]->getRadius()); ball1s.setPosition(balls_[i]->getPosition().getX(), balls_[i]->getPosition().getY()); window->draw(ball1s); } }
[/CODE]
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 enum TypeOfCollision {VERT, HORR, BALL, PADDLE}; class Level { private: int levelNumber_; int nbOfBricks_; int nbOfBalls_; Wall wall_; std::vector<Ball*> balls_; std::vector<Brick*> bricks_; public: Level(); Level(int _levelNumber, Ball* _ball, std::vector<Brick*> _bricks, int WIDTH_WINDOW, int HEIGHT_WINDOW); Level(int _levelNumber, std::vector<Ball*> _balls, std::vector<Brick*> _bricks, int WIDTH_WINDOW, int HEIGHT_WINDOW); int getLevelNumber() const {return levelNumber_;}; int getNbOfBricks() const {return nbOfBricks_;}; int getNbOfBalls() const {return nbOfBalls_;}; std::vector<Ball*> getBalls() const {return balls_;}; std::vector<Brick*> getBricks() const {return bricks_;}; void loadLevel(sf::RenderWindow *window); std::tuple<int, TypeOfCollision, int> dtCollision(); void dtballWallColllision (const Ball& _ball, const Wall& _wall, int& _dt, TypeOfCollision& _typeOfColl); void dtballBrickColllision(const Ball& _ball, Brick& _brick, int& _dt, TypeOfCollision& _typeOfColl); void updateBalls(int _dt_min, int _dt_next_collision, TypeOfCollision _typeOfCollision); void updateLevel(int _dt_min, int _dt_next_collision, TypeOfCollision _typeOfCollision, int _brickId); void updateBricks(int _brickId); }; std::ostream& operator<<(std::ostream &_flow, const Level& _level);
L'affichage de tous les objets est correct, la balle bouge correctement donne des bonnes collisions avec le mur et les bricks si je n'essaye pas de les faire disparaître avec updateBricks(), Mais avec cette fonction certaines bricks ne disparaissent pas ou bien plus tard et il n'y a plus de collision balle-brick. Si vous avez des idées je suis preneur svpp ? Je pense quele problème doit sans être le timing entre SFML (l'affichage qui est update après une certaine durée) et le jeu en lui même qui utilise aussi des durées pour afficher les objets. Est ce que une solution serait d'utiliser sf::Time ? Si oui, savez vous comment modifier mon code pour inclure ces variables temporelles ? Ou est ce un autre problème ?
Partager