void CApp::ResetMap(int mapIndex) { // remove all blocks for (auto itr = CBlock::BlockList.begin(); itr != CBlock::BlockList.end(); itr++) { CBlock* pBlock = *itr; if (pBlock) { pBlock->OnMove(-MAP_W, -MAP_H); // this will reset the tile if it was on its home delete pBlock; } } CBlock::BlockList.clear(); CurrentMap = mapIndex; if (CurrentMap > highestLevel) highestLevel = CurrentMap; CMap* pMap = maps[mapIndex]; ActionJackson.SetLoc(pMap->startX, pMap->startY); ActionJackson.map = pMap; ActionJackson.ClearUndoList(); // place all blocks for (int i = 0; i < pMap->startBlocks.size(); i++) { SDL_Point p = pMap->startBlocks[i]; CBlock* pBlock = new CBlock(p.x, p.y, pMap); pBlock->SetSpriteSheet(block); pBlock->OnMove(0, 0); // this will make the tile change to HOMEWITHBLOCK if applicable CBlock::BlockList.push_back(pBlock); } // add some flavor Uint8 redness = 2*(Uint8)CurrentMap; SDL_SetTextureColorMod(Texture, 255, 255 - redness, 255 - redness); }
void CPlayer::UndoLastMove() { if (!head) return; // don't undo anything, don't modify list, and DON'T decrement memories! pUndo toUndo = head; if (toUndo->dx == 0 && toUndo->dy == 0) { // do nothing } else { // undo the move (must check for blocks to replace too!) CBlock* pBlock = NULL; if (toUndo->pushed) { for (auto itr = CBlock::BlockList.begin(); itr != CBlock::BlockList.end(); itr++) { if (*itr) { int x, y; (*itr)->GetLoc(&x, &y); if ((x == X + toUndo->dx) && (y == Y + toUndo->dy)) pBlock = *itr; } } } X -= toUndo->dx; Y -= toUndo->dy; if (pBlock) pBlock->OnMove(-toUndo->dx, -toUndo->dy); } // remove the top of the list head = head->next; delete toUndo; if (head) // list is not empty head->prev = NULL; else // that was the last undo tail = NULL; memories--; }
void CApp::OnLoop() { // process input if (InputHappened) { NeedsRedraw = true; // quit game if (inputs.Quit) { Running = false; return; } // reset color modulation (easier on the eyes) if (inputs.Confirm) { SDL_SetTextureColorMod(Texture, 255, 255, 255); } // reset/change level if (inputs.Reset) { ResetMap(CurrentMap); } else if (inputs.NextLevel) { if (highestLevel > CurrentMap && CurrentMap < maps.size() - 1) ResetMap(CurrentMap+1); } else if (inputs.PrevLevel) { if (CurrentMap > 0) ResetMap(CurrentMap-1); } else { // movement CBlock* pushed = NULL; if (inputs.Left) { int result = ActionJackson.CanPlayerMoveLeft(&pushed); if (result != NO) { ActionJackson.OnMove(-1, 0, result == BLOCK); if (result == BLOCK) pushed->OnMove(-1, 0); } } else if (inputs.Right) { int result = ActionJackson.CanPlayerMoveRight(&pushed); if (result != NO) { ActionJackson.OnMove(1, 0, result == BLOCK); if (result == BLOCK) pushed->OnMove(1, 0); } } else if (inputs.Up) { int result = ActionJackson.CanPlayerMoveUp(&pushed); if (result != NO) { ActionJackson.OnMove(0, -1, result == BLOCK); if (result == BLOCK) pushed->OnMove(0, -1); } } else if (inputs.Down) { int result = ActionJackson.CanPlayerMoveDown(&pushed); if (result != NO) { ActionJackson.OnMove(0, 1, result == BLOCK); if (result == BLOCK) pushed->OnMove(0, 1); } } else if (inputs.Cancel) { ActionJackson.UndoLastMove(); } } // ~movement //if (PROCESS_ONCE) InputHappened = false; } // add other logic here FOR_EACH_ENTITY(this) if (entity->OnLoop()) { NeedsRedraw = true; } FOR_EACH_END // checking if all blocks are home bool blocksAreHome = true; FOR_EACH_BLOCK(&blocksAreHome) if (!block->CheckForHome()) blocksAreHome = false; FOR_EACH_END if (blocksAreHome) { if (CurrentMap == (maps.size() - 1)) Running = false; else { ResetMap(CurrentMap + 1); } } }