The object starts to freeze when approaching the end point

The object starts to freeze when approaching the end point
0

#21

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:


#22

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:


#23

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…


#24

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.


closed #25

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


opened #26

#27

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: