void FireMap::onTouchEnded(cocos2d::Touch* touch, cocos2d::Event* event) { auto touchPoint = touch->getLocation(); touchPoint = this->convertToNodeSpace(touchPoint); Vec2 test = tileCoordForPosition(touchPoint); log("%f, %f", test.x, test.y); }
bool PtMap::checkCollisionForPosition(CCPoint position) { bool collidable = false; position = tileCoordForPosition(position); int tileGID = _metaLayer->tileGIDAt(position); // Collision checking // In previous Versions, this method checked for every eventuality (Water, NPCs, etc) and that was very expensive. // Right now, it only checks for the Collidable property. Every NPC that steps on a tile makes it collidable and passable again after it // leaves. Water is collidable, but reacts on Action and has its own water property. if (tileGID) { CCStringToStringDictionary *properties = _tileMap->propertiesForGID(tileGID); if (properties) { CCString *collision = properties->objectForKey("Collidable"); if (collision && strcmp(collision->toStdString().c_str(),"True") == 0) { // If Collidable is true, return Yes collidable = true; } else { // If not, ... well. collidable = false; } } } return collidable; }
/*@return the highest layer could build, otherwise NONE */ int MapModel::canBuildOnTilePosition(Point pos){ Point TileLoc = tileCoordForPosition(pos); //@debug modify label. { char buffer[30]; sprintf(buffer, "row:%.0f, col:%.0f", TileLoc.x, TileLoc.y); //getlblTilePos()->setString(buffer); } //@var later need to Resoucre Manager PFComponent *target = nullptr; if (_status == HUD_ID::DEFENSE) target = Building::build(selID); if (_status == HUD_ID::ATTACK) target = Troop::addTroop(selID); CCASSERT(target != nullptr, "target != nullptr"); for (int lr = SZ(_pfLayers) - 1; lr >= 0; lr--){ Point buildingLoc = mapCoordForPosition(pos, lr); //@procedure check for no tiles on the tile. bool noTileOnDirectly = true; if (lr < SZ(_pfLayers) - 1){ for (int tr = 0; tr < target->getOccupy().X; tr++) for (int tc = 0; tc < target->getOccupy().Y; tc++){ for (int offset = 0; offset <= 1; offset++){ Point checkTileLoc = Point(TileLoc.x + tr, TileLoc.y - tc * 2 + offset); if (isTileInsideLayer(checkTileLoc, lr)){ int tileGid = _pfLayers.at(lr + 1)->getTileGIDAt(checkTileLoc); if (tileGid != EMPTY_TILE) noTileOnDirectly = false; } } } } if (!noTileOnDirectly) continue; int couldTileCnt = 0; for (int tr = 0; tr < target->getOccupy().X; tr++) for (int tc = 0; tc < target->getOccupy().Y; tc++){ for (int offset = 1; offset <= 2; offset++){ Point checkTileLoc = Point(TileLoc.x + tr, TileLoc.y - tc * 2 + offset); if (isTileInsideLayer(checkTileLoc, lr)){ int tileGid = _pfLayers.at(lr)->getTileGIDAt(checkTileLoc); Value props = _tileMap->getPropertiesForGID(tileGid); if (!props.isNull()){ ValueMap map = props.asValueMap(); int type_int = 0; if (map.size() == 0) type_int = 0; else type_int = map.at("buildable").asInt(); if (1 == type_int){ couldTileCnt++; break; } } } } } if (couldTileCnt == target->getOccupy().X*target->getOccupy().Y) return lr + 1; } return -1; }
__Array * Level::getSurroundingTilesAtPosition(Point position, TMXLayer * layer) { __Array * gids = __Array::create(); Point plPos = tileCoordForPosition(position); for (int i = 0; i < 9; i++) { int c = i % 3; int r = (int)(i / 3); Point tilePos = Point(plPos.x + (c - 1), plPos.y + (r - 1)); if (tilePos.y > (_map->getMapSize().height - 1)) { gameOver(0); return gids; } int tgid = layer->getTileGIDAt(tilePos); Rect tileRect = this->tileRectFromTileCoords(tilePos); Gid * tileDict = new Gid(tgid, tileRect.origin.x, tileRect.origin.y, tilePos); gids->addObject(tileDict); } gids->removeObjectAtIndex(4); gids->insertObject(gids->getObjectAtIndex(2), 6); gids->removeObjectAtIndex(2); gids->exchangeObjectAtIndex(4, 6); gids->exchangeObjectAtIndex(0, 4); return gids; }
std::vector<tileInfo> GameLevelLayer::getSurroundingTilesAtPosition(Vec2 position, TMXLayer* layer) { Vec2 plPos = tileCoordForPosition(position); //1 std::vector<tileInfo> gids; //2 for (int i = 0; i < 9; i++) { //3 int c = i % 3; int r = (int)(i / 3); Vec2 tilePos = Vec2(plPos.x + (c - 1), plPos.y + (r - 1)); if (tilePos.y > (m_pMap->getMapSize().height - 1)) { //fallen in a hole gameOver(false); return gids; } int tgid = layer->getTileGIDAt(tilePos); //4 Rect tileRect = tileRectFromTileCoords(tilePos); //5 tileInfo tileDict; tileDict.gid = tgid; tileDict.x = tileRect.origin.x; tileDict.y = tileRect.origin.y; tileDict.tilePos = tilePos; gids.push_back(tileDict); //6 } gids.erase(gids.begin()+4); gids.insert(gids.begin()+6, gids[2]); gids.erase(gids.begin()+2); tileInfo temp; temp = gids[6]; gids[6] = gids[4]; gids[4] = temp; temp = gids[0]; gids[0] = gids[4]; gids[4] = temp; /* for (int i=0;i<gids.size();++i) { printf("i: %d\n", i); printf("gid: %d\n", gids[i].gid); printf("tilePos.x: %f\n", gids[i].tilePos.x); printf("tilePos.y: %f\n", gids[i].tilePos.y); printf("x: %f\n", gids[i].x); printf("y: %f\n\n", gids[i].y); } */ return gids; }
void MapModel::tryTouchEnded(){ CCLOG("MapModel::tryTouchEnded()"); ResourceModel *rm = ResourceModel::getModel(); //@brief just click once CCLOG("ccpdist. %.2f\n", _pressLoc.distance(_touchLocation)); if (_pressLoc.distance(_touchLocation) < 6.5f){ TilePoint tileLoc = tileCoordForPosition(_touchLocationInGameLayer); for (int lr = 5; lr >= 0; lr--){ for (auto &building : _buildings) if (building->getID() == PFComponent::HQ_GID){ MapPoint coord = mapCoordForTilePoint(tileLoc, lr); if (coord == building->getCoord() && lr == building->getZ()){ CCLOG(">>@ The building belongs %s", building->getOwner().c_str()); char buffer[1000]; sprintf(buffer, ".%.0f-%.0f", coord.x, coord.y); string goMapStr = mapName + string(buffer) + ".tmx"; writeMapInfo(); SceneManager::goMapScreen(goMapStr, HUD_ID::DEFENSE); return; } } } } if (_selSprite){ bool forbid = false; if (_status == HUD_ID::ATTACK){ Rect backgroundRect = Rect(_background->getPositionX(), _background->getPositionY(), _background->getContentSize().width, _background->getContentSize().height); if (backgroundRect.containsPoint(_touchLocation)) forbid = true; } if (!forbid){ int isBuildableLevel = canBuildOnTilePosition(_touchLocationInGameLayer); if (~isBuildableLevel){ if (_status == HUD_ID::DEFENSE && PlayerManager::getInstance()->getCurPlayer()->canAddBuilding(selID)){ addBuilding(_touchLocationInGameLayer, isBuildableLevel); PlayerManager::getInstance()->getCurPlayer()->consumeResourceByBuilding(selID); } else if (_status == HUD_ID::ATTACK && PlayerManager::getInstance()->getCurPlayer()->canAddTroop(selID)){ addBuilding(_touchLocationInGameLayer, isBuildableLevel); PlayerManager::getInstance()->getCurPlayer()->consumeResourceByTroop(selID); //notify //send add building notify } } } _selGroups->removeAllChildren(); _selSprite = NULL; _selSpriteRange = NULL; showAllRange(false); } }
void TileMapScene::hitWall(float) { auto playerPoint = player->getPosition(); auto realPlayerPoint = playerPoint-bgOrigin; int tileGid = meta->getTileGIDAt(tileCoordForPosition(realPlayerPoint)); if(tileGid) { player->stopAllActions(); } }
CCArray* CollisionEngine::getSurroundingTilesAtPosition(CCPoint position, CCTMXLayer *layer) { CCPoint plPos = tileCoordForPosition(position); CCArray *gids = CCArray::create(); for (int i = 0; i < 9; i++) { int c = i % 3; int r = (int) (i / 3); CCPoint tilePos = ccp(plPos.x + (c - 1), plPos.y + (r - 1)); // fall into a hole if (tilePos.y > (map->getMapSize().height - 1)) { // kill the enemy here //this->gameOver(false); return NULL; } int tgid = layer->tileGIDAt(tilePos); CCRect tileRect = tileRectFromTileCoords(tilePos); CCDictionary *tileDict = CCDictionary::create(); CCXNumericData *tilePosData = CCXNumericData::create(); CCXNumericData *tgidData = CCXNumericData::create(); CCXNumericData *rectOrgXData = CCXNumericData::create(); CCXNumericData *rectOrgYData = CCXNumericData::create(); tilePosData->setPoint(tilePos); tgidData->setIntValue(tgid); rectOrgXData->setFloatValue(tileRect.origin.x); rectOrgYData->setFloatValue(tileRect.origin.y); tileDict->setObject(tgidData, "gid"); tileDict->setObject(rectOrgXData, "x"); tileDict->setObject(rectOrgYData, "y"); tileDict->setObject(tilePosData, "tilePos"); gids->addObject(tileDict); } gids->removeObjectAtIndex(4); gids->insertObject(gids->objectAtIndex(2), 6); gids->removeObjectAtIndex(2); gids->exchangeObjectAtIndex(4, 6); gids->exchangeObjectAtIndex(0, 4); return gids; }
void TileMapScene::onTouchEnded(Touch* ptouch,Event* pEvent) { auto movePoint = ptouch->getLocation(); auto playerPoint = player->getPosition()+Vec2(16,16); auto moveDistance = movePoint.distance(playerPoint); //auto offSetX = movePoint.x - playerPoint.x; //auto offSetY = movePoint.y - playerPoint.y; auto realMovePoint = movePoint-bgOrigin; auto realPlayerPoint = playerPoint-bgOrigin; //if(realMovePoint.x<=1280&&realMovePoint.x>=0&&realMovePoint.y<=1280&&realMovePoint.y>=0); { Point tileCoord = tileCoordForPosition(realMovePoint); int tileGid = meta->getTileGIDAt(tileCoord); if(tileGid) { auto properties = tilemap->getPropertiesForGID(tileGid).asValueMap(); if(!properties.empty()) auto collision = properties["Collidable"].asString(); } if(touchTime<10&&!tileGid) { int x = movePoint.x; int y = movePoint.y; auto playerTileCoord = tileCoordForPosition(realPlayerPoint); auto dist = playerTileCoord.distance(tileCoord); if(playerTileCoord==tileCoord) return; this->unscheduleAllSelectors(); vec.clear(); Astar(playerTileCoord,tileCoord); int c = count; this->schedule(schedule_selector(TileMapScene::move),0.2,c,0); } } }
bool FiledScene::init(){ if (!Layer::init()) return false; _isGameOver = false; auto visibleSize = Director::getInstance()->getVisibleSize(); _screenWidth = visibleSize.width; _screenHeight = visibleSize.height; _tileMap = TMXTiledMap::create("field_map.tmx"); _tileMap->setAnchorPoint(Vec2::ANCHOR_MIDDLE); _tileMap->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2)); // ②获取障碍层,并设置障碍层为不可见 _collidable = _tileMap->getLayer("collidable"); _collidable->setVisible(false); /********③初始化读取地图所有网格,并确定网格对象是否是障碍物,将信息保存到网格二维数组**************/ for (int i = 0; i < _tileMap->getMapSize().width; i++) { // 内部网格集合([x,0]-[x-20]),存储网格 Vector<Grid*> inner; for (int j = 0; j < _tileMap->getMapSize().height; j++) { // 设置网格对象的x轴和y轴以及是否可通过变量值 Grid *o = Grid::create(i, j); // 将网格加入到集合 inner.pushBack(o); } // 将内部集合加入到网格集合 _gridVector.push_back(inner); } // 循环保存根据每个网格的x轴和y轴查找对应的地图的GID,判断是否可通过 for (int i = 0; i < _gridVector.size(); i++) { Vector<Grid*> inner = _gridVector.at(i); // 循环内部网格集合 for (int j = 0; j < inner.size(); j++) { // 获取每一个网格对象 Grid *grid = inner.at(j); // 获取每一个网格对象对应的的坐标 Vec2 tileCoord = Vec2(grid->getX(), grid->getY()); // 使用TMXLayer类的tileGIDAt函数获取TileMap坐标系里的“全局唯一标识”GID int tileGid = _collidable->getTileGIDAt(tileCoord); if (tileGid) { // 使用GID来查找指定tile的属性,返回一个Value Value properties = _tileMap->getPropertiesForGID(tileGid); // 返回的Value实际是一个ValueMap ValueMap map = properties.asValueMap(); // 查找ValueMap,判断是否有”可碰撞的“物体,如果有,设置网格对象的isPass变量为false std::string value = map.at("collidable").asString(); if (value.compare("true") == 0) { grid->setPass(false); } } } } // 人物出场特效 auto effects_player_out = Sprite::create("effects/effects_player_out/effects_player_out_11.png"); effects_player_out->setPosition(Vec2(visibleSize.width*0.3,visibleSize.height*0.3)); this->addChild(effects_player_out, 1); auto player_out_animate = getAnimateByName("effects/effects_player_out/effects_player_out_", 0.1f, 11); auto delay1 = DelayTime::create(1.5f); auto fadeOut = FadeOut::create(0.2f); auto sequence = Sequence::create(delay1, player_out_animate, fadeOut, nullptr); effects_player_out->runAction(sequence); _player = SpriteBase::create("player/player_sword/player_sword_stand.png"); this->addChild(_player, 1); _player->setPosition(Vec2(visibleSize.width*0.3, visibleSize.height*0.3)); this->addChild(_tileMap,0); _player->setFlippedX(true); XmlTools::readPlayerData(_player); /// 传送门 ArmatureDataManager::getInstance()->addArmatureFileInfo("/buildings/gate/AnimationStart0.png", "/buildings/gate/AnimationStart0.plist", "/buildings/gate/AnimationStart.ExportJson"); Armature *armature = Armature::create("AnimationStart"); armature->getAnimation()->play("Start"); this->addChild(armature); armature->setScale(0.3); armature->setPosition(Vec2(visibleSize.width*0.9, visibleSize.height*0.7)); auto gate_effect = ParticleSystemQuad::create("effects/gate_effect.plist"); this->addChild(gate_effect); gate_effect->setScale(0.3); gate_effect->setPosition(Vec2(visibleSize.width*0.9, visibleSize.height*0.75)); gate_effect->setPositionType(kCCPositionTypeRelative); // 结束战斗按钮 auto end_fight_button = Button::create("ui/end_fight.png"); end_fight_button->setPosition(Vec2(visibleSize.width*0.95, visibleSize.height*0.97)); end_fight_button->setScale(0.5f); this->addChild(end_fight_button, 0); //结束战斗对话框 auto end_fight_dialog_bg = Sprite::create("ui/end_fight_dialog_bg.png"); end_fight_dialog_bg->setAnchorPoint(Vec2::ANCHOR_MIDDLE); end_fight_dialog_bg->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2)); this->addChild(end_fight_dialog_bg, 3); // 确定结束战斗按钮 auto end_fight_sub_button = Button::create("ui/end_fight_sub_button.png"); end_fight_dialog_bg->addChild(end_fight_sub_button); end_fight_sub_button->setAnchorPoint(Vec2::ZERO); end_fight_sub_button->setPosition(Vec2(20, 30)); end_fight_sub_button->addTouchEventListener([=](Ref* pSender, Widget::TouchEventType type){ XmlTools::writePlayerData(_player); auto transition = TransitionSplitCols::create(2, Game::createScene()); Director::getInstance()->pushScene(transition); }); // 取消结束战斗按钮 auto end_fight_cancel_button = Button::create("ui/end_fight_cancel_button.png"); end_fight_dialog_bg->addChild(end_fight_cancel_button); end_fight_cancel_button->setAnchorPoint(Vec2::ZERO); end_fight_cancel_button->setPosition(Vec2(140, 30)); end_fight_cancel_button->addTouchEventListener([=](Ref* pSender, Widget::TouchEventType type){ end_fight_dialog_bg->setVisible(false); }); end_fight_dialog_bg->setVisible(false); end_fight_button->addTouchEventListener([=](Ref* pSender, Widget::TouchEventType type){ if (type == Widget::TouchEventType::ENDED){ end_fight_dialog_bg->setVisible(true); } }); // ⑤创建事件监听器 auto gameListener = EventListenerTouchOneByOne::create(); // 响应触摸事件函数 gameListener->onTouchBegan = [](Touch* touch, Event* event){return true; }; gameListener->onTouchEnded = [=](Touch *touch, Event *event){ // OpenGL坐标 Vec2 touchLocation = touch->getLocation(); // 将触摸点坐标转换成相对的Node坐标 Vec2 nodeLocation = this->convertToNodeSpace(touchLocation); // 玩家镜像反转 if (_player->getPosition().x > nodeLocation.x) { if (_player->isFlippedX() == true){ _player->setFlippedX(false); } } else{ if (_player->isFlippedX() == false) _player->setFlippedX(true); } // 用玩家位置作为起点,触摸点作为终点,转换为网格坐标,在地图上查找最佳到达路径 Vec2 from = tileCoordForPosition(_player->getPosition()); Vec2 to = tileCoordForPosition(nodeLocation); // 如果终点是不可通过(即有障碍物)的位置,则直接return int tileGid = _collidable->getTileGIDAt(to); if (tileGid) { // 使用GID来查找指定tile的属性,返回一个Value Value properties = _tileMap->getPropertiesForGID(tileGid); // 返回的Value实际是一个ValueMap ValueMap map = properties.asValueMap(); // 查找ValueMap,判断是否有”可碰撞的“物体,如果有,直接返回 std::string value = map.at("collidable").asString(); if (value.compare("true") == 0) { return; } } /**************玩家精灵移动到指定位置************************/ // 在玩家精灵移动过程中,如果用户在此触摸屏幕移动玩家时,如果精灵没有运行动作,直接执行移动动作 if (_player->getNumberOfRunningActions() == 0) { this->playerMover(nodeLocation); } else { //如果精灵正在运行动作,先停止精灵动作和层动作,再执行移动动作 _player->stopAllActions(); this->stopAllActions(); this->playerMover(nodeLocation); } // 接触传送门, 如果boss被杀死, 则传送回主场景. if (_player->getBoundingBox().intersectsRect(armature->getBoundingBox())){ if (monster_1->isVisible()==false){ _player->setExp(_player->getExp() + 200); _player->setGold(_player->getGold() + 1000); XmlTools::writePlayerData(_player); const string player_task = FileUtils::getInstance()->fullPathForFilename("data/kill_count.xml"); ssize_t player_taskFile_size; char* pPlayerTaskContent = (char*)FileUtils::getInstance()->getFileData(player_task, "r", &player_taskFile_size); TiXmlDocument* player_task_el = new TiXmlDocument(); player_task_el->Parse(pPlayerTaskContent, 0, TIXML_ENCODING_UTF8); TiXmlElement* rootElement = player_task_el->RootElement();//Root TiXmlElement* player_kill_count_1 = rootElement->FirstChildElement(); string accept = player_kill_count_1->GetText(); TiXmlElement* player_kill_count_2 = player_kill_count_1->NextSiblingElement(); stringstream ss; string kill_count = player_kill_count_2->GetText(); int kill_count_int; ss << kill_count; ss >> kill_count_int; if (accept=="true"){ kill_count_int += 1; player_kill_count_2->Clear(); string kill_count_str; stringstream ss; ss << kill_count_int; ss >> kill_count_str; TiXmlText* kill_count_text = new TiXmlText(kill_count_str.c_str()); player_kill_count_2->LinkEndChild(kill_count_text); player_task_el->SaveFile(player_task.c_str()); } auto transform_to = TransitionSplitCols::create(2.0f, Game::createScene()); Director::getInstance()->pushScene(transform_to); }
MapPoint MapModel::mapCoordForPosition(Point position, int level){ Point tileLoc = tileCoordForPosition(position); return mapCoordForTilePoint(tileLoc, level); }