예제 #1
0
void BW_Sprite::updateMovePosition(float dt) {
	if (_currentAnimation != MOVE)
		return;

	BW_Point currentPosition = getPositionBW();

	float moveDistance = _speed * dt * 0.85; //multiply by 0.85 to achieve the same speed as the old move to version
	float maxDist = getPositionBW().distanceTo(_movingTo);
	BW_Point newPos;
	if (moveDistance >= maxDist) {
		newPos = _movingTo;
		spriteMoveFinished(_sprite);
	} else {
		float mult = moveDistance / maxDist;

		float x = _movingTo.x - currentPosition.x;
		float y = _movingTo.y - currentPosition.y;

		float xDelta = x * mult;
		float yDelta = y * mult;
		newPos = BW_Point(getPositionBW().x + xDelta, getPositionBW().y + yDelta);
	}

	if (!_isUnit) {
		//on projectiles there is no walk collition
		setPosition(newPos);
		return;
	}

	//we are a unit here, consider walk collition

	//get nearest unit to this point
	std::list<Unit*> allUnits = Model::getInstance()->getMyArmy(LEFT)->getUnits();
	std::list<Unit*> rightUnits = Model::getInstance()->getMyArmy(RIGHT)->getUnits();
	allUnits.insert(allUnits.end(), rightUnits.begin(), rightUnits.end());

	//get nearest position of other units
	BW_Point nearest;
	float minDist = -1;
	for (std::list<Unit*>::iterator it = allUnits.begin(); it != allUnits.end(); ++it) {
		if ((*it) == this)
			continue;

		BW_Point currentPos = (*it)->getPositionBW();
		float currentDist = newPos.distanceTo(currentPos);
		if (minDist == -1 || currentDist < minDist) {
			minDist = currentDist;
			nearest = currentPos;
		}
	}

	//check nearest position
	float minDistanceToOtherUnits = 50;
	if (minDist == -1 || minDist > minDistanceToOtherUnits) {
		//no problem
		setPosition(newPos);
		return;
	}

	//calculate intersections
	BW_Point i1, i2;
	int res = Trigonometric::intersectionsCircleCircle(getPositionBW(), moveDistance, nearest, minDistanceToOtherUnits, &i1, &i2);

	/**
	 * Returns 0 if intersections
	 * Returns -1 if same m
	 * Returns -2 if no intersections
	 */

	if (res == 0) {
		//intersections found
		newPos = _movingTo.distanceTo(i1) < _movingTo.distanceTo(i2) ? i1 : i2;
	} else if (res == -3 || res == -1) {
		//circle includes another one, move away
		BW_Point directionPoint;
		if (res == -3) {
			directionPoint.x = currentPosition.x - (nearest.x - currentPosition.x);
			directionPoint.y = currentPosition.y - (nearest.y - currentPosition.y);
		} else {
			//same points, move away in random direction
			//to be easy, just move in run direction
			directionPoint.x = Tools::random(0, Model::getInstance()->getFieldWidth());
			directionPoint.y = Tools::random(0, Model::getInstance()->getFieldHeigth());
		}
		// now scale this to moveDistance
		float scale = moveDistance / directionPoint.distanceTo(currentPosition);
		float distX = currentPosition.x - directionPoint.x;
		float distY = currentPosition.y - directionPoint.y;

		newPos.x -= distX * scale;
		newPos.y -= distY * scale;
	}

	//if (res == -2) no problem
	setPosition(newPos);
    
    float dx = _movingTo.x - currentPosition.x;
    float dy = _movingTo.y - currentPosition.y;
    if (dx == 0 && dy == 0) {
        doIdle();
    }

}
예제 #2
0
void Soko::menuRestartCallback(CCObject* pSender)
{
	InitialiseLevel("Soko.tmx");
	// Updates the move count labels and boxes
	spriteMoveFinished(NULL);
}