Jump to content
SubSpace Forum Network

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).

 

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...