I'm working on a hobby game, basically about train dispatcher's job.
(stack: Typescript, phaser.js)
My map is based on a grid, each tile can hold 1 rail tile (well, except junctions, but we can simplify it for now, since junctions are just multiple tiles, from which only one is active).
Example (black is grid, white is rail):
As you can see, we have basically three different tiles: straight rail, 45 degree turn and diagonal rail (which can be also considered straight rail). I don't plan to add more tiles, as you can already build pretty complex setups from these tiles.
On these rails, trains would drive. Each carriage has two "wheels" - positions, where it snaps to a track. This may be seen on the following example from my prototype:
However the existing system (see below) has some issues:
- when a train travels diagonally, sometimes it's x and y coordinates fit in a field than it should (example: traveling from 1|1 to 2|2, but at one point the train's coordinates correspond to the field 1|2 or 2|1).
- axles sometimes get closer or futher away from each other. This has almost no effect on resulting simulation (as the carriage is centered between those two axles), but may cause carriages to be closer or futher away from each other (this effect is visible on the prototype as weell)
- moving the train in a certain direction is handled by a big chunk of code that essentially lists all possibilities of directions and handles it. I'm interested if there's a better way to do it, so I could simplify the code.
I decided that I would improve the core. I'm wondering, what would be the best way to do this?
What I am looking for:
- how to save the rail pieces on the map?
- how to move train (I know it's x, y, speed and acceleration)?
- how to have the train continue to the next piece on the grid?
Current solution (broken in some edge cases, also not ideal):
- each rail piece has it's class (
CurvedRail
,StraightRail
) - each rail piece class has method
movePoint
, that acceptsx
,y
,direction
anddistance
and returns new point (that isdistance
away from the original point, but also considering track turns). It may also returndelta
, if the movement reached edge of the tile and it needs to be moved futher (on another piece). This is handled by a separate class, that finds the following rail piece and callsmovePoint
with thedelta
instead - it has issues, because sometimes trains passing diagonal connection don't exactly follow the diagonal, so they instead of ending up on the next diagonal piece, they end up on neighboring horizontal or vertical piece and derail.
One of the issues I may be facing is that tiles are 32x32 pixels, so it's hard to travel exactly in the "middle" of the piece, because it's "between two pixels", and although I'm using decimals, it may be a problem. Is it better to have a grid from odd-sized tiles?