Приветствуем, геймер! Ты можешь или
16+
Super_paper_mario

Геймер Spooner 5

88

Продолжаем писать Mario.

Продолжаем писать Mario.
Обо всем - Продолжаем писать Mario.Продолжаем писать Mario.

0.) Доброе время...

Доброе время суток мои читатели. Этот пост - продолжение постов про gamedev(игростроении). Давайте мельком пробежимся по уже сделанному нами.

  • Итак:

    Мы мельком рассмотрели основы графики и даже создали нашего героя.

  • Рассмотрели компоненты которые вскоре и помогут нам создать полноценную игру.
  • И рассмотрели стандартные классы и их иерархию.

Какие у нас планы на этот урок:

  • Мы должны поработать с DXInput - компонент отвечающий за ввод данных с устройств ввода
  • Рассмотреть основы анимации
  • Заставить mario бегать.

Вроде всё сказано, чего медлить ближе к делу!

1.) Чтение с устройств ввода

Я уже упоминал в прошлом посте про компонент TDXInput (подробнее тут) . Разберём его концепцию.

Продолжаем писать Mario.
Обо всем - Продолжаем писать Mario.Продолжаем писать Mario.

То есть TDXInput.States принимает состояние, если же оно совпадает с табличным значением(которое можно настраивать):

Продолжаем писать Mario.
Обо всем - Продолжаем писать Mario.Продолжаем писать Mario.

Когда мы должны узнавать о изменениях состояния? - Всё время. По этой причине мы должны добавить компонент таймер - TDXTimer. Его значение Interval лучше установить на 33. То есть частота обновления будет 33 милисекунды. Это же будет и частота обновления графики. Создаём его процедуру OnTimer.

Всё , что у нас было мы изменим. Теперь проверим можем ли мы рисовать? т.е. установлен ли DirectX , рабочая видеокарта и т.д.

Получим код :

if not DXDraw.CanDraw then exit; //если не можем рисовать - значит выход

Тем самым мы избавимся от ошибок. Интересно, что DirectX позволяет выводить текст. Мы этим и воспользуемся! Выведем нужную информацию:

{ Информация }

with DXDraw.Surface.Canvas do //работаем с холстом

begin

Brush.Style := bsClear; //прозрачный фон

Font.Color := clBlack; //цвет шрифта

Font.Size := 12; //размер шрифта

Textout(0, 0, 'FPS: '+inttostr(DXTimer.FrameRate)); //FS

Textout(0, 24, 'Sprite: '+inttostr(DXSpriteEngine.Engine.AllCount)); //кол - во спрайтов

Textout(0, 48, 'Draw: '+inttostr(DXSpriteEngine.Engine.DrawCount));

if FMoveMode then //Time mod

Textout(0, 72, 'Time mode: 60 FPS')

else

Textout(0, 72, 'Time mode: Real time');

Release; //Освобождаем память...

end; //конец работы с холстом

Мы хотели сделать проверку нажатий а занимаемся какой-то ерундой. Исправляемся! Всего одна строка :
DXInput.Update;
Обновит состояние Нашего "чтеца".

И в конце-концов наша процедура получит полностью извращённый вид:

procedure TMainForm.DXTimerTimer(Sender: TObject; LagCount: Integer);

begin

if not DXDraw.CanDraw then exit; //выходим при проблемах

DXInput.Update; //обновляем состояние

if FMoveMode then

LagCount := 1000 div 60; //кол-во перемещений

DXSpriteEngine.Move(LagCount); //перемещяем

DXSpriteEngine.Dead; //уираем

{ Рисование }

DXDraw.Surface.Fill(0);

DXSpriteEngine.Draw; //Нарисовать

{ Информация }

with DXDraw.Surface.Canvas do //работаем с холстом

begin

Brush.Style := bsClear; //прозрачный фон

Font.Color := clBlack; //цвет шрифта

Font.Size := 12; //размер шрифта

Textout(0, 0, 'FPS: '+inttostr(DXTimer.FrameRate)); //FS

Textout(0, 24, 'Sprite: '+inttostr(DXSpriteEngine.Engine.AllCount)); //кол - во спрайтов

Textout(0, 48, 'Draw: '+inttostr(DXSpriteEngine.Engine.DrawCount));

if FMoveMode then //Time mod

Textout(0, 72, 'Time mode: 60 FPS')

else

Textout(0, 72, 'Time mode: Real time');

Release; //Освобождаем память...

end; //конец работы с холстом

DXDraw.Flip; //Нарисовать

end;

"Не чего не изменилось!Он не бегает" - скажите вы.

Ответный вопрос - "А мы. что сказали ему , что либо сделать?".

Объясним mario!

Мы когда-то описывали процедуру

TMarioHero.DoMove(MoveCount: Integer);
Теперь мы её усовершенствуем. Мы уже имеем строку которая зовёт папу, что бы тот всё сделал. После неё пишем:

AnimLooped := False; //Прекращаем анимацию

Хотя анимацию мы разберём позже, строка нужна.

После опишем огромный код:

if (MainForm.DXInput.Joystick.X<>0) or (MainForm.DXInput.Joystick.Y<>0) then //если значения не равны нулю переместимся

begin

X := X + (MainForm.DXInput.Joystick.X/1000)*MoveCount;

Y := Y + (MainForm.DXInput.Joystick.Y/1000)*MoveCount;

end

else

begin

if isUp in MainForm.DXInput.States then //марио должен идти вверх?

begin

Y := Y - (300/1000)*MoveCount;

end;

if isDown in MainForm.DXInput.States then //или в низ?

begin

//

end;

if isLeft in MainForm.DXInput.States then //а может на лево

begin

X := X - (300/1000)*MoveCount;

end;

if isRight in MainForm.DXInput.States then //или на право

begin

X := X + (400/1000)*MoveCount;

end;

end;

Collision; // проверим столкновения

//обновим информацию движку

Engine.X := -X+Engine.Width div 2-Width div 2;

Engine.Y := -Y+Engine.Height div 2-Height div 2;

Как мы говорили выше мы просто проверили значения полученные от Клавиатуры.

2.) Анимация

Вот спрайты которые мы будем использовать(Эх сколько работы!)

Продолжаем писать Mario.
Обо всем - Продолжаем писать Mario.Продолжаем писать Mario.

Выделю важные моменты относительно Листа Изображений.

Продолжаем писать Mario.
Обо всем - Продолжаем писать Mario.Продолжаем писать Mario.

PaternWidth и PaternHeight обязаны быть отличны от нуля!

Рассмотрим основы анимации:

Продолжаем писать Mario.
Обо всем - Продолжаем писать Mario.Продолжаем писать Mario.

После всего процедура будет иметь такой вид:

procedure TMarioHero.DoMove(MoveCount: Integer);

begin

inherited DoMove(MoveCount);

AnimLooped := False;

if (MainForm.DXInput.Joystick.X<>0) or (MainForm.DXInput.Joystick.Y<>0) then

begin

X := X + (MainForm.DXInput.Joystick.X/1000)*MoveCount;

Y := Y + (MainForm.DXInput.Joystick.Y/1000)*MoveCount;

end

else

begin

if isUp in MainForm.DXInput.States then

begin

Y := Y - (300/1000)*MoveCount;

if Image.Name='mario_down' then

begin

Image := MainForm.ImageList.Items.Find('mario_downtoup'); //загружаем его спрайт

AnimCount := Image.PatternCount;

AnimLooped := True;

AnimSpeed := (400/1000);

end;

end;

if isDown in MainForm.DXInput.States then

if Image.Name<>'mario_down' then

begin

Image := MainForm.ImageList.Items.Find('mario_down'); //загружаем его спрайт

AnimCount := Image.PatternCount;

AnimLooped := True;

AnimSpeed := (400/1000);

end;

if isLeft in MainForm.DXInput.States then

begin

X := X - (300/1000)*MoveCount;

Image := MainForm.ImageList.Items.Find('mario_left'); //загружаем его спрайт

AnimCount := Image.PatternCount;

AnimLooped := True;

AnimSpeed := (300/1000);

end;

if isRight in MainForm.DXInput.States then

begin

X := X + (400/1000)*MoveCount;

Image := MainForm.ImageList.Items.Find('mario_right'); //загружаем его спрайт

AnimCount := Image.PatternCount;

AnimLooped := True;

AnimSpeed := (400/1000);

end;

end;

Collision;

Engine.X := -X+Engine.Width div 2-Width div 2;

Engine.Y := -Y+Engine.Height div 2-Height div 2;

end;

Я надеюсь, что вы уже сами разберётесь с каждой строчкой.

Теперь наша игра станет ещё интереснее и привлекательней, действия более анимированы, изменён фон игры, и добавлена игровая информация.

Сегодняшний The End :

Продолжаем писать Mario.
Обо всем - Продолжаем писать Mario.Продолжаем писать Mario.

88
Еще в блоге
Интересное на Gamer.ru

8 комментариев к «Продолжаем писать Mario.»

    Загружается
Чат