Логика рисования спрайта


Теория:
    1. Запоминаем картинку "как есть".
    2. Делаем два вспомогательных экземпляра, с помощью которых
       и будет происходить движение.
     * Первый экземпляр - картинка в белом цвете (все биты = 1111)
       (Черный цвет - прозрачен).
     * Второй экземпляр - картинка с трансформированными цветами
       color = (NOT color) AND 15
    3. Движение выполняется по стадиям:
     - Запоминаем фон
     - Накладываем белый спрайт операцией OR
     - Накладываем трансформированный спрайт операцией XOR
     - Делаем паузу
     - Восстанавливаем фон

Пример:

SCREEN 12
' Colors
FOR x = 0 TO 640 STEP 40
  LINE (x, 50)-(x + 40, 479), x \ 40, BF
NEXT
' Sprite
col = 10
DIM a(100), B(100), c(100)
LINE (0, 0)-(9, 9), (NOT col) AND 15, B
LINE (0, 10)-(9, 19), 15, B
GET (0, 0)-(9, 9), a
GET (0, 10)-(9, 19), B
a$ = INPUT$(1)

x = 0
dx = 1
DO
  GET (x, 200)-(x + 9, 209), c
  PUT (x, 200), B, OR
  PUT (x, 200), a, XOR
  MakePause 4
  PUT (x, 200), c, PSET
  IF x + dx < 0 OR x + dx > 610 THEN dx = -dx
  x = x + dx
LOOP WHILE INKEY$ = ""
SCREEN 0
END

DEFINT A-Z
'/////////////////////////////////////////////////////////////////////
' Эта процедура делает задержку. [Tic = 1/10 тика (Тик = 18.2 сек)]
'/////////////////////////////////////////////////////////////////////
SUB MakePause (Tic)
  FOR n = 1 TO Tic
    SOUND 32767, .1
  NEXT
END SUB

И еще один пример на стареньком C++

// Движение спрайта
#include "setgrmode.inc"
#include <dos.h>

int main()
{
  // Делаем фон
  for(int x=100,c=0;c<=15;c++,x+=20)
   {  setfillstyle(SOLID_FILL,c);
      bar(x,0,x+20,479);
   }

  //Рисуем картинку 20x20
  for(x=0,c=1;x<20;x+=2,c++)
   {  setfillstyle(SOLID_FILL,c);
      bar(x,0,x+2,19);
   }
  setfillstyle(SOLID_FILL,0);
  bar(5,5,15,15);

  // Делаем вспомогательную картинку для спрайта
  // МАСКА ЭКРАНА (должна быть черно белой)
  for(int y=0;y<20;y++) for(x=0;x<20;x++)
    putpixel(x,y+20,(getpixel(x,y)==0?15:0));

  // Запоминаем две картинки
  char p1[1000],p2[1000],p3[1000];
  getimage(0,0,19,19,p1);
  getimage(0,20,19,39,p2);
  int d=getch();

  // Начинаем движение
  for(x=70;x<600;x++)
  {   //Запоминаем фон
      getimage(x,100,x+19,119,p3);
      // Создаем спрайт с прозрачным черным цветом!!!
      // Для этого операцией AND кладем маску экрана
      // а потом операцией XOR восстанавливаем спрайт
      putimage(x,100,p2,AND_PUT);
      putimage(x,100,p1,XOR_PUT);
      delay(100);
      // Восстанавливаем фон
      putimage(x,100,p3,COPY_PUT);
      if (kbhit()) break;
  }

  closegraph();
  return 0;
}