Type Segment
Field Mesh
End Type
Function SnakeGrowUp(Reference)
;Берем последний элемент - конец хвоста
Local Segment.Segment = Last Segment
;Если последний элемент существует
If (Segment <> Null) Then
;Берем его координаты
Local PosX = EntityX(Segment\Mesh)
Local PosZ = EntityZ(Segment\Mesh)
;Создаем новый сегмент
Segment = New Segment
Segment\Mesh = CopyEntity(Reference)
;Ставим его в позицию последнего сегмента
PositionEntity(Segment\Mesh, PosX, 0, PosZ)
EndIf
End Function
Function SnakeGrowDown()
;Берем последний элемент - конец хвоста
Local Segment.Segment = Last Segment
;Если последний элемент существует и это не голова
If (Segment <> Null) And (Segment <> First Segment) Then
;Удаляем меш сегмента
FreeEntity(Segment\Mesh)
;Удаляем сегмент
Delete Segment
EndIf
End Function
Function SnakeUpdate(OffsetX#, OffsetZ#)
Local PrevPosX# = 0
Local PrevPosZ# = 0
;берем первый элемент списка - голова
Local Segment.Segment = First Segment
;берем координаты головы и вычисляем следующую ее позицию (новые координаты)
Local NextPosX# = EntityX(Segment\Mesh) + OffsetX
Local NextPosZ# = EntityZ(Segment\Mesh) + OffsetZ
;Перебираем весь список чтобы последовательно обновить всю змею
For Segment = Each Segment
;Запоминаем позицию текущего элемента
PrevPosX = EntityX(Segment\Mesh)
PrevPosZ = EntityZ(Segment\Mesh)
;позиционируем текущий элемент (новыми координатами)
PositionEntity(Segment\Mesh, NextPosX, 0, NextPosZ)
;Новые координаты становятся предыдущими
NextPosX = PrevPosX
NextPosZ = PrevPosZ
Next
End Function
Function SnakeCreate(PosX, PosZ, Segments, Reference)
Local Segment.Segment
;Создаем список элементов - сегменты змеи
;с 0 начинаем потому что голова должна быть обязательно
For i = 0 To Segments
Segment = New Segment
Segment\Mesh = CopyEntity(Reference)
;Позиционируем (только по X, Z потому что движение в одной плоскости)
PositionEntity(Segment\Mesh, PosX, 0, PosZ)
Next
;обновляем змею
SnakeUpdate(0, 0)
End Function
;#############################
;Размер клетки поля
Const CellSizeX# = 1
Const CellSizeZ# = 1
Graphics3D(800, 600, 0, 2)
;Текстура земли
Ground_Tex = CreateTexture(32, 32, 9)
SetBuffer(TextureBuffer(Ground_Tex))
Color(100, 100, 100)
Rect(0, 0, 32, 32)
Color(50, 255, 50)
Line(0, 16, 32, 16)
Line(16, 0, 16, 32)
SetBuffer(BackBuffer())
ScaleTexture(Ground_Tex, CellSizeX, CellSizeZ)
;Земля
Ground_Mesh = CreatePlane()
EntityTexture(Ground_Mesh, Ground_Tex)
;Сегмент - образец
Reference = CreateCube()
ScaleEntity(Reference, CellSizeX * 0.5, 1, CellSizeZ * 0.5)
EntityColor(Reference, 255, 50, 50)
HideEntity(Reference)
;Создаем змею с 4-мя сегментами
SnakeCreate(0, 0, 4, Reference)
;Устанавливаем камеру
Camera = CreateCamera()
PositionEntity(Camera, 0, 25, 0)
RotateEntity(Camera, 90, 0, 0)
;Направление движения змеи
DirX = 0
DirZ = 1
Repeat
;Обновляем змею каждые 300 миллисекунд
If ((MilliSecs() - StepPeriod) > 300) Then
;Сдвигаем змею на размер клетки в соответствии с направлением движения
SnakeUpdate(DirX * CellSizeX, DirZ * CellSizeZ)
StepPeriod = MilliSecs()
EndIf
RenderWorld()
Flip()
Until KeyDown(1)
End