Friday, March 27, 2015

xna - How do I check collision when firing bullet?


I'm currently creating 2D game from top perspective. I'm having problems with bullets. Yes, I currently simulate their movement so user can see them (about 2x ). Moving them with


// this is static

Direction = new Vector2(mouse.X, mouse.Y) - new Vector2(player.x, player.y);
Direction.Normalize();
Speed = 900f;

//this is called in Draw(GameTime gameTime)
Position += Direction * 9f * Speed * (float)gameTime.ElapsedGameTime.TotalSeconds;

actually it's working perfectly, however, they're too fast so I can't check their collision each frame and I need to re-play their way each frame. How would I do it? And how would I do this available for both server (which doesn't use XNA as I want to port it to Linux later) and client (using XNA)?


Here's an image which shows the problem (1. bullet is before target 2. bullet is behind target, so it can no longer intersect the target. My goal is to calculate whether it intersected the target before)




I have almost forgot to mention! These objects are moving, these are player, that means that user can get out of the bullet's trace



Answer



The simplest way to solve this problem is to use fixed time steps in XNA and tell it you want more fps for your update method, this makes your update code run more often and with smaller time steps which in turn means that your bullet will travel a shorter distance each time you check for collisions. This is essentially what Nick mentioned above, but with less changes needed to your code.


In the constructor for your Game class put the following two lines of code:


base.IsFixedTimeStep = true;
base.TargetElapsedTime = new TimeSpan((long)(TimeSpan.TicksPerSecond / 600f));

600f Is the number of frames per second you want, most likely your already running with fixed time step (this is the default in XNA) at 60fps, by changing it to 600 your bullets will be checked 10 times more often.


Once you understood how this works in practice however I would recommend that you do this manually by dividing the ElapsedGameTime you receive in your update with the speed of your bullet and then update the bullet multiple times per update, this way you don't force your entire game to run at higher frames per second just to accommodate your bullets moving fast. Hope this helps.





PS. Swept objects is an interesting solution to this problem, while probably overkill for your scenario, it involves sweeping the object (the bullet) along its movement vector and then comparing this new shape to the other objects for collision. Sweeping a circle would give you a capsule for instance. You would normally do this with the bounding boxes of the sprites since its easier to calculate, but using algorithms like GJK you can do it with arbitrary shapes as well (in both 2D and 3D).


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...