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

Категории раздела
Уроки по созданию игр [38]
Программирование игр разной сложности
Игровые алгоритмы [24]
Алгоритмы, которые уже реализованы для разных жанров игр
Графика [5]
Учимся работать с графикой в Делфи
Мультимедиа [3]
Работа с мультимедийными возможностями Делфи
Другие статьи [18]
Статьи не вошедшие не в один из разделов
Ошибки [4]
Всевозможные ошибки и пути их решения
Среда, 01.05.2024, 14:17
Приветствую Вас Гость

Статьи по программированию

Главная » Статьи » Уроки по созданию игр

игра Танчики часть 1

Сегодня мы напишем с вами маленькую игрушку на подобие танчиков. Я использую Делфи 7. Итак запускаем Делфи, в итоге у нас автоматически создается форма и проект. Мы нажимает Файл—Сохранить и выбираем папку, в которой будет находиться наша игра. Наш проект сохранен, теперь создаем папку для хранения графики. И рисуем в графическом редакторе, например пеинте, два вида танков и пулю. Танки должны быть нарисованы с поворотами в разные стороны, на каждую сторону по две картинки с разным движением гусениц (для имитации езды). Размер изображений я выбрал 60х60. Я рисовал одну картинку, а потом просто поворачивал ее (Рисунок—Повернуть/Наклонить—повернуть на 90 градусов). В итоге мы получаем что-то такое:

Картинки танчиков

Под каждым рисунком вам видна его подпись. Буква в подписи означает имя танка (одна буква для простоты), первая цифра обозначает номер поворота (1-вверх, 2-вправо, 3-вниз, 4-влево), вторая цифра – номер движения гусеницы.

 


Далее кликаем на форме. В обджект инспекторе выбираем вкладку EVENTS (это события формы). Дважды кликам по событию FormCreate (создание формы). Откроется листинг в котором мы напишем загрузку всех необходимых картинок для игры. И они будут загружаться сразу после появления формы на экране.

Сначала обьявляем переменные.

После слова Var перед Implementation, которое немного выше места с курсором пишем следующее:

  Tanki:array[1..2,1..2,1..4]of TBitmap;

  Textures:array[1..3] of TBitmap;

  Flag:array[1..2]of TFlag;

  Map:array[0..10,0..10] of integer;

  Tank:array[1..4]of TTank;

  Puli:array[1..20] of Tpulya;

  Pulya,Buf:Tbitmap;

  path:string;

  qUp,qDown,qLeft,qRight:boolean;

  i,j:integer;

 

Теперь обьясняю. Массив Tanki будет хранить картинки (Битмапы (БМП)) всех танков. В нашем случае «1..2» означает два вида танков, следующие «1..2» означают два вида движения гусеницы, «1..4» означает поворот танка в 4 стороны. Переменная Pulya будет хранить картинку выпущенных пуль. Path будет хранить путь к нашей игре на компьютере, независимо где находиться папка при запуске. Она нужна для правильной загрузки картинок, можно обойтись без нее, но если загружать много картинок из разных папок и тд., могут произойти ошибки, которые будут только иногда появляться. Чтобы этого не произошло мы используем эту переменную. Buf – это графический буфер, в который мы будем все прорисовывать, а потом этот буфер рисовать на саму форму. Если рисовать без него, то когда будут рисоваться одни картинки поверх других, вся игра будет мигать. Up,Down,Left,Right – это клавиши управления танком, с их помощью мы будем проверять какая из них нажата последней и куда нам ехать.

Далее пишем саму загрузку картинок с паки img, которая находится в папке с игрой. i,j – это просто вспомогвтельные переменные. Flagэто характеристики и картинки флагов соперников на карте. Texturesмассив картинок обьектов для заполнения игровой карты. Map это массив клеток игровой карты, в котором храняться номера текстур для каждой ячейки.

 

procedure TForm1.FormCreate(Sender: TObject);

var

i,j:integer;

begin

path:=extractFileDir(Application.ExeName);

   

  //zagruzka kartinok tankov

   for i:=1 to 4 do

   for j:=1 to 2 do

   begin

     Tanki[1,i,j]:=Tbitmap.create;

     Tanki[2,i,j].TransparentColor:=clWhite;

     Tanki[1,i,j].loadfromFile(path+'\img\'+'t'+inttostr(i)+inttostr(j)+'.bmp');

     Tanki[2,i,j]:=Tbitmap.create;

     Tanki[2,i,j].TransparentColor:=clWhite;

     Tanki[2,i,j].loadfromFile(path+'\img\'+'q'+inttostr(i)+inttostr(j)+'.bmp');

   end;

 

  //zagruzka tekstur

   for i:=1 to 4 do

   begin

   Textures[i]:=Tbitmap.Create;

   Textures[i].LoadFromFile(path+'\img\'+inttostr(i)+'.bmp');

   end;

 

   //zagruzka puli

   Pulya:=Tbitmap.Create;

   Pulya.LoadFromFile(path+'\img\p.bmp');

  

   Buf:=Tbitmap.Create;

   Buf.Width:=600;

   buf.Height:=600;

 

   qLeft:=false;

   qRight:=false;

   qUp:=false;

   qDown:=false;

end;

 

Как видно, сначала мы создаем место под картинки, а затем загружаем картинку из папки. Мы установили ширину и высоту буфера 600х600. Затем я устанавливаю клавиши управления танком в неактивное положение (w-a-s-d). Следующим шагом будет создание записи для характеристик нашего танка. После слова Type в самом верху пишем:

 

TTank=record

Speed,x,y,Povorot:integer;

Go,Anim,Fight,Vistrelil:boolean;

Zaderhka_Vistrela,Max_vistrel:integer;

end;

 

Speed – это скорость танка

X – координата х на карте игры

Y – координата у на карте игры

Povorotномер поворота танка

Anim – Номер анимации гусеницы (два значения истина- первая анимация, лож – вторая анимация)

Go – может принимать два значения истина (true) и лож (false). Переменная показывает движется танк или стоит на одном месте.

Fightвыстрел танка

Zaderhka_Vistrelaнужна для отсчета времени между выстрелами

Max_vistrel – задержка выстрела.

Vistrelil – показатель выстрелил уже танк или нет.

Вторую запись пишем для всех выпущенных пуль:

 

Tpulya=record

x,y,speed,povorot:integer;

visible:boolean;

end;

 

x,y – координаты

speed – скорость

povorot – в какую сторону лететь

visible – видимость (видима пуля только когда выпущена танком)

После слова Var написаны следующие строки

Tank:array[1..4]of TTank;

Puli:array[1..20] of Tpulya;

Это значит, что четыре танка будут иметь эти характеристики и 20 пуль будут иметь свои характеристики.

Теперь напишем начальные характеристики нашего танка и всех пуль. А затем случайное создание карты. После загрузки картинки пули пишем строки:

 

Tank[1].Speed:=5;

Tank[1].x:=60;

Tank[1].y:=60;

Tank[1].Povorot:=1;

Tank[1].Go:=false;

Tank[1].Anim:=1;

Tank[1].Fight:=false;

Tank[1].Zaderhka_Vistrela:=0;

Tank[1].Max_vistrel:=10;

Tank[1].Vistrelil:=false;

   for i:=1 to 20 do

   begin

   Puli[i].x:=0;

   Puli[i].y:=0;

   Puli[i].speed:=10;

   Puli[i].povorot:=0;

   Puli[i].visible:=false;

   end;

Далее пишем случайное генерирование карты 10х10 клеточек:

//generirovaniye karti

   randomize;

   for i:=0 to 9 do

   for j:=0 to 9 do

   begin

   map[i,j]:=random(100)+1;

   if map[i,j]<=50 then map[i,j]:=1;

   if (map[i,j]>50) and (map[i,j]<=80) then map[i,j]:=2;

   if (map[i,j]>80) and (map[i,j]<=100) then map[i,j]:=3;

   end;

   map[9,0]:=4;

   map[trunc(Tank[1].x/60),trunc(Tank[1].y/60)]:=1;

 

Теперь при появлении танка под ним будет только проходимый участок.

Далее кликаем по форме и перетаскиваем с вкладки System компонент Timer, который не будет виден при запуске игры, но каждый промежуток времени он будет прорисовывать все изменения игры. Дважды кликаем по таймеру и пишем прорисовку карты и прорисовку нашего танка поверх карты:

//prorisovka karti

   for i:=0 to 9 do

   for j:=0 to 9 do

   buf.Canvas.Draw(i*60,j*60,Textures[ map[i,j] ]);

 

if Tank[1].Go=true then

   begin

     if Tank[1].Anim=1 then Tank[1].Anim:=2

     else Tank[1].Anim:=1;

   end;

   buf.Canvas.Draw(Tank[1].x,Tank[1].y,Tanki[1,Tank[1].povorot,Tank[1].anim]);

   form1.Canvas.Draw(0,0,buf);

Сохраните проект и запустите его клавишей F9. Вы видите на экране наш недвижимый танк в указаних начальних координатах. Анимация гусениц вступит в силу после того, как мы сделаем обработку нажатих управляючих клавиш. Кликаем по нашей форме, а затем дважды щелкаем по событию OnKeyDown. Это событие проверяет нажатые клавиши. Пишем там следующий код:

  if key=87 then

  begin

  qUp:=true;

  Tank[1].Go:=true;

  Tank[1].Povorot:=1;

  end;

 

  if key=65 then

  begin

  qLeft:=true;

  Tank[1].Go:=true;

Tank[1].Povorot:=4;

  end;

 

  if key=83 then

  begin

  qDown:=true;

  Tank[1].Go:=true;

Tank[1].Povorot:=3;

  end;

 

  if key=68 then

  begin

  qRight:=true;

  Tank[1].Go:=true;

Tank[1].Povorot:=2;

  end;

Из этого видно, что если нажата клавиша с номерами 87 (w), 65 (a), 83 (s), 68 (d), то танку присваиваем движение гусениц и делаем клавишу нажатой. Плюс к тому же мы определяем поворот танка. Затем дважды кликаем по событию OnKeyUp. Здесь мы проверяем если не нажата ни одна из управляючих кнопок, то анимация танка отключается. И отключаем не нажате клавиши.

  if (key=87) then qUp:=false;

  if (key=65) then qLeft:=false;

  if (key=83) then qDown:=false;

  if (key=68) then qRight:=false;

  if (qUp=false) and (qLeft=false) and (qDown=false) and (qRight=false) then Tank[1].Go:=false;

Чтобы анимация была быстрее кликните по таймеру и выставте интервал 100. Сохраните и запустите проект. Теперь наш танк умеет поворачивать и ездить. Теперь наша задача сделать, чтобы он не мог проезжать через непроходимые участки. Нужно изменить написанный ранее код изменения координат.

   //izmeneniye koordinat tanka

   if Tank[1].Go=true then

   begin

     //vverh

     if (Tank[1].Povorot=1) and (map[trunc(Tank[1].x/60),trunc( (Tank[1].y-Tank[1].Speed)/60)]=1)

     and (map[trunc( (Tank[1].x+59) /60),trunc( (Tank[1].y-Tank[1].Speed)/60)]=1)

     and (Tank[1].y-Tank[1].Speed>=0) then Tank[1].y:=Tank[1].y-Tank[1].Speed;

     //vniz

     if (Tank[1].Povorot=3) and (map[trunc(Tank[1].x/60),trunc( (Tank[1].y+Tank[1].Speed+59)/60)]=1)

     and (map[trunc( (Tank[1].x+59) /60),trunc( (Tank[1].y+Tank[1].Speed+59)/60)]=1)

     and (Tank[1].y+Tank[1].Speed<=540) then Tank[1].y:=Tank[1].y+Tank[1].Speed;

     //vpravo

     if (Tank[1].Povorot=2) and (map[trunc( (Tank[1].x+Tank[1].Speed+59)/60),trunc(Tank[1].y/60)]=1)

     and (map[trunc( (Tank[1].x+Tank[1].Speed+59)/60),trunc( (Tank[1].y+59) /60)]=1)

     and (Tank[1].x+Tank[1].Speed<=540) then Tank[1].x:=Tank[1].x+Tank[1].Speed;

     //vlevo

     if (Tank[1].Povorot=4) and (map[trunc( (Tank[1].x-Tank[1].Speed)/60),trunc(Tank[1].y/60)]=1)

     and (map[trunc( (Tank[1].x-Tank[1].Speed)/60),trunc( (Tank[1].y+59) /60)]=1)

     and (Tank[1].x-Tank[1].Speed>=0) then Tank[1].x:=Tank[1].x-Tank[1].Speed;

   end;

Таким образом когда танк будет ехать будет проверяться попадание двух его передних угров на попадание в непроходимый участок. К тому же мы не позволяем выехать танку за пределы игровой карты.

Теперь нужно научить наш танк стрелять. Для этого мы в управление танком добавим клавишу пробел (например), для стрельбы. А затем будем создавать пулю и просчитывать в какую сторону ей лететь и когда пропадать.

 

 Для пуль создается тип с номерами пуль, координатами и поворотом.

Но это будет в продолжении статьи


Автор: Соколов Виталий

Источник: delgame.at.ua

Категория: Уроки по созданию игр | Добавил: Armageddets (05.07.2012)
Просмотров: 8108 | Рейтинг: 2.0/1
Всего комментариев: 6
5 Antis28  
0
Да, ваш совет помог, но теперь выходит такая ошибка при запуске: Access Violation at adress ...
дебагер указывает на строку в таймере :
 
Код
buf.Canvas.Draw(i*60,j*60,Textures[ map[i,j] ]);

6 Armageddets  
0
Эта ошибка появляется когда мы выходим за пределы границ массива. Здесь может быть несколько вариантов: возможно размер буфера, на который мы рисуем меньше чем нужен, второй это мы вылазим за пределы карты (хотя здесь все нормально должно быть). У меня все работало безошибочно. Возможно в статье сделал опечатку где-то. Если интересно зайди в раздел "каталог файлов" и скачай там эти танчики. Открой исходный код и сравни со своим его.

3 Antis28  
1
На этом участке кода
if Tank[1].Anim=1 then Tank[1].Anim:= 2

выдает ошибку

[dcc32 Error] MainUnit.pas(237): E2010 Incompatible types: 'Boolean' and 'Integer'

4 Armageddets  
1
Эта ошибка говорит о том что ты пытаешься булевому типу (истина или ложь) присвоить обычную цифру. Это моя опечатка. Просто в записи танка перенеси Anim к типу integer. И ошибки больше не будет. Извиняюсь за свою оплошность...

2 DikolA  
0
Привет Админ! Напиши пожалуйста продолжения начатой игры
Пожалуйста =\\

1 Евгений  
2
Ну и где продолжение?

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Наш опрос
Уроки по созданию каких игр Вам интересны?
Всего ответов: 167
Мини-чат
Друзья сайта
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz
  • Статистика

    Онлайн всего: 1
    Гостей: 1
    Пользователей: 0