Files
Sprinter-SDCC/libbgi/common/sprite_moveto.c
T
snark13 eb9ca0179d libbgi: авто-анимация спрайтов — кадровая + tween (tests/spranim все PASS)
Реализация §9г по требованиям пользователя:
- sprite_anim(first,last,speed,mode): ANIM_LOOP / ANIM_PINGPONG /
  ANIM_ONCE (one-shot замирает на last), | ANIM_HORIZ для
  горизонтальных лент.  Смена кадра в тике = ±an_step к оси ленты —
  без умножений (осевое смещение first считается в setup циклом).
- sprite_moveto(tx,ty,max_step,interval): Брезенхэм порциями
  ≤max_step вдоль большей оси (меньшая — err-аккумулятором,
  нелинейные шаги Y сами собой), деления нет.
- Одновременность кадровой и tween — независимые поля/биты.
- Статус: sprite_anim_status() — битовое поле SPR_ANIM_ON/DONE +
  SPR_MOVE_ON/DONE; sprite_anim_frame() — текущий индекс кадра;
  sprite_moving().
- Стопы: sprite_anim_stop(frame | -1 = текущий);
  sprite_move_stop(0 = замереть / 1 = прыжок в цель + DONE).
- Тикер _sprite_tick — проход 0 sprite_update через funcptr
  _spr_tick_fn (DCE: без sprite_anim/moveto код не линкуется,
  цена — один if на кадр; +40 Б программе с движком, sprite_t +18 Б).

tests/spranim (MAME dev, все PASS): LOOP/PINGPONG (разворот на границе
без удвоения краёв)/ONCE+DONE; пример (0,0)→(100,50), шаг 5,
интервал 4 → ровно 80 кадров, Y идёт 3/2/3/2; стопы обоих видов.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 16:14:31 +03:00

47 lines
1.6 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* sprite_moveto — запустить tween-перемещение к (tx,ty): раз в interval
* кадров тикер делает до max_step итераций Брезенхэма (большая ось —
* итерация = пиксель; меньшая подтягивается err-аккумулятором).
* Пример: (0,0)→(100,50), max_step 5, interval 4 → 20 шагов × 4 кадра
* = 80 кадров (1.6 с), Y идёт 2/3/2/3.
*
* Дельты/знаки/аккумулятор считаются здесь один раз. Если цель ==
* текущая позиция — сразу SPR_MOVE_DONE (тикер не включается).
* Кадровые статусы (SPR_ANIM_*) не трогаются.
*/
#include "../_bgi.h"
#include <sprite.h>
void sprite_moveto(sprite_t *s, int tx, int ty,
uint8_t max_step, uint8_t interval)
{
int dx = tx - s->x;
int dy = ty - s->y;
s->mv_sgnx = 1;
if (dx < 0) { dx = -dx; s->mv_sgnx = -1; }
s->mv_sgny = 1;
if (dy < 0) { dy = -dy; s->mv_sgny = -1; }
s->an_flags &= (uint8_t)~SPR_MOVE_DONE;
if (dx == 0 && dy == 0) {
s->an_flags = (s->an_flags & (uint8_t)~SPR_MOVE_ON) | SPR_MOVE_DONE;
return;
}
s->mv_tx = tx;
s->mv_ty = ty;
s->mv_dx = dx;
s->mv_dy = -dy;
s->mv_err = dx - dy;
if (!max_step) max_step = 1;
if (!interval) interval = 1;
s->mv_step = max_step;
s->mv_speed = interval;
s->mv_timer = interval;
s->an_flags |= SPR_MOVE_ON;
_spr_tick_fn = _sprite_tick;
}