|
Anet physics (newbie problem)
#286783
08/27/09 11:34
08/27/09 11:34
|
Joined: May 2008
Posts: 33 Russia/Netherlands
Hand_Of_Law
OP
Newbie
|
OP
Newbie
Joined: May 2008
Posts: 33
Russia/Netherlands
|
I am making a simple experiment and need some advice on how to make it work. The basic is the 3D chat example, with an added ball entity. When the 'b' key is pressed the ball appears for all players, but when a client touches the ball it appears double and constantly jumps between the two positions. Code:
//Lite-C:
function receive_ballkick(var sender,STRING* msg)
{
if (msg = "bounce") {
// Create a local speed vector
VECTOR vKick;
// Use a horizontal and vertical speed to give the ball an upwards kick.
vKick.x = 3; vKick.y = 0; vKick.z = 1;
// Rotate it in camera direction.
// Now apply the speed to the ball, and play a hit sound.
phent_addvelcentral(me,vKick);
}
}
function bounce_event()
{
VECTOR bdirect;
if (event_type == EVENT_PUSH)
{
}
if (event_type == EVENT_IMPACT)
{
enet_clsend_event(19,_str("bounce"),-2);
}
}
function move_ball()
{
VECTOR ball_dist; //needed for the movement
VECTOR save_pos; //stores the entity.pos (needed to find out if the position has changed)
VECTOR temp; //a temporary vector
var save_pan = 0; //stores the entity.pan (needed to find out if the pan has changed)
me.flags |= SHADOW;
// Now let's set the ball's physical properties.
phent_settype(me,PH_RIGID,PH_SPHERE);
phent_setmass(me,1,PH_SPHERE);
phent_setfriction(me,90);
phent_setelasticity(me,75,100);
phent_setdamping(me,30,5);
// We add a small speed to give it a little sidewards kick.
// phent_addvelcentral(me,vector(10,10,0));
// A ball game would be no fun without gravity.
ph_setgravity(vector(0,0,-500));
me.emask |= (ENABLE_FRICTION | ENABLE_PUSH | ENABLE_IMPACT);
me.push = 1;
me.event = bounce_event;
while(enet_ent_globpointer(my) == -1) {wait(1);} //wait until the entity gets a global pointer
if(enet_get_connection() !=2)
{
while(1) {
wait(1); //needed for c_updatehull
c_updatehull(my,0); //updates the collsision hull
enet_send_pos(enet_ent_globpointer(my),-1);
wait(1);
}
}
}
function ball_startup()
{
VECTOR creating_pos; //position were the entity will be created
while(enet_get_connection() == 0) {wait(1);} //wait until a host is initialized
while(1) {
if(key_b == ON && enet_get_connection() != 2)
{
if (ingame == 0) {
creating_pos.x = 0;creating_pos.y = 0;creating_pos.z=0;
eBall = enet_ent_create(_str("ball.mdl"),creating_pos,_str("move_ball"));
ingame = 1;
}
}
if(key_c == ON && enet_get_connection() != 1)
{
enet_clsend_event(19,_str("shoot"),-2); //sends the shoot message to the server
while (key_c == ON) {wait(1);}
}
wait(1);
}
}
Any quick help appreciated
|
|
|
Re: Anet physics (newbie problem)
[Re: Hand_Of_Law]
#286824
08/27/09 15:53
08/27/09 15:53
|
Joined: Jun 2006
Posts: 2,640 Earth
Germanunkol
Expert
|
Expert
Joined: Jun 2006
Posts: 2,640
Earth
|
this doesn't look good to me. you don't need to update the hull every two frames:
while(1) {
wait(1); //needed for c_updatehull
c_updatehull(my,0); //updates the collsision hull
enet_send_pos(enet_ent_globpointer(my),-1);
wait(1);
}
try this instead:
function move_ball()
{
wait(1); //needed for c_updatehull
c_updatehull(my,0); //updates the collsision hull
VECTOR ball_dist; //needed for the movement
VECTOR save_pos; //stores the entity.pos (needed to find out if the position has changed)
VECTOR temp; //a temporary vector
var save_pan = 0; //stores the entity.pan (needed to find out if the pan has changed)
me.flags |= SHADOW;
while(enet_ent_globpointer(my) == -1) {wait(1);} //wait until the entity gets a global pointer
if(enet_get_connection() !=2)
{
//only do physics on the server:
// Now let's set the ball's physical properties.
phent_settype(me,PH_RIGID,PH_SPHERE);
phent_setmass(me,1,PH_SPHERE);
phent_setfriction(me,90);
phent_setelasticity(me,75,100);
phent_setdamping(me,30,5);
// We add a small speed to give it a little sidewards kick.
// phent_addvelcentral(me,vector(10,10,0));
// A ball game would be no fun without gravity.
ph_setgravity(vector(0,0,-500));
//only do the events on the server:
me.emask |= (ENABLE_FRICTION | ENABLE_PUSH | ENABLE_IMPACT);
me.push = 1;
me.event = bounce_event;
var timePassed = 0;
while(1) {
timePassed += time_frame;
if(timePassed >= 2) { //only send 8 times a second.
timePassed = 0;
enet_send_pos(enet_ent_globpointer(my),-1);
}
wait(1);
}
}
else
{
while(my) {
//do movement prediction in here
wait(1);
}
}
}
This may not work. For smooth movent, you should add the movement prediction in the client's part of the ball function. You were sending the position once a frame, which may work on a LAN game and for testing purposes, but it'll produce way too much traffic when you play an internet game or when you have more people join. Instead of sending the position directly, you should also put it into skills and send those, then you can easily (more or less) work from those skills on the clients, to predict where the ball will go next. Also, receive_ballkick(var sender,STRING* msg) must be a server event that the client triggers on the server. I can't see here whether it is or not. Hope this helps...
Last edited by Germanunkol; 08/27/09 15:53.
~"I never let school interfere with my education"~ -Mark Twain
|
|
|
Re: Anet physics (newbie problem)
[Re: Germanunkol]
#286857
08/27/09 20:38
08/27/09 20:38
|
Joined: May 2008
Posts: 33 Russia/Netherlands
Hand_Of_Law
OP
Newbie
|
OP
Newbie
Joined: May 2008
Posts: 33
Russia/Netherlands
|
The server event is set in the main.c as event 19. Your solution works as I do no longer get the 'jumping' balls. Thanks and I will keep the thread for newt problems
|
|
|
Re: Anet physics (newbie problem)
[Re: Germanunkol]
#288129
09/04/09 11:46
09/04/09 11:46
|
Joined: May 2008
Posts: 33 Russia/Netherlands
Hand_Of_Law
OP
Newbie
|
OP
Newbie
Joined: May 2008
Posts: 33
Russia/Netherlands
|
A new problem, with the same base error I made earlier... perhaps someone can make me understand the basic of my thought error.
In the code above I added:
if (eBall.y >1085) { enet_clsend_event(30,_str("out"),-2); }
and the event (which is initialized on the startup with svsend and clsend)
function detect_out(var sender,STRING* msg) { if (eBall.y >1085) { error("Out"); enet_ent_remove(enet_ent_globpointer(eBall)); } }
The error is a debug. This makes a constat display of 'empty pointer' error. Idea is to remove the eBall entity if it crosses a line.
An alternative approach I have tried: if (my.y >1085) { my.x = 0 ; my.y = 0; } This results in the same 'jump' as I had previous. My expectation is that by setting the position to 0,0 on the server the enet_send_pos would update the position on all clients as well. However instead the eBall entity seems to be on the old place for some and in the 0,0 position for others, jumping around. It does not react on collision at the 0,0 position but does react on a 'shot' button, at which time the ball starts rolling back from the line instead of from the 0,0 position.
|
|
|
Re: Anet physics (newbie problem)
[Re: Hand_Of_Law]
#288321
09/05/09 11:28
09/05/09 11:28
|
Joined: Jul 2005
Posts: 1,930 Austria
Dark_samurai
Serious User
|
Serious User
Joined: Jul 2005
Posts: 1,930
Austria
|
Empty pointer means that the entity was removed but you are still using the pointer. Always do a check before you are using an entity pointer:
if(eBall != NULL) //entity wasn't removed yet
{
if(eBall.y > 1085)
{
//...
}
}
ANet - A stable and secure network plugin with multi-zone, unlimited players, voip, server-list features,... (for A7/A8)! get free version
|
|
|
|