Показать сообщение отдельно
Старый 22.07.2006, 22:27   #6
SubZer0
Администратор
 
Аватар для SubZer0
 
Регистрация: 03.09.2005
Сообщений: 2,408
Написано 301 полезных сообщений
(для 996 пользователей)
Сообщение Туториал "Змейка" (Скорость)

И снова доброго времени суток! для читателя пройдет наверное час, а для писателя с последнего урока прошел уже целый день

Продолжим!

на сегодня сделаем змее изменение скорости. Как уже упоминалось, если сделать интуитивно, т.е. увеличить шаг змеи, то получится нежелательный эффект "растягивания" змеи. Можно конечно это компенсировать динамичным количеством промежуточных хранилищ координат, если скорость (шаг) увеличивается, то уменьшать количество промежуточных хранилищ и наоборот. Но мы поступим по другому, мы введем время, через которое будет делаться шаг. Получится меньше гемороя в коде и соответственно потратится меньше трудов на его составление

поехали:

время будет меряться следующим образом: будут две дополнительные переменные, в одной будет хранится текущее время, а в другой сколько его было с самого начала, чтоб можно было не один раз время отмерять... и в самой процедуре передвижения мы будем вычитать их переменной текущего времени единицу, и если переменная стала нулем или меньше, то сделаем шаг и восстановим значение времени на первоначальное взяв его из переменной которая его надежно хранила выжыдав этого момента

ну хватит теории к коду!

добавим в тип вспомагательного массива эти самые две переменные
Type sn
 Field id%
 Field h%
 Field x#
 Field y#
 Field z#
 Field ax#
 Field ay#
 Field az#
End Type 

Type snm
 Field id%
 Field t%
 Field mt%
 Field s%
 Field x#
 Field y#
 Field z#
 Field ax#
 Field ay#
 Field az#
End Type
Переменная t% будет хранить текущее время, а mt% будет хранить изначальное время для последующего его восстановления...


Добавим в процедуру создания змеи значение времени, чтобы можно было сразу при создании задать скорость змее
Function SnakeCreate%(h%,t%,s%,x#,y#,z#)
 id%=1
 For SnakeManager.snm = Each snm
  id%=id%+1
 Next
 SnakeManager.snm=New snm
 SnakeManager\id%=id%
 SnakeManager\mt%=t%
 SnakeManager\t%=t%
 SnakeManager\s%=s%
 SnakeManager\x#=x#
 SnakeManager\y#=y#
 SnakeManager\z#=z#
 SnakeManager\ax#=EntityPitch(h%)
 SnakeManager\ay#=EntityYaw(h%)
 SnakeManager\az#=EntityRoll(h%)
 Snake.sn=New sn
 Snake\id%=id%
 Snake\h%=h%
 Snake\x#=x#
 Snake\y#=y#
 Snake\z#=z#
 Snake\ax#=EntityPitch(h%)
 Snake\ay#=EntityYaw(h%)
 Snake\az#=EntityRoll(h%)
 Return id%
End Function
Занесем значение времени как в текущее. так и в резерв для восстановления, чтобы змея при создании сразу не сорвалась с места, а ждала нужное время


Внесем изменения в процедуру движения змеи
Function SnakeMove(id%,x#,y#,z#)
 For SnakeManager.snm = Each snm
  If id%=SnakeManager\id% Then
   SnakeManager\t%=SnakeManager\t%-1
   If SnakeManager\t%<=0 Then 
    SnakeManager\t%=SnakeManager\mt%
    SnakeManager\x#=SnakeManager\x#+x#
    SnakeManager\y#=SnakeManager\y#+y#
    SnakeManager\z#=SnakeManager\z#+z#
    x#=SnakeManager\x#
    y#=SnakeManager\y#
    z#=SnakeManager\z#
    ax#=SnakeManager\ax#
    ay#=SnakeManager\ay#
    az#=SnakeManager\az#
    For Snake.sn=Each sn
     If id%=Snake\id% Then
      x1#=Snake\x
      y1#=Snake\y
      z1#=Snake\z
      ax1#=Snake\ax
      ay1#=Snake\ay
      az1#=Snake\az
      Snake\x=x#
      Snake\y=y#
      Snake\z=z#
      Snake\ax=ax#
      Snake\ay=ay#
      Snake\az=az#
      x#=x1#
      y#=y1#
      z#=z1#
      ax#=ax1#
      ay#=ay1#
      az#=az1#
     EndIf
    Next
   EndIf
   Exit
  EndIf
 Next

End Function
Здесь уменьшаем значение текущего времени на единицу, если оно получилось ноль или меньше, то восстанавливаем значение времени и передвигаем змею на шаг...

здесь я переместил процедуру ротации координат основного массива внутрь цикла поиска змеи (зеленое), чтобы не писать условие времени дважды, да и при таком расположении не будет лишнего "прогона" цикла обработки основного массива при несуществующем идентификаторе...


Добавим процедуру изменения скорости, чтобы можно было в программе изменить скорость змеи
Function SnakeSetSpeed(id%,t%)
 For SnakeManager.snm = Each snm
  If id=SnakeManager\id% Then
   SnakeManager\mt%=t%
   SnakeManager\t%=t%
   Exit
  EndIf
 Next
End Function
Здесь как и в остальных процедурах, ищем нужную змею по id% и заменяем значения времени новым, при этом надо заменить оба значения: mt% для восстановления времени, t% - новое значение текущего времени, чтобы при уменьшении скорости если текущее время будет больше чем теперь вообще возможное мы можем потерять несколько шагов или иными словами сказать "змея будет не сразу реагировать на изменение скорости"


вот и всё! теперь можно изменять скорость передвижения змеи без ее растягивания...

пример рабочего кода на этом шаге лежит в аттаче
__________________
Как минимум я помог многим (с)
(Offline)
 
Ответить с цитированием