Problem with shooting

Started by Melssj5, November 10, 2008, 04:06:18 PM

Previous topic - Next topic

Melssj5

Hi again yesterday I coded a bit again on my project and I am having problems with this again. My problem is this one:


I create the bullets, set the collision mode and add a COlisionListener to them, on the client side, I move them until reaching an obstacle and then I drop the bullet from the world. My problem is, that as the bullet is shot from the craft position then it collides with their owner craft and are never shot.

I thouht about saving some information on the Bullet class to determine with craft shot it and avoid that collision to stop the bullet, but I cant determine this.

The bullet class has a String with the craft name, but when the collision is done I cant determine which object was the target of the collision generated by the bullet, so I cant know if it was the own craft or another object3d.

Would be very usefull to add a getTarget method on the CollisionListener / CollisionEvent becausse there are things that cant be done with the getSource. The getTarget should return an array with all the targets. and basicly the problem is that crafts and bullets move on the client. So, sometimes the source can be the bullet and in some other cases the source can be the craft, But I must check on somehow who was hit by a bullet. Any ideas about how to sove this?????
Nada por ahora

EgonOlsen

Personally, i disable each player in Robombs before checking collision from his bullets. If you want to get the target of a collision, attach the listener to the target. It doesn't have to be attached solely to the object that collides, it can also be attached to the object that is the collision target.
Anyway, this may not help in this situation, because knowing that the bullet collided with the ship itself doesn't prevent the collision from happen, i.e. the direction vector will be shortened anyway and the bullet will stop moving before actually leaving the ship. Another solution would be to use small offset to prevent the bullet from intersecting with the ship.

Melssj5

Ok, I could add the listener to the ship too, but it wont change anything in that problem becausse I wont be able to know if the ship collided with an own bullet or with another one becausse Iwont be able to recognize the target. Of course that from one collision, one is the source and the another one is the target, but I cant relationate on event with the another one. Or does the Collision event has a unique numer to match?????

in my Thread. I first move all the ships, one to one, and then I move the bullets, ont to one.

But lets imagine this:

case1: Listener on the ship
Ship 1: moves and collides with Bullet 1 (I know there were a collision so I can remove the bullet from the world, and reduce the life of that ship, but as I dont know the target I cant know the kind of bullet to know: how much life to reduce and who shoted?????? and I cannot do the check for not colliding with its owner) Source: Ship1

or this another one case:

case2: Listener on the bullet
Bullet 1 moves and collides with Ship 1 (I know there were a collision so I can remove the bullet from the world and I know how much life to reduce from the target if it was a ship, but as I dont know the target I cant know the ship so I cant reduce the life to anybody and I cannot do the check for not colliding with its owner) Source: Bullet1

case3: Listener on Both, all ships and all bullet
Bullet1 moves and collide ship1 (Cant know which ship was afected becausse I cant know the target) Source Bullet 1.

I have a BulletListener class that is the collisionListener for all the Bullets, Maybe I would have to use a new CollisionCHecking class for each ship on both CLIENT and SEVER sides.  On that way I can solve the problem on case 3. I guess the only way to do it is to have exclusive Collision Checking instances for each bullet and ship in the world.
That class will hava a reference to the object, so when a collision happens I can know the objects involved. (I dont care about who was source or target, I just care about the objects involved).

Wouldnt this increase the resources needed or maybe generate a bit of lag, having a new class for each object3d?

Nada por ahora

EgonOlsen

Not quite...if you attach the listener to the ship and the bullet moves, getObject() returns you the target, i.e. the ship and getSource() returns you the bullet. IMHO, you don't need to check if the ship collides with a bullet. Doing that check on the bullet side only should be sufficient.
In Robombs, there is only one generic listener (ClientObjectCollisionListener) for all kinds of collisions. It is attached to all possible targets (players, bombs, crates...) and all it does is to call a hits(target)-method on the source. The source itself knows what it is. If it's, for example, a bullet, it calls hitByBullet(source) on the given target. If it's an explosion, it calls hitByExplosion(source) on the target and so on. That's very convinient to use once you grasp the concept of double dispatch.

Melssj5

Well, I am afarid I do not understand well what you said.

I added a new CollisionListener to each ship and bullet and the lag went to the hell, I will try what you say. but:

QuoteNot quite...if you attach the listener to the ship and the bullet moves, getObject() returns you the target,

And what if: if you attach the listener to the ship and the ship moves then getObject() returns you the target??????????

the problem is that both are moving, the bullet and the ship. first all the ships and then all the bullets, not on different Threads but anyway any of both can fire the collision.

Can you give a example about what you said before becausse I didnt quite understood.
Nada por ahora

EgonOlsen

Quote from: Melssj5 on November 11, 2008, 03:31:27 PM
And what if: if you attach the listener to the ship and the ship moves then getObject() returns you the target??????????
No, but i don't think that this i required. If the listener is solely attached to all possible targets, this should be sufficient IMHO. If a ship moves and collides with another ship, the listener on the target ship gives you the source (i.e. your moving ship) and the target. If a bullet hits a ship (in the bullet-move-phase), the ship's listener gives you the target (the ship) and the source (the bullet). The same works for the terrain ans similar entities.
If the ship moves into a bullet during the ship-move-phase, it doesn't matter, because in the next bullet iteration, the collision will be detected anyway. Otherwise (with one listener per entity, i.e. one on the bullet and one on the ship), you'll get two events. One caused by the bullet hitting the ship and one by the ship being hit by the bullet...and that is one too much IMHO, because the one on the ship already has all the information you need to process this event.


Melssj5

QuoteIf the ship moves into a bullet during the ship-move-phase, it doesn't matter, because in the next bullet iteration, the collision will be detected anyway



Yes, I was thinking on that too, but the problem is that it requires 2 movements to detectc the collision and that may result on a no detection on cases in which the bullet speed is too high. For example. (This can always happens but detecting on every movement reduces the posibilities)

Nada por ahora

EgonOlsen

#7
But figure three will be detected as a collision. Depending on the collision method used, the resulting direction vector may not be very useful to resolve the collision, but that doesn't matter for bullets and the event will be fired anyway. The ellipsoid collision detection is a sweep algorithm, i.e. it will detect any collision on the bullets way, not just in its start and/or end position.

Edit: Ship and bullet will do a collision detection anyway, it's just that the bullet needs no listener attached. That way, figure three can never happen, because they will never intersect.

Melssj5

Yes, I know that perfectly. But is about the target detection. In figure 3 the collision will be detected on the collisionListener on the ship, but the source will be the ship and the object will be ship too. In the another post before you told me that I must wait until the next bullet movement to get the next collision detection to have the objects needed to work but on the pic I am trying to show a case in which the collision is only made by the ship movement and not by the bullet movement. It was my fault to writte "NO DETECTION CASE" instead of "USELESS DETECTION CASE".

Egon, would be very very very difficult and imposible to add a:

Object3d [] getTargets () {

}

method??????

Sorry for being a pain in the ass!  ::)
Nada por ahora

EgonOlsen

Quote from: Melssj5 on November 11, 2008, 05:35:41 PM
Yes, I know that perfectly. But is about the target detection. In figure 3 the collision will be detected on the collisionListener on the ship, but the source will be the ship and the object will be ship too. In the another post before you told me that I must wait until the next bullet movement to get the next collision detection to have the objects needed to work but on the pic I am trying to show a case in which the collision is only made by the ship movement and not by the bullet movement. It was my fault to writte "NO DETECTION CASE" instead of "USELESS DETECTION CASE".
Agreed. If the ship is moving and has a listener attached (you can disable collision listeners for that purpose by the way), then the event will be source==object. But i don't see why this should be a problem. In the next bullet movement, it should intersect with the ship unless the ship is moving in such large steps that it literally jumps from the front of the bullet right behind the bullet, which is very unlikely unless your bullets are moving extremely slow when compared to the ship or your frame rate can be meassured in seconds per frame.

Quote from: Melssj5 on November 11, 2008, 05:35:41 PM
Egon, would be very very very difficult and imposible to add a:

Object3d [] getTargets () {

}

method??????

Sorry for being a pain in the ass!  ::)
No problem...it's just that my gut feeling tells me that this isn't needed. I've never needed it. Not for Paradroidz, not for Robombs and not for the various test cases and demo applications that i've written. I feel that collision detection and the listener concept are already twisted enough...at least it manages to confuse me from time to time when thinking about which listener should be attached to which object and when it is the source or the target or whatever...

Anyway...i'll look into it...

Melssj5

Thanks. ;D

And Yes, it may happens when the bullet or the ships moves  at great speeds, especially when they move one to each other, it may happen that. I should consider doing on that way having a max speed for a bullet considering the ship size/speed and the bullet size/speed!
Nada por ahora

EgonOlsen

Please give this jar a try: http://www.jpct.net/download/beta/jpct.jar

I haven't really tested if CollisionEvent.getTargets() works as expected, but at least the rest still works... ;D

Melssj5

I havent try it yet, but I am running into a performance problem I would like to fix first.

The client had 3 Threads.

1.- rendering Thread
2.- Event managment and networking Thread
3.- Bullet moving Thread (a while loop moving all bullets one by one)

When they are a few bullets, the performance is good, but when they are many alive bullets then the performance goes to the hell. I mean more than 20 alive bullets.

The ship movement was the same but the bullets began to move too slowly. It was becausse the bullets moves one by one inside a while loop. So the more bullets they are, the slower they will move.

After that I created a separate Thread for moving each bullet But now I am having a global performance problem and I am afraid that having hundreds of Threads inside a single process will bring me some problems. Now all Threads are slowly and the processor usage goes to 100%:

1.- rendering Thread
2.- Event managment and networking Thread
3.- Bullet moving Thread (a while loop checking all bullet movement one by one)
4, 5, 6, 7......... A ShotMoving Thread (Moving the bullet and sleeping 40 ms)

I guess that this is happening because the processor is always being used. Maybe I should sync all the bullets movement to have a sleep on the same moment to let the rendering and event managment threads to use the processor, but I dont know. Any ideas?
Nada por ahora

EgonOlsen

Don't spawn one thread per bullet! Just measure the time between two bullet movements and move the bullets accordingly. Let's say that you move the bullets one unit/10ms and 35ms have passed, just move them 3.5 units.

Melssj5

mmm, do you mean having a relation between the whole bullets moving time and the movement distance for each bullet???? Then when they are few bullets I will need to move then and lower speeds to have the same behavior than moving faster when they take a larger time to move all the bullets??????

The problem on that is the precision and collision detection, doing the bullets jumping large distances will make them look bad on the game and will avoid doing a correct collision detection. I am talking about 350 ms for moving 40 bullets, so I guess that a normal game may have more that a hundred alive bullets on the fly, so having 1 sec for moving all the bullets will make that bullets moves at huge speeds. Anyway I will try it to see is it helps.
Nada por ahora