Saturday, February 25, 2017

Okay, just rearranged collision detection code!

Last post I explained how I got stuck into spaghetti code, and I said I'll try to fix it, and I did.  Now I'll explain what I did

Instead of having the BG collision detection routine do all the sprite movement itself, I can now move sprites outside of the collision routine, just as long as I save the old coordinates before I moved them.  This cut my multijointed boss joint code in half, since I can share a much larger subroutine between non-collision and collision joints.

Friday, February 24, 2017

Learning from programming mistakes, the hard way.

If there is ever something that is really hard to do is finding the easy way of doing things.  Every single time I try programming something the "easy way" it ends up making it harder in the long run.  Obviously the smart thing to do is "think ahead," but there is always that one thing you didn't initially think of when you first started.

When I started I had this not-so-wonderful idea of using 8.8 bit signed velocities and 16.8 bit coordinates.  I was thinking, hey I don't need 32-bit math to do subpixel physics, all I need is to calculate the 8.8 bit velocity, and then use a routine to add that to the 16.8 bit coordinates.  I thought this would fix all my subpixel math problems but man was I wrong.

The first problem I had with this technique was BG collision detection (which is a million times more complicated than object-object collision, for some reason people think it's the other way around).  If the playfield is made out of square blocks like Super Mario Bros, it's not that big of a deal, and you don't really need to know what direction a sprite is coming from.  If one side hit's a wall, push it back from whatever side hit it.  However if you want pass-through tiles, slope tiles, and even pass-through slope tiles, you have to know where you're sprite is coming from.  I honestly think I was so worried about glitches, I made my routine a little bit too physically accurate.  I think most games did more physical cheats when it came to this, such as snapping a sprite to a pass-through platform when the sprite is close enough to it.

So what I did was integrate the vertical and horizontal movement into my collision routine.  Move vertically first, detect any ceilings or floors.  Then move horizontally, first detecting any sloped platforms it comes in contact to, move the sprite up or down if it does, and then detect if it hits a wall.

I was able to get rid of the sprite movement code for sprites that had BG collision applied, which worked nice to some sprites.  However, other sprites got MORE convoluted, such as multi-jointed sprites, where velocity didn't matter that much, because sprites were controlled by the angle in which they are connected from the sprite they are connected to.  However, I had to back-track to figure out the velocity vectors, which made my code longer and slower.  I had to have 2 almost entirely different routines for multi-jointed sprites.  One for collision sprites, and one for collision-free sprites.

To make matters worse, I had problems when a multi-jointed boss changed directions.  A sprite joint might move more than 128 pixels in either direction when that happens, which 8.8 bit values don't allow.  I had to write more code to flip the sprite around first, (when the boss changes directions), so that the sprite joints don't break off when they move more than 128 pixels.

Now, as you can probably tell, my code looks like an overly complicated, poorly written, unmaintainable shit-fest, and it would seem like I made it complicated in the first place.  You might say "This only happened because you programmed you're game in ASM!" and in this place you're right.  Eventually I will start programming in C, I just hope I can get it running fast enough for the types of games I want to make.

Next post I'll start talking about how I plan on cleaning up this mess.