#include "match3field.h" #include "../main_code.h" #include #define ZLEVEL 0 void TChipTemplateParams::Serialize(boost::property_tree::ptree& propertyTree) { std::string selectedShaderName = propertyTree.get("SelectedShaderName"); std::string selectedTexName = propertyTree.get("SelectedTexName"); std::string selectedNormTexName = propertyTree.get("SelectedNormTexName"); std::string finishingTexName = propertyTree.get("FinishingTexName"); SelectedRenderParams.ShaderName = selectedShaderName; SelectedRenderParams.SamplerMap[SE::CONST_STRING_TEXTURE_UNIFORM] = selectedTexName; SelectedRenderParams.SamplerMap[SE::CONST_STRING_NORMALMAP_UNIFORM] = selectedNormTexName; SelectedRenderParams.transparencyFlag = SE::TRenderParams::opaque; //SelectedRenderParams.Transparency = 1.f; FinishingRenderParams.ShaderName = ""; FinishingRenderParams.SamplerMap[SE::CONST_STRING_TEXTURE_UNIFORM] = finishingTexName; FinishingRenderParams.SamplerMap[SE::CONST_STRING_NORMALMAP_UNIFORM] = ""; SelectedRenderParams.transparencyFlag = SE::TRenderParams::opaque; //FinishingRenderParams.Transparency = 1.f; std::string selectedAnimFileName = propertyTree.get("SelectedAnimFileName"); std::string finishingAnimFileName = propertyTree.get("FinishingAnimFileName"); auto px = SE::FileToPropertyTree(selectedAnimFileName); SelectedTemplateAnimObject.Serialize(*px); px = SE::FileToPropertyTree(finishingAnimFileName); FinishingTemplateAnimObject.Serialize(*px); } void TMatch3FieldParams::Serialize(boost::property_tree::ptree& propertyTree) { TChipTemplateParams chipTemplateParams; FieldWidth = propertyTree.get("Match3Params.FieldWidth"); FieldHeight = propertyTree.get("Match3Params.FieldHeight"); CellWidth = propertyTree.get("Match3Params.CellWidth"); CellHeight = propertyTree.get("Match3Params.CellHeight"); ChipLowestSpeed = propertyTree.get("Match3Params.ChipLowestSpeed"); ChipAcceleration = propertyTree.get("Match3Params.ChipAcceleration"); ChipPositionEpsilon = propertyTree.get("Match3Params.ChipPositionEpsilon"); ChipVelocityEpsilon = propertyTree.get("Match3Params.ChipVelocityEpsilon"); ChipK = propertyTree.get("Match3Params.ChipK"); ChipMatchTime = propertyTree.get("Match3Params.ChipMatchTime"); ChipTypeCount = propertyTree.get("Match3Params.ChipTypeCount"); for (boost::property_tree::ptree::value_type &v : propertyTree.get_child("Match3Params.ChipList")) { boost::property_tree::ptree& p = v.second.get_child(""); chipTemplateParams.Serialize(p); ChipTemplateParamsArr.push_back(chipTemplateParams); } } int TChip::StaticAnimationIndex = 0; TChip::TChip(int chipType, SE::TRenderPairList::iterator renderPair, size_t vertexListShift, TChipState chipState) : ChipType(chipType) , RenderPair(renderPair) , VertexListShift(vertexListShift) , ChipState(chipState) , Velocity(0) { AnimName = "test_anim"+SE::tostr(StaticAnimationIndex++); } TChip::~TChip() { } Eigen::Vector2f TChip::GetLeftBottomPos() { std::vector::iterator i = RenderPair->second.Data.Vec3CoordArr[SE::CONST_STRING_POSITION_ATTRIB].begin() + VertexListShift; return Eigen::Vector2f((*i)[0], (*i)[1]); } void TChip::SetLeftBottomPos(Eigen::Vector2f newPos) { Eigen::Vector2f shift = newPos - GetLeftBottomPos(); MoveLeftBottomPos(shift); } void TChip::MoveLeftBottomPos(Eigen::Vector2f shift) { for (int i=0; i<6; i++) { *(RenderPair->second.Data.Vec3CoordArr[SE::CONST_STRING_POSITION_ATTRIB].begin() + VertexListShift + i) += Eigen::Vector3f(shift[0], shift[1], 0); } } TMatch3Logic::TMatch3Logic() //: TemplateAnimObject(TRenderPairList::iterator(), 0, 1) { //TemplateAnimObject.Serialize(FileToPropertyTree("chip1_xml.xml")); } TMatch3Logic::~TMatch3Logic() { //Match3FieldParams.ChipTemplateParamsArr.clear(); } void TMatch3Logic::FillRandomChipMatrix(std::vector renderPairIteratorVector, Eigen::Vector2f leftBottomPos) { RenderPairIteratorVector = renderPairIteratorVector; LeftBottomPosField = leftBottomPos; ChipTypeCount = Match3FieldParams.ChipTypeCount; ChipMatrix.resize(Match3FieldParams.FieldWidth); for (size_t i = 0; i < Match3FieldParams.FieldWidth; ++i) { for (size_t j=0; j < Match3FieldParams.FieldHeight; ++j) { int chipType = rand() % ChipTypeCount; if (i == 0 && j == 6) { //AddChipToUp(i, chipType, GetExpectedLeftBottomPos(i, j), TChip::CS_LOCKED); InnerAddChipToUp(i, chipType, GetExpectedLeftBottomPos(i, j), TChip::CS_STANDBY); } else { InnerAddChipToUp(i, chipType, GetExpectedLeftBottomPos(i, j), TChip::CS_STANDBY); } } } std::vector chipList; do { chipList = GetAvailableMatchingChips(); UnmatchChips(chipList); } while (!chipList.empty()); for (size_t i = 0; i < ChipMatrix.size(); i++) { for (size_t j = 0; j < ChipMatrix[i].size(); j++) { //ReplaceAnimation(Eigen::Vector2i(i, j)); } } } Eigen::Vector2f TMatch3Logic::GetExpectedLeftBottomPos(size_t x, size_t y) { return LeftBottomPosField + Eigen::Vector2f(x*Match3FieldParams.CellWidth, y*Match3FieldParams.CellHeight); } void TMatch3Logic::StartAnimateChip(size_t x, size_t y) { //return; SE::ResourceManager->HalibutAnimationManager.StartAnimation(ChipMatrix[x][y].AnimName); } void TMatch3Logic::StopAnimateChip(size_t x, size_t y) { //return; SE::ResourceManager->HalibutAnimationManager.StopAnimation(ChipMatrix[x][y].AnimName); } bool TMatch3Logic::ChipIsLocked(Eigen::Vector2i chip) { return ChipMatrix[chip[0]][chip[1]].ChipState == TChip::CS_LOCKED; } bool TMatch3Logic::ChipIsFinishing(Eigen::Vector2i chip) { return ChipMatrix[chip[0]][chip[1]].ChipState == TChip::CS_FINISHING; } bool TMatch3Logic::ChipIsStable(Eigen::Vector2i chip) { return ChipMatrix[chip[0]][chip[1]].ChipState == TChip::CS_STANDBY || ChipMatrix[chip[0]][chip[1]].ChipState == TChip::CS_LOCKED; } bool TMatch3Logic::ChipCanBeSelected(Eigen::Vector2i chip) { if (ChipMatrix[chip[0]][chip[1]].ChipState != TChip::CS_STANDBY) { return false; } if (chip[1] == 0) { return true; } int i = chip[1] - 1; while (i >= 0 && ChipIsStable(Eigen::Vector2i(chip[0], i)) && !ChipIsLocked(Eigen::Vector2i(chip[0], i))) { i--; } if (i < 0 || ChipIsLocked(Eigen::Vector2i(chip[0], i))) { return true; } return false; } bool TMatch3Logic::ChipsCanBeSwapped(Eigen::Vector2i p1, Eigen::Vector2i p2) { float distance_x = static_cast(p1[0] - p2[0]); float distance_y = static_cast(p1[1] - p2[1]); if ((((fabs(distance_x) == 1) && (fabs(distance_y) == 0)) || ((fabs(distance_x) == 0) && (fabs(distance_y) == 1))) && ChipCanBeSelected(p1) && ChipCanBeSelected(p2)) { return true; } return false; } bool TMatch3Logic::ChipCanBeMatchedUp(Eigen::Vector2i chip) { if (chip[1] <= Match3FieldParams.FieldHeight - 3) { if ((ChipMatrix[chip[0]][chip[1]].ChipType == ChipMatrix[chip[0]][chip[1] + 1].ChipType) && (ChipMatrix[chip[0]][chip[1]].ChipType == ChipMatrix[chip[0]][chip[1] + 2].ChipType)) { if (ChipMatrix[chip[0]][chip[1]].ChipState == TChip::CS_STANDBY && ChipMatrix[chip[0]][chip[1] + 1].ChipState == TChip::CS_STANDBY && ChipMatrix[chip[0]][chip[1] + 2].ChipState == TChip::CS_STANDBY) { return true; } } } return false; } bool TMatch3Logic::ChipCanBeMatchedDown(Eigen::Vector2i chip) { if (chip[1] >= 2) { if ((ChipMatrix[chip[0]][chip[1]].ChipType == ChipMatrix[chip[0]][chip[1] - 1].ChipType) && (ChipMatrix[chip[0]][chip[1]].ChipType == ChipMatrix[chip[0]][chip[1] - 2].ChipType)) { if (ChipMatrix[chip[0]][chip[1]].ChipState == TChip::CS_STANDBY && ChipMatrix[chip[0]][chip[1] - 1].ChipState == TChip::CS_STANDBY && ChipMatrix[chip[0]][chip[1] - 2].ChipState == TChip::CS_STANDBY) { return true; } } } return false; } bool TMatch3Logic::ChipCanBeMatchedLeft(Eigen::Vector2i chip) { if (chip[0] >= 2) { if ((ChipMatrix[chip[0]][chip[1]].ChipType == ChipMatrix[chip[0] - 1][chip[1]].ChipType) && (ChipMatrix[chip[0]][chip[1]].ChipType == ChipMatrix[chip[0] - 2][chip[1]].ChipType)) { if (ChipMatrix[chip[0]][chip[1]].ChipState == TChip::CS_STANDBY && ChipMatrix[chip[0] - 1][chip[1]].ChipState == TChip::CS_STANDBY && ChipMatrix[chip[0] - 2][chip[1]].ChipState == TChip::CS_STANDBY) { return true; } } } return false; } bool TMatch3Logic::ChipCanBeMatchedRight(Eigen::Vector2i chip) { if (chip[0] <= Match3FieldParams.FieldWidth - 3) { if ((ChipMatrix[chip[0]][chip[1]].ChipType == ChipMatrix[chip[0] + 1][chip[1]].ChipType) && (ChipMatrix[chip[0]][chip[1]].ChipType == ChipMatrix[chip[0] + 2][chip[1]].ChipType)) { if (ChipMatrix[chip[0]][chip[1]].ChipState == TChip::CS_STANDBY && ChipMatrix[chip[0] + 1][chip[1]].ChipState == TChip::CS_STANDBY && ChipMatrix[chip[0] + 2][chip[1]].ChipState == TChip::CS_STANDBY) { return true; } } } return false; } void TMatch3Logic::UnmatchChips(std::vector chipList) { std::vector::iterator i; for (i = chipList.begin(); i != chipList.end(); ++i) { ChangeChipType(*i); } } void TMatch3Logic::ReplaceAnimation(Eigen::Vector2i p) { TChip& chip = ChipMatrix[p[0]][p[1]]; if (SE::ResourceManager->HalibutAnimationManager.AnimationExists(chip.AnimName)) { SE::ResourceManager->HalibutAnimationManager.ReplaceAnimationObject(chip.AnimName, chip.RenderPair, chip.VertexListShift / 6); } else { SE::THalibutExternalAnimObject testAnimObject(Match3FieldParams.ChipTemplateParamsArr[chip.ChipType].SelectedTemplateAnimObject); testAnimObject.ReplaceAnimObject(chip.RenderPair, chip.VertexListShift / 6); SE::ResourceManager->HalibutAnimationManager.AddAnimationObject(chip.AnimName, testAnimObject); } SE::ResourceManager->HalibutAnimationManager.StopAnimation(chip.AnimName); } void TMatch3Logic::MoveVertexListShiftBack(SE::TRenderPairList::iterator renderPairItr, size_t moveFrom) { for (size_t i = 0; i < ChipMatrix.size(); i++) { for (size_t j = 0; j < ChipMatrix[i].size(); j++) { if (ChipMatrix[i][j].RenderPair == renderPairItr) { if (ChipMatrix[i][j].VertexListShift > moveFrom) { ChipMatrix[i][j].VertexListShift -= 6; //ReplaceAnimation(Eigen::Vector2i(i, j)); } } } } } void TMatch3Logic::MoveVertexListShiftBackWithoutAnimation(SE::TRenderPairList::iterator renderPairItr, size_t moveFrom) { for (size_t i = 0; i < ChipMatrix.size(); i++) { for (size_t j = 0; j < ChipMatrix[i].size(); j++) { if (ChipMatrix[i][j].RenderPair == renderPairItr) { if (ChipMatrix[i][j].VertexListShift > moveFrom) { ChipMatrix[i][j].VertexListShift -= 6; //ReplaceAnimation(Eigen::Vector2i(i, j)); } } } } } void TMatch3Logic::InnerAddChipToUp(size_t colNum, int chipType, Eigen::Vector2f spawnPos, TChip::TChipState chipState) { Eigen::Vector2f posFrom = spawnPos; Eigen::Vector2f posTo = posFrom + Eigen::Vector2f(Match3FieldParams.CellWidth, Match3FieldParams.CellHeight); size_t renderPairIndex; if (chipState == TChip::CS_LOCKED) { renderPairIndex = chipType + Match3FieldParams.ChipTypeCount; } else { renderPairIndex = chipType; } SE::TTriangleList& triangleList = RenderPairIteratorVector[renderPairIndex]->second; std::vector vertexCoordArr = SE::MakeVertexCoordVec(posFrom, posTo, ZLEVEL); std::vector texCoordArr = SE::MakeTexCoordVec(); triangleList.Data.Vec3CoordArr[SE::CONST_STRING_POSITION_ATTRIB].insert(triangleList.Data.Vec3CoordArr[SE::CONST_STRING_POSITION_ATTRIB].end(), vertexCoordArr.begin(), vertexCoordArr.end()); triangleList.Data.Vec2CoordArr[SE::CONST_STRING_TEXCOORD_ATTRIB].insert(triangleList.Data.Vec2CoordArr[SE::CONST_STRING_TEXCOORD_ATTRIB].end(), texCoordArr.begin(), texCoordArr.end()); size_t vertexListShift = RenderPairIteratorVector[renderPairIndex]->second.Data.Vec3CoordArr[SE::CONST_STRING_POSITION_ATTRIB].size()-6; ChipMatrix[colNum].push_back(TChip(chipType, RenderPairIteratorVector[renderPairIndex], vertexListShift, chipState)); //triangleList.NeedRefreshBuffer = true; } void TMatch3Logic::AddChipToUp(size_t colNum, int chipType, Eigen::Vector2f spawnPos, TChip::TChipState chipState) { size_t yPos = ChipMatrix[colNum].size(); InnerAddChipToUp(colNum, chipType, spawnPos, chipState); //ReplaceAnimation(Eigen::Vector2i(colNum, yPos)); } void TMatch3Logic::InsertEmptyChip(size_t colNum, size_t rowNum, int chipType) { Eigen::Vector2f posFrom = GetExpectedLeftBottomPos(colNum, rowNum); Eigen::Vector2f posTo = posFrom + Eigen::Vector2f(Match3FieldParams.CellWidth, Match3FieldParams.CellHeight); size_t renderPairIndex = Match3FieldParams.ChipTypeCount * 2 + chipType; TChip::TChipState chipState = TChip::CS_X; SE::TTriangleList& triangleList = RenderPairIteratorVector[renderPairIndex]->second; std::vector vertexCoordArr = SE::MakeVertexCoordVec(posFrom, posTo, ZLEVEL); std::vector texCoordArr = SE::MakeTexCoordVec(); triangleList.Data.Vec3CoordArr[SE::CONST_STRING_POSITION_ATTRIB].insert(triangleList.Data.Vec3CoordArr[SE::CONST_STRING_POSITION_ATTRIB].end(), vertexCoordArr.begin(), vertexCoordArr.end()); triangleList.Data.Vec2CoordArr[SE::CONST_STRING_TEXCOORD_ATTRIB].insert(triangleList.Data.Vec2CoordArr[SE::CONST_STRING_TEXCOORD_ATTRIB].end(), texCoordArr.begin(), texCoordArr.end()); size_t vertexListShift = RenderPairIteratorVector[renderPairIndex]->second.Data.Vec3CoordArr[SE::CONST_STRING_POSITION_ATTRIB].size()-6; ChipMatrix[colNum].insert(ChipMatrix[colNum].begin() + rowNum, TChip(chipType, RenderPairIteratorVector[renderPairIndex], vertexListShift, chipState)); //ReplaceAnimation(Eigen::Vector2i(colNum, rowNum)); //triangleList.NeedRefreshBuffer = true; Eigen::Vector2f pos = GetExpectedLeftBottomPos(colNum, rowNum); ChipDeletingVector.push_back(TChipDeletingData(Eigen::Vector2i(colNum, rowNum), pos)); } void TMatch3Logic::UpdateChipSwapping(size_t dt) { std::vector::iterator i = ChipSwappingPairVector.begin(); std::vector > chipsToSwapAgain; while (i != ChipSwappingPairVector.end()) { i->T += dt / static_cast(Match3FieldParams.ChipMatchTime); if (i->T >= 1.f) { Eigen::Vector2i chip1pos = i->Chip1; Eigen::Vector2i chip2pos = i->Chip2; bool isReturning = i->IsReturning; TChip& chip1 = ChipMatrix[chip1pos[0]][chip1pos[1]]; TChip& chip2 = ChipMatrix[chip2pos[0]][chip2pos[1]]; TChip c = chip1; chip1 = chip2; chip2 = c; ResetChipPos(chip1pos); ResetChipPos(chip2pos); chip1.ChipState = TChip::CS_STANDBY; chip2.ChipState = TChip::CS_STANDBY; i = ChipSwappingPairVector.erase(i); //Check if chips do if (!isReturning) { std::vector matchingChipList = GetAvailableMatchingChips(); if (matchingChipList.size() == 0) { //SwapChips(chip1pos, chip2pos); chipsToSwapAgain.push_back(std::pair(chip1pos, chip2pos)); } } } else { TChip& chip1 = ChipMatrix[i->Chip1[0]][i->Chip1[1]]; TChip& chip2 = ChipMatrix[i->Chip2[0]][i->Chip2[1]]; auto x = i->Chip1RealPosFrom + (i->Chip2RealPosFrom - i->Chip1RealPosFrom) * i->T; auto y = i->Chip2RealPosFrom + (i->Chip1RealPosFrom - i->Chip2RealPosFrom) * i->T; Eigen::Vector3f newPosChip1 = Eigen::Vector3f(x[0], x[1], 0); Eigen::Vector3f newPosChip2 = Eigen::Vector3f(y[0], y[1], 0); Eigen::Vector3f shiftChip1 = newPosChip1 - chip1.RenderPair->second.Data.Vec3CoordArr[SE::CONST_STRING_POSITION_ATTRIB][chip1.VertexListShift]; Eigen::Vector3f shiftChip2 = newPosChip2 - chip2.RenderPair->second.Data.Vec3CoordArr[SE::CONST_STRING_POSITION_ATTRIB][chip2.VertexListShift]; for (int k = 0; k < 6; k++) { chip1.RenderPair->second.Data.Vec3CoordArr[SE::CONST_STRING_POSITION_ATTRIB][chip1.VertexListShift + k] += shiftChip1; chip2.RenderPair->second.Data.Vec3CoordArr[SE::CONST_STRING_POSITION_ATTRIB][chip2.VertexListShift + k] += shiftChip2; } //chip1.RenderPair->second.NeedRefreshBuffer = true; //chip2.RenderPair->second.NeedRefreshBuffer = true; } if (i != ChipSwappingPairVector.end()) { ++i; } } std::vector >::iterator pairVecItr; for (pairVecItr = chipsToSwapAgain.begin(); pairVecItr != chipsToSwapAgain.end(); ++pairVecItr) { SwapChips(pairVecItr->first, pairVecItr->second, true); } } void TMatch3Logic::UpdateChipPosition(size_t dt) { for (size_t i=0; i 0 && ChipIsFinishing(Eigen::Vector2i(i, j-1)))) { chip.Velocity = -chip.Velocity * Match3FieldParams.ChipK; chip.SetLeftBottomPos(GetExpectedLeftBottomPos(i, j)); } if (fabs(chip.Velocity) <= Match3FieldParams.ChipVelocityEpsilon) { if (fabs(expectedPos[0] - realPos[0]) <= Match3FieldParams.ChipPositionEpsilon && fabs(expectedPos[1] - realPos[1]) <= Match3FieldParams.ChipPositionEpsilon ) { chip.ChipState = TChip::CS_STANDBY; chip.SetLeftBottomPos(GetExpectedLeftBottomPos(i, j)); chip.Velocity = 0.f; } } //chip.RenderPair->second.NeedRefreshBuffer = true; for (size_t k = j + 1; k < ChipMatrix[i].size(); k++) { TChip& chipAbove = ChipMatrix[i][k]; Eigen::Vector2f posAbove = chipAbove.GetLeftBottomPos(); if (chipAbove.GetLeftBottomPos()[1] - chip.GetLeftBottomPos()[1] < Match3FieldParams.CellHeight) { if (!ChipIsLocked(Eigen::Vector2i(i, k)) && !ChipIsFinishing(Eigen::Vector2i(i, k))) { chipAbove.ChipState = TChip::CS_FALLING; chipAbove.SetLeftBottomPos(chip.GetLeftBottomPos() + Eigen::Vector2f(0, Match3FieldParams.CellHeight)); chipAbove.Velocity = chip.Velocity; //chipAbove.RenderPair->second.NeedRefreshBuffer = true; } } } } } } } void TMatch3Logic::RemoveBubbles() { size_t max_y = ChipMatrix.size()-1; for (size_t i=0; i < ChipMatrix[max_y].size(); i++) { if (ChipMatrix[i][max_y].ChipState == TChip::CS_FINISHING) { DestroyChip(Eigen::Vector2i(i, max_y)); AddChipToUp(i, rand() % ChipTypeCount, GetExpectedLeftBottomPos(i, ChipMatrix[i].size())+Eigen::Vector2f(0, Match3FieldParams.CellHeight)); } } } void TMatch3Logic::TryMatchAllChips() { std::vector matchingChips = GetAvailableMatchingChips(); std::vector::iterator i; for (i = matchingChips.begin(); i != matchingChips.end(); ++i) { Eigen::Vector2i p = *i; int chipType = ChipMatrix[p[0]][p[1]].ChipType; DestroyChip(p); InsertEmptyChip(p[0], p[1], chipType); } } void TMatch3Logic::DestroyChip(Eigen::Vector2i p) { //ChipMatrix[p[0]][p[1]].RenderPair->second.NeedRefreshBuffer = true; SE::ResourceManager->HalibutAnimationManager.DeleteAnimationObject(ChipMatrix[p[0]][p[1]].AnimName); ChipMatrix[p[0]][p[1]].RenderPair->second.Data.Vec3CoordArr[SE::CONST_STRING_POSITION_ATTRIB].erase( ChipMatrix[p[0]][p[1]].RenderPair->second.Data.Vec3CoordArr[SE::CONST_STRING_POSITION_ATTRIB].begin() + ChipMatrix[p[0]][p[1]].VertexListShift, ChipMatrix[p[0]][p[1]].RenderPair->second.Data.Vec3CoordArr[SE::CONST_STRING_POSITION_ATTRIB].begin() + ChipMatrix[p[0]][p[1]].VertexListShift + 6); ChipMatrix[p[0]][p[1]].RenderPair->second.Data.Vec2CoordArr[SE::CONST_STRING_TEXCOORD_ATTRIB].erase( ChipMatrix[p[0]][p[1]].RenderPair->second.Data.Vec2CoordArr[SE::CONST_STRING_TEXCOORD_ATTRIB].begin() + ChipMatrix[p[0]][p[1]].VertexListShift, ChipMatrix[p[0]][p[1]].RenderPair->second.Data.Vec2CoordArr[SE::CONST_STRING_TEXCOORD_ATTRIB].begin() + ChipMatrix[p[0]][p[1]].VertexListShift + 6); MoveVertexListShiftBackWithoutAnimation(ChipMatrix[p[0]][p[1]].RenderPair, ChipMatrix[p[0]][p[1]].VertexListShift); ChipMatrix[p[0]].erase(ChipMatrix[p[0]].begin() + p[1]); /* for (size_t i=p[1]; i < ChipMatrix[p[0]].size(); i++) { if (!ChipIsLocked(Eigen::Vector2i(p[0], i)) && !ChipIsFinishing(Eigen::Vector2i(p[0], i))) { ChipMatrix[p[0]][i].ChipState = TChip::CS_FALLING; } }*/ } void TMatch3Logic::ChangeChipType(Eigen::Vector2i p) { size_t newChipType = rand() % ChipTypeCount; TChip& chip = ChipMatrix[p[0]][p[1]]; std::vector::iterator vertexCoordItrBegin = chip.RenderPair->second.Data.Vec3CoordArr[SE::CONST_STRING_POSITION_ATTRIB].begin() + chip.VertexListShift; std::vector::iterator vertexCoordItrEnd = vertexCoordItrBegin + 6; std::vector::iterator texCoordItrBegin = chip.RenderPair->second.Data.Vec2CoordArr[SE::CONST_STRING_TEXCOORD_ATTRIB].begin() + chip.VertexListShift; std::vector::iterator texCoordItrEnd = texCoordItrBegin + 6; std::vector vertexCoordSubVec(vertexCoordItrBegin, vertexCoordItrEnd); std::vector texCoordSubVec(texCoordItrBegin, texCoordItrEnd); chip.RenderPair->second.Data.Vec3CoordArr[SE::CONST_STRING_POSITION_ATTRIB].erase(vertexCoordItrBegin, vertexCoordItrEnd); chip.RenderPair->second.Data.Vec2CoordArr[SE::CONST_STRING_TEXCOORD_ATTRIB].erase(texCoordItrBegin, texCoordItrEnd); MoveVertexListShiftBack(chip.RenderPair, chip.VertexListShift); //chip.RenderPair->second.NeedRefreshBuffer = true; chip.ChipType = newChipType; RenderPairIteratorVector[newChipType]->second.Data.Vec3CoordArr[SE::CONST_STRING_POSITION_ATTRIB].insert(RenderPairIteratorVector[newChipType]->second.Data.Vec3CoordArr[SE::CONST_STRING_POSITION_ATTRIB].end(), vertexCoordSubVec.begin(), vertexCoordSubVec.end()); RenderPairIteratorVector[newChipType]->second.Data.Vec2CoordArr[SE::CONST_STRING_TEXCOORD_ATTRIB].insert(RenderPairIteratorVector[newChipType]->second.Data.Vec2CoordArr[SE::CONST_STRING_TEXCOORD_ATTRIB].end(), texCoordSubVec.begin(), texCoordSubVec.end()); //RenderPairIteratorVector[newChipType]->second.NeedRefreshBuffer = true; chip.RenderPair = RenderPairIteratorVector[newChipType]; chip.VertexListShift = RenderPairIteratorVector[newChipType]->second.Data.Vec3CoordArr[SE::CONST_STRING_POSITION_ATTRIB].size() - 6; //Hack to make sure animation is replaced by new one SE::ResourceManager->HalibutAnimationManager.DeleteAnimationObject(chip.AnimName); //ReplaceAnimation(Eigen::Vector2i(p[0], p[1])); } void TMatch3Logic::innerUpdateAnimation(size_t dt) { for (int i = 0; i < ChipMatrix[0].size(); ++i) { for (int j = 0; j < ChipMatrix[i].size(); ++j) { if (Eigen::Vector2i(i, j) != selectedChip) { ReplaceAnimation(Eigen::Vector2i(i, j)); } } } SE::ResourceManager->HalibutAnimationManager.Update(dt); } void TMatch3Logic::SelectChip(Eigen::Vector2i pos) { if (!(selectedChip == Eigen::Vector2i(-1, -1))) { StopAnimateChip(selectedChip[0], selectedChip[1]); } StartAnimateChip(pos[0], pos[1]); selectedChip = pos; } void TMatch3Logic::UnselectChip() { if (!(selectedChip == Eigen::Vector2i(-1, -1))) { StopAnimateChip(selectedChip[0], selectedChip[1]); selectedChip = Eigen::Vector2i(-1, -1); } } Eigen::Vector2i TMatch3Logic::GetSelectedChip() { return selectedChip; } std::vector TMatch3Logic::GetAvailableMatchingChips() { std::vector result; for (size_t x=0; x vertexCoordVec = SE::MakeVertexCoordVec(posFrom, posTo, ZLEVEL); TChip& chip = ChipMatrix[p[0]][p[1]]; for (size_t i = 0; isecond.Data.Vec3CoordArr[SE::CONST_STRING_POSITION_ATTRIB][chip.VertexListShift + i] = vertexCoordVec[i]; } //chip.RenderPair->second.NeedRefreshBuffer = true; } void TMatch3Logic::UpdateLogic(size_t dt) { if (dt > 1000) { dt = 1000; //To prevent float overflow during looong laaaag } UpdateChipSwapping(dt); UpdateChipPosition(dt); TryMatchAllChips(); std::vector::iterator i; bool erased = false; for (i = ChipDeletingVector.begin(); i != ChipDeletingVector.end();) { erased = false; i->T += dt / 150.f; if (i->T > 1.f) { i->T = 1.f; } Eigen::Vector2i p = i->Chip; Eigen::Vector2f leftBottomPos = i->Pos; Eigen::Vector2f halfPos = Eigen::Vector2f(Match3FieldParams.CellWidth / 2.f, Match3FieldParams.CellHeight / 2.f); Eigen::Vector2f centerPos = leftBottomPos + halfPos; std::vector vertexCoordArr = SE::MakeVertexCoordVec(centerPos - (1.f - i->T)*halfPos, centerPos + (1.f - i->T)*halfPos, ZLEVEL); for (int t = 0; t < 6; t++) { ChipMatrix[p[0]][p[1]].RenderPair->second.Data.Vec3CoordArr[SE::CONST_STRING_POSITION_ATTRIB][ChipMatrix[p[0]][p[1]].VertexListShift + t] = vertexCoordArr[t]; } if (i->T == 1.f) { ChipMatrix[p[0]][p[1]].ChipState = TChip::CS_FINISHING; i = ChipDeletingVector.erase(i); erased = true; } if (i != ChipDeletingVector.end() && !erased) { ++i; } } RemoveBubbles(); } void TMatch3Logic::HitFieldWithPattern(Eigen::Vector2i pos, std::vector > pattern, std::vector > jumpingPattern) { const float CONST_VELOCITY_TO_ADD = 0.2f; for (size_t i = 0; i < pattern.size(); i++) { for (int j = static_cast(pattern[i].size()-1); j >=0; j--) { Eigen::Vector2i fieldPos = pos + Eigen::Vector2i(i,j); if (fieldPos[0] >= 0 && fieldPos[0] < static_cast(ChipMatrix.size()) && fieldPos[1] >= 0 && fieldPos[1] < static_cast(ChipMatrix[fieldPos[0]].size())) { if (ChipIsStable(fieldPos)) { if (pattern[i][j] > 0) { DestroyChip(fieldPos); InsertEmptyChip(fieldPos[0], fieldPos[1], 0); } } if (ChipIsLocked(fieldPos)) { ChipMatrix[fieldPos[0]][fieldPos[1]].ChipState = TChip::CS_STANDBY; } } } } for (size_t i = 0; i < jumpingPattern.size(); i++) { Eigen::Vector2i abovePos = pos + Eigen::Vector2i(i, jumpingPattern[i].size()); if (abovePos[0] >= 0 && abovePos[0] < static_cast(ChipMatrix.size()) && abovePos[1] >= 0 && abovePos[1] < static_cast(ChipMatrix[i].size())) { if (ChipMatrix[abovePos[0]][abovePos[1]].ChipState == TChip::CS_FALLING || ChipMatrix[abovePos[0]][abovePos[1]].ChipState == TChip::CS_STANDBY) { ChipMatrix[abovePos[0]][abovePos[1]].ChipState = TChip::CS_FALLING; ChipMatrix[abovePos[0]][abovePos[1]].Velocity += CONST_VELOCITY_TO_ADD; } } for (size_t j = 0; j < jumpingPattern[i].size(); j++) { Eigen::Vector2i fieldPos = pos + Eigen::Vector2i(i,j); if (fieldPos[0] >= 0 && fieldPos[0] < static_cast(ChipMatrix.size()) && fieldPos[1] >= 0 && fieldPos[1] < static_cast(ChipMatrix[fieldPos[0]].size())) { if (ChipMatrix[fieldPos[0]][fieldPos[1]].ChipState == TChip::CS_FALLING || ChipMatrix[fieldPos[0]][fieldPos[1]].ChipState == TChip::CS_STANDBY) { if (jumpingPattern[i][j] > 0) { ChipMatrix[fieldPos[0]][fieldPos[1]].ChipState = TChip::CS_FALLING; ChipMatrix[fieldPos[0]][fieldPos[1]].Velocity += CONST_VELOCITY_TO_ADD; } } } } } } //================================================ //============ TMatch3Field ====================== //================================================ TMatch3Field::TMatch3Field() { LastTappedPos = Eigen::Vector2f(0,0); } TMatch3Field::TMatch3Field(const TMatch3Field& m) { LastTappedPos = m.LastTappedPos; LastMovePos = m.LastMovePos; } TMatch3Field& TMatch3Field::operator=(const TMatch3Field& m) { LastTappedPos = m.LastTappedPos; LastMovePos = m.LastMovePos; return *this; } TMatch3Field::TMatch3Field(TMatch3Controller& match3Controller) //: Match3Controller(match3Controller) { //Match3Controller.Match3Field = this; FillBasicChipMatrixAndTriangleList(); } TMatch3Field::~TMatch3Field() { } void TMatch3Field::FillBasicChipMatrixAndTriangleList() { SE::TRenderParams renderParams; //renderParams.Transparency = 1.f; renderParams.transparencyFlag = SE::TRenderParams::opaque; auto px = SE::FileToPropertyTree("match3params.xml"); Match3FieldParams.Serialize(*px); for (size_t i = 0; i < Match3FieldParams.ChipTypeCount; i++) { TriangleListVector.push_back(SE::TRenderPair(Match3FieldParams.ChipTemplateParamsArr[i].SelectedRenderParams, SE::TTriangleList())); } renderParams.SamplerMap[SE::CONST_STRING_TEXTURE_UNIFORM] = "chip1locked"; TriangleListVector.push_back(SE::TRenderPair(renderParams, SE::TTriangleList())); renderParams.SamplerMap[SE::CONST_STRING_TEXTURE_UNIFORM] = "chip2locked"; TriangleListVector.push_back(SE::TRenderPair(renderParams, SE::TTriangleList())); renderParams.SamplerMap[SE::CONST_STRING_TEXTURE_UNIFORM] = "chip3locked"; TriangleListVector.push_back(SE::TRenderPair(renderParams, SE::TTriangleList())); renderParams.SamplerMap[SE::CONST_STRING_TEXTURE_UNIFORM] = "chip4locked"; TriangleListVector.push_back(SE::TRenderPair(renderParams, SE::TTriangleList())); for (size_t i = 0; i < Match3FieldParams.ChipTypeCount; i++) { TriangleListVector.push_back(SE::TRenderPair(Match3FieldParams.ChipTemplateParamsArr[i].FinishingRenderParams, SE::TTriangleList())); } std::vector triangleListVec; for (SE::TRenderPairList::iterator i = TriangleListVector.begin(); i != TriangleListVector.end(); ++i) { triangleListVec.push_back(i); } LeftBottomPos = Eigen::Vector2f(150, 0); FillRandomChipMatrix(triangleListVec, LeftBottomPos); //Init everything selectedChip = Eigen::Vector2i(-1, -1); for (SE::TRenderPairList::iterator i = TriangleListVector.begin(); i != TriangleListVector.end(); ++i) { //i->second.NeedRefreshBuffer = false; i->second.RefreshBuffer(); } } Eigen::Vector2i TMatch3Field::PosToChip(Eigen::Vector2f pos) { int x, y; Eigen::Vector2f fieldPos = pos - LeftBottomPos; x = static_cast(fieldPos[0] / Match3FieldParams.CellWidth); y = static_cast(fieldPos[1] / Match3FieldParams.CellHeight); return Eigen::Vector2i(x, y); } void TMatch3Field::Update(size_t dt) { TMatch3Logic::UpdateLogic(dt); SE::TRenderPairList::iterator i; for (i = TriangleListVector.begin(); i != TriangleListVector.end(); ++i) { i->second.RefreshBuffer(); } innerUpdateAnimation(dt); } void TMatch3Field::OnTapDown(Eigen::Vector2f pos) { //See also OnMove LastTappedPos = pos; LastMovePos = LastTappedPos; Eigen::Vector2i chip = PosToChip(pos); /* To hit field by pattern std::vector > pattern; pattern.resize(3); pattern[0].resize(3); pattern[1].resize(3); pattern[2].resize(3); pattern[0][0] = 0; pattern[1][0] = 1; pattern[2][0] = 0; pattern[0][1] = 1; pattern[1][1] = 1; pattern[2][1] = 1; pattern[0][2] = 0; pattern[1][2] = 1; pattern[2][2] = 0; std::vector > jumpingPattern; jumpingPattern.resize(3); jumpingPattern[0].resize(3); jumpingPattern[1].resize(3); jumpingPattern[2].resize(3); jumpingPattern[0][0] = 0; jumpingPattern[1][0] = 0; jumpingPattern[2][0] = 0; jumpingPattern[0][1] = 0; jumpingPattern[1][1] = 0; jumpingPattern[2][1] = 0; jumpingPattern[0][2] = 1; jumpingPattern[1][2] = 0; jumpingPattern[2][2] = 1; HitFieldWithPattern(chip - Eigen::Vector2i(1, 1), pattern, jumpingPattern); return;*/ if (selectedChip == chip) { UnselectChip(); } else { if (ChipsCanBeSwapped(selectedChip, chip)) { SwapChips(selectedChip, chip); UnselectChip(); } else { if (ChipCanBeSelected(chip)) { SelectChip(chip); } } } } void TMatch3Field::OnTapUp(Eigen::Vector2f pos) { } void TMatch3Field::OnMove(Eigen::Vector2f shift) { if (selectedChip == Eigen::Vector2i(-1, -1)) { return; } LastMovePos += shift; if ((LastTappedPos - LastMovePos)[0] >= Match3FieldParams.CellWidth * 0.5f) { Eigen::Vector2i newPosChip = selectedChip + Eigen::Vector2i(1, 0); if (selectedChip[0] <= Match3FieldParams.FieldWidth - 2) { if (ChipsCanBeSwapped(selectedChip, newPosChip)) { SwapChips(selectedChip, newPosChip); UnselectChip(); } } } else if ((LastMovePos - LastTappedPos)[0] >= Match3FieldParams.CellWidth * 0.5f) { Eigen::Vector2i newPosChip = selectedChip - Eigen::Vector2i(1, 0); if (selectedChip[0] >= 1) { if (ChipsCanBeSwapped(selectedChip, newPosChip)) { SwapChips(selectedChip, newPosChip); UnselectChip(); } } } else if ((LastMovePos - LastTappedPos)[1] >= Match3FieldParams.CellHeight * 0.5f) { Eigen::Vector2i newPosChip = selectedChip + Eigen::Vector2i(0, 1); if (selectedChip[1] <= Match3FieldParams.FieldHeight - 2) { if (ChipsCanBeSwapped(selectedChip, newPosChip)) { SwapChips(selectedChip, newPosChip); UnselectChip(); } } } else if ((LastTappedPos - LastMovePos)[1] >= Match3FieldParams.CellHeight * 0.5f) { Eigen::Vector2i newPosChip = selectedChip - Eigen::Vector2i(0, 1); if (selectedChip[1] >= 1) { if (ChipsCanBeSwapped(selectedChip, newPosChip)) { SwapChips(selectedChip, newPosChip); UnselectChip(); } } } } bool TMatch3Field::CheckClick(Eigen::Vector2f mousePos) { Eigen::Vector2f fieldPos = mousePos - LeftBottomPos; if (fieldPos[0] >= 0 && fieldPos[0] < Match3FieldParams.FieldWidth*Match3FieldParams.CellWidth) { if (fieldPos[1] >= 0 && fieldPos[1] < Match3FieldParams.FieldHeight*Match3FieldParams.CellHeight) { return true; } } return false; } void TMatch3Field::HighlightMatch3() { std::vector chips = GetAvailableMatchingChips(); std::vector::iterator i; for (i = chips.begin(); i != chips.end(); ++i) { SE::ResourceManager->HalibutAnimationManager.StartAnimation(ChipMatrix[(*i)[0]][(*i)[1]].AnimName); } }