program Sprite;
{простейшая демонстрация работы со спрайтами}
uses dos, {для работы с прерыванием VideoBIOS}
crt; {для работы с клавиатурой}
const
Xsize = 20; {размеры спрайта, точек}
Ysize = 20;
TransparentColor = $FF; {?прозрачный? цвет}
type
SpriteArrayType =
array[0..Ysize-1,0..Xsize-1]of byte;
{массив равный по размеру спрайту}
SpriteType = record
x,y : word; {текущие координаты спрайта}
dx,dy : integer; {приращения координат спрайта}
Img : ^SpriteArrayType;
{для массива с изображением спрайта}
Back : ^SpriteArrayType;
{для массива, хранящего фон под спрайтом}
end;
ScreenType = array[0..199,0..319]of byte;
{для экрана}
var
Sprt : SpriteType; {спрайт}
r : registers; {для вызова прерывания BIOS}
Scr : ^ScreenType; {экран}
procedure GetBuffer;
{сохранение фона под спрайтом в буфере}
var
i,j : word; {переменные цикла}
begin
for j := 0 to Ysize-1 do
for i := 0 to Xsize-1 do
with Sprt do
Back^[j,i] := Scr^[j+y,i+x];
end;
procedure PutBuffer; {восстановление фона}
var
i,j : word; {переменные цикла}
begin
for j := 0 to Ysize-1 do
for i := 0 to Xsize-1 do
with Sprt do
Scr^[j+y,i+x] := Back^[j,i];
end;
procedure PutSprite; {вывод спрайта на экран}
var
i,j : word; {переменные цикла}
begin
for j := 0 to Ysize-1 do
for i := 0 to Xsize-1 do
with Sprt do
if Img^[j,i] <> TransparentColor then
{ставим только точки,}
{цвет которых отличается от ?прозрачного?}
Scr^[j+y,i+x] := Img^[j,i];
end;
procedure PutBackground; {создание фона на экране}
var
i,j : word; {переменные цикла}
begin
for j := 0 to 199 do
for i := 0 to 319 do
Scr^[j,i] := lo(i+j*8);
end;
procedure CreateSprite(s:string; x,y,dx,dy:integer);
{?создание? спрайта}
var
f : file; {файл с изображением спрайта}
begin
getmem(Sprt.Img,sizeof(SpriteArrayType));
{выделяем память для спрайта}
getmem(Sprt.Back,sizeof(SpriteArrayType));
{выделяем память для буфера}
assign(f,s); {bmp-файл размерами Xsize на Ysize}
reset(f,1); {открываем файл со спрайтом}
seek(f,1078); {пропускаем заголовок}
blockread(f,Sprt.Img^,Xsize*Ysize);
{читаем изображение}
close(f);
Sprt.x := x;
Sprt.y := y; { задаем начальные значения }
Sprt.dx := dx; { координат и приращений }
Sprt.dy := dy;
end;
procedure DestroySprite; {?уничтожение? спрайта}
begin
{ возвращаем память }
freemem(Sprt.Back,sizeof(SpriteArrayType));
freemem(Sprt.Img,sizeof(SpriteArrayType));
end;
procedure CalcSpritePosition; {вычисление координат}
begin {спрайта и их приращений}
{по достижении границы экрана делаем,}
{ чтобы спрайт ?отразился? от нее}
with Sprt do begin
if (x + Xsize + dx) >= 319 then
dx := -dx; {вычисляем новые приращения}
if (x + dx) <= 0 then
dx := -dx; {реализующие ?отражение?}
if (y + Ysize + dy) >= 199 then
dy := -dy; {спрайта от стенок}
if (y + dy) <= 0 then
dy := -dy;
x := x+dx; { вычисляем новые }
y := y+dy; { координаты спрайта }
end;
end;
begin
CreateSprite(?sprt01.bmp?,0,0,1,1);
r.ax := $13; { устанавливаем режим }
intr($10,r); { 320х200х256 цветов }
Scr := ptr(SegA000,0); {адрес видеопамяти}
PutBackGround; {рисуем фон}
GetBuffer; {сохраняем фон под спрайтом}
PutSprite; {и рисуем на его месте спрайт}
repeat {теперь спрайт будет двигаться по экрану}
{до тех пор, пока мы не нажмем на клавишу}
PutBuffer; {восстанавливаем фон}
CalcSpritePosition;
GetBuffer; {сохраняем фон}
PutSprite; {рисуем спрайт}
while (port[$3da] and 8) = 0 do;
{ожидаем обратный ход луча кадровой развертки}
until keypressed;
readkey; {чистим буфер клавиатуры}
r.ax := $3;
intr($10,r); {возвращаемся в текстовый режим}
DestroySprite;
end.