/* * 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 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; }