#include "match3/match3field.h" #include "main_code.h" #include 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.TexName = selectedTexName; SelectedRenderParams.NormTexName = selectedNormTexName; SelectedRenderParams.Transparency = 1.f; FinishingRenderParams.ShaderName = ""; FinishingRenderParams.TexName = finishingTexName; FinishingRenderParams.NormTexName = ""; FinishingRenderParams.Transparency = 1.f; std::string selectedAnimFileName = propertyTree.get("SelectedAnimFileName"); std::string finishingAnimFileName = propertyTree.get("FinishingAnimFileName"); boost::shared_ptr px = FileToPropertyTree(selectedAnimFileName); SelectedTemplateAnimObject.Serialize(*px); px = 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"); BOOST_FOREACH(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, TRenderPairList::iterator renderPair, cardinal vertexListShift, TChipState chipState) : ChipType(chipType) , RenderPair(renderPair) , VertexListShift(vertexListShift) , ChipState(chipState) , Velocity(0) { AnimName = "test_anim"+tostr(StaticAnimationIndex++); } TChip::~TChip() { } vec2 TChip::GetLeftBottomPos() { std::vector::iterator i = RenderPair->second.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].begin() + VertexListShift; return vec2(i->v[0], i->v[1]); } void TChip::SetLeftBottomPos(vec2 newPos) { vec2 shift = newPos - GetLeftBottomPos(); MoveLeftBottomPos(shift); } void TChip::MoveLeftBottomPos(vec2 shift) { for (int i=0; i<6; i++) { *(RenderPair->second.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].begin() + VertexListShift + i) += vec3(shift, 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, vec2 leftBottomPos) { RenderPairIteratorVector = renderPairIteratorVector; LeftBottomPosField = leftBottomPos; ChipTypeCount = Match3FieldParams.ChipTypeCount; ChipMatrix.resize(Match3FieldParams.FieldWidth); for (cardinal i = 0; i < Match3FieldParams.FieldWidth; ++i) { for (cardinal j=0; j < Match3FieldParams.FieldHeight; ++j) { int chipType = rand() % ChipTypeCount; if (i == 0 && j == 6) { //AddChipToUp(i, chipType, GetExpectedLeftBottomPos(i, j), TChip::CS_LOCKED); AddChipToUp(i, chipType, GetExpectedLeftBottomPos(i, j), TChip::CS_STANDBY); } else { AddChipToUp(i, chipType, GetExpectedLeftBottomPos(i, j), TChip::CS_STANDBY); } } } std::vector chipList = GetAvailableMatchingChips(); while (chipList.size() != 0) { UnmatchChips(chipList); chipList = GetAvailableMatchingChips(); } } vec2 TMatch3Logic::GetExpectedLeftBottomPos(cardinal x, cardinal y) { return LeftBottomPosField + vec2(x*Match3FieldParams.CellWidth, y*Match3FieldParams.CellHeight); } void TMatch3Logic::StartAnimateChip(cardinal x, cardinal y) { ResourceManager->HalibutAnimationManager.StartAnimation(ChipMatrix[x][y].AnimName); } void TMatch3Logic::StopAnimateChip(cardinal x, cardinal y) { ResourceManager->HalibutAnimationManager.StopAnimation(ChipMatrix[x][y].AnimName); } bool TMatch3Logic::ChipIsLocked(ivec2 chip) { return ChipMatrix[chip.v[0]][chip.v[1]].ChipState == TChip::CS_LOCKED; } bool TMatch3Logic::ChipIsFinishing(ivec2 chip) { return ChipMatrix[chip.v[0]][chip.v[1]].ChipState == TChip::CS_FINISHING; } bool TMatch3Logic::ChipIsStable(ivec2 chip) { return ChipMatrix[chip.v[0]][chip.v[1]].ChipState == TChip::CS_STANDBY || ChipMatrix[chip.v[0]][chip.v[1]].ChipState == TChip::CS_LOCKED; } bool TMatch3Logic::ChipCanBeSelected(ivec2 chip) { if (ChipMatrix[chip.v[0]][chip.v[1]].ChipState != TChip::CS_STANDBY) { return false; } if (chip.v[1] == 0) { return true; } int i = chip.v[1] - 1; while (i >= 0 && ChipIsStable(ivec2(chip.v[0], i)) && !ChipIsLocked(ivec2(chip.v[0], i))) { i--; } if (i < 0 || ChipIsLocked(ivec2(chip.v[0], i))) { return true; } return false; } bool TMatch3Logic::ChipsCanBeSwapped(ivec2 p1, ivec2 p2) { float distance_x = static_cast(p1.v[0] - p2.v[0]); float distance_y = static_cast(p1.v[1] - p2.v[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(ivec2 chip) { if (chip.v[1] <= Match3FieldParams.FieldHeight - 3) { if ((ChipMatrix[chip.v[0]][chip.v[1]].ChipType == ChipMatrix[chip.v[0]][chip.v[1] + 1].ChipType) && (ChipMatrix[chip.v[0]][chip.v[1]].ChipType == ChipMatrix[chip.v[0]][chip.v[1] + 2].ChipType)) { if (ChipMatrix[chip.v[0]][chip.v[1]].ChipState == TChip::CS_STANDBY && ChipMatrix[chip.v[0]][chip.v[1] + 1].ChipState == TChip::CS_STANDBY && ChipMatrix[chip.v[0]][chip.v[1] + 2].ChipState == TChip::CS_STANDBY) { return true; } } } return false; } bool TMatch3Logic::ChipCanBeMatchedDown(ivec2 chip) { if (chip.v[1] >= 2) { if ((ChipMatrix[chip.v[0]][chip.v[1]].ChipType == ChipMatrix[chip.v[0]][chip.v[1] - 1].ChipType) && (ChipMatrix[chip.v[0]][chip.v[1]].ChipType == ChipMatrix[chip.v[0]][chip.v[1] - 2].ChipType)) { if (ChipMatrix[chip.v[0]][chip.v[1]].ChipState == TChip::CS_STANDBY && ChipMatrix[chip.v[0]][chip.v[1] - 1].ChipState == TChip::CS_STANDBY && ChipMatrix[chip.v[0]][chip.v[1] - 2].ChipState == TChip::CS_STANDBY) { return true; } } } return false; } bool TMatch3Logic::ChipCanBeMatchedLeft(ivec2 chip) { if (chip.v[0] >= 2) { if ((ChipMatrix[chip.v[0]][chip.v[1]].ChipType == ChipMatrix[chip.v[0] - 1][chip.v[1]].ChipType) && (ChipMatrix[chip.v[0]][chip.v[1]].ChipType == ChipMatrix[chip.v[0] - 2][chip.v[1]].ChipType)) { if (ChipMatrix[chip.v[0]][chip.v[1]].ChipState == TChip::CS_STANDBY && ChipMatrix[chip.v[0] - 1][chip.v[1]].ChipState == TChip::CS_STANDBY && ChipMatrix[chip.v[0] - 2][chip.v[1]].ChipState == TChip::CS_STANDBY) { return true; } } } return false; } bool TMatch3Logic::ChipCanBeMatchedRight(ivec2 chip) { if (chip.v[0] <= Match3FieldParams.FieldWidth - 3) { if ((ChipMatrix[chip.v[0]][chip.v[1]].ChipType == ChipMatrix[chip.v[0] + 1][chip.v[1]].ChipType) && (ChipMatrix[chip.v[0]][chip.v[1]].ChipType == ChipMatrix[chip.v[0] + 2][chip.v[1]].ChipType)) { if (ChipMatrix[chip.v[0]][chip.v[1]].ChipState == TChip::CS_STANDBY && ChipMatrix[chip.v[0] + 1][chip.v[1]].ChipState == TChip::CS_STANDBY && ChipMatrix[chip.v[0] + 2][chip.v[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(ivec2 p) { TChip& chip = ChipMatrix[p.v[0]][p.v[1]]; if (ResourceManager->HalibutAnimationManager.AnimationExists(chip.AnimName)) { ResourceManager->HalibutAnimationManager.ReplaceAnimationObject(chip.AnimName, chip.RenderPair, chip.VertexListShift / 6); } else { THalibutExternalAnimObject testAnimObject(Match3FieldParams.ChipTemplateParamsArr[chip.ChipType].SelectedTemplateAnimObject); testAnimObject.ReplaceAnimObject(chip.RenderPair, chip.VertexListShift / 6); ResourceManager->HalibutAnimationManager.AddAnimationObject(chip.AnimName, testAnimObject); } ResourceManager->HalibutAnimationManager.StopAnimation(chip.AnimName); } void TMatch3Logic::MoveVertexListShiftBack(TRenderPairList::iterator renderPairItr, cardinal moveFrom) { for (cardinal i = 0; i < ChipMatrix.size(); i++) { for (cardinal 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(ivec2(i, j)); } } } } } void TMatch3Logic::AddChipToUp(cardinal colNum, int chipType, vec2 spawnPos, TChip::TChipState chipState) { cardinal yPos = ChipMatrix[colNum].size(); vec2 posFrom = spawnPos; vec2 posTo = posFrom + vec2(Match3FieldParams.CellWidth, Match3FieldParams.CellHeight); cardinal renderPairIndex; if (chipState == TChip::CS_LOCKED) { renderPairIndex = chipType + Match3FieldParams.ChipTypeCount; } else { renderPairIndex = chipType; } TTriangleList& triangleList = RenderPairIteratorVector[renderPairIndex]->second; std::vector vertexCoordArr = MakeVertexCoordVec(posFrom, posTo); std::vector texCoordArr = MakeTexCoordVec(); triangleList.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].insert(triangleList.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].end(), vertexCoordArr.begin(), vertexCoordArr.end()); triangleList.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].insert(triangleList.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].end(), texCoordArr.begin(), texCoordArr.end()); cardinal vertexListShift = RenderPairIteratorVector[renderPairIndex]->second.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].size()-6; ChipMatrix[colNum].push_back(TChip(chipType, RenderPairIteratorVector[renderPairIndex], vertexListShift, chipState)); ReplaceAnimation(ivec2(colNum, yPos)); triangleList.NeedRefreshBuffer = true; } void TMatch3Logic::InsertEmptyChip(cardinal colNum, cardinal rowNum, int chipType) { vec2 posFrom = GetExpectedLeftBottomPos(colNum, rowNum); vec2 posTo = posFrom + vec2(Match3FieldParams.CellWidth, Match3FieldParams.CellHeight); cardinal renderPairIndex = Match3FieldParams.ChipTypeCount * 2 + chipType; TChip::TChipState chipState = TChip::CS_X; TTriangleList& triangleList = RenderPairIteratorVector[renderPairIndex]->second; std::vector vertexCoordArr = MakeVertexCoordVec(posFrom, posTo); std::vector texCoordArr = MakeTexCoordVec(); triangleList.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].insert(triangleList.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].end(), vertexCoordArr.begin(), vertexCoordArr.end()); triangleList.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].insert(triangleList.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].end(), texCoordArr.begin(), texCoordArr.end()); cardinal vertexListShift = RenderPairIteratorVector[renderPairIndex]->second.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].size()-6; ChipMatrix[colNum].insert(ChipMatrix[colNum].begin() + rowNum, TChip(chipType, RenderPairIteratorVector[renderPairIndex], vertexListShift, chipState)); ReplaceAnimation(ivec2(colNum, rowNum)); triangleList.NeedRefreshBuffer = true; vec2 pos = GetExpectedLeftBottomPos(colNum, rowNum); ChipDeletingVector.push_back(TChipDeletingData(ivec2(colNum, rowNum), pos)); } void TMatch3Logic::UpdateChipSwapping(cardinal 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) { ivec2 chip1pos = i->Chip1; ivec2 chip2pos = i->Chip2; bool isReturning = i->IsReturning; TChip& chip1 = ChipMatrix[chip1pos.v[0]][chip1pos.v[1]]; TChip& chip2 = ChipMatrix[chip2pos.v[0]][chip2pos.v[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.v[0]][i->Chip1.v[1]]; TChip& chip2 = ChipMatrix[i->Chip2.v[0]][i->Chip2.v[1]]; vec3 newPosChip1 = vec3(i->Chip1RealPosFrom + (i->Chip2RealPosFrom - i->Chip1RealPosFrom) * i->T, 0); vec3 newPosChip2 = vec3(i->Chip2RealPosFrom + (i->Chip1RealPosFrom - i->Chip2RealPosFrom) * i->T, 0); vec3 shiftChip1 = newPosChip1 - chip1.RenderPair->second.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB][chip1.VertexListShift]; vec3 shiftChip2 = newPosChip2 - chip2.RenderPair->second.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB][chip2.VertexListShift]; for (int k = 0; k < 6; k++) { chip1.RenderPair->second.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB][chip1.VertexListShift + k] += shiftChip1; chip2.RenderPair->second.Vec3CoordArr[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(cardinal dt) { for (cardinal i=0; i 0 && ChipIsFinishing(ivec2(i, j-1)))) { chip.Velocity = -chip.Velocity * Match3FieldParams.ChipK; chip.SetLeftBottomPos(GetExpectedLeftBottomPos(i, j)); } if (fabs(chip.Velocity) <= Match3FieldParams.ChipVelocityEpsilon) { if (fabs(expectedPos.v[0] - realPos.v[0]) <= Match3FieldParams.ChipPositionEpsilon && fabs(expectedPos.v[1] - realPos.v[1]) <= Match3FieldParams.ChipPositionEpsilon ) { chip.ChipState = TChip::CS_STANDBY; chip.SetLeftBottomPos(GetExpectedLeftBottomPos(i, j)); chip.Velocity = 0.f; } } chip.RenderPair->second.NeedRefreshBuffer = true; for (cardinal k = j + 1; k < ChipMatrix[i].size(); k++) { TChip& chipAbove = ChipMatrix[i][k]; vec2 posAbove = chipAbove.GetLeftBottomPos(); if (chipAbove.GetLeftBottomPos().v[1] - chip.GetLeftBottomPos().v[1] < Match3FieldParams.CellHeight) { if (!ChipIsLocked(ivec2(i, k)) && !ChipIsFinishing(ivec2(i, k))) { chipAbove.ChipState = TChip::CS_FALLING; chipAbove.SetLeftBottomPos(chip.GetLeftBottomPos() + vec2(0, Match3FieldParams.CellHeight)); chipAbove.Velocity = chip.Velocity; chipAbove.RenderPair->second.NeedRefreshBuffer = true; } } } } } } } void TMatch3Logic::RemoveBubbles() { cardinal max_y = ChipMatrix.size()-1; for (cardinal i=0; i < ChipMatrix[max_y].size(); i++) { if (ChipMatrix[i][max_y].ChipState == TChip::CS_FINISHING) { DestroyChip(ivec2(i, max_y)); AddChipToUp(i, rand() % ChipTypeCount, GetExpectedLeftBottomPos(i, ChipMatrix[i].size())+vec2(0, Match3FieldParams.CellHeight)); } } } void TMatch3Logic::TryMatchAllChips() { std::vector matchingChips = GetAvailableMatchingChips(); std::vector::iterator i; for (i = matchingChips.begin(); i != matchingChips.end(); ++i) { ivec2 p = *i; int chipType = ChipMatrix[p.v[0]][p.v[1]].ChipType; DestroyChip(p); InsertEmptyChip(p.v[0], p.v[1], chipType); } } void TMatch3Logic::DestroyChip(ivec2 p) { ChipMatrix[p.v[0]][p.v[1]].RenderPair->second.NeedRefreshBuffer = true; ResourceManager->HalibutAnimationManager.DeleteAnimationObject(ChipMatrix[p.v[0]][p.v[1]].AnimName); ChipMatrix[p.v[0]][p.v[1]].RenderPair->second.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].erase( ChipMatrix[p.v[0]][p.v[1]].RenderPair->second.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].begin() + ChipMatrix[p.v[0]][p.v[1]].VertexListShift, ChipMatrix[p.v[0]][p.v[1]].RenderPair->second.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].begin() + ChipMatrix[p.v[0]][p.v[1]].VertexListShift + 6); ChipMatrix[p.v[0]][p.v[1]].RenderPair->second.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].erase( ChipMatrix[p.v[0]][p.v[1]].RenderPair->second.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].begin() + ChipMatrix[p.v[0]][p.v[1]].VertexListShift, ChipMatrix[p.v[0]][p.v[1]].RenderPair->second.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].begin() + ChipMatrix[p.v[0]][p.v[1]].VertexListShift + 6); MoveVertexListShiftBack(ChipMatrix[p.v[0]][p.v[1]].RenderPair, ChipMatrix[p.v[0]][p.v[1]].VertexListShift); ChipMatrix[p.v[0]].erase(ChipMatrix[p.v[0]].begin() + p.v[1]); /* for (cardinal i=p.v[1]; i < ChipMatrix[p.v[0]].size(); i++) { if (!ChipIsLocked(ivec2(p.v[0], i)) && !ChipIsFinishing(ivec2(p.v[0], i))) { ChipMatrix[p.v[0]][i].ChipState = TChip::CS_FALLING; } }*/ } void TMatch3Logic::ChangeChipType(ivec2 p) { cardinal newChipType = rand() % ChipTypeCount; TChip& chip = ChipMatrix[p.v[0]][p.v[1]]; std::vector::iterator vertexCoordItrBegin = chip.RenderPair->second.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].begin() + chip.VertexListShift; std::vector::iterator vertexCoordItrEnd = vertexCoordItrBegin + 6; std::vector::iterator texCoordItrBegin = chip.RenderPair->second.Vec2CoordArr[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.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].erase(vertexCoordItrBegin, vertexCoordItrEnd); chip.RenderPair->second.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].erase(texCoordItrBegin, texCoordItrEnd); MoveVertexListShiftBack(chip.RenderPair, chip.VertexListShift); chip.RenderPair->second.NeedRefreshBuffer = true; chip.ChipType = newChipType; RenderPairIteratorVector[newChipType]->second.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].insert(RenderPairIteratorVector[newChipType]->second.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].end(), vertexCoordSubVec.begin(), vertexCoordSubVec.end()); RenderPairIteratorVector[newChipType]->second.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].insert(RenderPairIteratorVector[newChipType]->second.Vec2CoordArr[CONST_STRING_TEXCOORD_ATTRIB].end(), texCoordSubVec.begin(), texCoordSubVec.end()); RenderPairIteratorVector[newChipType]->second.NeedRefreshBuffer = true; chip.RenderPair = RenderPairIteratorVector[newChipType]; chip.VertexListShift = RenderPairIteratorVector[newChipType]->second.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB].size() - 6; //Hack to make sure animation is replaced by new one ResourceManager->HalibutAnimationManager.DeleteAnimationObject(chip.AnimName); ReplaceAnimation(ivec2(p.v[0], p.v[1])); } void TMatch3Logic::SelectChip(ivec2 pos) { if (!(selectedChip == ivec2(-1, -1))) { StopAnimateChip(selectedChip.v[0], selectedChip.v[1]); } StartAnimateChip(pos.v[0], pos.v[1]); selectedChip = pos; } void TMatch3Logic::UnselectChip() { if (!(selectedChip == ivec2(-1, -1))) { StopAnimateChip(selectedChip.v[0], selectedChip.v[1]); selectedChip = ivec2(-1, -1); } } ivec2 TMatch3Logic::GetSelectedChip() { return selectedChip; } std::vector TMatch3Logic::GetAvailableMatchingChips() { std::vector result; for (cardinal x=0; xIsReturning = isReturning; ChipMatrix[p1.v[0]][p1.v[1]].ChipState = TChip::CS_SWAPPING; ChipMatrix[p2.v[0]][p2.v[1]].ChipState = TChip::CS_SWAPPING; } void TMatch3Logic::ResetChipPos(ivec2 p) { vec2 posFrom(LeftBottomPosField.v[0] + p.v[0]*Match3FieldParams.CellWidth, LeftBottomPosField.v[1] + p.v[1]*Match3FieldParams.CellHeight); vec2 posTo(LeftBottomPosField.v[0] + (p.v[0] + 1)*Match3FieldParams.CellWidth, LeftBottomPosField.v[1] + (p.v[1] + 1)*Match3FieldParams.CellHeight); std::vector vertexCoordVec = MakeVertexCoordVec(posFrom, posTo); TChip& chip = ChipMatrix[p.v[0]][p.v[1]]; for (cardinal i = 0; isecond.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB][chip.VertexListShift + i] = vertexCoordVec[i]; } chip.RenderPair->second.NeedRefreshBuffer = true; } void TMatch3Logic::UpdateLogic(cardinal 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; } ivec2 p = i->Chip; vec2 leftBottomPos = i->Pos; vec2 halfPos = vec2(Match3FieldParams.CellWidth / 2.f, Match3FieldParams.CellHeight / 2.f); vec2 centerPos = leftBottomPos + halfPos; std::vector vertexCoordArr = MakeVertexCoordVec(centerPos - (1.f - i->T)*halfPos, centerPos + (1.f - i->T)*halfPos); for (int t = 0; t < 6; t++) { ChipMatrix[p.v[0]][p.v[1]].RenderPair->second.Vec3CoordArr[CONST_STRING_POSITION_ATTRIB][ChipMatrix[p.v[0]][p.v[1]].VertexListShift + t] = vertexCoordArr[t]; } if (i->T == 1.f) { ChipMatrix[p.v[0]][p.v[1]].ChipState = TChip::CS_FINISHING; i = ChipDeletingVector.erase(i); erased = true; } if (i != ChipDeletingVector.end() && !erased) { ++i; } } RemoveBubbles(); } void TMatch3Logic::HitFieldWithPattern(ivec2 pos, std::vector > pattern, std::vector > jumpingPattern) { const float CONST_VELOCITY_TO_ADD = 0.2f; for (cardinal i = 0; i < pattern.size(); i++) { for (int j = static_cast(pattern[i].size()-1); j >=0; j--) { ivec2 fieldPos = pos + ivec2(i,j); if (fieldPos.v[0] >= 0 && fieldPos.v[0] < static_cast(ChipMatrix.size()) && fieldPos.v[1] >= 0 && fieldPos.v[1] < static_cast(ChipMatrix[fieldPos.v[0]].size())) { if (ChipIsStable(fieldPos)) { if (pattern[i][j] > 0) { DestroyChip(fieldPos); InsertEmptyChip(fieldPos.v[0], fieldPos.v[1], 0); } } if (ChipIsLocked(fieldPos)) { ChipMatrix[fieldPos.v[0]][fieldPos.v[1]].ChipState = TChip::CS_STANDBY; } } } } for (cardinal i = 0; i < jumpingPattern.size(); i++) { ivec2 abovePos = pos + ivec2(i, jumpingPattern[i].size()); if (abovePos.v[0] >= 0 && abovePos.v[0] < static_cast(ChipMatrix.size()) && abovePos.v[1] >= 0 && abovePos.v[1] < static_cast(ChipMatrix[i].size())) { if (ChipMatrix[abovePos.v[0]][abovePos.v[1]].ChipState == TChip::CS_FALLING || ChipMatrix[abovePos.v[0]][abovePos.v[1]].ChipState == TChip::CS_STANDBY) { ChipMatrix[abovePos.v[0]][abovePos.v[1]].ChipState = TChip::CS_FALLING; ChipMatrix[abovePos.v[0]][abovePos.v[1]].Velocity += CONST_VELOCITY_TO_ADD; } } for (cardinal j = 0; j < jumpingPattern[i].size(); j++) { ivec2 fieldPos = pos + ivec2(i,j); if (fieldPos.v[0] >= 0 && fieldPos.v[0] < static_cast(ChipMatrix.size()) && fieldPos.v[1] >= 0 && fieldPos.v[1] < static_cast(ChipMatrix[fieldPos.v[0]].size())) { if (ChipMatrix[fieldPos.v[0]][fieldPos.v[1]].ChipState == TChip::CS_FALLING || ChipMatrix[fieldPos.v[0]][fieldPos.v[1]].ChipState == TChip::CS_STANDBY) { if (jumpingPattern[i][j] > 0) { ChipMatrix[fieldPos.v[0]][fieldPos.v[1]].ChipState = TChip::CS_FALLING; ChipMatrix[fieldPos.v[0]][fieldPos.v[1]].Velocity += CONST_VELOCITY_TO_ADD; } } } } } } //================================================ //============ TMatch3Field ====================== //================================================ TMatch3Field::TMatch3Field() { LastTappedPos = vec2(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() { TRenderParams renderParams; renderParams.Transparency = 1.f; boost::shared_ptr px(FileToPropertyTree("match3params.xml")); Match3FieldParams.Serialize(*px); std::vector triangleListVec; for (cardinal i = 0; i < Match3FieldParams.ChipTypeCount; i++) { TriangleListVector.push_back(TRenderPair(Match3FieldParams.ChipTemplateParamsArr[i].SelectedRenderParams, TTriangleList())); } renderParams.TexName = "chip1locked"; TriangleListVector.push_back(TRenderPair(renderParams, TTriangleList())); renderParams.TexName = "chip2locked"; TriangleListVector.push_back(TRenderPair(renderParams, TTriangleList())); renderParams.TexName = "chip3locked"; TriangleListVector.push_back(TRenderPair(renderParams, TTriangleList())); renderParams.TexName = "chip4locked"; TriangleListVector.push_back(TRenderPair(renderParams, TTriangleList())); for (cardinal i = 0; i < Match3FieldParams.ChipTypeCount; i++) { TriangleListVector.push_back(TRenderPair(Match3FieldParams.ChipTemplateParamsArr[i].FinishingRenderParams, TTriangleList())); } for (TRenderPairList::iterator i = TriangleListVector.begin(); i != TriangleListVector.end(); ++i) { triangleListVec.push_back(i); } LeftBottomPos = vec2(150, 0); FillRandomChipMatrix(triangleListVec, LeftBottomPos); //Init everything selectedChip = ivec2(-1, -1); for (TRenderPairList::iterator i = TriangleListVector.begin(); i != TriangleListVector.end(); ++i) { i->second.RefreshBuffer(); } } ivec2 TMatch3Field::PosToChip(vec2 pos) { int x, y; vec2 fieldPos = pos - LeftBottomPos; x = static_cast(fieldPos.v[0] / Match3FieldParams.CellWidth); y = static_cast(fieldPos.v[1] / Match3FieldParams.CellHeight); return ivec2(x, y); } void TMatch3Field::Update(cardinal dt) { TMatch3Logic::UpdateLogic(dt); TRenderPairList::iterator i; for (i = TriangleListVector.begin(); i != TriangleListVector.end(); ++i) { if (i->second.NeedRefreshBuffer) { i->second.RefreshBuffer(); } } int y = 6; y = 6 + y; } void TMatch3Field::OnTapDown(vec2 pos) { //See also OnMove LastTappedPos = pos; LastMovePos = LastTappedPos; ivec2 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 - ivec2(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(vec2 pos) { } void TMatch3Field::OnMove(vec2 shift) { if (selectedChip == ivec2(-1, -1)) { return; } LastMovePos += shift; if ((LastTappedPos - LastMovePos).v[0] >= Match3FieldParams.CellWidth * 0.5f) { ivec2 newPosChip = selectedChip + ivec2(1, 0); if (selectedChip.v[0] <= Match3FieldParams.FieldWidth - 2) { if (ChipsCanBeSwapped(selectedChip, newPosChip)) { SwapChips(selectedChip, newPosChip); UnselectChip(); } } } else if ((LastMovePos - LastTappedPos).v[0] >= Match3FieldParams.CellWidth * 0.5f) { ivec2 newPosChip = selectedChip - ivec2(1, 0); if (selectedChip.v[0] >= 1) { if (ChipsCanBeSwapped(selectedChip, newPosChip)) { SwapChips(selectedChip, newPosChip); UnselectChip(); } } } else if ((LastMovePos - LastTappedPos).v[1] >= Match3FieldParams.CellHeight * 0.5f) { ivec2 newPosChip = selectedChip + ivec2(0, 1); if (selectedChip.v[1] <= Match3FieldParams.FieldHeight - 2) { if (ChipsCanBeSwapped(selectedChip, newPosChip)) { SwapChips(selectedChip, newPosChip); UnselectChip(); } } } else if ((LastTappedPos - LastMovePos).v[1] >= Match3FieldParams.CellHeight * 0.5f) { ivec2 newPosChip = selectedChip - ivec2(0, 1); if (selectedChip.v[1] >= 1) { if (ChipsCanBeSwapped(selectedChip, newPosChip)) { SwapChips(selectedChip, newPosChip); UnselectChip(); } } } } bool TMatch3Field::CheckClick(vec2 mousePos) { vec2 fieldPos = mousePos - LeftBottomPos; if (fieldPos.v[0] >= 0 && fieldPos.v[0] <= Match3FieldParams.FieldWidth*Match3FieldParams.CellWidth) { if (fieldPos.v[1] >= 0 && fieldPos.v[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) { ResourceManager->HalibutAnimationManager.StartAnimation(ChipMatrix[i->v[0]][i->v[1]].AnimName); } }