The object starts to freeze when approaching the end point

Many thanks to everyone who helped! I’m very grateful to you!)
I will try to do everything according to your recommendations.
Thanks for your time :slight_smile:

1 Like

You got this. Already coming to the table with some working code, image, video means you are more dedicated than most SO users :slight_smile:

1 Like

Excuse for troubling.
But the problem still persists… :disappointed_relieved:
I redid the program according to your recommendations:

TrajectoryParser.h (has definitions of structure and vector)

struct WayPoint
	{
		int ID;
		std::string RoadType;
		bool Passenger;
		bool Truck;
		bool Bus;
		bool Bike;
		cocos2d::Vec2 PointCoordinates;
		bool Generation;
		float Rotation;
		std::vector<int> NextPointID;
	};
WayPoint wayPoint;
std::vector<WayPoint> getFilledVectorWithWayPoints();

TrajectoryParser.cpp (has a function that loads data of way points into a vector):

std::vector<TrajectoryParser::WayPoint> TrajectoryParser::getFilledVectorWithWayPoints()
{
	std::vector<WayPoint> WayPointsList;
	rapidjson::Value &points = tDoc["wayPoints"];
	if (points.IsArray())
	{
		for (int i = 0; i < points.Size(); ++i)
		{
			rapidjson::Value &point = points[i];
			wayPoint.NextPointID.clear();

			wayPoint.ID = point["ID"].GetInt();
			wayPoint.RoadType = point["rType"].GetString();
			
			wayPoint.Passenger = false;
			wayPoint.Truck = false;
			wayPoint.Bus = false;
			wayPoint.Bike = false;
			rapidjson::Value &vehicleTypes = point["vType"];
			for (int e = 0; e < vehicleTypes.Size(); e++)
			{
				if (0 == strcmp("pas", vehicleTypes[e]["type"].GetString()))
				{
					wayPoint.Passenger = true;
				}
				else if (0 == strcmp("truck", vehicleTypes[e]["type"].GetString()))
				{
					wayPoint.Truck = true;
				}
				else if (0 == strcmp("bus", vehicleTypes[e]["type"].GetString()))
				{
					wayPoint.Bus = true;
				}
				else if (0 == strcmp("bike", vehicleTypes[e]["type"].GetString()))
				{
					wayPoint.Bike = true;
				}
			}
			
			wayPoint.PointCoordinates = Point(point["point"]["x"].GetDouble(), point["point"]["y"].GetDouble());
			wayPoint.Generation = point["gen"].GetBool();
			wayPoint.Rotation = point["rot"].GetDouble();
			rapidjson::Value &nextID = point["next"];
			for (int ee = 0; ee < nextID.Size(); ee++)
			{
				wayPoint.NextPointID.push_back(nextID[ee]["nID"].GetInt());
			}
			WayPointsList.push_back(wayPoint);
		}
	}
	return WayPointsList;
}

in Level1.h I declared vectors like:

VehicleAI *vehicleAITest;
std::vector<std::shared_ptr<VehicleAI>> vehicleAIList;
std::vector<TrajectoryParser::WayPoint> WayPointsList;

in bool Level1::init() I assign the vector loaded in the parser.:

TrajectoryParser::getInstance()->parseJsonFile("traectory3.json");
WayPointsList = TrajectoryParser::getInstance()->getFilledVectorWithWayPoints();
TrajectoryParser::getInstance()->clearCache();
vehicleAITest = new VehicleAI();

void Level1::update(float dt):

{
	hud = static_cast<HUD*>(Director::getInstance()->getRunningScene()->getChildByTag(999));
	wheelRotationPercentage = hud->wheelRotationPercentage;
	speedPercentage = hud->speedPersentage;
	
	vehiclePlayer->updateMovementPlayerVehicle(dt, wheelRotationPercentage, speedPercentage, crashPlayerVehicle);
	if (crashPlayerVehicle)
	{
		crashPlayerVehicle = false;
		hud->returnSlidersToStandardPosition();
	}
	cocos2d::Vec2 vehiclePlayerPosition = vehiclePlayer->getPositionPlayerVehicle();

	if (vehicleAIList.size() < MAX_NUM_OF_GENERATED_AIVEHICLES)
	{
		int pointID = vehicleAITest->getPointIDForSpawnAIVehicle(vehiclePlayerPosition, visibleSize, vehicleAIList, WayPointsList);
		if (pointID != -1)
		{
			TrajectoryParser::WayPoint wayPoint = WayPointsList.at(pointID);
			auto vehicleAI = std::shared_ptr<VehicleAI>(new VehicleAI(this, 0x3, 9, wayPoint));
			vehicleAIList.push_back(vehicleAI);
		}
	}
	if (vehicleAIList.size() != 0)
	{
		//while (vehicleAIList.size() != iterator)
		for (auto iterator = vehicleAIList.begin() ; iterator != vehicleAIList.end(); )
		{
			auto vai = iterator->get();
			int it = iterator - vehicleAIList.begin();
			cocos2d::Vec2 vehicleAIPosition = vai->getPositionAIVehicle();
			if (vehiclePlayerPosition.distance(vehicleAIPosition) > MAX_DISTANCE_FOR_DELETE_GENERATED_AIVEHICLES || vai->isCancelled())
			{				
				vehicleAIList.erase(iterator);
				iterator = vehicleAIList.begin() + it;
			}
			else
			{
				vai->vehicleAIMovement(dt, vehiclePlayerPosition, vehicleAIList, WayPointsList, it);
				iterator++;
			}
		}
	}
}

VehicleAI.cpp:

VehicleAI::VehicleAI()
{

}
VehicleAI::VehicleAI(cocos2d::Layer *layerVAI, int bitMaskVAI, int numLayerVAI, TrajectoryParser::WayPoint wayPoint)
{
	nextPointVAI = Point(wayPoint.PointCoordinates.x, wayPoint.PointCoordinates.y);
	float startRotation = wayPoint.Rotation;
	rotationOnPoint = startRotation;
	pointID = wayPoint.ID;

	vehicleAISprite = Sprite::create(spriteVAI);
	vehicleAISprite->setPosition(nextPointVAI);
	vehicleAISprite->setAnchorPoint(Point(0.5, 1));
	vehicleAISprite->setRotation(startRotation);
	fScreen = vehicleAISprite->getRotation();
	vehicleBase = vehicleAISprite->getContentSize().height;
	maxSpeedForward = 400;
	maxWheelRotationAngle = 45;
	layerVAI->addChild(vehicleAISprite, numLayerVAI);

	Cancelled = false;
}

VehicleAI::~VehicleAI()
{
	vehicleAISprite->removeFromParentAndCleanup(true);
}

int VehicleAI::getPointIDForSpawnAIVehicle(cocos2d::Vec2 playerVehiclePosition, cocos2d::Size visibleScreenSize, std::vector<std::shared_ptr<VehicleAI>> vehicleAIList, std::vector<TrajectoryParser::WayPoint> WayPointsList)
{
	int pointID = -1;
	bool pointIsBusy = false;
	std::vector<int> pointsList;
	for (int iter = 0; iter < WayPointsList.size(); iter++)
	{
		TrajectoryParser::WayPoint wayPoint = WayPointsList.at(iter);
		if (wayPoint.Generation)
		{
			cocos2d::Vec2 XY = Point(wayPoint.PointCoordinates.x, wayPoint.PointCoordinates.y);
			cocos2d::Rect screenRect = Rect(playerVehiclePosition.x - visibleScreenSize.width / 2, playerVehiclePosition.y - visibleScreenSize.height / 2, visibleScreenSize.width, visibleScreenSize.height);
			if (!screenRect.containsPoint(XY))
			{
				if (XY.distance(playerVehiclePosition) < MAX_DISTANCE_FOR_GENERATE_AIVEHICLES)
				{
					int nextPointID = wayPoint.NextPointID.at(0);
					cocos2d::Vec2 nextXY = Point(WayPointsList.at(nextPointID).PointCoordinates.x, WayPointsList.at(nextPointID).PointCoordinates.y);
					if (playerVehiclePosition.distance(nextXY) < playerVehiclePosition.distance(XY))
					{
						for (auto vAI: vehicleAIList)
						{
							cocos2d::Vec2 vAIPosition = vAI->getPositionAIVehicle();
							if (vAIPosition.distance(XY) < RADIUS_OF_POINT_FOR_GENERATE_AIVEHICLES)
							{
								pointIsBusy = true;
								break;
							}
						}
						if (!pointIsBusy)
						{
							pointsList.push_back(iter);
						}
					}
				}
			}
		}
	}
	int count = pointsList.size();
	if (count > 0)
	{
		int r = 0;
		if (count > 1)
		{
			r = random<int>(0, count - 1);
		}
		pointID = pointsList.at(r);
		pointsList.clear();
	}
	else
	{
		pointID = -1;
	}
	return pointID;
}

void VehicleAI::vehicleAIMovement(float dt, cocos2d::Vec2 vehiclePlayerPosition, std::vector<std::shared_ptr<VehicleAI>> vehicleAIList, std::vector<TrajectoryParser::WayPoint> WayPointsList, int iterator)
{
	if (nextPointVAI.distance(vehicleAISprite->getPosition()) < DISTANCE_BETWEEN_AIVEHICLE_N_POINT)
	{
		roadType = WayPointsList.at(pointID).RoadType;
		rotationOnPoint = WayPointsList.at(pointID).Rotation;

		// get data about new point
		int nextPointIndex = random<int>(0, WayPointsList.at(pointID).NextPointID.size() - 1);
		pointID = WayPointsList.at(pointID).NextPointID.at(nextPointIndex);
		if (pointID != -2)
		{
			nextRoadType = WayPointsList.at(pointID).RoadType;
			prevPointVAI = Point(nextPointVAI.x, nextPointVAI.y);
			nextPointVAI = Point(WayPointsList.at(pointID).PointCoordinates.x, WayPointsList.at(pointID).PointCoordinates.y);
	}
	//other calculations
}

File describing waypoints now has a slightly modified structure:


(nID = -2 means that this is the last point on a particular trajectory and the object should be removed)

Jerking of cars has not disappeared (such as seen on previously recorded video) :frowning:
and I do not know what to do next…

In whichever part of the code you update the movement of the vehicle objects, put a conditional check in there for new X values that are less than the current X value, and then put a breakpoint on the inside of that check. Once it hits the breakpoint, you should be able to see what led to that incorrect result.

2 Likes

This topic was automatically closed 60 minutes after the last reply. New replies are no longer allowed.

Thanks again for your help for me!
The problem turned out to be not at all in the processing of a file or an array with waypoints.
Data types (float, double) cannot correctly handle calculations in boundary conditions (where very small or very large numbers are calculated). I could not even think about it initially…

If somebody does a similar game to mine and faces the same problem, then my advice is this: set the error for your calculations (for example, 0.001%), and not a hard condition (like if (variable! = 0) {do something}) :slight_smile:

Thanks for the help, friends! :smiley:

1 Like