Здравствуйте, у меня такой вопросик! Есть в определенной папке спрайты с анимацией персонажа. Не на одной картинке а на отдельных. Например: количество спрайтов для движения влево 0.bmp, 1.bmp 2.bmp., для движения вправо: 3.bmp, 4.bmp, 5.bmp Вниз допустим меньше количество: 6.bmp, 7.bmp - вверх аналогично как низ. Как сделать при движении персонажа анимации спрайтов, при ходьбе влево соответственно грузит левые спрайты). Это что, нужно создавать отдельные массивы для движения? Или можно создать один от 0..7 и как-то выводить их? Подскажите...
Все верно. Сначала создаем один массив для всех картинок анимации (исключительно для удобства так как способов много), например:
var Img:array[1..7] of TBitmap;
Затем загружаем эти картинки:
for i:=1 to 7 do begin Img:=TBitmap.Create; Img.LoadfromFile(inttostr(i)+'.bmp'); end;
Допустим мы создали переменную Povorot:Integer;. Она будет хранить номер поворота (хотя можно хранить в виде текста). Допустим 1-вверх, 2-вниз, 3-влево, 4-вправо. При нажатии управляющих кнопок (OnKeyDown) нужно присваивать нужное значение для переменной Povorot, а также для некой переменной animate присваиваем номер картинки с которой нужно начинать рисовать:
if key=VK_Up then begin Povorot:=1; n:=6; end;
if key=VK_Down then begin Povorot:=2; n:=8; end;
if key=VK_Left then begin Povorot:=3; n:=0; end;
if key=VK_Right then begin Povorot:=4; n:=3; end;
А затем в таймере мы делаем проверку какие картинки рисовать. Проверки будут выглядеть примерно так:
if povorot=1 then begin form1.Canvas.Draw(Player.x,Player.y, Img[ n ]); n:=n+1; if n>7 then n:=6; end;
if povorot=2 then begin form1.Canvas.Draw(Player.x,Player.y, Img[ n ]); n:=n+1; if n>9 then n:=7; end;
if povorot=3 then begin form1.Canvas.Draw(Player.x,Player.y, Img[ n ]); n:=n+1; if n>2 then n:=0; end;
if povorot=4 then begin form1.Canvas.Draw(Player.x,Player.y, Img[ n ]); n:=n+1; if n>5 then n:=3; end;
Спасибо! Помогли очень. Но у меня проблема, делаю вроде правильно, рисую на буфере, но при анимации остается черный экран! Если бы можно было выложить мой исходник на сайте, чтобы Вы посмотрели что не правильно! В принципе вот код, он не большой:
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin
if key=vk_up then begin povorot:=4; nomer:=1; gou:=true;
end;
if key=vk_down then begin povorot:=3; nomer:=4; gou:=true;
end;
if key=vk_left then begin povorot:=2; nomer:=7; gou:=true;
end;
if key=vk_right then begin povorot:=1; nomer:=10; gou:=true;
end;
end;
procedure TForm1.go; begin if gou=true then begin case povorot of 1: px:=px+speed; // вправо 2: px:=px-speed; // влево 3: py:=py+speed; // вниз 4: py:=py-speed; // вверх end; nomer:=nomer+1; if nomer>12 then nomer:=1;
end;
end; procedure TForm1.Timer1Timer(Sender: TObject); begin if povorot=1 then // вправо begin buf.Canvas.Draw(px,py,player[nomer]);
if nomer=12 then nomer:=10; end;
if povorot=2 then // влево begin buf.Canvas.Draw(px,py,player[nomer]);
if nomer=9 then nomer:=7; end;
if povorot=3 then // вниз begin buf.Canvas.Draw(px,py,player[nomer]);
if nomer=6 then nomer:=4; end;
if povorot=4 then // вверх begin buf.Canvas.Draw(px,py,player[nomer]);
if nomer=3 then nomer:=1; end;
go; form1.Canvas.Draw(0,0,buf);
end;
procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); begin if (Key=VK_Up) or (Key=VK_Down) or (Key=VK_Left) or (Key=VK_Right) then Gou:=False; end;
Если твои картинки, которые ты загружаешь нарисованы на черном фоне, то это фон также прорисовывается. Чтобы этого не происходило нужно загружать их с прозрачностью то есть так:
for i:=1 to 12 do begin Player:=Tbitmap.Create; Player.Transparent:=true; player.LoadFromFile('Images/'+inttostr (i)+'.bmp'); end;
Тоесть Transparent:=true должно быть выставлено до загрузки изображения, ато у тебя изображение уже загрузилось, а ты потом пытаешься его прозрачным сделать. К тому же у тебя должна появляться ошибка в строках с Player:=Tbitmap.Create потому, что нужно указывать номер элемента массива в квадратных скобках. А так вроде ошибок не видно. Если хочешь чтобы я посмотрел твой исходник - присылай его на почту: okzona1@rambler.ru
В твоем случае дело вот в чем. Ты рисуешь своего персонажа на пустом месте. А в пустом месте никогда ничего не рисуется, а значит в нем всегда остаются следы от последнего что там рисовалось. Поэтому под персонажем нужно или просто все заполнять каким-либо цветом (рисовать квадрат заполненный цветом) или же рисовать какие-то картинки земли или еще чего-нибудь...
Теперь все стало ясно! И еще одно, в этом же исходнике, при нажатии на любую клавишу и удержания стрелки для ходьбы персонажа, срабатывает анимация, но она потом не начинается заново, игрок зависает на постоянной картинке и никаких движений больше нет! А если нажимать и постепенно отжимать, то анимация идет нормально. В чем это может быть проблема? А если убрать код из FormKeyUp, то при нажатии стрелки персонаж будет идти по таймеру, ну анимация срабатывает нормально!
Сообщение отредактировал Дивиджей - Четверг, 24.04.2014, 14:15
Я обчно решаю эту проблему тем что на каждую сторону я создаю булевую переменную. И при нажатии я присваиваю истину тому направлению в которую нажата кнопка:
if key=VK_UP then begin qUp:=true; gou:=true; end;
if key=VK_Down then begin qDown:=true; gou:=true; end;
if key=VK_Left then begin qLeft:=true; gou:=true; end;
if key=VK_Right then begin qRight:=true; gou:=true; end;
А когда отпускают эту кнопку, то присваиваю ложь этой переменной:
if key=VK_UP then qUp:=false; if key=VK_Down then qDown:=false; if key=VK_Left then qLeft:=false; if key=VK_Right then qRight:=false;
А переменной, которая аналогична твоей gou я делаю проверку по таймеру:
if (qLeft=false) and (qRight=false) and (qUp=false) and (qDown=false) then gou:=false;
Также в таймере и делаем движение героя:
if qUp=true then Player.y:=Player.y-Player.Speed; if qDown=true then Player.y:=Player.y+Player.Speed; if qLeft=true then Player.x:=Player.x-Player.Speed; if qRight=true then Player.x:=Player.x+Player.Speed;
Анимация так делается тогда: if gou=true then АНИМАЦИЯ