Ended up missing my update last week because I lost a significant amount of dev time to a nasty stomach bug, and holiday obligations ended up interrupting me on more than one occasion, so these two weeks effectively combine into a single week's worth of work. So what did we get done? I fixed a few bugs that cropped up with my tile destruction system, as well as implemented basic architecture for enemies and created our first enemy. I wanted to stick with something simple enough for my initial foray into enemy implementation, so I decided to go with one of the first enemies you encounter in Metroid; the Geemer. Or at least that was the plan, but because of my struggles with Super Metroid Sprites, I ended up using the Metroid Fusion equivalent of the same enemy design. It's called an "Owtch", which really is a top-tier name. Now, it's not that I couldn't find sprites for the Geemer this time around, just that they were cut up in a way that was a bit nonsensical and putting them together would have been a small nightmare. Besides, the Owtch does exist in Super Metroid so it still counts. As far as enemies go, these guys just move along flat surfaces, following the geometry of the terrain as they encounter walls or ledges. Very simple to the player, relatively painless in terms of coding. For something like this you just need move forward and have one raycast downward and one facing forward to check for walls or cliffs. If it finds one, play an animation to smooth the transition and update which directions the enemy thinks is "forward" and "down" so that the new surface becomes its "ground". Godot seems to have some interesting quirks with raycasts, such as them not being able to properly detect surfaces on the first frame the enemies exist, or needing to create a "query" object in order to actually use them, but besides that they behaved mostly as expected. Most of my issues involved two main factors: getting the sprites to properly reorient themselves to the surface they are attached to, and getting the enemy to properly re-attached to a surface after it encounters a cliff (the movement shown in the gif on the right). The former issue is born from the fact that I only actually have sprites for when the Owtch is upright or attached to a left wall. For ceilings and right walls, I need to carefully time a sprite flip when the transition animation finishes. You can probably see a little bit of popping in the gifs above when the enemy finishes rounding the top-right corner. I have since fixed that particular issue but didn't have time to grab new screenshots before making my post. The second issue involves the fact that when the enemy encounters a cliff, there is a frame or two when it's in the middle of it's transition animation where it's not technically touching the ground at all, and early on in my tinkering it thought it was just constantly encountering cliffs when this happened, leading the enemy to spin in place in the air. The solution to this one was to shift the source of my ground-detection raycasts based on what part of the transition it is in. when it knows its firmly attached it searches from the back edge of it's hitbox, but while its in the process of transitioning around a corner it looks from the front edge instead. Luckily, it seems the way I set up the movement logic on these guys plays nice with the destroyable terrain. I'm going to need to add in some safety checks to make sure the destructible blocks can't reform on top of an enemy, but I was honestly going to have to deal with that for the player anyway. With all that working, I added actual health tracking to enemies, made it so that projectiles can actually hit them, and made it so that they can die properly. Still need to add death VFX of course, as well as making it so that enemies can hurt the player as well. Those will probably be in my next list of goals. That being said, this should be my last update for the year. The holidays are basically upon us and I'm not going to be able to spend much time at a desk.
Happy Holidays to anyone reading, and see you next time. No update for last week, between the Holiday and a few personal obligations, I didn't really accomplish much worth talking about. Mostly I just did some research into my next project goal; tile sets. Turns out Godot has plenty of tools to make setting up tile sets particularly simple, and a bunch more tools to give you just about all the control you could need. So, armed with a bunch of new knowledge I started off this week by... realizing that the tile set sprites I found for Super Metroid were incomplete. Honestly, I'm finding more and more that the Super Metroid sprites that I have access to are far from the comprehensive collection that I had first thought they were. The GBA Metroid games on the other hand, have proven to be quite thorough. In this particular case, the sprites that I was missing were these little guys: These represent tiles that can be destroyed by specific weapons from Samus' arsenal. For some reason, all of the sprite collections I could find for the Super Metroid tiles only had the tiles representing Speed Boost and Power Bomb blocks, and I did quite a bit of digging. Those ones up above are specifically the versions from Zero Mission, and since these are lower resolution than the tiles from the SNES, I've decided to just use the GBA tiles in general moving forward. I would do that same with Samus' own sprites to keep things consistent, but redoing all of the animations, let alone having to clean up and repair the sprite sheets would likely take more than a full work week by itself. If it bothers me enough as I continue through this project I'll consider revisiting the issue later, but for now we'll simply have to live with it. Now, getting the tile sets working within Godot was actually pretty fast and easy once I found the sheets I wanted to use. I messed around a bit with setting up the auto-tiling tool with a few different terrain types, applied physics shapes to the individual tiles I was using, and then went about replacing the white block platforms of my test scene. Here are the results: Definitely an improvement visually. As a bonus, I also figured out how to get slope movement working properly. Usually that's a massive pain, good on Godot for having built-in systems to handle it. In any case, because getting the tiles in went so smoothly, I moved onto the "stretch goal" that I set myself for the week; tile destruction. This is something that I've been thinking over for a decent while, and I think I came up with a pretty decent solution. Tile maps in Godot are considered to be a single object, so no matter what tile a projectile hits, it returns the tile map itself as the object it hit, and the tiles themselves don't have any logic attached to them. That means that I can't attach any sort of "Destroyable" script to tiles that I want to be able to blast away. Instead, I leveraged the ability to create multiple tile map layers, and I placed tiles on a second layer to signify both that they can be destroyed, and specifically what they can be destroyed by. When a projectile registers a collision with a tile map, I get the coordinates of the tile it hit and see if a corresponding tile exists on the "destructible" layer. If it does, I check to see if that tile can be destroyed by the projectile that hit it before removing the tile on both the "destructible" and "terrain" layers. I then spawn a pooled object that plays the tile destruction animation while also storing information about the tile in question, include what type of tile it was originally as well as whether or not it will need to reform after a few seconds (since that's a thing that happens sometimes in Metroid games). Reformed tiles only show the "destructible" layer version of the tile, since that's how it works in the source material. There's still some work to be done here, such as how certain weapons can reveal a destructible tile without actually destroying it, but that sort of stuff is probably going to have to wait until I actually get more weapons implemented. First though, I think I'm going to make my next goal getting a basic enemy working, that way we have something besides the ground to shoot at.
See you next time. |
Archives
April 2025
Categories
All
|