Jump to content
SSForum.net is back!

Recommended Posts

Posted

I am writing a subspace clone in javascript/canvas. I am at the point that I can fly around any .lvl file. I implemented collisions by just using rectangles. Every tile is a rectangle and the player is a rectangle, but it doesn't feel the same as in continuum. Someone knows how continuum does collision detection?

Posted

Here are a couple of pointers:

 

  • Subspace simulates 100 frames a second (a 'tick") and catches up when it is no longer in sync with the clock (as opposed to using delta time in every formula)
  • Every tick you simply use the Euler method to update the position for a step, this is accurate because you are syncing ticks instead of using delta time. So all you do is "newPosition = oldPosition.add(velocity)". If you are using delta time Euler is a bad idea, lookup Runge–Kutta 4 for one of the different methods
  • Avoid using Date to get the clock, it is very inaccurate and subject to changes to the clock by the user (or something like NTP). Try using Performance.now
  • If your tiles are axis aligned and square, the following works for projectiles (0 size):
    • Try storing your projectiles in a grid so that you can look them up by location very fast, instead of looping over every single projectile. If you make sure that " cell size = 2x " you can use bitshifts instead of division to get the cell coordinates.
    • Decide if you want to simulate the collision path for the full position step within a tick (e.g. multiple collisions possible for a single entity within a tick), or only up to the first collision. The latter option is easier but less accurate at high speeds.
    • If you are using synced ticks, you can do simple ray casting between the oldPosition and the newPosition to walk through all the tiles that might get hit. There are many methods for ray casting/tracing. I have used a modified "bresenham line algorithm" before, but I needed that specific one because I wanted to only use integers, so a different one is probably more suitable for you.
    • When you have the tile you want to collide, figure out the tile line it should collide with (a tile has 4 lines). For example by calculating the distances between the center of the line and your oldPosition
    • What you have now are two lines segments, find the intersection. You can easily find a good method for this. (for example Graphics Gems III page 199).
    • You now have the specific tile you collided with, the point of intersection, and the tile side. If the projectile is something that bounces, flip the velocity along the proper axis and apply a bounce factor
  • Collision between ships and tiles is a bit harder because they have a size (ships are square in subspace ;) ). One thing you could do is turn the path the ship has taken into a convex polygon and find out the two intersection points between that convex polygon and a tile side.
  • If you are doing multiplayer, look up dead reckon convergence for your ships. This book explains it in short (page 193)
  • If you are doing multiplayer, make sure you understand the limitations of floating points, e.g. stuff like "cos(x) != cos(x)". Every number in javascript is 64 bit floating point (IEEE 754 to be precise).
Posted

Thanks, but knew most of this already (except for the subspace specific stuff).

The thing I am most intrested in is, ships are just squares in subspace? Are they 32x32 pixels?

 

 

Here are a couple of pointers:

 

  • Subspace simulates 100 frames a second (a 'tick") and catches up when it is no longer in sync with the clock (as opposed to using delta time in every formula)
  • Every tick you simply use the Euler method to update the position for a step, this is accurate because you are syncing ticks instead of using delta time. So all you do is "newPosition = oldPosition.add(velocity)". If you are using delta time Euler is a bad idea, lookup Runge–Kutta 4 for one of the different methods
  • Avoid using Date to get the clock, it is very inaccurate and subject to changes to the clock by the user (or something like NTP). Try using Performance.now
  • If your tiles are axis aligned and square, the following works for projectiles (0 size):
    • Try storing your projectiles in a grid so that you can look them up by location very fast, instead of looping over every single projectile. If you make sure that " cell size = 2x " you can use bitshifts instead of division to get the cell coordinates.
    • Decide if you want to simulate the collision path for the full position step within a tick (e.g. multiple collisions possible for a single entity within a tick), or only up to the first collision. The latter option is easier but less accurate at high speeds.
    • If you are using synced ticks, you can do simple ray casting between the oldPosition and the newPosition to walk through all the tiles that might get hit. There are many methods for ray casting/tracing. I have used a modified "bresenham line algorithm" before, but I needed that specific one because I wanted to only use integers, so a different one is probably more suitable for you.
    • When you have the tile you want to collide, figure out the tile line it should collide with (a tile has 4 lines). For example by calculating the distances between the center of the line and your oldPosition
    • What you have now are two lines segments, find the intersection. You can easily find a good method for this. (for example Graphics Gems III page 199).
    • You now have the specific tile you collided with, the point of intersection, and the tile side. If the projectile is something that bounces, flip the velocity along the proper axis and apply a bounce factor
  • Collision between ships and tiles is a bit harder because they have a size (ships are square in subspace ;) ). One thing you could do is turn the path the ship has taken into a convex polygon and find out the two intersection points between that convex polygon and a tile side.
  • If you are doing multiplayer, look up dead reckon convergence for your ships. This book explains it in short (page 193)
  • If you are doing multiplayer, make sure you understand the limitations of floating points, e.g. stuff like "cos(x) != cos(x)". Every number in javascript is 64 bit floating point (IEEE 754 to be precise).

 

Posted

Yes they are squares. The "radius" varies by zone, but the default is 14 pixels, which would make the box 28 or 29 to a side, depending on how the math works out.

Freedom is the right to be wrong.
Posted

SSC Distension Owner
SSCU Trench Wars Developer


3:JabJabJab> sometimes i feel like when im in this mood im like a productive form of Cheese
Dr Brain> Pretty much everything you said was wrong. Except where you called me a lazy jerk with no time. That was true.
3:KrynetiX> do you ever open your web browser and type ?go google
5:Ceiu> Wow. My colon decided that was a good time to evacuate itself.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...