Меню сайта
Форма входа

Четверг, 09.01.2025, 07:07
Приветствую Вас Гость

Анимация персонажа - Форум

[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Анимация персонажа
ДивиджейДата: Среда, 23.04.2014, 13:56 | Сообщение # 1
Сержант
Группа: Пользователи
Сообщений: 22
Репутация: 2
Статус: Offline
Здравствуйте, у меня такой вопросик! Есть в определенной папке спрайты с анимацией персонажа. Не на одной картинке а на отдельных. Например: количество спрайтов для движения влево 0.bmp, 1.bmp 2.bmp., для движения вправо: 3.bmp, 4.bmp, 5.bmp
Вниз допустим меньше количество: 6.bmp, 7.bmp - вверх аналогично как низ. Как сделать при движении персонажа анимации спрайтов, при ходьбе влево соответственно грузит левые спрайты). Это что, нужно создавать отдельные массивы для движения? Или можно создать один от 0..7 и как-то выводить их? Подскажите...
 
ArmageddetsДата: Среда, 23.04.2014, 21:07 | Сообщение # 2
Лейтенант
Группа: Администраторы
Сообщений: 68
Репутация: 4
Статус: Offline
Все верно. Сначала создаем один массив для всех картинок анимации (исключительно для удобства так как способов много), например:

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;
 
ДивиджейДата: Четверг, 24.04.2014, 10:01 | Сообщение # 3
Сержант
Группа: Пользователи
Сообщений: 22
Репутация: 2
Статус: Offline
Спасибо! Помогли очень. Но у меня проблема, делаю вроде правильно, рисую на буфере, но при анимации остается черный экран! Если бы можно было выложить мой исходник на сайте, чтобы Вы посмотрели что не правильно! В принципе вот код, он не большой:

Кодunit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls;

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure Timer1Timer(Sender: TObject);
    procedure FormKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
  private

  procedure go;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  player: array [1..12] of tbitmap;
  px,py: integer;
  speed,povorot: integer;
  buf: tbitmap;
  nomer,i: integer;
  gou: boolean;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
buf:=tbitmap.Create;
buf.Width:=640;
buf.Height:=480;

for i:=1 to 12 do
begin
player:=tbitmap.Create;
player.LoadFromFile('Images/'+inttostr (i)+'.bmp');
player.Transparent:=true;
end;

px:=288;
py:=208;
speed:=4;
povorot:=2;
nomer:=1;
gou:=false;

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;

end.
 
ArmageddetsДата: Четверг, 24.04.2014, 11:04 | Сообщение # 4
Лейтенант
Группа: Администраторы
Сообщений: 68
Репутация: 4
Статус: Offline
Если твои картинки, которые ты загружаешь нарисованы на черном фоне, то это фон также прорисовывается. Чтобы этого не происходило нужно загружать их с прозрачностью то есть так:

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
 
ArmageddetsДата: Четверг, 24.04.2014, 13:20 | Сообщение # 5
Лейтенант
Группа: Администраторы
Сообщений: 68
Репутация: 4
Статус: Offline
В твоем случае дело вот в чем. Ты рисуешь своего персонажа на пустом месте. А в пустом месте никогда ничего не рисуется, а значит в нем всегда остаются следы от последнего что там рисовалось. Поэтому под персонажем нужно или просто все заполнять каким-либо цветом (рисовать квадрат заполненный цветом) или же рисовать какие-то картинки земли или еще чего-нибудь...
Прикрепления: 2815762.rar (170.3 Kb)
 
ДивиджейДата: Четверг, 24.04.2014, 13:51 | Сообщение # 6
Сержант
Группа: Пользователи
Сообщений: 22
Репутация: 2
Статус: Offline
Теперь все стало ясно!
И еще одно, в этом же исходнике, при нажатии на любую клавишу и удержания стрелки для ходьбы персонажа, срабатывает анимация, но она потом не начинается заново, игрок зависает на постоянной картинке и никаких движений больше нет! А если нажимать и постепенно отжимать, то анимация идет нормально. В чем это может быть проблема? 
А если убрать код из FormKeyUp, то при нажатии стрелки персонаж будет идти по таймеру, ну анимация срабатывает нормально!


Сообщение отредактировал Дивиджей - Четверг, 24.04.2014, 14:15
 
ArmageddetsДата: Четверг, 24.04.2014, 15:48 | Сообщение # 7
Лейтенант
Группа: Администраторы
Сообщений: 68
Репутация: 4
Статус: Offline
Я обчно решаю эту проблему тем что на каждую сторону я создаю булевую переменную. И при нажатии я присваиваю истину тому направлению в которую нажата кнопка:

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 АНИМАЦИЯ
 
ДивиджейДата: Четверг, 24.04.2014, 17:57 | Сообщение # 8
Сержант
Группа: Пользователи
Сообщений: 22
Репутация: 2
Статус: Offline
Ухты, интересно, нужно попробовать. Спасибо большое)
 
ArmageddetsДата: Пятница, 25.04.2014, 09:34 | Сообщение # 9
Лейтенант
Группа: Администраторы
Сообщений: 68
Репутация: 4
Статус: Offline
Рад помочь biggrin
 
  • Страница 1 из 1
  • 1
Поиск:

Наш опрос
Оцените мой сайт
Всего ответов: 103
Мини-чат
Друзья сайта
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz
  • Статистика