Game in 7 Days, Day 4: Tracking back
7days1game programming unity fun weapons movement physics worms
As usual, had to wait some time for next day of development. Kid's got runny nose, he's coughing, and his teeth are growing. Talk about bad combo for holidays. And I'm down with some flu as well. At least this meant that I don't have to be socially active and finally I get some time in front of the computer (whenever the kid's asleep).
So, where were we? Looking at my chart it seems like I should be doing Day 4: Gameplay. But I didn't feel like it. I decided that I don't want stationary targets shooting with two types of weapon. So I tracked back a little. Firstly, I've added walking.
Walking while easy in polygon or tile world, is massive pain in the backside in the per-pixel collision world. Let's take a look at the algorithm:
1) First, check ground-level pixel in the direction you're moving. If it's empty, check one above it and so on till you've checked enough pixels for the character to pass through. If you managed to find enough space, allow movement.
2) Now, if one of those pixels was non-empty (that is, part of landscape), check how high above the ground is it. If it's less than allowedSlopeDifference variable, zero the free pixel counter and start counting from the pixel above it, returning to 1)
3) If you detect that there is not enough free space to move, well then, stop movement.
4) Check pixels underneath. If there's a fall, and that fall is less then maxFallDistance, step down. If it's more than that, 'physics' kicks in and free fall starts.
Well, that's it. Doesn't sound that complex, and really isn't (and should be replaced with something better later on), but it allows me for implementing movement based gameplay.
That is, WEAPONS!
Well, ok, not all of them needed movement to be used, but only when movement is used do they truly show their potential. Without further ado:
Shotgun, lightly damaging weapon that you can fire twice. Useful to put two opponents out of their misery or cut through small wall. Implementation was simple enough - hitscan that causes explosion the moment it hits something. A simple line algorithm that iterates through level and looks at each pixel on its way, testing for collision.
Dynamite. Huge power, huge radius of explosion. Implementation was modified grenade script. Also has timed fuse (set to 5 seconds currently, will be changeable in game). Doesn't bounce though, and the throw strength is only at couple percent of the normal strength, so while it can be thrown off ledge, it's never going to fly far horizontally.
Airstrike. 7 small projectiles that are dropped from the air onto the enemies. They can arrive from left or right, creating different attack patterns. Implementation wise, this is still only prototype version. I take (+/-0.5, 1, 0) vector from target position, collide it with drop line, and then create couple bombs there, centred around the origin point, then drop them in the opposite direction. What I could however do is:
1) as Zao proposed, do a binary approximation, launch couple virtual (properly physics-based) shots, and align them left/right, till I'm within some margin of error, and then fire off real shot
2) calculate the time required for the shot to fall down from the sky to the target level, and then from that calculate the side movement it needs to do, and calculate the position properly.
Oh, and I probably should have the bombs actually face the direction they're falling to
That's it for weapons for now (special weapons will be added with when/if the crate drops will be added, some more basic weapons could also be created - fire punch, suicide attack, mine, etc)
I've also added some navigation tools:
Shovel. To get to those unreachable places. Currently the problem is that, unlike Worms, it uses your movement speed to progress, so when you accidentally point your shovel down, you're going to do a free fall while digging your own route to hell. This definitely needs fixing.
Concrete slab. It can be used defensively - to protect your character from enemy shots, or to run away. It also can be used offensively, to create route to enemy or to guide weapons towards him. From coding perspective, this was a nightmare. Original Worms had girder rotating not only at 90 degrees, but at 45 deg increments. So, how would I solve it? First, find axis-aligned bounding box that contains whole concrete slab (or girder, as it was in the original), whatever its orientation is. Then, for each pixel on the map that overlaps with AABB, check if it's within tightly-packed oriented bounding box. If there is any, don't allow player to place the girder. If the map allows, place the block there by looking up each pixel from the girder based on coordinate and rotation. This is costly. Like, really costly. My solution for this is pre-drawing concrete slab in 4 positions (vertical, horizontal, and angled up-left to bottom-right and down-left to top-right), and use them as look up textures, to alleviate the calculations done on per-pixel basis. But for now, I've just used the horizontal and vertical positions, which don't need no calculations (also, their AABB is equal to their OBB, accelerating the collision checking process as well).
That's it for today. Haven't added Skip Turn and Concede, as they actually need gameplay implemented to be used, and, most importantly, haven't implemented Ninja Rope. This one will be a biggie, and I hope to implement it before the 7 days is up, but I don't want to do it before I'm sure I have everything else done. Going back to these steps cost me one day, which means that probably Audio and GFX day will have to be merged.
And as usual, all art is temporary, but concrete slab is really temporary, as it was done at 1am (when my usual sleep time now with kid around is around 9pm), and I wanted to just get it over with as fast as possible.
I hope I'll manage to squeeze in Day 5 before the weekend, but we'll see. See you then!
Story so far: