replay
This commit is contained in:
@@ -98,8 +98,12 @@ namespace Game::AGame {
|
|||||||
mTransform.y -= mTex->getHeight() * mTransform.adjustedScaleY() / 2.f;
|
mTransform.y -= mTex->getHeight() * mTransform.adjustedScaleY() / 2.f;
|
||||||
|
|
||||||
LOG("W: " << mW << " H: " << mH);
|
LOG("W: " << mW << " H: " << mH);
|
||||||
|
|
||||||
|
// Only spawn level entities during normal gameplay, not during replay
|
||||||
|
if (GameManager::getCurrentGameState() != GameStateEnum::REPLAY) {
|
||||||
spawnLevel(1);
|
spawnLevel(1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Background::render(Game::Renderer::Renderer* renderer, Game::Renderer::RendererConfig config) {
|
void Background::render(Game::Renderer::Renderer* renderer, Game::Renderer::RendererConfig config) {
|
||||||
if (!renderer || !mTex || !mSeaTex) {
|
if (!renderer || !mTex || !mSeaTex) {
|
||||||
|
|||||||
@@ -37,10 +37,10 @@ namespace Game {
|
|||||||
// Handle REPLAY state
|
// Handle REPLAY state
|
||||||
if (mCurrentGameState == GameStateEnum::REPLAY) {
|
if (mCurrentGameState == GameStateEnum::REPLAY) {
|
||||||
if (!playReplayFrame()) {
|
if (!playReplayFrame()) {
|
||||||
// No more frames - end replay
|
// No more frames - end replay and pause
|
||||||
stopReplayMode();
|
stopReplayMode();
|
||||||
mCurrentGameState = GameStateEnum::STOPPED;
|
mCurrentGameState = GameStateEnum::PAUSED;
|
||||||
LOG("Replay finished");
|
LOG("Replay finished - pausing");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto entities = State::GameState::getInstance().getEntitiesSnapshot();
|
auto entities = State::GameState::getInstance().getEntitiesSnapshot();
|
||||||
@@ -104,7 +104,7 @@ namespace Game {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool GameManager::initReplayMode() {
|
bool GameManager::initReplayMode() {
|
||||||
// Read and parse replay.txt
|
// Read and parse replay.txt (supports both 5-column legacy and 6-column new format)
|
||||||
std::ifstream replayFile("replay.txt");
|
std::ifstream replayFile("replay.txt");
|
||||||
if (!replayFile.is_open()) {
|
if (!replayFile.is_open()) {
|
||||||
WARN("Failed to open replay.txt for reading");
|
WARN("Failed to open replay.txt for reading");
|
||||||
@@ -120,15 +120,24 @@ namespace Game {
|
|||||||
|
|
||||||
std::istringstream iss(line);
|
std::istringstream iss(line);
|
||||||
ReplayFrame frame;
|
ReplayFrame frame;
|
||||||
int isShip;
|
int isShip = 0;
|
||||||
|
|
||||||
|
// Try to parse 6 columns first (new format with form state)
|
||||||
if (iss >> frame.x >> frame.y >> frame.rotation >> frame.scaleX >> frame.scaleY >> isShip) {
|
if (iss >> frame.x >> frame.y >> frame.rotation >> frame.scaleX >> frame.scaleY >> isShip) {
|
||||||
frame.isShipMode = (isShip != 0);
|
frame.isShipMode = (isShip != 0);
|
||||||
mReplayFrames.push_back(frame);
|
mReplayFrames.push_back(frame);
|
||||||
|
} else {
|
||||||
|
// Reset stream and try 5-column legacy format
|
||||||
|
iss.clear();
|
||||||
|
iss.seekg(0);
|
||||||
|
if (iss >> frame.x >> frame.y >> frame.rotation >> frame.scaleX >> frame.scaleY) {
|
||||||
|
frame.isShipMode = false; // Default to ground mode for legacy replays
|
||||||
|
mReplayFrames.push_back(frame);
|
||||||
} else {
|
} else {
|
||||||
WARN("Failed to parse replay line: " << line);
|
WARN("Failed to parse replay line: " << line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
replayFile.close();
|
replayFile.close();
|
||||||
LOG("Loaded " << mReplayFrames.size() << " replay frames");
|
LOG("Loaded " << mReplayFrames.size() << " replay frames");
|
||||||
@@ -137,6 +146,7 @@ namespace Game {
|
|||||||
|
|
||||||
bool GameManager::playReplayFrame() {
|
bool GameManager::playReplayFrame() {
|
||||||
if (mReplayFrames.empty() || mCurrentReplayFrame >= mReplayFrames.size()) {
|
if (mReplayFrames.empty() || mCurrentReplayFrame >= mReplayFrames.size()) {
|
||||||
|
LOG("Replay complete: played " << mCurrentReplayFrame << " frames");
|
||||||
return false; // Replay finished
|
return false; // Replay finished
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,6 +161,11 @@ namespace Game {
|
|||||||
player->getTransform()->scaleX = frame.scaleX;
|
player->getTransform()->scaleX = frame.scaleX;
|
||||||
player->getTransform()->scaleY = frame.scaleY;
|
player->getTransform()->scaleY = frame.scaleY;
|
||||||
player->setShipMode(frame.isShipMode);
|
player->setShipMode(frame.isShipMode);
|
||||||
|
|
||||||
|
// Log every 100 frames to track progress
|
||||||
|
if (mCurrentReplayFrame % 100 == 0) {
|
||||||
|
LOG("Playing replay frame " << mCurrentReplayFrame << "/" << mReplayFrames.size());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mCurrentReplayFrame++;
|
mCurrentReplayFrame++;
|
||||||
|
|||||||
15
src/main.cpp
15
src/main.cpp
@@ -96,10 +96,20 @@ static void performStartGameTransition() {
|
|||||||
deactivateAndQueueRemoval("Title");
|
deactivateAndQueueRemoval("Title");
|
||||||
deactivateAndQueueRemoval("NameBox");
|
deactivateAndQueueRemoval("NameBox");
|
||||||
deactivateAndQueueRemoval("StartButton");
|
deactivateAndQueueRemoval("StartButton");
|
||||||
|
deactivateAndQueueRemoval("ReplayButton");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void performReplayTransition() {
|
static void performReplayTransition() {
|
||||||
// Spawn minimal game entities for replay
|
// Clear all existing entities to start fresh
|
||||||
|
auto allEntities = State::GameState::getInstance().getEntitiesSnapshot();
|
||||||
|
for (auto* entity : allEntities) {
|
||||||
|
if (entity && entity->getName() != "BG" && entity->getName() != "Player" && entity->getName() != "HUD") {
|
||||||
|
entity->setActive(false);
|
||||||
|
State::GameState::getInstance().queueEntityRemoval(entity->getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spawn minimal game entities for replay (only Background and Player, no HUD)
|
||||||
State::GameState::getInstance().addEntity(std::make_unique<AGame::Background>("BG", std::make_shared<Game::Renderer::Texture>("../resources/bgtest.png", gSDLRenderer), Object::DEFAULT_TRANSFORM));
|
State::GameState::getInstance().addEntity(std::make_unique<AGame::Background>("BG", std::make_shared<Game::Renderer::Texture>("../resources/bgtest.png", gSDLRenderer), Object::DEFAULT_TRANSFORM));
|
||||||
|
|
||||||
auto* player = dynamic_cast<AGame::Player*>(
|
auto* player = dynamic_cast<AGame::Player*>(
|
||||||
@@ -117,9 +127,6 @@ static void performReplayTransition() {
|
|||||||
player->setGroundTexture(std::make_shared<Game::Renderer::Texture>("../resources/l3player.png", gSDLRenderer));
|
player->setGroundTexture(std::make_shared<Game::Renderer::Texture>("../resources/l3player.png", gSDLRenderer));
|
||||||
}
|
}
|
||||||
|
|
||||||
// HUD
|
|
||||||
State::GameState::getInstance().addEntity(std::make_unique<AGame::HUDText>("HUD", std::make_shared<Game::Renderer::Font>("../resources/roboto.ttf", gSDLRenderer, 60, "HUDFont"), Object::Transform{0.f, 0.f, 0.f, 1.f, 1.f}, 320.f, 40.f));
|
|
||||||
|
|
||||||
// Initialize and start replay
|
// Initialize and start replay
|
||||||
if (GameManager::initReplayMode()) {
|
if (GameManager::initReplayMode()) {
|
||||||
GameManager::setCurrentGameState(GameStateEnum::REPLAY);
|
GameManager::setCurrentGameState(GameStateEnum::REPLAY);
|
||||||
|
|||||||
Reference in New Issue
Block a user