Anet physics (newbie problem)

Posted By: Hand_Of_Law

Anet physics (newbie problem) - 08/27/09 11:34

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:
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
Posted By: Germanunkol

Re: Anet physics (newbie problem) - 08/27/09 15:53



this doesn't look good to me. you don't need to update the hull every two frames:
Code:
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:
Code:
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...
Posted By: Hand_Of_Law

Re: Anet physics (newbie problem) - 08/27/09 20:38

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 laugh
Posted By: Germanunkol

Re: Anet physics (newbie problem) - 08/28/09 07:45

Glad to help laugh
Posted By: Hand_Of_Law

Re: Anet physics (newbie problem) - 09/04/09 11:46

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.
Posted By: Dark_samurai

Re: Anet physics (newbie problem) - 09/05/09 11:28

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:

Code:
if(eBall != NULL) //entity wasn't removed yet
{
   if(eBall.y > 1085)
   {
   //...
   }
}


Posted By: Hand_Of_Law

Re: Anet physics (newbie problem) - 09/06/09 11:03

I knew it was something simple I missed, thanks.
© 2024 lite-C Forums