2021 Gameboy SHMUP Devlog #2 – Solid Progress

This is the second devlog for my 2021 Gameboy SHMUP. However, this is the first meaningful devlog. The previous devlog was sort of an introduction. It’s purpose was to explain some underlying topics. In Devlog #2 i’ll explain my current progress.

Pretty solid progress has been made on my Gameboy SHMUP. Player’s can select a level, after which, a story segment will be shown. In the level gameplay players can shoot multiple zig-zagging waves of enemies. Enemies when damaged will show multiple explosion effects, and score will increase. If a player collides with an enemy he/she will lose a life. Afterwards, Upon level completion, players are shown a stats and the next level unlocks.

Current Progress for 2021 Gameboy SHMUP
Current progress summed up in one gif

The Player’s Ship

The first element added for the game was obviously the player. The player is able to move in 4 directions via the Gameboy D-Pad. This is in every gameboy shmup. In addition, the player can also shoot bullets via the “A” button. This is super easy. My first ship was only 8×8. However, it was later resized to be 16×16.

The ship is designed in Gameboy Tile Designer. It supports drawing and exporting sprites/tiles for making gameboy games.

V2 of the Player's Ship
16×16 Version 2 of the Player’s ship

SHMUP Enemies

Next i designed the enemies and their ships. The enemy ships are also designed via Gameboy Tile Designer (GBTD). The enemy ships, like the player; started as 8×8 sprites. However, for the sake of fidelity i increased them to 16×16.

Enemy Ships designed in GBTD for a SHMUP
4 Ships designed in GBTD

Every Gameboy shmup will have multiple enemies on screen. Thus arrays must be used to dynamically handle eachone. In addition, I created a basic Enemy struct in C for organization. Below is a snippet similar to what i did. The “onScreenEnemies” array is set with 30 elements. Because this array is not constant, it’s values can be changed and will be stored in RAM.

typedef struct Enemy{

    UINT8 health;
    UINT8 x;
    UINT8 y;
    UINT8 sprite;
    UINT8 active;
} Enemy;

Enemy onScreenEnemies[30];

When spawning enemies, which “sprite” the enemy uses must be saved. This value is saved so it can be later updated. Additionally, enemies were given a random X value when spawning. Once logic is setup to spawn enemies, a basic for loop is used to update each enemy who’s “active” variable is set to 1. When an enemy is offscreen, it’s “active” value is set to 0 and it’s “sprite” is moved offscreen.

Bullets

A Gameboy SHMUP wouldn’t be a SHMUP without bullets right? For bullets, I took a path similar to enemies. I allocated a bunch using a Bullet struct for organization:


typedef struct Bullet{

    UINT8 x;
    UINT8 y;
    UINT8 recycle;
    UINT8 sprite;
    UINT8 active;

} Bullet;

Bullet onScreenBullets[30];

I also designed 3 types of bullets in GBTD. Each has increasing strength. As the player get’s powerups his bullet sprites change to the next one. Each frame I update each “active” bullet, moving it up more until it’s offscreen. The bullet is then set to inactive.

Double Shot bullet sprite in GBTD
Double Shot bullet sprite in GBTD

SHMUP Enemy Paths

After basic implementation, Enemies were given motion paths like you would see in other gameboy shmup games.

typedef struct Enemy{

    UINT8 health;
    UINT8 x;
    UINT8 y;
    UINT8 death;
    UINT8 *path;
    UINT16 pathStep;
    UINT8 recycle;
    UINT8 sprite;
    UINT8 sprite2;
    UINT8 active;
    struct Enemy *next;
} Enemy;

The “path” variable points to a list of integers. Each 2 integers on this list represents a coordinate on the screen. Ultimately this single list of integers represents a motion path. The “pathStep” variable represents which coordinate the enemy is currently at.

Using Linked Lists with Enemies and Bullets

I implemented a linked list of “active” enemies & bullets. The “next” variable in each bullet/enemy struct points to the next “active” bullet/enemy. The reason for this is performance. This allows me to only update/check active items. However, it does add complexity to the code.

What’s Next for my SHMUP?

Bombs and bosses are still needed. Bombs will be rare, but when used will remove all on screen enemies. Bosses will be larger and shoot back at the player. Optimization for enemy/bullet collision tests is needed. Color sprites and Color backgrounds will be added soon. Physical cartridge tests will happen, when the neccesary hardware arrives.

Finally, NodeJS might be used to generate content. This is not necessary. However, it will ease the process of fleshing out actual final product elements. In addition, there is an idea in the back of my head NodeJS may help with.

Thanks for visiting Larold’s Jubilant Junkyard.

Comments are closed.