From af7e23ab119eba7c0579796abd288c027edabfa9 Mon Sep 17 00:00:00 2001 From: Paul Oliver Date: Thu, 29 Feb 2024 19:20:22 +0100 Subject: Initial commit --- src/Stage.cpp | 192 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 src/Stage.cpp (limited to 'src/Stage.cpp') diff --git a/src/Stage.cpp b/src/Stage.cpp new file mode 100644 index 0000000..b9fa67a --- /dev/null +++ b/src/Stage.cpp @@ -0,0 +1,192 @@ +#include + +using namespace sf; +using namespace std; + +int +Stage::load(const std::string& fileName) +{ + ifstream stageFile(fileName); + + if (!stageFile) { + return EXIT_FAILURE; + } + + auto until = numeric_limits::max(); + + while (!stageFile.eof()) { + stageFile.ignore(until, '<'); + + string command; + getline(stageFile, command, '>'); + + if (command == "WALL") { + _walls.emplace_back(LinesStrip); + hn::Vector vertices; + + stageFile.ignore(until, '<'); + + while (stageFile.peek() != '/') { + Vector2f vtxPos; + + stageFile >> vtxPos.x; + stageFile.ignore(until, ','); + stageFile >> vtxPos.y; + stageFile.ignore(until, '<'); + + _walls.back().append({ vtxPos, WALL_COLOR }); + vertices.emplace_back(vtxPos.x, vtxPos.y); + } + + b2ChainShape shape; + shape.CreateChain(vertices.data(), vertices.size()); + + b2BodyDef bodyDef; + _wallBodies.emplace_back(_world.CreateBody(&bodyDef)); + _wallBodies.back()->CreateFixture(&shape, 0.0f); + } else if (command == "FACTORY") { + Vector2f factPos; + double factRot = 0.0; + + stageFile.ignore(until, '<'); + stageFile >> factPos.x; + stageFile.ignore(until, ','); + stageFile >> factPos.y; + stageFile.ignore(until, ','); + stageFile >> factRot; + stageFile.ignore(until, '<'); + + _factory.setPosition(factPos); + _factory.setRotation(factRot); + _factory.setOrigin(AGENT_RAD + 2, AGENT_RAD + 2); + _factory.setFillColor(Color::Black); + _factory.setOutlineColor(FACTORY_COLOR); + _factory.setOutlineThickness(2.0f); + } else if (command == "CHECKPOINT") { + stageFile.ignore(until, '<'); + + while (stageFile.peek() != '/') { + _checkPoints.emplace_back(); + + Vector2f vtx1Pos; + Vector2f vtx2Pos; + b2Vec2 shVx[2]; + + stageFile >> vtx1Pos.x; + shVx[0].x = vtx1Pos.x; + stageFile.ignore(until, ','); + stageFile >> vtx1Pos.y; + shVx[0].y = vtx1Pos.y; + stageFile.ignore(until, ','); + stageFile >> vtx2Pos.x; + shVx[1].x = vtx2Pos.x; + stageFile.ignore(until, ','); + stageFile >> vtx2Pos.y; + shVx[1].y = vtx2Pos.y; + stageFile.ignore(until, ','); + stageFile >> _checkPoints.back()._value; + stageFile.ignore(until, '<'); + + _checkPoints.back()._line.append({ vtx1Pos, CHECKPNT_COLOR }); + _checkPoints.back()._line.append({ vtx2Pos, CHECKPNT_COLOR }); + + _checkPoints.front().calculateSegment(_checkPoints.back()); + + b2ChainShape cpShape; + cpShape.CreateChain(shVx, 2); + + b2FixtureDef cpFixture; + cpFixture.shape = &cpShape; + cpFixture.isSensor = true; + + b2BodyDef cpDef; + _checkPoints.back()._body = _world.CreateBody(&cpDef); + _checkPoints.back()._body->CreateFixture(&cpFixture); + + if (_checkPoints.size() > 1) { + auto& prev = _checkPoints[_checkPoints.size() - 2]; + + _checkPoints.back().calculateSegment(prev); + } + } + + for (auto & i : _checkPoints) { + i._body->GetFixtureList()->SetUserData(&i); + } + } else if (command == "TRAP") { + stageFile.ignore(until, '<'); + + while (stageFile.peek() != '/') { + sf::Vector2f v1; + sf::Vector2f v2; + + stageFile >> v1.x; + stageFile.ignore(until, ','); + stageFile >> v1.y; + stageFile.ignore(until, ','); + stageFile >> v2.x; + stageFile.ignore(until, ','); + stageFile >> v2.y; + stageFile.ignore(until, '<'); + + _trapRects.emplace_back(sf::Vector2f(v2.x - v1.x, v2.y - v1.y)); + _trapRects.back().setPosition(v1); + _trapRects.back().setFillColor({ 128, 32, 32, 128 }); + + _traps.emplace_back(); + _traps.back().lowerBound.Set(v1.x, v1.y); + _traps.back().upperBound.Set(v2.x, v2.y); + } + } + } + + _world.SetContactListener(&_listener); + _listener._stage = this; + + return EXIT_SUCCESS; +} + +void +Stage::update() +{ + _world.Step(_TIME_STEP, _VEL_ITERS, _POS_ITERS); +} + +void +Stage::drawOn(RenderWindow& surface) const +{ + for (auto& i : _trapRects) { + surface.draw(i); + } + + for (auto& i : _walls) { + surface.draw(i); + } + + surface.draw(_factory); + + for (auto& i : _checkPoints) { + surface.draw(i._line); + } +} + +void +Stage::CheckPoint::calculateSegment(const CheckPoint& prev) +{ + float32 a0X = prev._line[0].position.x; + float32 a0Y = prev._line[0].position.y; + float32 a1X = prev._line[1].position.x; + float32 a1Y = prev._line[1].position.y; + + float32 b0X = _line[0].position.x; + float32 b0Y = _line[0].position.y; + float32 b1X = _line[1].position.x; + float32 b1Y = _line[1].position.y; + + float32 dA0B0 = dist( { a0X, a0Y }, { b0X, b0Y }); + float32 dA0B1 = dist( { a0X, a0Y }, { b1X, b1Y }); + float32 dA1B0 = dist( { a1X, a1Y }, { b0X, b0Y }); + float32 dA1B1 = dist( { a1X, a1Y }, { b1X, b1Y }); + + _segment = min(min(dA0B0, dA0B1), min(dA1B0, dA1B1)); +} -- cgit v1.2.1