Тема: Змейка
Показать сообщение отдельно
Старый 06.10.2007, 23:10   #13
Platon
Знающий
 
Регистрация: 04.08.2006
Адрес: Россия
Сообщений: 297
Написано 39 полезных сообщений
(для 70 пользователей)
Re: Змейка

Змею лучше делать списком, вот попробуй
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
(Offline)
 
Ответить с цитированием