void FieldAsset::drawPath( const Vec2& from, const Vec2& to, bool isLast, const Color4F& fromColor, const Color4F& toColor ) { Vec2 control = (from + to)/2 + Vec2(0, from.distance(to) / 4); float t = 0; Vec2 lastVertex; Vec2 vertex; float drawUpperLimit = 1; if(isLast) drawUpperLimit = _fieldModel->birdJumpProgress; while(t < drawUpperLimit) { // TODO: compute this value somewhere else float x = powf(1 - t, 2) * from.x + 2.0f * (1 - t) * t * control.x + t * t * to.x; float y = powf(1 - t, 2) * from.y + 2.0f * (1 - t) * t * control.y + t * t * to.y; vertex = Vec2(x, y); if(lastVertex.distance(vertex) >= 6) { auto colorBorder = Color4F::GRAY; auto colorInnder = mixColors(fromColor, toColor, 1-t); _errorPathDrawer->drawDot(vertex, 2.5, colorBorder); _errorPathDrawer->drawDot(vertex, 2, colorInnder); lastVertex = vertex; } t += 0.005; } }
const Vec2& GameData::getNearTargetByPos( const Vec2& curPos ) { Vec2 nearPos = Vec2(0,0); float dis = 100000.0f; auto plVec = m_EnemyPlaneVec; for (auto it = plVec.begin(); it != plVec.end(); it++) { auto pl = (*it); if (pl) { Vec2 pos = pl->convertToWorldSpaceAR(Vec2::ZERO); float TempDis = pos.distance(curPos); if (TempDis < dis) { dis = TempDis; nearPos = pos; } } else { log(""); } } return nearPos; }
Vec2 SeaFireFlyMove::immediateMove(Sprite* seaFirefly, SeaFireFly* targetObject) { Vec2 targetPos = targetObject->getPosition(); Sprite* character = seaFirefly; Vec2 myPos = character->getPosition(); if (targetObject->getState() != FOLLOW)return Vec2(); float distance = 0; float dx = targetPos.x - character->getPosition().x; float dy = targetPos.y - character->getPosition().y; Vec2 change = Vec2(dx, dy); distance = myPos.distance(targetPos); if (100 > distance) { change.normalize(); change *= -distance; } else if (distance > 120) { change.normalize(); change *= distance; } else { change *= 0.0f; } return (change); }
Vec2 SteeringForce::Hide(const Vehicle *target, std::vector<Vehicle *> &obstacles) { double DistToClosest = MAXFLOAT; Vec2 BestHidingSpot; std::vector<Vehicle*>::iterator curOb = obstacles.begin(); while (curOb!=obstacles.end()) { if (*curOb!=target && *curOb != m_pVehicle) { //计算这个障碍物的hide地点 Vec2 HidingSpot = GetHidingPosition((*curOb)->getPosition(), (*curOb)->getContentSize().width/2, target->getPosition()); double dist = HidingSpot.distance(m_pVehicle->getPosition()); if (dist <DistToClosest) { DistToClosest = dist; BestHidingSpot = HidingSpot; } } ++curOb; } if (DistToClosest == MAXFLOAT) { return Evade(target); } return Arrive(BestHidingSpot, fast); }
bool Leukocyte::isCollideByOtherLeukocyte(const cocos2d::Vec2 centerPosition, float radius) const { Vec2 posA = this->getPosition(); float distance = posA.distance(centerPosition); return (distance <= this->getCollideRadius() + radius); }
bool FocusLayer::onTouchBegan(Touch* t, Event* e) { auto pt = t->getLocation(); for(auto rc : _rectList) { if(rc.second._rect.containsPoint(pt)) { log("rect touch"); if(rc.second._callback) rc.second._callback(rc.first); return false; } } for(auto circle : _circleList) { Vec2 pos = circle.second._pos; float radius = circle.second._radius; float distance = pos.distance(pt); if(distance < radius) { log("circle touch"); if(circle.second._callback) circle.second._callback(circle.first); return false; } } return true; }
bool StructureManager::containsStructure(int gid, Vec2 location) { for (BrokenStructure* e : *structarray) { if (e->getGID() == gid && location.distance(e->location) == 0) return true; } return false; }
Type LineSegment2x<Type>::point_distance(const Vec2<Type> &point) { Type L = pow2(q.x - p.x) + pow2(q.y - p.y); Type r = ((point.x - p.x)*(q.x - p.x) + (point.y - p.y)*(q.y - p.y)) / L; if (r <= 0 || r >= 1) { return min(point.distance(p), point.distance(q)); } Type s = ((p.y - point.y)*(q.x - p.x) - (p.x - point.x)*(q.y - p.y)) / L; s *= sqrt(L); if (s < ((Type)0)) s = -s; return s; }
bool GravityCtrlLayer::checkIsCancelled(cocos2d::Point& screenPosition) { cocos2d::Size screenSize = Director::getInstance()->getWinSize(); Vec2 center = Vec2(screenSize.width/2, screenSize.height/2); Vec2 touch = Vec2(screenPosition.x, screenPosition.y); float distance = center.distance(touch); if (distance < screenSize.width * m_ratioToCancel / 2) return false; else return true; }
void Grid::OnCross(Plane& plane, Plane* old_plane, grid_ptr from, grid_ptr to) { // 击毁已有的Plane if (NULL != old_plane) { float sub_t = 0.0f; if (to) { using cocos2d::Vec2; Vec2 t = Vec2(to->GetPositionX(), to->GetPositionY()); Vec2 m = Vec2(GetPositionX(), GetPositionY()); sub_t = t.distance(m) / Config::GetInstance().Plane.FlySpeed; } // 被击毁飞机回家 old_plane->GoHome(LGR_KICKOFF, plane.GetActionTime() - sub_t); } }
void HRocker::onTouchMoved(Touch* touch, Event* event) { Vec2 touchPoint = touch->getLocationInView(); touchPoint = Director::getInstance()->convertToGL(touchPoint); if (touchPoint.distance(centerPoint) > radius) { touchPoint.subtract(centerPoint); touchPoint.normalize(); touchPoint *= radius; touchPoint.add(centerPoint); currentPoint = touchPoint; // currentPoint = ccpAdd(centerPoint, // ccpMult(ccpNormalize(ccpSub(touchPoint, centerPoint)), radius)); } else { currentPoint = touchPoint; } }
Vec2 SeaFireFlyMove::distantMove(Sprite* seaFirefly, Vec2 centerPosition) { Vec2 velocity; Vec2 myPosition = seaFirefly->getPosition(); velocity = centerPosition - myPosition; float distance = myPosition.distance(centerPosition); if (distance <= 60)return Vec2(0, 0); velocity.normalize(); velocity *= 5; return (velocity); }
void SinglePlayerScene::onContactSeparate(cocos2d::PhysicsContact &contact) { auto nodeA = contact.getShapeA()->getBody()->getNode(); auto nodeB = contact.getShapeB()->getBody()->getNode(); if (nodeA == _takyan || nodeB == _takyan) { auto otherNode = nodeA == _takyan ? nodeB : nodeA; if (otherNode == _kicker && !m_game->isOver()) { auto takyanBody = _takyan->getPhysicsBody(); Vec2 v = takyanBody->getVelocity(); float limitY = takyanBody->getMass() * 1.0f; if (v.y < limitY) { v.y = MAX(limitY, v.y * 2.5f); } float limitX = takyanBody->getMass() * 1.0f; if (v.x < -limitX || v.x > limitX) { v.x = limitX * (v.x < 0 ? -1 : 1); } if (m_scoreCanAcquire == 3) { Vec2 zero; float distance = zero.distance(v); v.x = 0; v.y = distance; } takyanBody->setVelocity(v); } else if (otherNode == _floorBounds && m_game->isPracticeMode()) { m_game->setScore(0); auto takyanBody = _takyan->getPhysicsBody(); Vec2 velocity; velocity.y = takyanBody->getMass() * 2.50f; takyanBody->setVelocity(velocity); } } }
bool HRocker::onTouchBegan(Touch* touch, Event* event) { if (!active) { return false; } this->setVisible(true); Vec2 touchPoint = touch->getLocationInView(); touchPoint = Director::getInstance()->convertToGL(touchPoint); if (!isFollowRole) { if (touchPoint.distance(centerPoint) > radius) { return false; } } currentPoint = touchPoint; if (isFollowRole) { centerPoint = currentPoint; jsSprite->setPosition(currentPoint); this->getChildByTag(88)->setPosition(currentPoint); } return true; }
void SeaFireFlyMove::move(Sprite* seaFireFly, SeaFireFly* targetObject,Vec2 centerVel, Vec2 centerPos) { Vec2 targetPos = targetObject->getPosition(); Sprite* character = seaFireFly; Vec2 myPos = character->getPosition(); float distance = 0; float dx = centerPos.x - character->getPosition().x; float dy = centerPos.y - character->getPosition().y; Vec2 change = Vec2(dx, dy); distance = myPos.distance(centerPos); if (40 > distance) { change.normalize(); change *= -distance; } else if (distance > 80) { change.normalize(); change *= distance; } else { change *= 0.0f; } if ( !seaFireFly ) return; //if (change==nullptr)return; auto phisycs = seaFireFly->getPhysicsBody(); seaFireFly->getPhysicsBody()->setVelocity(change); if (seaFireFly->getName() == targetObject->getName())return; seaFireFlyBoid(seaFireFly,targetObject,centerPos); }
void BaseScene::electricBallAreaEffect(){ auto balls = SceneDesigner::balls; for (int i = 0; i < int(balls->size()); i++){ if (balls->at(i)->type == b_electricballball_small || balls->at(i)->type == b_electricball_mid){ auto e_ball = balls->at(i); for (int j = 0; j < int(balls->size()); j++){ auto ball = balls->at(j); if (e_ball != ball){ float distanceSquar = e_ball->getSprite()->getPosition().distanceSquared(ball->getSprite()->getPosition()); float forceValue = e_ball->effectRadius *RTM_RATIO * RTM_RATIO * e_ball->effectRadius / distanceSquar; if (forceValue >= 1){ // 进入作用域 forceValue = forceValue * 0.3; // 作用域最远处,加速度为0.3 // 吸引的方向 Vec2 direction = e_ball->getSprite()->getPosition() - ball->getSprite()->getPosition(); if (direction == Vec2(0, 0)) continue; direction = direction / direction.distance(Vec2::ZERO); // 吸引电球和铁球 if (ball->type == b_ironball_mid || ball->type == b_ironball_small || ball->type == b_electricballball_small || ball->type == b_electricball_mid){ ball->applyForce(forceValue * direction, true); e_ball->applyForce(-forceValue * direction, true); } // 排斥其他球 else{ direction *= -1; ball->applyForce(forceValue * direction, true); e_ball->applyForce(-forceValue * direction, true); } } } } } } }
void GameManager::ProcessState() { switch (m_player->GetState()) { case ENTER_BABE: // Enter -> In { m_babeBg->setOpacity(105); m_babe->SetState(CONTROLED); m_player->EnterEvent(m_babe->getPosition()); } break; case IN_BABE: // In -> Exit { Vec2 playerPos = m_player->getPosition(); Vec2 babePos = m_babe->getPosition(); Vec2 deltaPos = (playerPos - babePos) / 20; if (babePos.distance(playerPos) > 100) { m_babe->setPosition(babePos + deltaPos); } } break; case EXIT_BABE: // Exit -> Out { m_babeBg->setOpacity(0); m_babe->SetState(WALKAROUND); m_player->ExitEvent(); } break; case OUT_BABE: // Out -> Enter { } } }
bool DomainComp::contains(Vec2 center, Vec2 target) { return (center.distance(target) <= radius); }
void GameScene::setupTouchHandling() { auto touchListener = EventListenerTouchOneByOne::create(); static Vec2 firstTouchPos; static Vec2 lastTouchPos; static bool allowRotate = true; static std::clock_t touchStartedTime; touchListener->onTouchBegan = [&](Touch* touch, Event* event) { firstTouchPos = this->convertTouchToNodeSpace(touch); lastTouchPos = firstTouchPos; touchStartedTime = clock(); allowRotate = true; return true; }; touchListener->onTouchMoved = [&](Touch* touch, Event* event) { Vec2 touchPos = this->convertTouchToNodeSpace(touch); Vec2 difference = touchPos - lastTouchPos; Tetromino* activeTetromino = grid->getActiveTetromino(); if (activeTetromino) { //Coordinate touchCoordinate = this->convertPositionToCoodinate(touchPos); Coordinate differenceCoordinate = this->convertPositionToCoodinate(difference); Coordinate activeTetrominoCoodinate = grid->getActiveTetrominoCoodinate(); if (differenceCoordinate.y <= -1000) { Coordinate newTetrominoCoodinate = Coordinate(activeTetrominoCoodinate.x, activeTetrominoCoodinate.y -1); grid->setActiveTetrominoCoodinate(newTetrominoCoodinate); allowRotate = false; lastTouchPos = touchPos; } else if (abs(differenceCoordinate.x) >= 1) { Coordinate newTetrominoCoodinate; bool movingRight = (differenceCoordinate.x > 0); newTetrominoCoodinate = Coordinate(activeTetrominoCoodinate.x + (movingRight ? 1 : -1), activeTetrominoCoodinate.y); grid->setActiveTetrominoCoodinate(newTetrominoCoodinate); lastTouchPos = touchPos; allowRotate = false; } } }; touchListener->onTouchEnded = [&](Touch* touch, Event* event) { Vec2 touchEndPos = this->convertTouchToNodeSpace(touch); Size blockSize = this->grid->getBlockSize(); float distance = touchEndPos.distance(firstTouchPos); if (distance < blockSize.width && allowRotate) { grid->rotateActiveTetromino(); } else { Vec2 difference = touchEndPos - firstTouchPos; std::clock_t clockDifference = clock() - touchStartedTime; if (clockDifference <= 0) { return; } float touchDuration = (float) (clock() - touchStartedTime) / CLOCKS_PER_SEC; float velocity = fabsf(difference.y / touchDuration); if (velocity > DROP_VELOCITY) { grid->dropActiveTetromino(); this->updateScoreStateFromScore(); } } }; this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(touchListener, this); }
void Leukocyte::updateLeukocyte(float dt, const Leukocyte *other) { static int lockFrame = 0; float currentScale = this->getCurrentScale(); if (currentState == LeukocyteState::LOCK) { lockFrame++; if (lockFrame >= PLAYER_MOVING_LOCK_FRAME) { lockFrame = 0; currentState = LeukocyteState::STOP; } } else { Vec2 playerPos = this->getPosition(); float distance = playerLastTouchPos.distance(playerPos); // 距離がしきい値以下なら加速度を再計算して速度固定 if (distance <= ATTRACTED_DISTANCE * (1.0f / currentScale) && currentState == LeukocyteState::MOVE && !isCPU) { playerAccelerate = this->getCurrentPlayerAccelerateToTouchPosition(); playerVelocity = sqrt(3.0f * MAX_VELOCITY * (1.0f / currentScale)) * playerAccelerate.getNormalized(); } else { if (currentState == LeukocyteState::DASH) { if (playerVelocity.getLengthSq() > MAX_VELOCITY * (1.0f / currentScale)) { playerAccelerate = this->getCurrentPlayerAccelerateToTouchPosition(); Vec2 addedVelocity = playerVelocity - playerAccelerate * 10 * dt * (1.0f / currentScale); if (addedVelocity.getLengthSq() > playerVelocity.getLengthSq()) { addedVelocity = playerVelocity + playerAccelerate * 10 * dt * (1.0f / currentScale); } playerVelocity = addedVelocity; } else { currentState = LeukocyteState::MOVE; } } else { // 加速度から速度計算 playerAccelerate = this->getCurrentPlayerAccelerateToTouchPosition(); Vec2 addedVelocity = playerVelocity + playerAccelerate * dt * (1.0f / currentScale); // max値を超えない場合のみプレイヤーの速度を更新する playerVelocity = addedVelocity; if (playerVelocity.getLengthSq() > MAX_VELOCITY * (1.0f / currentScale)) { Vec2 normalizedPlayerVelocity = playerVelocity.getNormalized(); playerVelocity = sqrt(MAX_VELOCITY * (1.0f / currentScale)) * normalizedPlayerVelocity; } } } if (currentState != LeukocyteState::ATTACKED && currentState != LeukocyteState::DASH) { currentState = playerVelocity.length() > 0.0f ? LeukocyteState::MOVE : LeukocyteState::STOP; } // 壁際反射判定 Vec2 updatedPos = playerPos + playerVelocity; auto playerSprite = this->getChildByName<Sprite*>("player"); Size playerSize = Size(currentScale * playerSprite->getContentSize().width, currentScale * playerSprite->getContentSize().height); Size visibleSize = Director::getInstance()->getVisibleSize(); if (updatedPos.x - playerSize.width / 2 < 0 || updatedPos.x + playerSize.width / 2 > visibleSize.width) { SimpleAudioEngine::getInstance()->playEffect(SE_HIT_WALL); playerVelocity.x *= -1.0f; if (currentState == LeukocyteState::DASH) { playerVelocity = sqrt(MAX_VELOCITY * (1.0f / currentScale)) * playerVelocity.getNormalized(); currentState = LeukocyteState::MOVE; } } if (updatedPos.y - playerSize.height / 2 < 0 || updatedPos.y + playerSize.height / 2 > visibleSize.height) { SimpleAudioEngine::getInstance()->playEffect(SE_HIT_WALL); playerVelocity.y *= -1.0f; if (currentState == LeukocyteState::DASH) { playerVelocity = sqrt(MAX_VELOCITY * (1.0f / currentScale)) * playerVelocity.getNormalized(); currentState = LeukocyteState::MOVE; } } // 他プレイヤー衝突判定 if (other) { if (other->isCollideByOtherLeukocyte(updatedPos, this->getCollideRadius())) { // 半径和からプレイヤー間距離を引いた値が補正値 float sumRadius = this->getCollideRadius() + other->getCollideRadius(); float distance = updatedPos.distance(other->getPosition()); Vec2 adjustVec = (sumRadius - distance) * (other->getPosition() - updatedPos).getNormalized(); if (playerVelocity.getLength() > other->getPlayerVelocity().getLength()) { this->setPosition(updatedPos - adjustVec); } } else { this->setPosition(playerPos + playerVelocity); } } else { // プレイヤー座標を更新する this->setPosition(playerPos + playerVelocity); } // 目標地点との距離がしきい値以下なら到着 if (currentState != LeukocyteState::ATTACKED && !isCPU) { updatedPos = this->getPosition(); float updated_distance = updatedPos.distance(playerLastTouchPos); if (updated_distance <= REACHED_DISTANCE) { this->setPosition(playerLastTouchPos); playerVelocity = Vec2::ZERO; playerAccelerate = Vec2::ZERO; if (currentState == LeukocyteState::MOVE) { currentState = LeukocyteState::LOCK; dashGauge = 0; float duration = Director::getInstance()->getAnimationInterval() * PLAYER_MOVING_LOCK_FRAME; Blink* blink = Blink::create(duration, 3); this->runAction(blink); } } } playerPrevFrameTouchPos = playerLastTouchPos; dashProgress->setPercentage(float(dashGauge) / PLAYER_DASH_CHARGE_MAX * 100.0f); } // 成長に合わせて壁に埋まる場合があるので補正 Vec2 currentPosition = this->getPosition(); Vec2 newPosition = Utility::getAdjustedPositionFromWall(currentPosition, this->getLeukocyteSize()); if (currentPosition != newPosition) { this->setPosition(newPosition); } // decrease chain frame if (this->chainLeftFrame > 0 && !this->isLockChainLeftFrame) { this->chainLeftFrame--; if (this->chainLeftFrame <= 0) { this->chainCount = 0; this->sendData(JSONPacker::ActionType::TOUCH); } } // CPU logic if (this->isCPU) { this->updateForCPU(); } }
template<class G, class N> static double angle(const Vec2<G> v, const Vec2<N> u){return acos((v*u)/(v.distance()*u.distance()));}