Well I remember doing this same process in Garry's mod and it got pretty laggy. I can blame most of it on the physics, but the line of sight checks seemed to actually cause quite a bit of lag when I benchmarked them.
I'm just going to throw out the blueprints of the code and hopefully someone can point out any problems and help me conquer some hurdles.
Pieces-
-Ships are made of pieces. Each piece is individually defined.
-Each piece will become it's own shape.
Code: Select all
-- {image, { polygon coords} }
Pieces = {}
Pieces['wond_sec'] = {love.graphics.newImage('gfx/pieces/wond_sec01.png'), {0,30,17,0 ,55,0,72,30}}
Pieces['kae_sec47'] = { love.graphics.newImage('gfx/pieces/kae_sec47.png'), {0,0,15,0,32,17,32,25}}
Pieces['old_ce60'] = { love.graphics.newImage('gfx/pieces/Old_CE60.png'), {15,0,72,21,15,42,0,33,3,21,0,9}}
Ships-
-contain one core piece on which all other pieces most somehow indirectly or directly connect to.
-are a table of pieces.
-will correspond to one body, with one shape per piece.
Code: Select all
Ship1 = {}
Ship1['Core'] = 'old_ce60'
Ship1['Pieces'] = {}
Ship1['Weapons'] = {}
-- {Parent #, X Offset, Y Offset, Flip x, Flip y, Rotation, type}
Ship1['Pieces'][1] = {0, 0, 20, true, true, 0, 'wond_sec'}
Ship1['Pieces'][2] = {0, 0, -20, false, false, 0, 'wond_sec'}
Ship1['Pieces'][3] = {1, 0, 40, false, true, 0, 'kae_sec47'}
Ship1['Pieces'][4] = {2, 0, -40, false, false, 0, 'kae_sec47'}
Serverside -
1. A physics world is created.
2. Ships are created
---a. Add a body to represent each ship
---b. Go through each piece in the ship file and add the corresponding shape to this body.
3. Send created ships to new joining players as well as a table of which pieces are destroyed.
4. Simulate physics
5. Send updated ship positions.
5. Accept client input
Clientside-
1.Create a dummy physics world.
2.Draw the ships the server sends us from simple data (i.e. {ShipType, xpos, ypos, angle}). No physics will be simulated.
3.Send client commands.
Weapon Checks-
Here's the tricky part
0. If it's time to find a new target....
1. Loop through all shapes throwing out shapes that are too far away.
---a. How do we determine the distance between two shapes? There is no shape:getPos() or equivalent that I know of.
---b. If we get the center of a piece it's kind of inaccurate because the center might not be in range, but an edge might.
2. Check to see if the targeted shape is in the firing arc of the weapon
3. Loop through all remaining shapes and use shape:testLineSegment() to make sure there is nothing between the weapons and the target. If there is, try the next shape.
4. Fire
This last part could derail the whole project or at least drastically change all the guns to manual instead of auto-targetting, which makes this an entirely different game.
The only way I can think of doing this is to store the position of every single shape in the game (as in hundreds of them) in a big table that gets updated every time physics update. Each time I have to
1. Lookup the shape's body
2. Get the bodies position
3. Lookup the piece's relative offsets
4. Add that to the body postion
5. do rotation...
local finalx = (xoffset * math.cos(rotation) - yoffset * math.sin(rotation)) + centerx
local finaly = (xoffset * math.sin(rotation) + yoffset * math.cos(rotation)) + centery
to find the final position
Now if I have to do that for every single physics.update that seems awful, especially considering box2d has to have the x,y of each shape stored somewhere.