
Hey folks,
I'm trying to figure out how to recreate this wavy sprite/screen effect but I'm unsure where to start. Any pointers would be greatly appreciated.
I did something like that for DuckBlur:

Basically I move every line some pixel to the left/right based on a sinus function.
Here I am moving the content of the frame buffer but you could draw only one sprite using the same technique on a new bitmap.
EDIT: Here is the code (it is made in C but you should be able to do the same thing with Lua).
static const int kBytesInARow = 52;
static const int kBitsInAByte = 8;
static const int kEntriesInARow = kBytesInARow / sizeof(uint8_t);
static const float kDistortion = 3.0f;
static float water = 0;
void WaterEffectDraw(MELIntRectangle waterArea) {
water += DELTA;
uint8_t *frame = playdate->graphics->getFrame();
for (int y = 0; y < LCD_ROWS; y++) {
const int shift = (int)(cosf(water + y / 20.0f) * kDistortion);
if (shift > 0) {
const int maskShift = sizeof(uint8_t) * kBitsInAByte - shift;
for (int x = 0; x < kEntriesInARow - 1; x++) {
const uint8_t next = frame[x + y * kEntriesInARow + 1];
frame[x + y * kEntriesInARow] = (frame[x + y * kEntriesInARow] << shift) | (next >> maskShift);
}
frame[kEntriesInARow + y * kEntriesInARow - 1] = frame[kEntriesInARow + y * kEntriesInARow - 1] << shift;
} else if (shift < 0) {
const int maskShift = sizeof(uint8_t) * kBitsInAByte + shift;
uint8_t last = frame[y * kEntriesInARow];
frame[y * kEntriesInARow] = last >> -shift;
for (int x = 1; x < kEntriesInARow; x++) {
const uint8_t current = frame[x + y * kEntriesInARow];
frame[x + y * kEntriesInARow] = (frame[x + y * kEntriesInARow] >> -shift) | (last << maskShift);
last = current;
}
}
}
}