void CivilianBAIState::setupPatrol() { Node *node; if (_toNode != 0 && _unit->getPosition() == _toNode->getPosition()) { if (_traceAI) { Log(LOG_INFO) << "Patrol destination reached!"; } // destination reached // head off to next patrol node _fromNode = _toNode; _toNode = 0; } if (_fromNode == 0) { // assume closest node as "from node" // on same level to avoid strange things, and the node has to match unit size or it will freeze int closest = 1000000; for (std::vector<Node*>::iterator i = _save->getNodes()->begin(); i != _save->getNodes()->end(); ++i) { node = *i; int d = _save->getTileEngine()->distanceSq(_unit->getPosition(), node->getPosition()); if (_unit->getPosition().z == node->getPosition().z && d < closest && node->getType() & Node::TYPE_SMALL) { _fromNode = node; closest = d; } } } // look for a new node to walk towards int triesLeft = 5; while (_toNode == 0 && triesLeft) { triesLeft--; _toNode = _save->getPatrolNode(true, _unit, _fromNode); if (_toNode == 0) { _toNode = _save->getPatrolNode(false, _unit, _fromNode); } if (_toNode != 0) { _save->getPathfinding()->calculate(_unit, _toNode->getPosition()); if (_save->getPathfinding()->getStartDirection() == -1) { _toNode = 0; } _save->getPathfinding()->abortPath(); } } if (_toNode != 0) { _patrolAction->actor = _unit; _patrolAction->type = BA_WALK; _patrolAction->target = _toNode->getPosition(); } else { _patrolAction->type = BA_RETHINK; } }
vector<CL_Vec2f> nodes::aStarNodeVersion(Node* start, Node* end) { vector<CL_Vec2f> path; // Define points to work with //Point *start = getPointFromCoord(x1, y1); //Point *end = getPointFromCoord(x2, y2); Node *current; Node *child; // Define the open and the close list list<Node*> openList; list<Node*> closedList; list<Node*>::iterator i; // Add the start point to the openList openList.push_back(start); start->opened = true; current = start; bool skip_cuz_not_found = false; //we had to skip because we didnt found it int x,y; while (current != end) { if (openList.size() == 0) { skip_cuz_not_found = true; break; } i = openList.begin(); current = (*i); // Look for the smallest F value in the openList and make it the current point for (i; i != openList.end(); ++ i) { if ((*i)->getFScore() <= current->getFScore()) { current = (*i); } } // Stop if we reached the end if (current == end) { break; } // Remove the current point from the openList openList.remove(current); current->opened = false; // Add the current point to the closedList closedList.push_back(current); current->closed = true; // Get all current's adjacent walkable points for (int i = 0; i < current->childs.size(); i++) { /*// If it's current point then pass if (i==0) { x=1; y=0; } else if (i==1) { x=-1; y=0; } else if (i==2) { x=0; y=1; } else if (i==3) { x=0; y=-1; } // Get this point*/ child = current->childs[i]; // If it's closed or not walkable then pass if (child == 0 || child->closed || !child->walkable) { continue; } // If it's already in the openList if (child->opened) { // If it has a wroste g score than the one that pass through the current point // then its path is improved when it's parent is the current point if (child->getGScore() > child->getGScore(current)) { // Change its parent and g score child->setParent(current); child->computeScores(end); } } else { // Add it to the openList with current point as parent openList.push_back(child); child->opened = true; // Compute it's g, h and f score child->setParent(current); child->computeScores(end); } } } // Reset for (i = openList.begin(); i != openList.end(); ++ i) { (*i)->opened = false; } for (i = closedList.begin(); i != closedList.end(); ++ i) { (*i)->closed = false; } // Resolve the path starting from the end point if (skip_cuz_not_found) { return path; //we return an empty path :P } while (current->hasParent() && current != start) { //LogMsg("%f %f", current->getPosition().x,current->getPosition().y); path.push_back(current->getPosition()); current = current->getParent(); } return path; }
/** * cause for moving the robot from way point to another way point */ void Robot::TryToReachNextWaypoint() { double x = _pp.GetXPos(); double y = _pp.GetYPos(); double yaw = _pp.GetYaw(); //double deg = Settings::radiansToDeg(yaw); Node* nextWayPoint = wayPoints[nextWayPointIndex]; Position nextWaypointPosition = nextWayPoint->getPosition(); double cy = mapToWorldY(nextWaypointPosition.first); double cx = mapToWorldX(nextWaypointPosition.second); double deltaX = cx-x; double deltaY = cy-y; double s = atan2(deltaY , deltaX); float linearSpeed = Settings::LINEAR_SPEED; float radialSpeed = Settings::RADIAL_SPEED; cout << "Yaw is " << yaw << endl; cout << "S is " << s << endl; if (yaw >=0 && s >= 0) { cout<<"Q I"<<endl; if (yaw > s + 0.1) { cout << "a" << endl; _pp.SetSpeed(0, -radialSpeed); } else if (yaw < s - 0.3) { cout << "b" << endl; _pp.SetSpeed(0, radialSpeed); // (radialSpeed old value was 0.3) } else { cout << "c" << endl; _pp.SetSpeed(linearSpeed, 0); } } else if (yaw < 0 && s < 0) { cout<<"Q II"<<endl; if (yaw > s + 0.3) { cout << "a" << endl; _pp.SetSpeed(0, -radialSpeed); } else if (yaw < s - 0.3) { cout << "b" << endl; _pp.SetSpeed(0, radialSpeed); } else { cout<<"Q IV"<<endl; cout << "c" << endl; _pp.SetSpeed(linearSpeed, 0); } } else if (yaw >=0 && s < 0) { cout<<"Q III"<<endl; if (M_PI - yaw + M_PI - abs(s) > yaw + abs(s)) { cout << "a" << endl; _pp.SetSpeed(0, -radialSpeed); } else if (M_PI - yaw + M_PI - abs(s) < yaw + abs(s)) { cout << "b" << endl; _pp.SetSpeed(0, radialSpeed); } else { cout << "c" << endl; _pp.SetSpeed(linearSpeed, 0); } } else if (yaw < 0 && s >= 0) { if (M_PI - abs(yaw) + M_PI - s > abs(yaw) + s) { cout << "a" << endl; _pp.SetSpeed(0, radialSpeed); } else if (M_PI - abs(yaw) + M_PI - s < abs(yaw) + s) { cout << "b" << endl; _pp.SetSpeed(0, -radialSpeed); } else { cout << "c" << endl; _pp.SetSpeed(linearSpeed, 0); } } cout << "next way point: " << nextWayPointIndex << " The point is: " << cx << "," << cy << endl; }
static std::string getPositionString(const Node& node) { return " decl" + to_string(node.getPosition()); }
bool GamesScence::init() { if ( !Layer::init() ) { return false; } m_blockSize = 20.0f; m_isGgameRunning = false; m_next3Tetrominos.clear(); Widget* pRootWidget = cocostudio::GUIReader::getInstance()->widgetFromJsonFile("TetrisUi/TetrisUi.ExportJson"); this->addChild(pRootWidget,0); //最高分显示 m_highestLabel = (TextAtlas*)Helper::seekWidgetByName(pRootWidget,"atlHighest"); int highest = UserDefault::getInstance()->getIntegerForKey("TheHighestScore",0); char strHighest[20]; sprintf(strHighest,"%d",highest); m_highestLabel->setString(strHighest); //分数显示 m_scoreCount.setNumberLabel((TextAtlas*)Helper::seekWidgetByName(pRootWidget,"atlScore")); //提示消除了多少行 m_clearCount.setNumberLabel((TextAtlas*)Helper::seekWidgetByName(pRootWidget,"atlNumClear")); //菜单按钮 m_btMenu = (Button*)Helper::seekWidgetByName(pRootWidget,"btMenu"); m_btMenu->addTouchEventListener(CC_CALLBACK_2(GamesScence::btMenuCallback,this)); //底板的纵横线 m_imgFrame = (ImageView*)Helper::seekWidgetByName(pRootWidget,"imgFrame"); //下一个方块的提示 ImageView* nextTip = (ImageView*)Helper::seekWidgetByName(pRootWidget,"imgTipBoard"); m_nextTipPos = nextTip->getPosition(); m_nextTipSize = nextTip->getContentSize(); //游戏菜单 m_panelManager.setMenuPanel((Layout*)Helper::seekWidgetByName(pRootWidget,"layMenu")); m_panelManager.setMenuPanelVisible(false,true); ((Button*)Helper::seekWidgetByName(pRootWidget,"btStart"))->addTouchEventListener(CC_CALLBACK_2(GamesScence::btStartCallback,this)); ((Button*)Helper::seekWidgetByName(pRootWidget,"btContinue"))->addTouchEventListener(CC_CALLBACK_2(GamesScence::btContinueCallback,this)); ((Button*)Helper::seekWidgetByName(pRootWidget,"btRankList"))->addTouchEventListener(CC_CALLBACK_2(GamesScence::btRankListCallback,this)); ((Button*)Helper::seekWidgetByName(pRootWidget,"btHelp"))->addTouchEventListener(CC_CALLBACK_2(GamesScence::btHelpCallback,this)); ((Button*)Helper::seekWidgetByName(pRootWidget,"btLeave"))->addTouchEventListener(CC_CALLBACK_2(GamesScence::btLeaveCallback,this)); //GameOver菜单 m_panelManager.setGameOverPanel((Layout*)Helper::seekWidgetByName(pRootWidget,"layGameOver")); m_panelManager.setGameOverPanelVisible(false); ((Button*)Helper::seekWidgetByName(pRootWidget,"btRestart"))->addTouchEventListener(CC_CALLBACK_2(GamesScence::btRestartCallback,this)); //上传分数面板 m_panelManager.setUploadScorePanel((Layout*)Helper::seekWidgetByName(pRootWidget,"layUploadScore")); m_panelManager.setUploadScorePanelVisible(0,false); m_nickNameInput = (TextField*)Helper::seekWidgetByName(pRootWidget,"tfNickName"); ((Button*)Helper::seekWidgetByName(pRootWidget,"btConfirmation"))->addTouchEventListener(CC_CALLBACK_2(GamesScence::btConfirmationCallback,this)); ((Button*)Helper::seekWidgetByName(pRootWidget,"btCancel"))->addTouchEventListener(CC_CALLBACK_2(GamesScence::btCancelCallback,this)); //排行榜(只是显示用,与服务器的交互放m_list里实现) ListView* uilist = (ListView*)Helper::seekWidgetByName(pRootWidget,"listRankList"); m_panelManager.setRankList(uilist); m_panelManager.setRankListVisible(false); ////真正与服务器交互的排行榜功能类 m_list = RankList::create(uilist); this->addChild(m_list); //游戏底板 Node* pFrame = Helper::seekWidgetByName(pRootWidget,"imgFrame"); Size frameSize = pFrame->getContentSize(); m_bgBpard = BackgroundBoard::create(m_blockSize); m_bgBpard->setPosition(pFrame->getPosition()); m_bgBpard->setScaleX(frameSize.width/BACKGROUND_COL/m_blockSize); m_bgBpard->setScaleY(frameSize.height/BACKGROUND_ROW/m_blockSize); m_bgBpard->setDropDelayTime(0.5f); m_bgBpard->setClearLineListener(this,clearLine_selector(GamesScence::onAddScore)); m_bgBpard->setNextBlockListener(this,nextBlock_selector(GamesScence::onNextBlock)); m_bgBpard->setGameOverListener(this,gameOver_selector(GamesScence::onGameOver)); Helper::seekWidgetByName(pRootWidget,"root")->addChild(m_bgBpard,0); return true; }
void Packing::layout_hyperbolic(int centerCircle) { qDebug() << "Performing hyperbolic layout..."; QList<Node*> unplacedNodes(this->nodes); //Nodes which have not yet been placed QList<Node*> placedNodes; //nodes which have been placed but do not have full flowers. QList<Node*> floweredNodes; //nodes for which their entire flower has been placed. //place the first circle bool foundCenterCircle = false; for(Node* n: unplacedNodes){ //find the circle that is to be the center circle. if (n->getId() == centerCircle){ qDebug() << "Placing first node #" << n->getId() << " at (0, 0)"; n->setPosition(QPointF(0, 0)); placedNodes.append(n); unplacedNodes.removeAll(n); //place the second node to right of the first node. Node *m = n->getNeibhours().first(); if(!n->hasFullFlower()){ int mindex = 1; do{ m = n->getNeibhours().at(mindex); mindex++; } while(!m->hasFullFlower() && mindex < n->getNeibhours().length()); if(mindex >= n->getNeibhours().length()){ qDebug() << "Neither M or N has full flower. Fail."; return; } } qreal h1 = n->getRadius(); qreal h2 = m->getRadius(); //using the inverse of the log-formula //since the first point is at the origin we don't have to use an //isometry. qreal s = (exp(h1 + h2) - 1)/(exp(h1 + h2) + 1); m->setPosition(QPointF(s, 0)); qDebug() << "Placing second node #" << m->getId() << " at (" << s << ", 0)"; placedNodes.append(m); unplacedNodes.removeAll(m); foundCenterCircle = true; break; } } //fail if we didn't find the center circle if(!foundCenterCircle){ qDebug() << "Could not find specified center circle. Fail."; return; } //now continue until all nodes have been placed... while(!unplacedNodes.empty()){ bool nonFullOp = false; //find a placed node that does not have a full flower Node *w; int wIndex = 0; do{ w = placedNodes.at(wIndex); wIndex++; } while(!w->hasFullFlower() && wIndex < placedNodes.length()); //if w does not have a full flower at this point, then we need to get creative if(!w->hasFullFlower() && unplacedNodes.contains(w->getNeibhours().first())){ nonFullOp = true; } //find a nbhr of w which has been placed. int nbhrIndex = 0; if(nonFullOp){ nbhrIndex = w->getNeibhourCount() - 1; while(unplacedNodes.contains(w->getNeibhours().at(nbhrIndex))) nbhrIndex--; } else{ //not an infinite loop since every placed node has at least one placed neibhour. while(unplacedNodes.contains(w->getNeibhours().at(nbhrIndex))) nbhrIndex++; } //now continue going around the nodes until we find the first one that is unplaced //we also need to check if the full flower has been placed. bool fullFlower = false; int nbhrOrigin = nbhrIndex; while(!unplacedNodes.contains(w->getNeibhours().at(nbhrIndex))){ nbhrIndex = (nbhrIndex + 1) % w->getNeibhours().length(); //if we wrap completely around, then we know that w's full flower //has been placed. if(nbhrIndex == nbhrOrigin){ fullFlower = true; break; } } //if the full flower is complete, then update the lists and try again //with a different node. if(fullFlower){ placedNodes.removeAll(w); floweredNodes.append(w); continue; } Node *u; if(nonFullOp){ if(nbhrIndex == w->getNeibhourCount() - 1) u = w->getNeibhours().first(); else u = w->getNeibhours().at(nbhrIndex+1); } else{ if(nbhrIndex == 0) u = w->getNeibhours().last(); else u = w->getNeibhours().at(nbhrIndex-1); } //now v becomes this "first unplaced node" Node *v = w->getNeibhours().at(nbhrIndex); if(!unplacedNodes.contains(v)){ } //now we create a lambda phi which is an isometry QPointF wp = w->getPosition(); auto phi = [wp](QPointF zz)->QPointF{ std::complex<double> c(wp.x(), wp.y()); std::complex<double> cbar(wp.x(), -wp.y()); std::complex<double> z(zz.x(), zz.y()); std::complex<double> result = (z - c)/(1.0 - cbar*z); return QPointF(result.real(), result.imag()); }; auto phiinv = [wp](QPointF zz)->QPointF{ std::complex<double> c(wp.x(), wp.y()); std::complex<double> cbar(wp.x(), -wp.y()); std::complex<double> z(zz.x(), zz.y()); std::complex<double> result = (z + c)/(1.0 + cbar*z); return QPointF(result.real(), result.imag()); }; //find the angle <UWV=alpha qreal alpha = this->angle(w, u, v); QPointF relU = phi(u->getPosition()); qreal beta = atan2(relU.y(), relU.x()); //we need to determine if the nodes are currently being laid out in a //clockwise or anticlockwise manner. Thus we need to look at the two //previous unplaced nodes, and look at their relative angles. //this only works if w has two or more placed neibhours so far. int placedCount = 0; int isCCW = true; for(Node *n: placedNodes + floweredNodes){ if(w->isNeibhour(n)) placedCount++; } if(placedCount >= 2 && w->getNeibhours().length() >= 3){ //grab uprime Node *uprime; if(nonFullOp){ if(nbhrIndex == w->getNeibhourCount() - 1){ uprime = w->getNeibhours().at(1); } else if(nbhrIndex == w->getNeibhourCount() - 2){ uprime = w->getNeibhours().at(2); } else{ uprime = w->getNeibhours().at(nbhrIndex + 2); } } else{ if(nbhrIndex == 0){ uprime = w->getNeibhours().at(w->getNeibhours().length() - 2); } else if(nbhrIndex == 1){ uprime = w->getNeibhours().last(); } else{ uprime = w->getNeibhours().at(nbhrIndex - 2); } } //now look at angles of uprime and u //QPointF relUPrime = uprime->getPosition() - w->getPosition(); QPointF relUPrime = phi(uprime->getPosition()); qreal betaprime = atan2(relUPrime.y(), relUPrime.x()); //difference between angles should be less than PI radians qreal diff = fmod(betaprime - beta + 2*PI, 2*PI); if(diff < PI){ //betaprime is "ahead" of beta, so we should continue clockwise isCCW = false; } else{ //betaprime is "behind" beta, so continue anticlockwise isCCW = true; } } qreal arg; if(isCCW) arg = fmod(beta+alpha+2*PI, 2*PI); else arg = fmod(beta-alpha+2*PI, 2 * PI); //now we plot the position of v, assuming that w is at the origin. //find euclidean distance s such that the hyperbolic distance from 0 to //s is equal to the sum of the hyperbolic radii. qreal r = w->getRadius() + v->getRadius(); qreal s = (exp(r) - 1.0)/(exp(r)+1.0); //now plot the point using sin and cosine QPointF pos(s*cos(arg), s*sin(arg)); //this is teh position relative to w. Now for //set the position of v, remembering to take the isometry into account. QPointF position = phiinv(pos); //QPointF position = w->getPosition() + pos; v->setPosition(position); //and update the lists unplacedNodes.removeAll(v); placedNodes.append(v); //and then we continue } qDebug() << "Layout complete"; }
void CFootBotUN::ControlStep() { printf("\n --------- UN %s - Simulation step %d -----------\n", GetRobot().GetRobotId().c_str(), CSimulator::GetInstance().GetSpace().GetSimulationClock()); m_pcLEDs->SetAllColors(CColor::BLUE); /** Wifi communications section */ std::ostringstream str(ostringstream::out); if (amIaGenerator) { if (m_iSendOrNotSend % m_generatePacketInterval == 0) { if (skipFirstSend) { skipFirstSend = false; } else { sendPackets++; str << "Hi I'm " << str_Me << " and I say \"Hello " << str_Dest << "\""; str << ",Hi I'm " << str_Me << " and I say \"Hello " << str_Dest << "\""; m_pcWifiActuator->SendMessageTo(str_Dest, str.str()); //std::cout << str_Me << " sending\n"; } } } m_iSendOrNotSend++; //searching for the received msgs TMessageList t_incomingMsgs; m_pcWifiSensor->GetReceivedMessages(t_incomingMsgs); for (TMessageList::iterator it = t_incomingMsgs.begin(); it != t_incomingMsgs.end(); it++) { receivedPackets++; std::cout << str_Me << " received: " << it->Payload << " from " << it->Sender << " (total received=)" << receivedPackets << std::endl; } /** End of wifi*/ /** LCM for getting current positions and obtaining the next target point */ UInt8 robotID = atoi(GetRobot().GetRobotId().substr(3).c_str()); /* New target point from the COMMAND engine*/ if (lcmThreadCommand.getLcmHandler()->existNode(robotID)) { Node nodeCommand = lcmThreadCommand.getLcmHandler()->getNodeById(robotID); targetPosition.Set(nodeCommand.getPosition().GetX(), nodeCommand.getPosition().GetY()); printf("ID %d - TARGET: (%f,%f)\n", robotID, nodeCommand.getPosition().GetX(), nodeCommand.getPosition().GetY()); } else { if (lcmThread.getLcmHandler()->existNode(robotID)) { Node nodeCommand = lcmThread.getLcmHandler()->getNodeById(robotID); targetPosition.Set(nodeCommand.getPosition().GetX(), nodeCommand.getPosition().GetY()); printf("ID %d - TARGET: (%f,%f)\n", robotID, nodeCommand.getPosition().GetX(), nodeCommand.getPosition().GetY()); } } if (lcmThread.getLcmHandler()->existNode(robotID)) { //lcmThread.getLcmHandler()->printNodeListElements(); /** LCM related Node information */ //To get the other nodes locations through LCM listNodeObstacles = lcmThread.getLcmHandler()->retrieveNodeList(); //Get myself mySelf = lcmThread.getLcmHandler()->getNodeById(robotID); printf("ID %d\n", mySelf.getId()); printf("POS (%f,%f)\n", mySelf.getPosition().GetX(), mySelf.getPosition().GetY()); printf("QUAT (%f,%f,%f,%f)\n", mySelf.getOrientation().GetW(), mySelf.getOrientation().GetX(), mySelf.getOrientation().GetY(), mySelf.getOrientation().GetZ()); printf("VEL %d\n", mySelf.getVelocity()); /** From the simulator */ CVector2 oldPosition = position; CSpace& space = CSimulator::GetInstance().GetSpace(); const std::string stringIdA = GetRobot().GetRobotId(); CFootBotEntity *robotEntityA = static_cast<CFootBotEntity*>(&space.GetEntity(stringIdA)); CVector3 cFootBotPositionA = robotEntityA->GetEmbodiedEntity().GetPosition(); CQuaternion cFootBotOrientationA = robotEntityA->GetEmbodiedEntity().GetOrientation(); CVector3 axis; CRadians oA; cFootBotOrientationA.ToAngleAxis(oA, axis); if (axis.GetZ() < 0) oA = -oA; // Position position = CVector2(cFootBotPositionA.GetX(), cFootBotPositionA.GetY()); // Angle angle = oA; // Velocity //velocity = CVector2(speed, 0); velocity = CVector2(mySelf.getVelocity(), 0); /** NAVIGATION AND AVOIDING COLLISION */ updateAgent(agent); agent->clearObstacles(); addNodesAsObstacles(listNodeObstacles); if ((targetPosition - position).Length() < m_targetMinPointDistance) { // 2 cm state = ARRIVED_AT_TARGET; printf("State: STOPPED\n"); } else { state = MOVING; printf("State: MOVING\n"); } updateNavigation(); } }
bool Node::operator==(const Node &node) const { return (this->getPosition() == node.getPosition()); }
void NBEFileParser::save(Project* project,irr::core::stringc file){ std::ofstream myfile (file.c_str()); if (myfile.is_open()){ myfile << "MINETEST NODEBOX EDITOR\n"; myfile << "PARSER 1\n"; myfile << "NAME "; if (project->name == "") myfile << "test"; else myfile << project->name.c_str(); myfile << "\n\n"; int a = 1; list<Node*>* nodes = project->GetList(); for (irr::core::list<Node*>::Iterator it=nodes->begin();it!=nodes->end();it++){ printf("Looping...\n"); Node* node = *it; myfile << "NODE "; if (node->name == ""){ myfile << "Node"; myfile << a; }else myfile << node->name.c_str(); myfile << "\n"; myfile << "POSITION "; myfile << node->getPosition().X; myfile << " "; myfile << node->getPosition().Y; myfile << " "; myfile << node->getPosition().Z; myfile << "\n"; std::vector<NodeBox*> boxes = node->GetBoxes(); for (std::vector<NodeBox*>::const_iterator it = boxes.begin(); it != boxes.end(); ++it) { NodeBox* box = *it; myfile << "NODEBOX "; myfile << box->name.c_str(); myfile << " "; myfile << box->one.X; myfile << " "; myfile << box->one.Y; myfile << " "; myfile << box->one.Z; myfile << " "; myfile << box->two.X; myfile << " "; myfile << box->two.Y; myfile << " "; myfile << box->two.Z; myfile << "\n"; } myfile << "END NODE"; a++; } myfile.close(); }else printf("Unable to write to file\n"); }
bool LHDistanceJointNode::lateLoading() { this->findConnectedNodes(); Node* nodeA = this->getNodeA(); Node* nodeB = this->getNodeB(); Point relativePosA = this->getLocalAnchorA(); Point relativePosB = this->getLocalAnchorB(); if(nodeA && nodeB) { //this ensures that all transformations are set on the body prior creating the joint nodeA->setPosition(nodeA->getPosition()); nodeB->setPosition(nodeB->getPosition()); #if LH_USE_BOX2D LHScene* scene = (LHScene*)this->getScene(); LHGameWorldNode* pNode = scene->getGameWorldNode(); b2World* world = pNode->getBox2dWorld(); if(world == nullptr)return false; b2Body* bodyA = LH_GET_BOX2D_BODY(this->getNodeA()); b2Body* bodyB = LH_GET_BOX2D_BODY(this->getNodeB()); if(!bodyA || !bodyB)return false; b2Vec2 relativeA = scene->metersFromPoint(relativePosA); b2Vec2 posA = bodyA->GetWorldPoint(relativeA); b2Vec2 relativeB = scene->metersFromPoint(relativePosB); b2Vec2 posB = bodyB->GetWorldPoint(relativeB); b2DistanceJointDef jointDef; jointDef.Initialize(bodyA, bodyB, posA, posB); jointDef.collideConnected = this->getCollideConnected(); jointDef.frequencyHz = _frequency; jointDef.dampingRatio = _dampingRatio; b2DistanceJoint* joint = (b2DistanceJoint*)world->CreateJoint(&jointDef); joint->SetUserData(this); this->setJoint(joint); #else//chipmunk if(nodeA->getPhysicsBody() && nodeB->getPhysicsBody()) { CCLOG("\n\nWARNING: Distance joint is not supported when using Chipmunk physics engine.\n\n"); // PhysicsJointLimit* joint = PhysicsJointLimit::construct(nodeA->getPhysicsBody(), // nodeB->getPhysicsBody(), // relativePosA, // relativePosB, // 0, // _length); // // this->getScene()->getPhysicsWorld()->addJoint(joint); // // this->setJoint(joint); return true; } #endif } return false; }
//------------------------------------------------------------------ // // MenuLayerMainMenu // //------------------------------------------------------------------ MenuLayerMainMenu::MenuLayerMainMenu() { _touchListener = EventListenerTouchOneByOne::create(); _touchListener->setSwallowTouches(true); _touchListener->onTouchBegan = CC_CALLBACK_2(MenuLayerMainMenu::onTouchBegan, this); _touchListener->onTouchMoved = CC_CALLBACK_2(MenuLayerMainMenu::onTouchMoved, this); _touchListener->onTouchEnded = CC_CALLBACK_2(MenuLayerMainMenu::onTouchEnded, this); _touchListener->onTouchCancelled = CC_CALLBACK_2(MenuLayerMainMenu::onTouchCancelled, this); _eventDispatcher->addEventListenerWithFixedPriority(_touchListener, 1); // Font Item auto spriteNormal = Sprite::create(s_MenuItem, Rect(0,23*2,115,23)); auto spriteSelected = Sprite::create(s_MenuItem, Rect(0,23*1,115,23)); auto spriteDisabled = Sprite::create(s_MenuItem, Rect(0,23*0,115,23)); auto item1 = MenuItemSprite::create(spriteNormal, spriteSelected, spriteDisabled, CC_CALLBACK_1(MenuLayerMainMenu::menuCallback, this) ); // Image Item auto item2 = MenuItemImage::create(s_SendScore, s_PressSendScore, CC_CALLBACK_1(MenuLayerMainMenu::menuCallback2, this) ); // Label Item (LabelAtlas) auto labelAtlas = LabelAtlas::create("0123456789", "fonts/labelatlas.png", 16, 24, '.'); auto item3 = MenuItemLabel::create(labelAtlas, CC_CALLBACK_1(MenuLayerMainMenu::menuCallbackDisabled, this) ); item3->setDisabledColor( Color3B(32,32,64) ); item3->setColor( Color3B(200,200,255) ); // Font Item auto item4 = MenuItemFont::create("I toggle enable items", [&](Object *sender) { _disabledItem->setEnabled(! _disabledItem->isEnabled() ); }); item4->setFontSizeObj(20); item4->setFontName("Marker Felt"); // Label Item (LabelBMFont) auto label = LabelBMFont::create("configuration", "fonts/bitmapFontTest3.fnt"); auto item5 = MenuItemLabel::create(label, CC_CALLBACK_1(MenuLayerMainMenu::menuCallbackConfig, this)); // Testing issue #500 item5->setScale( 0.8f ); // Events MenuItemFont::setFontName("Marker Felt"); // Bugs Item auto item6 = MenuItemFont::create("Bugs", CC_CALLBACK_1(MenuLayerMainMenu::menuCallbackBugsTest, this)); // Font Item auto item7= MenuItemFont::create("Quit", CC_CALLBACK_1(MenuLayerMainMenu::onQuit, this)); auto item8 = MenuItemFont::create("Remove menu item when moving", CC_CALLBACK_1(MenuLayerMainMenu::menuMovingCallback, this)); auto color_action = TintBy::create(0.5f, 0, -255, -255); auto color_back = color_action->reverse(); auto seq = Sequence::create(color_action, color_back, NULL); item7->runAction(RepeatForever::create(seq)); auto menu = Menu::create( item1, item2, item3, item4, item5, item6, item7, item8, NULL); menu->alignItemsVertically(); // elastic effect auto s = Director::getInstance()->getWinSize(); int i=0; Node* child; auto pArray = menu->getChildren(); Object* pObject = NULL; CCARRAY_FOREACH(pArray, pObject) { if(pObject == NULL) break; child = static_cast<Node*>(pObject); auto dstPoint = child->getPosition(); int offset = (int) (s.width/2 + 50); if( i % 2 == 0) offset = -offset; child->setPosition( Point( dstPoint.x + offset, dstPoint.y) ); child->runAction( EaseElasticOut::create(MoveBy::create(2, Point(dstPoint.x - offset,0)), 0.35f) ); i++; } _disabledItem = item3; item3->retain(); _disabledItem->setEnabled( false ); addChild(menu); menu->setPosition(Point(s.width/2, s.height/2)); }
bool LHGearJointNode::lateLoading() { this->findConnectedNodes(); this->findConnectedJoints(); Node* nodeA = this->getNodeA(); Node* nodeB = this->getNodeB(); if(nodeA && nodeB && _jointA && _jointB) { //this ensures that all transformations are set on the body prior creating the joint nodeA->setPosition(nodeA->getPosition()); nodeB->setPosition(nodeB->getPosition()); #if LH_USE_BOX2D LHScene* scene = (LHScene*)this->getScene(); LHGameWorldNode* pNode = scene->getGameWorldNode(); b2World* world = pNode->getBox2dWorld(); if(world == nullptr)return false; b2Body* bodyA = LH_GET_BOX2D_BODY(this->getNodeA()); b2Body* bodyB = LH_GET_BOX2D_BODY(this->getNodeB()); if(!bodyA || !bodyB)return false; LHJointsProtocol* jointAProt = dynamic_cast<LHJointsProtocol*>(_jointA); LHJointsProtocol* jointBProt = dynamic_cast<LHJointsProtocol*>(_jointB); b2Joint* jtA = jointAProt->getJoint(); b2Joint* jtB = jointBProt->getJoint(); b2GearJointDef jointDef; jointDef.joint1 = jtA; jointDef.joint2 = jtB; jointDef.bodyA = bodyA; jointDef.bodyB = bodyB; jointDef.ratio = _ratio; jointDef.collideConnected = this->getCollideConnected(); b2GearJoint* joint = (b2GearJoint*)world->CreateJoint(&jointDef); joint->SetUserData(this); this->setJoint(joint); #else//chipmunk if(nodeA->getPhysicsBody() && nodeB->getPhysicsBody()) { CCLOG("\n\nWARNING: Gear joint is not supported when using Chipmunk physics engine.\n\n"); // PhysicsJointLimit* joint = PhysicsJointLimit::construct(nodeA->getPhysicsBody(), // nodeB->getPhysicsBody(), // relativePosA, // relativePosB, // 0, // _length); // // this->getScene()->getPhysicsWorld()->addJoint(joint); // // this->setJoint(joint); return true; } #endif } return false; }
void TableScreen::makeTiles(std::vector<std::string> v) { Node* layer = getChildByTag(GUI_LAYER); Node* icons = getChildByTag(ICON_LAYER); bool needInit = true; for (int i = 0; i < 9; ++i) { if(layer->getChildByTag(TAG_BG_ICON + i)) { needInit = false; break; } } TableLogic* gl = static_cast<TableLogic*>(GlobalVar::gameLogic); bool needHidBG = false; if(gl->cat == "colors" || gl->cat == "positions") needHidBG = true; Size eachTile(tilesRect.size.width/3,tilesRect.size.height/3); size_t wordSize = v.size(); Size bgSize; float scaleBG = 1; for (int i = 0; i < 9; ++i) { if(needInit) // both layers are emptied { // add bg; Node* bg = util::graphic::getSprite(StringUtils::format("%s%d",Constants::ASS_ICO_BG_TABLE,i)); bg->setVisible(!needHidBG); if (i == 0) { bgSize = bg->getContentSize(); if (bgSize.width > eachTile.width) { scaleBG = eachTile.width / (bgSize.width+20); bgSize.width = (bgSize.width+20)*scaleBG; bgSize.height = (bgSize.height+20)*scaleBG; } } int row = 2-(i/3); int col = i%3; bg->setAnchorPoint(Vec2::ANCHOR_MIDDLE); bg->setScale(scaleBG); layer->addChild(bg); Vec2 posBG(tilesRect.getMinX() + eachTile.width*(col + 0.5f), tilesRect.getMinY() + eachTile.height*(row + 0.5f)); bg->setPosition(posBG); util::effects::reveal(bg, 0.05f*i); bg->setTag(TAG_BG_ICON+i); EventListenerTouchOneByOne* evt = EventListenerTouchOneByOne::create(); evt->onTouchBegan = CC_CALLBACK_2(TableScreen::onTouchWordTileBegan,this); evt->onTouchEnded = CC_CALLBACK_2(TableScreen::onTouchWordTileEnded, this); evt->setSwallowTouches(true); bg->getEventDispatcher()->addEventListenerWithSceneGraphPriority(evt, bg); // add icon if(i < wordSize) { std::string iconName = v[i]; bg->setName(iconName); Node* icon = util::graphic::getSprite(iconName); icon->setAnchorPoint(Vec2::ANCHOR_MIDDLE); icons->addChild(icon); Size sbg = bgSize; sbg.width-=50; sbg.height-=50; icon->setScale(util::graphic::fit(sbg,icon)); icon->setPosition(posBG); util::effects::reveal(icon, 0.05f*i); icon->setTag(TAG_ICON+i); } } else { Vector<FiniteTimeAction*> vAct; // get existing bg Node* bg = layer->getChildByTag(TAG_BG_ICON+i); if(bg) { if (i == 0) { bgSize = bg->getContentSize(); if (bgSize.width > eachTile.width) { scaleBG = eachTile.width / (bgSize.width+20); bgSize.width = (bgSize.width+20)*scaleBG; bgSize.height = (bgSize.height+20)*scaleBG; } } float time = 0.05f*i; if(time > 0) vAct.pushBack(DelayTime::create(time)); vAct.pushBack(ScaleTo::create(0.2f,0.01f)); vAct.pushBack(ScaleTo::create(0.4f,scaleBG)); // add child icon Node* oldIcon = icons->getChildByTag(TAG_ICON+i); Vector<FiniteTimeAction*> vOld; if(oldIcon) { if(time > 0) vOld.pushBack(DelayTime::create(time)); vOld.pushBack(ScaleTo::create(0.2f,0.01f)); vOld.pushBack(RemoveSelf::create()); } // new icon std::string iconName = v[i]; bg->setName(iconName); Node* icon = util::graphic::getSprite(iconName); icon->setAnchorPoint(Vec2::ANCHOR_MIDDLE); icons->addChild(icon); icon->setPosition(bg->getPosition()); icon->setScale(0.01f); icon->setOpacity(0); icon->setTag(TAG_ICON+i); auto sbg = bgSize; sbg.width -= 50; sbg.height -= 50; Vector<FiniteTimeAction*> iconActs; iconActs.pushBack(DelayTime::create(time+0.2f)); iconActs.pushBack(Spawn::createWithTwoActions( FadeIn::create(0.4f), ScaleTo::create(0.4f,util::graphic::fit(sbg,icon)) )); if(oldIcon) oldIcon->runAction(Sequence::create(vOld)); icon->runAction(Sequence::create(iconActs)); bg->runAction(Sequence::create(vAct)); } } } }
void Packing::layout_euclidean(int centerCircle) { qDebug() << "Performing euclidean layout..."; QList<Node*> unplacedNodes(this->nodes); //Nodes which have not yet been placed QList<Node*> placedNodes; //nodes which have been placed but do not have full flowers. QList<Node*> floweredNodes; //nodes for which their entire flower has been placed. //place the first circle bool foundCenterCircle = false; for(auto n: unplacedNodes){ //find the circle that is to be the center circle. if (n->getId() == centerCircle){ qDebug() << "Placing first node #" << n->getId() << " at (0, 0)"; n->setPosition(QPointF(0, 0)); placedNodes.append(n); unplacedNodes.removeAll(n); //place the second node to right of the first node. Node *m = n->getNeibhours().first(); //at least one of m and n need to have a full flower if(!n->hasFullFlower()){ int mindex = 1; do{ m = n->getNeibhours().at(mindex); mindex++; } while(!m->hasFullFlower() && mindex < n->getNeibhours().length()); //fail if we didn't find a proper m. if(mindex >= n->getNeibhours().length()){ qDebug() << "Neither M or N has full flower. Fail."; return; } } qreal h1 = n->getRadius(); qreal h2 = m->getRadius(); qreal s = h1+h2; m->setPosition(QPointF(s, 0)); qDebug() << "Placing second node #" << m->getId() << " at (" << s << ", 0)"; placedNodes.append(m); unplacedNodes.removeAll(m); foundCenterCircle = true; break; } } //fail if we don't find the specified center circle. if(!foundCenterCircle){ qDebug() << "Could not find specified center circle. Fail"; return; } //now continue until all nodes have been placed... while(!unplacedNodes.empty()){ bool nonFullOp = false; //qDebug() << "--NEXT NODE--"; //find a placed node that does not have its full flower placed. //we require that the w node does in fact have a full flower. Node *w; int wIndex = 0; do{ w = placedNodes.at(wIndex); wIndex++; } while(!w->hasFullFlower() && wIndex < placedNodes.length()); //if w does not have a full flower at this point, then we need to get creative if(!w->hasFullFlower() && unplacedNodes.contains(w->getNeibhours().first())){ nonFullOp = true; //return; } //find a nbhr of w which has been placed. int nbhrIndex = 0; if(nonFullOp){ nbhrIndex = w->getNeibhourCount() - 1; while(unplacedNodes.contains(w->getNeibhours().at(nbhrIndex))) nbhrIndex--; } else{ //not an infinite loop since every placed node has at least one placed neibhour. while(unplacedNodes.contains(w->getNeibhours().at(nbhrIndex))) nbhrIndex++; } //now continue going around the nodes until we find the first one that is unplaced //we also need to check if the full flower has been placed. bool fullFlower = false; int nbhrOrigin = nbhrIndex; while(!unplacedNodes.contains(w->getNeibhours().at(nbhrIndex))){ nbhrIndex = (nbhrIndex + 1) % w->getNeibhours().length(); //if we wrap completely around, then we know that w's full flower //has been placed. if(nbhrIndex == nbhrOrigin){ fullFlower = true; break; } } //if the full flower is complete, then update the lists and try again //with a different node. if(fullFlower){ placedNodes.removeAll(w); floweredNodes.append(w); continue; } Node *u; if(nonFullOp){ if(nbhrIndex == w->getNeibhourCount() - 1) u = w->getNeibhours().first(); else u = w->getNeibhours().at(nbhrIndex+1); } else{ if(nbhrIndex == 0) u = w->getNeibhours().last(); else u = w->getNeibhours().at(nbhrIndex-1); } //now v becomes this "first unplaced node" Node *v = w->getNeibhours().at(nbhrIndex); if(v->getId() == 1){ } //find the angle <UWV=alpha qreal alpha = this->angle(w, u, v); //find the argument of u QPointF relU = u->getPosition() - w->getPosition(); qreal beta = atan2(relU.y(), relU.x()); //we need to determine if the nodes are currently being laid out in a //clockwise or anticlockwise manner. Thus we need to look at the two //previous unplaced nodes, and look at their relative angles. //this only works if w has two or more placed neibhours so far. int placedCount = 0; int isCCW = true; for(Node *n: placedNodes + floweredNodes){ if(w->isNeibhour(n)) placedCount++; } if(placedCount >= 2 && w->getNeibhours().length() >= 3){ //grab uprime Node *uprime; if(nonFullOp){ if(nbhrIndex == w->getNeibhourCount() - 1){ uprime = w->getNeibhours().at(1); } else if(nbhrIndex == w->getNeibhourCount() - 2){ uprime = w->getNeibhours().at(2); } else{ uprime = w->getNeibhours().at(nbhrIndex + 2); } } else{ if(nbhrIndex == 0){ uprime = w->getNeibhours().at(w->getNeibhours().length() - 2); } else if(nbhrIndex == 1){ uprime = w->getNeibhours().last(); } else{ uprime = w->getNeibhours().at(nbhrIndex - 2); } } //now look at angles of uprime and u QPointF relUPrime = uprime->getPosition() - w->getPosition(); qreal betaprime = atan2(relUPrime.y(), relUPrime.x()); //difference between angles should be less than PI radians qreal diff = fmod(betaprime - beta + 2*PI, 2*PI); if(diff < PI){ //betaprime is "ahead" of beta, so we should continue clockwise isCCW = false; } else{ //betaprime is "behind" beta, so continue anticlockwise isCCW = true; } } //then the actual argument of v is beta + alpha or beta - alpha qreal arg; if(isCCW) arg = fmod(beta+alpha+2*PI, 2*PI); else arg = fmod(beta-alpha+2*PI, 2 * PI); qreal r = w->getRadius() + v->getRadius(); //now plot the point using sin and //remember that this point is an offset from w. QPointF pos(r*cos(arg), r*sin(arg)); pos += w->getPosition(); //set the position of v v->setPosition(pos); //and update the lists unplacedNodes.removeAll(v); placedNodes.append(v); //and then we continue } qDebug() << "Layout complete"; }
void MainLayer::doFocusChange(EventKeyboard::KeyCode keyCode, bool isStartOnEnd) { Node* next = nullptr; if (isStartOnEnd) next = LsTools::getCornerFocus(keyCode == EventKeyboard::KeyCode::KEY_DPAD_RIGHT ? CornerType::TOP_LEFT : CornerType::TOP_RIGHT, _tabNode); else next = LsTools::getNextFocus(keyCode, _tabNode); int exNormalZOrder = 0; if (_focus) exNormalZOrder = _mapFocusZOrder.at(_focus->getTag()); //是否有下一个焦点 if (next) { commonFocusAction(next); ZM->showSelect(true, next->getContentSize() * FOCUS_SCALE_NUM, next->getPosition()); } else { //找不到焦点 switch (keyCode) { case EventKeyboard::KeyCode::KEY_DPAD_UP: { //向上进入分页选择 _isFocusNotOnTab = false; removeFocusAction(); _tabNode->setUserObject(nullptr); getCurTabBtn()->setScale(TAB_BTN_SCALE); } break; case EventKeyboard::KeyCode::KEY_DPAD_RIGHT: { //向右,进入下一个分页,无下一个分页,则不处理 int index = _pageView->getCurPageIndex(); index++; if (index >= PAGE_COUNT) return; ZM_SELECT->_box->setPositionX(-MY_SCREEN.width * 0.5f); removeFocusAction(false); _tabNode->setUserObject(nullptr); changeTab(index); doFocusChange(keyCode, false); } break; case EventKeyboard::KeyCode::KEY_DPAD_LEFT: { //向左,进入下一个分页,无下一个分页,则不处理 int index = _pageView->getCurPageIndex(); index--; if (index < 0) return; ZM_SELECT->_box->setPositionX(MY_SCREEN.width * 1.5f); removeFocusAction(false); _tabNode->setUserObject(nullptr); changeTab(index); doFocusChange(keyCode, true); } break; default: break; } } //createSpecRecomend(); }
/** * Runs any code the state needs to keep updating every * AI cycle. */ void PatrolBAIState::think(BattleAction *action) { /* Patrolling is mainly walking from one node to another node until bumping into hostiles There are a few rules: - if the from node is a rank 0 node (scout) the to node must be a rank 0 node (scouts stay outside) - a to-node can only be allocated for one unit, if it's already allocated, it will walk towards a random connected node, if no free connected node, stand still */ Node *node; if (_unit->_hidingForTurn) { action->type = BA_NONE; action->TU = 0; if (Options::getBool("traceAI")) { Log(LOG_INFO) << "PatrolBAIState::think()? Better not... #" << action->number; } return; } if (Options::getBool("traceAI")) { Log(LOG_INFO) << "PatrolBAIState::think() #" << action->number; } if (_toNode != 0 && _unit->getPosition() == _toNode->getPosition()) { if (Options::getBool("traceAI")) { Log(LOG_INFO) << "Patrol destination reached!"; } // destination reached // take a peek through window before walking to the next node int dir = _game->getTileEngine()->faceWindow(_unit->getPosition()); if (dir != -1 && dir != _unit->getDirection()) { _unit->lookAt(dir); while (_unit->getStatus() == STATUS_TURNING) { _unit->turn(); } action->TU = 0; // tus are already decreased while walking if (_unit->getFaction() == FACTION_NEUTRAL) { _unit->_hidingForTurn = true; // pretend to be terrified by all the soldiers and tanks rolling down your street or through your yard } return; } else { // head off to next patrol node _fromNode = _toNode; _toNode->freeNode(); _toNode = 0; } } if (_fromNode == 0) { // assume closest node as "from node" // on same level to avoid strange things, and the node has to match unit size or it will freeze int closest = 1000000; for (std::vector<Node*>::iterator i = _game->getNodes()->begin(); i != _game->getNodes()->end(); ++i) { node = *i; int d = _game->getTileEngine()->distanceSq(_unit->getPosition(), node->getPosition()); if (_unit->getPosition().z == node->getPosition().z && d < closest && (!(node->getType() & Node::TYPE_SMALL) || _unit->getArmor()->getSize() == 1)) { _fromNode = node; closest = d; } } } if (_toNode == 0) { // look for a new node to walk towards bool scout = true; if (_game->getMissionType() != "STR_BASE_DEFENSE") { int aliensAlive = 0; for (std::vector<BattleUnit*>::iterator i = _game->getUnits()->begin(), end = _game->getUnits()->end(); i != end; ++i) { if (!(*i)->isOut() && (*i)->getFaction() == FACTION_HOSTILE) ++aliensAlive; if (aliensAlive > 1) break; // all the info we need } // after turn 20 or if the morale is low, everyone moves out the UFO and scout // also anyone standing in fire should also probably move if (_game->getTurn() > 20 || (aliensAlive < 2 && _game->getTurn() > 10) || !_fromNode || _fromNode->getRank() == 0 || (_game->getTile(_unit->getPosition()) && _game->getTile(_unit->getPosition())->getFire())) { scout = true; } else { scout = false; } } // in base defense missions, the smaller aliens walk towards target nodes - or if there, shoot objects around them if (_game->getMissionType() == "STR_BASE_DEFENSE" && _unit->getArmor()->getSize() == 1) { // can i shoot an object? if (_fromNode->isTarget() && _unit->getMainHandWeapon() && _unit->getMainHandWeapon()->getAmmoItem()->getRules()->getDamageType() != DT_HE) { // scan this room for objects to destroy int x = (_unit->getPosition().x/10)*10; int y = (_unit->getPosition().y/10)*10; for (int i = x; i < x+9; i++) for (int j = y; j < y+9; j++) { MapData *md = _game->getTile(Position(i, j, 1))->getMapData(MapData::O_OBJECT); if (md && md->getDieMCD() && md->getArmor() < 60 ) { action->actor = _unit; action->target = Position(i, j, 1); action->weapon = action->actor->getMainHandWeapon(); action->type = BA_SNAPSHOT; action->TU = action->actor->getActionTUs(action->type, action->weapon); _unit->lookAt(action->target); while (_unit->getStatus() == STATUS_TURNING) { _unit->turn(); } return; } } } else { // find closest high value target which is not already allocated int closest = 1000000; for (std::vector<Node*>::iterator i = _game->getNodes()->begin(); i != _game->getNodes()->end(); ++i) { if ((*i)->isTarget() && !(*i)->isAllocated()) { node = *i; int d = _game->getTileEngine()->distanceSq(_unit->getPosition(), node->getPosition()); if (!_toNode || (d < closest && node != _fromNode)) { _toNode = node; closest = d; } } } } } if (_toNode == 0) { _toNode = _game->getPatrolNode(scout, _unit, _fromNode); } } if (_toNode != 0) { _toNode->allocateNode(); action->actor = _unit; action->type = BA_WALK; action->target = _toNode->getPosition(); _unit->lookAt(action->target); while (_unit->getStatus() == STATUS_TURNING) { _unit->turn(); } action->TU = 0; // tus are already decreased while walking } else { action->type = BA_NONE; action->TU = 0; } }
bool Demo::init(PhysicsWorld* world) { if (!Layer::init()) { return false; } m_world = world; Size winSize = Director::getInstance()->getWinSize(); //边界 Node* bound = Node::create(); PhysicsBody* boundBody = PhysicsBody::createEdgeBox(winSize); boundBody->setDynamic(false); bound->setPhysicsBody(boundBody); bound->setPosition(winSize.width / 2, winSize.height / 2); addChild(bound); /* 注意_contactTestBitmask的默认值为0x00000000,即任何碰撞都不检测 */ Size visibleSize = Director::getInstance()->getVisibleSize(); Vec2 origin = Director::getInstance()->getVisibleOrigin(); dispatcher = Director::getInstance()->getEventDispatcher(); auto bgsprite = Sprite::create("BG.png"); float odds; float oddsY; oddsY = bgsprite->getContentSize().height / visibleSize.height; odds = bgsprite->getContentSize().width / visibleSize.width; bgsprite->setScaleY(1 / oddsY); bgsprite->setScaleX(1 / odds); bgsprite->setPosition(Vec2(visibleSize / 2) + origin); addChild(bgsprite); Node* ground = Node::create(); ground->setPhysicsBody(PhysicsBody::createEdgeSegment(Vec2(0, 80), Vec2(visibleSize.width, 80))); ground->getPhysicsBody()->setDynamic(false); addChild(ground); Node* ropeBase = Node::create(); ropeBase->setPhysicsBody(PhysicsBody::createCircle(ropeBase->getContentSize().width / 2)); ropeBase->getPhysicsBody()->setDynamic(false); ropeBase->setPosition(visibleSize.width / 2, visibleSize.height-11); addChild(ropeBase); rope = Sprite::create("rope.png"); rope->setScale(2); rope->setPhysicsBody(PhysicsBody::createBox(rope->getContentSize()*2)); rope->setAnchorPoint(ccp(0, 0)); rope->setPosition(winSize.width / 2 + rope->getContentSize().width + 1, winSize.height-11); addChild(rope); PhysicsJointPin* pinJoint = PhysicsJointPin::construct( rope->getPhysicsBody(), ropeBase->getPhysicsBody(), ropeBase->getPosition()); m_world->addJoint(pinJoint); cat1 = Sprite::create("2_cat_cry.png"); cat1->setPosition(visibleSize.width - cat1->getContentSize().width / 2, 120); cat1->setPhysicsBody(PhysicsBody::createEdgeBox(cat1->getContentSize())); cat1->getPhysicsBody()->setContactTestBitmask(0x1); cat1->setTag(1); addChild(cat1); cat2 = Sprite::create("2_cat_cry.png"); cat2->setPosition(cat2->getContentSize().width, 120); cat2->setPhysicsBody(PhysicsBody::createEdgeBox(cat2->getContentSize())); cat2->getPhysicsBody()->setContactTestBitmask(0x1); cat2->setTag(1); addChild(cat2); apple = Sprite::create("apple.png"); apple->setScale(2); apple->setTag(2); apple->setPosition(rope->getPosition().x + rope->getContentSize().width, rope->getPosition().y); apple->setPhysicsBody(PhysicsBody::createCircle(apple->getContentSize().width)); apple->getPhysicsBody()->setContactTestBitmask(0x1); addChild(apple); fixedJoint = PhysicsJointFixed::construct( rope->getPhysicsBody(), apple->getPhysicsBody(), apple->getPosition()); m_world->addJoint(fixedJoint); brick1 = Sprite::create("brick_high.png"); brick1->setScale(2.5); brick1->setPosition(cat1->getPosition().x - cat1->getContentSize().width / 2 - brick1->getContentSize().width / 2, cat1->getPosition().y); brick1->setPhysicsBody(PhysicsBody::createEdgeBox(brick1->getContentSize()*2)); brick1->getPhysicsBody()->setContactTestBitmask(0xFFFFFFFF); addChild(brick1); brick2 = Sprite::create("brick_high.png"); brick2->setScale(2.5); brick2->setPosition(cat2->getPosition().x + brick2->getContentSize().width / 2 + cat2->getContentSize().width / 2, cat2->getPosition().y); brick2->setPhysicsBody(PhysicsBody::createEdgeBox(brick2->getContentSize()*2)); brick2->getPhysicsBody()->setContactTestBitmask(0xFFFFFFFF); addChild(brick2); testContact(); testTouchEvent(); isCut = false; //testCustomEvent(); //testContactFilter(); //testPhysicsJointSpring(); //testPhysicsJointDistance(); //testParticleFireworks(); //testParticleSnow(); //testExternalParticle(); return true; }
void CDR::update(NBEditor* editor,bool drag,rect<s32> offset){ if (!editor->GetState()->project){ printf("Project for NBEditor::updatePoint() not found!\n"); return; } if (!editor->GetState()->Settings()->getSettingAsBool("always_show_position_handle")){ if (editor->GetState()->keys[KEY_LSHIFT]==EKS_UP){ if (type == CDR_XY || type == CDR_XZ || type == CDR_ZY){ return; } }else{ if (!(type == CDR_XY || type == CDR_XZ || type == CDR_ZY)){ return; } } } Node* node = editor->GetState()->project->GetCurrentNode(); if (!node) return; NodeBox* box = node->GetCurrentNodeBox(); if (!box) return; if (drag){ // get mouse position position2di target = editor->GetState()->mouse_position; target.X -= 5; target.Y -= 5; target -= offset.UpperLeftCorner; // get the ray line3d<irr::f32> ray = editor->GetState()->GetDevice()->getSceneManager()->getSceneCollisionManager()->getRayFromScreenCoordinates(target,editor->GetState()->GetDevice()->getSceneManager()->getActiveCamera()); // contains the output values vector3df wpos = vector3df(0,0,0); // the collision position #if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8 const ISceneNode* tmpNode; // not needed, but required for function #else ISceneNode* tmpNode; // not needed, but required for function #endif triangle3df tmpTri; // not needed, but required for function // Execute ray editor->GetState()->GetDevice()->getSceneManager()->getSceneCollisionManager()->getCollisionPoint(ray,editor->GetState()->plane_tri,wpos,tmpTri,tmpNode); // Snapping wpos -= vector3df(node->getPosition().X,node->getPosition().Y,node->getPosition().Z); if (editor->GetState()->Settings()->getSettingAsBool("snapping")==true){ for (int i=0;i<15;i++){ if (wpos.X > editor->snappers[i]-0.0313 && wpos.X < editor->snappers[i]+0.0313){ wpos.X = editor->snappers[i]; } if (wpos.Y > editor->snappers[i]-0.0313 && wpos.Y < editor->snappers[i]+0.0313){ wpos.Y = editor->snappers[i]; } if (wpos.Z > editor->snappers[i]-0.0313 && wpos.Z < editor->snappers[i]+0.0313){ wpos.Z = editor->snappers[i]; } } } // Do node limiting if (editor->GetState()->Settings()->getSettingAsBool("limiting")==true){ // X Axis if (wpos.X < -0.5) wpos.X = -0.5; else if (wpos.X > 0.5) wpos.X = 0.5; // Y Axis if (wpos.Y < -0.5) wpos.Y = -0.5; else if (wpos.Y > 0.5) wpos.Y = 0.5; // Z Axis if (wpos.Z < -0.5) wpos.Z = -0.5; else if (wpos.Z > 0.5) wpos.Z = 0.5; } // Call required function if (type < CDR_XZ){ box->resizeNodeBoxFace(editor->GetState(),type,wpos,editor->GetState()->keys[KEY_LCONTROL]==EKS_DOWN); }else{ box->moveNodeBox(editor->GetState(),type,wpos); } node->remesh(); } vector3df pos; vector3df center = box->GetCenter(); switch (type){ case CDR_X_P: pos = center; pos.X = box->two.X; break; case CDR_X_N: pos = center; pos.X = box->one.X; break; case CDR_Y_P: pos = center; pos.Y = box->two.Y; break; case CDR_Y_N: pos = center; pos.Y = box->one.Y; break; case CDR_Z_P: pos = center; pos.Z = box->two.Z; break; case CDR_Z_N: pos = center; pos.Z = box->one.Z; break; case CDR_XZ: pos = center; break; case CDR_XY: pos = center; break; case CDR_ZY: pos = center; break; } pos.X+=node->getPosition().X; pos.Y+=node->getPosition().Y; pos.Z+=node->getPosition().Z; #if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8 vector2d<irr::s32> cpos = editor->GetState()->GetDevice()->getSceneManager()->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(pos,editor->GetState()->GetDevice()->getSceneManager()->getActiveCamera()); #else vector2d<irr::s32> cpos = editor->GetState()->GetDevice()->getSceneManager()->getSceneCollisionManager()->getScreenCoordinatesFrom3DPosition(pos,editor->GetState()->GetDevice()->getSceneManager()->getActiveCamera(),true); #endif position = cpos += offset.UpperLeftCorner; visible = true; return; }