Posted May 19, 2021 by rem
#zxnext #spectrum-next
During game play it always bothered me that there was no fluidity to the interaction. That is, you select a block and they swap into the right place.
There’s no falling effect, no selection effect, just - vanish.
NextBASIC doesn’t have much bandwidth (compared to assembly) but it does leverage hardware sprites via a handful of NextBASIC (software) routines (AKA the Sprite System), which translates to: do a bit more for a bit less.
So I’ve added this animation when you select a block in the game. It’s a bit of a fiddle, mostly because I’m working within the constraints of NextBASIC but I think it does the trick:
The animation above plays the selection in slow motion (around 10% speed), then repeats the animation (for demonstration purposes) faster and faster until it’s 100% speed.
What’s nice is that the animation works for all the different block themes I’ve designed. It’s an animating layer over the top of each of the blocks settling on a solid black, as seen below in the four frames (note that the white is actually transparent):
So what are you actually seeing with respect to layers and sprites?
All of the blocks for the game are sprites (rather than tiles which might be a more traditional approach). This is a bit of a cheap move on my part, but it let’s me do “low cost” collision testing. I can also address each block from an index which happens to be the block index in memory.
When you select a block (a collision is detected between the pointer sprite and the block), underneath the block sprite a 16x16 tile is painted (so if I removed the sprite, it would look like the block was still there).
Then the sprite block’s pattern (the image in the sprite) is changed to transparent. So you’re seeing through the sprite to the tile underneath.
Now a sprite pattern sequence is run using SPRITE CONTINUE
running through the frames you saw earlier. The effect is that the black border closes in on the block making it look like it’s shrinking. Once the sequence has come to it’s end (something I have to check in the code), the tiles are removed by painting the entire layer with black - and the “layer” is under the sprites so this doesn’t change any appearance.
Each block that matches the block type/pattern has the following code applied:
SPRITE CONTINUE %k, STOP , STOP ,51 TO 54, BIN 01100000,10,0
Pages 9 and 10 of the NextBASIC new commands and features shows how BIN 0110000
works:
Though I didn’t find bit 5 actually useful, because I needed a way to know when the animation had completed, so I could then make the blocks fall.
To solve that, I run a loop - which is required to get the animation to update anyway - and I check the pattern state of just one of the sprites:
REPEAT
SPRITE MOVE
; %k is the last sprite id, 2 means "test pattern value"
%i=% SPRITE AT (k,2)
REPEAT UNTIL %i=54 :; 54 is the final pattern in the animation
With those small bits working together, I get a little animation. It’s not quite perfect, because during that REPEAT
the whole interface is locked - specifically the player’s cursor can’t move, and adding a call to update it’s position significantly slows the animation, so there’s no point.