Race Positions
by Chris Byars · in Torque Game Engine · 06/19/2006 (5:43 pm) · 14 replies
Now, this topic has been only mentioned I believe, once, in the forums around here, and even so, there wasn't really any solution to it, only theory.
I am looking for a way to calculate the "race positions" (First, second, third, etc) of players in a race. The players in this game must pass through checkpoints periodically (so they all stay in the same general direction, to curb cheating). Immediately I thought of calculating the distance from the player to the next checkpoint, and the player with the lowest distance and the highest number of checkpoints completed to be judged as being First in the race, and so on.
The problem I find myself trying to solve is: How do you calculate the distance between an object and another in script?
Edit: Found an old thread with how:
Will work on this and post the resulting functional code to help anyone else who may need it.
I am looking for a way to calculate the "race positions" (First, second, third, etc) of players in a race. The players in this game must pass through checkpoints periodically (so they all stay in the same general direction, to curb cheating). Immediately I thought of calculating the distance from the player to the next checkpoint, and the player with the lowest distance and the highest number of checkpoints completed to be judged as being First in the race, and so on.
The problem I find myself trying to solve is: How do you calculate the distance between an object and another in script?
Edit: Found an old thread with how:
%distance = VectorDist(%obj1.getPosition(),%obj2.getPosition());
Will work on this and post the resulting functional code to help anyone else who may need it.
#2
For example, this code works fine in function CheckPointTrigger::onEnterTrigger(%this,%trigger,%obj):
But that only finds the player's position when they enter the trigger, I need to be able to do something similar in another function that can call itself every 100ms.
06/19/2006 (7:56 pm)
I'm having difficulty finding a good way to get a player's position at any given time. I can get it when they walk through a trigger, or when they spawn, just not by using a function that gets called every 100 ms.. I don't know what to put as the local variable.For example, this code works fine in function CheckPointTrigger::onEnterTrigger(%this,%trigger,%obj):
%positionOne = %obj.getPosition();
But that only finds the player's position when they enter the trigger, I need to be able to do something similar in another function that can call itself every 100ms.
#3
06/20/2006 (5:30 am)
To iterate over all players, you could do something like this:%count = ClientGroup.getCount();
for(%i=0; %i < %count; %i++)
{
%client = ClientGroup.getobject(%i);
%player = %client.player;
%pos1 = %player.getPosition();
//do something with the player position here
}
#4
Looks like your code snippet will do the job of getting all player's positions. I'll just have to find a way for the server to sort each one out and find each one's number of laps and checkpoints completed, and make it say the one who has the most laps and checkpoints completed, and the least distance to the next checkpoint for them, is first and so on.
06/20/2006 (7:56 am)
I eventually was able to get the current player's position, the next checkpoint's position for that player, and the distance between both every 100ms. Unfortunately that becomes useless except for client side reporting to each player how far the next checkpoint for them is.Looks like your code snippet will do the job of getting all player's positions. I'll just have to find a way for the server to sort each one out and find each one's number of laps and checkpoints completed, and make it say the one who has the most laps and checkpoints completed, and the least distance to the next checkpoint for them, is first and so on.
#5
06/20/2006 (11:58 am)
Well that above code does the job of getting my player position, and I assume it will get all of the players' positions as well. How would I sort out who's who?
#6
I keep thinking there is a better way to get the text of the client name from the server side, but haven't found one yet. This works, in any case.
You should also be able to store any number of identifiers and statistics in both the %client and %client.player instances.
06/20/2006 (12:41 pm)
You could look at the client names, ie., %client.name. That usually returns the numeric ID of the client, but you can force it to be the text name like this:%username = detag(getTaggedString(%client.name));
%username = StripMLControlChars(%username);I keep thinking there is a better way to get the text of the client name from the server side, but haven't found one yet. This works, in any case.
You should also be able to store any number of identifiers and statistics in both the %client and %client.player instances.
#7
that would make determining positions simple.
one function to convert the track to a straight line.
one piece of code to calculate percentage of section car is at.
Done like Dinner.
Edit:
actually you dont even need to convert the track.
simply use a percentage for each car (percentage of section + current section.)
even Easier.
now you just pool up all the percentages and see who is highest.
Edit2:
Actually, heh... straightening out the path would be benificial for determinig percentage amounts via distance.
so it's still a good idea to do that.
Edit3:
Ok, i'm stupid sometimes.
you don't need to straighten the path.
for each car you need to know:
1.) how many laps
2.) what node they are on
with this data you can then use it with a percentage of completion of the current leg (node to node) to determine who is in first.
final answer.
06/20/2006 (1:07 pm)
I would make the track a straight line, and then calculate a percentage value to the next node for each car.that would make determining positions simple.
one function to convert the track to a straight line.
one piece of code to calculate percentage of section car is at.
Done like Dinner.
Edit:
actually you dont even need to convert the track.
simply use a percentage for each car (percentage of section + current section.)
even Easier.
now you just pool up all the percentages and see who is highest.
Edit2:
Actually, heh... straightening out the path would be benificial for determinig percentage amounts via distance.
so it's still a good idea to do that.
Edit3:
Ok, i'm stupid sometimes.
you don't need to straighten the path.
for each car you need to know:
1.) how many laps
2.) what node they are on
with this data you can then use it with a percentage of completion of the current leg (node to node) to determine who is in first.
final answer.
#8
I need separated calculations for each player, so they can be compared. This function above, I think, is supposed to get all player's positions. Well, we would need to know which player corresponds to which position to make a judgment on who's in first, second, and third.
06/20/2006 (2:01 pm)
I mean, how to sort out who's who as in, that code snippet you provided..%count = ClientGroup.getCount();
for(%i=0; %i < %count; %i++)
{
%client = ClientGroup.getobject(%i);
%player = %client.player;
%pos1 = %player.getPosition(); // [i]Which[/i] player's position is this? All? Mine? Who's?
}I need separated calculations for each player, so they can be compared. This function above, I think, is supposed to get all player's positions. Well, we would need to know which player corresponds to which position to make a judgment on who's in first, second, and third.
#9
should be more like :
Bah, its incomplete but I hope you get the idea.
Edit:
should change this group to be Racers .. not just ai.
unless only the ai are racing?
:)
everyone in this group should be tested for this not just compare ai to you.
06/20/2006 (2:08 pm)
C2:should be more like :
%count = ClientGroup.getCount();
for(%i=0; %i < %count; %i++)
{
%client = ClientGroup.getobject(%i);
%player = %client.player;
%pos1 = %player.getPosition(); // Which player's position is this? All? Mine? Who's?
%laps = %client.laps;
%node = %client.node;
// now get the next node from track
%nextnode = %node+1;
// verify we have not looped the track just now
if(%nextnode >= %track.EnumNodes())
{
// compensate.
}
%nodepos = %track.GetNodePosition(%node);
%nextnodepos = %track.GetNodePosition(%nextnode);
%dist = %nextnodepos - %nodepos;
// make %pos1 a percentage of dist
// right now anyone with less laps or a smaller node are less than us.
// anyone matching our laps and node will have to determine who has a higher percentage of this leg.
}Bah, its incomplete but I hope you get the idea.
Edit:
should change this group to be Racers .. not just ai.
unless only the ai are racing?
:)
everyone in this group should be tested for this not just compare ai to you.
#10
Right now its real easy to calculate how many laps a client has completed, how many checkpoints a client has completed, and the distance to the next checkpoint.
All I need is a way to find every client that is connected's data like that, and then I can code the logic judgment from there. I don't know how to get the server to find each client individually's data like that.
06/20/2006 (2:21 pm)
I don't get what you mean by using nodes, it makes sense to calculate it like I said: "a way for the server to sort each [player] out and find each [player]'s number of laps and checkpoints completed, and make it say the one who has the most laps and checkpoints completed, and the least distance to the next checkpoint for them, is first and so on."Right now its real easy to calculate how many laps a client has completed, how many checkpoints a client has completed, and the distance to the next checkpoint.
All I need is a way to find every client that is connected's data like that, and then I can code the logic judgment from there. I don't know how to get the server to find each client individually's data like that.
#11
that is all the clients connected.
and there is an AI group as well prolly.
in that group there is a unique id for each player you can then retrieve the data related to that player from that id.
is that the question?
06/20/2006 (3:08 pm)
ClientGroup.getCount();that is all the clients connected.
and there is an AI group as well prolly.
in that group there is a unique id for each player you can then retrieve the data related to that player from that id.
is that the question?
#12
06/20/2006 (4:03 pm)
Thanks, yeah. I am just not familiar at all with how the ClientGroup calls and calculations work. I'll just need to find a way to retrieve the data and I'm golden.
#13
06/20/2006 (4:24 pm)
Does that clear it up for you then bud?
#14
06/20/2006 (6:17 pm)
Somewhat, still working on the logic of getting and comparing each client's data to each other.
Torque Owner Brian Hill
I'd put triggers in at the checkpoints, and keep track of the last checkpoint passed (you're probably already doing this). Then have a way of looking up the next checkpoint in a list (either a simset or indexed variables), and just use vectorDist on the positions of the players and their next checkpoint. It would be much quicker than doing any raycasts (since there are going to be a known, finite set of checkpoints).