fix: invert mouth curve (smile was rendering as frown); smoother blink
Parabola sign was backwards — positive curve bowed the center up, an upside-down U. Also: lid reveal now sweeps bottom-up like a rising lid, blink runs in smaller steps, and the pupil redraw waits until the lid has actually cleared it instead of flashing through mid-blink. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+10
-4
@@ -116,17 +116,21 @@ void setLids(int8_t pct) {
|
|||||||
if (newH > oldH) {
|
if (newH > oldH) {
|
||||||
tft.fillRect(cx - EYE_R, EYE_Y - EYE_R + oldH, 2 * EYE_R + 1, newH - oldH, BG);
|
tft.fillRect(cx - EYE_R, EYE_Y - EYE_R + oldH, 2 * EYE_R + 1, newH - oldH, BG);
|
||||||
} else if (newH < oldH) {
|
} else if (newH < oldH) {
|
||||||
for (int y = EYE_Y - EYE_R + newH; y < EYE_Y - EYE_R + oldH; y++) {
|
// reveal bottom-up so the lid visually rises
|
||||||
|
for (int y = EYE_Y - EYE_R + oldH - 1; y >= EYE_Y - EYE_R + newH; y--) {
|
||||||
int dy = y - EYE_Y;
|
int dy = y - EYE_Y;
|
||||||
int w = (int)sqrt((float)(EYE_R * EYE_R - dy * dy));
|
int w = (int)sqrt((float)(EYE_R * EYE_R - dy * dy));
|
||||||
tft.drawFastHLine(cx - w, y, 2 * w + 1, SCLERA);
|
tft.drawFastHLine(cx - w, y, 2 * w + 1, SCLERA);
|
||||||
}
|
}
|
||||||
|
// redraw pupil only once the lid has cleared it (no through-lid flash)
|
||||||
|
if (EYE_Y - EYE_R + newH <= EYE_Y + cur.pdy - PUPIL_R) {
|
||||||
tft.fillCircle(cx + cur.pdx, EYE_Y + cur.pdy, PUPIL_R, PUPIL);
|
tft.fillCircle(cx + cur.pdx, EYE_Y + cur.pdy, PUPIL_R, PUPIL);
|
||||||
tft.fillCircle(cx + cur.pdx - 8, EYE_Y + cur.pdy - 8, 7, SCLERA);
|
tft.fillCircle(cx + cur.pdx - 8, EYE_Y + cur.pdy - 8, 7, SCLERA);
|
||||||
if (newH > 0)
|
if (newH > 0)
|
||||||
tft.fillRect(cx - EYE_R, EYE_Y - EYE_R, 2 * EYE_R + 1, newH, BG);
|
tft.fillRect(cx - EYE_R, EYE_Y - EYE_R, 2 * EYE_R + 1, newH, BG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
cur.lid = pct;
|
cur.lid = pct;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,7 +142,8 @@ void drawMouth(int8_t curve, int8_t openR) {
|
|||||||
tft.drawCircle(MOUTH_X, MOUTH_Y, openR + 1, SCLERA);
|
tft.drawCircle(MOUTH_X, MOUTH_Y, openR + 1, SCLERA);
|
||||||
} else {
|
} else {
|
||||||
for (int x = -MOUTH_HW; x <= MOUTH_HW; x += 4) {
|
for (int x = -MOUTH_HW; x <= MOUTH_HW; x += 4) {
|
||||||
int y = MOUTH_Y - (int32_t)curve * (32 - (x * x) / 113) / 100;
|
// +curve bows the center DOWN (U = smile), -curve up (frown)
|
||||||
|
int y = MOUTH_Y - 16 + (int32_t)curve * (32 - (x * x) / 113) / 100;
|
||||||
tft.fillCircle(MOUTH_X + x, y, 5, SCLERA);
|
tft.fillCircle(MOUTH_X + x, y, 5, SCLERA);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -225,8 +230,9 @@ void bumpMood(int8_t d) {
|
|||||||
|
|
||||||
void blinkOnce() {
|
void blinkOnce() {
|
||||||
int8_t base = moodLid();
|
int8_t base = moodLid();
|
||||||
setLids(100);
|
setLids(55); delay(20);
|
||||||
delay(90);
|
setLids(100); delay(70);
|
||||||
|
setLids(55); delay(20);
|
||||||
setLids(base);
|
setLids(base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user