Разработка RPG – LittleAge (тестовое приложение)

Опубликовал – 23.07.2010

Для начала давайте разберемся. Так как игра у нас не маленькая, я люблю тестировать разные части будущей программы в тестовых вариантах. Вот сегодня именно такой случай, давайте создадим просто хаотичный макет карты и попробуем по нему побегать.

Не пугайтесь, размеры карт у нас будут куда больше и на один экран умещаться не будут. Итак, давайте откроем Delphi и создадим новый проект. Назовем его например Testing.

Теперь мы будем небрежно писать код. Вы спросите:  «почему небрежно?» отвечаю: «Сейчас нас не интересует ООП подход либо графика». Это этакие наброски, которые всегда помогают в разработке больших проектов.

Итак, в нашем созданном проекте, находим на панели с инструментами компонент TTimer и выключаем его, в свойствах устанавливаем Enabled: false. Его мы будем использовать для цикла отрисовки карты и нашего героя, который будет из себя представлять лишь шарик. Если Вам понравится статья, после прочтений кликните на рекламу перед комментариями от гугла, Вам это ничего не будет стоить, Спасибо.

Наша карта будет состоять из двумерного массива World[n][m], значение каждого элемента этого массива будет хранить информацию о препятствиях, в нашем случае 1 или 0. А герой будет хранить свои переменные в некой структуре, например TMan, которая будет содержать данные о координатах, размере, векторам, скорости и состоянию героя. Давайте я приведу полный код всего приложения и просто прокомментирую его:

unit uMain;

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

type
  TfrmMain = class(TForm)
    tmrMain: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure tmrMainTimer(Sender: TObject);
    procedure FormKeyDown(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure FormKeyUp(Sender: TObject; var Key: Word;
      Shift: TShiftState);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

const
  szW = 30; //размер 30х30
  szTile = 15; //размер тайла

type
  TMan = packed record //главный герой
    pos: TPoint; //координаты
    size: TPoint; //размер
    velocity: TPoint; //скорость
    vec: TPoint; //вектор
    jumpY: Integer; //сила прыжка
    stay: Boolean; //двигается ли
  end;

//управление героем
procedure ToLeft();
procedure ToRight();
procedure StopMove();
procedure Jump();

var
  frmMain: TfrmMain; //наша форма
  World: array [0..szW, 0..szW] of Integer; //карта
  man: TMan; //герой
  keys: array [0..256] of boolean; //клавиатура
implementation

{$R *.dfm}

procedure TfrmMain.FormCreate(Sender: TObject);
var
  i, j: Integer;
begin
  //размеры формы
  frmMain.ClientWidth := szW * szTile;
  frmMain.ClientHeight := szW * szTile;

  //включаем таймер
  tmrMain.Interval := 30;
  tmrMain.Enabled := not tmrMain.Enabled; 

  randomize;

  //обнуляем карту
  for i := 0 to pred(szW) do
    for j := 0 to pred(szW) do
      World[i][j] := 0;

  //заполняем все края..
  for i := 0 to pred(szW) do begin
    World[i][0] := 1;
    World[i][pred(szW)] := 1;
    World[0][i] := 1;
    World[pred(szW)][i] := 1;
  end;

  //хаотично генерируем
  for i := 0 to pred(szW) do
    for j := 0 to pred(szW) do
      if ((round(random * (szW div 3))) = 1) then World[i][j] := 1;

  //несколько длинных платформ
  for i := 0 to pred(5) do
    World[i][szW div 2] := 1;

  //несколько длинных платформ
  for i := 0 to pred(13) do
    World[szW-13+i][szW - szW div 4] := 1;

  man.pos := POINT(40, 40); //позиция человека
  man.size := POINT(10, 10); //размер
  man.velocity := POINT(2, 2); //ускорение
end;

procedure TfrmMain.tmrMainTimer(Sender: TObject);
var
  i, j: Integer;
  npos: TPoint;
  rr: Integer;
begin
  //рисуем карту
  for i := 0 to pred(szW) do
    for j := 0 to pred(szW) do begin

      if (World[i][j] = 1) then //если препятствие
        canvas.Brush.Color := $ccbbaa
      else
        canvas.Brush.Color := $FFFFFF;

      canvas.FillRect(RECT(i * szTile, j * szTile, i * szTile + szTile, j * szTile + szTile));
    end;

  //обнуляем вектор.. и ждем клавиатуру
  StopMove();
  if (keys[VK_LEFT]) then ToLeft();
  if (keys[VK_RIGHT]) then ToRight();
  if (keys[VK_SPACE]) then Jump();

  man.vec.Y := 1; //гравитация
  man.velocity := POINT(2, 2); //ускорение

  //проверяем силу прыжка и прыгаем
  if (man.jumpY > 0) then begin
    man.vec.Y := -1;
    dec(man.jumpY);
    man.velocity := POINT(1, 3);
  end;

  //временные позиции для проверки столкновений
  npos.x := man.pos.X + man.vec.X * man.velocity.X;
  npos.y := man.pos.Y + man.vec.Y * man.velocity.Y;

  //проверяем столкновение
  if (man.vec.X = -1) then
    if (world[npos.X div szTile][man.pos.Y div szTile] = 1)
      or (world[npos.X div szTile][(man.pos.Y + man.size.Y) div szTile] = 1) then
        man.vec.X := 0;

  if (man.vec.X = 1) then
    if (world[(npos.X + man.size.X) div szTile][man.pos.Y div szTile] = 1)
      or (world[(npos.X + man.size.X) div szTile][(man.pos.Y + man.size.Y) div szTile] = 1) then
        man.vec.X := 0;

  if (man.vec.Y = -1) then
    if (world[man.pos.X div szTile][npos.Y div szTile] = 1)
      or (world[(man.pos.X + man.size.X) div szTile][npos.Y div szTile] = 1) then
        man.vec.Y := 0;

  if (man.vec.Y = 1) then
    if (world[man.pos.X div szTile][(npos.Y + man.size.Y)div szTile] = 1)
      or (world[(man.pos.X + man.size.X) div szTile][(npos.Y + man.size.Y)div szTile] = 1) then begin
        man.vec.Y := 0;
        man.stay := true;
        man.pos.Y := ((npos.Y + man.size.Y) div szTile) * szTile - man.size.Y -1;
      end else begin
        man.stay := false;
        man.velocity.Y := 5;
    end;

  //теперь двигаемся
  man.pos.X := man.pos.X + man.vec.X * man.velocity.X;
  man.pos.Y := man.pos.Y + man.vec.Y * man.velocity.Y;

  //и рисуем героя
  canvas.Brush.Color := $0000FF;
  canvas.Ellipse(RECT(man.pos.X, man.pos.Y, man.pos.X + man.size.X, man.pos.Y + man.size.Y));
end;

//дальше все ясно
procedure ToLeft();
begin
  man.vec.X := -1;
end;

procedure ToRight();
begin
  man.vec.X := 1;
end;

procedure StopMove();
begin
  man.vec.X := 0;
end;

procedure Jump();
begin
  if (man.stay) then begin
    man.jumpY := 25;
    man.stay := false;
  end
end;

procedure TfrmMain.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  keys[key] := true;
end;

procedure TfrmMain.FormKeyUp(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  keys[key] := false;
end;

end.

Собственно, вот архив с исходными кодами и самой программой Testing

Рассказать друзьям:
  • Добавить ВКонтакте заметку об этой странице
  • Мой Мир
  • Facebook
  • Twitter
  • Яндекс.Закладки
  • В Живую Ленту Google
  • Сто закладок
Комментарии (2) - Разработка RPG – LittleAge (тестовое приложение)

Ответ

  1. Саня:

    Прикольно) спасибо за урок)

    Thumb up Thumb down 0

Ответить

Comments

Перед отправкой формы: