Include "Includes\BlitzGrass.bb"		; дополнение Трава
Include "Includes\Draw3D2.bb"		; дополнение 3Д HUD-а

Type Snake_Type	; тип змеи
	Field body%		; модель в цепи змеи
	Field size%			; размер змеи
	Field body_time#	; время цепи на задержку
End Type

Type Stone_Type	; тип камней
	Field body%
	Field size%
	Field x#
	Field y#				; текущая позиция Y
	Field ty#			; точка Y над землей
	Field z#
End Type

Graphics3D 800,600,32,1
SetBuffer BackBuffer()
SeedRnd MilliSecs()	; рандомизация

Camera=CreateCamera()

PositionEntity Camera,0,10,-20
RotateEntity Camera,20,0,0
RotateEntity CreateLight(1),0,50,0
Camera_scale#=20	; приближение камеры при изометрическом виде (не используется)

DrawInit3D(Camera)	; загрузка 3Д Hud-а
Global Font=FontRange3D(LoadImage3D("Data\Textures\Standard · Hectic (31).png",2,2,0,-100)):SetFont3D(Font,1,1,-4,0)

; загрузка данных змеи

Snake_main_head=LoadMesh("Data\Models\Head.3ds")	; грузим модель головы
Snake_main_body=LoadMesh("Data\Models\Body.3ds")	; грузим модель тела
Snake_main_tail=LoadMesh("Data\Models\Tail.3ds")		; грузим модель хвоста

Snake_body_tex=LoadTexture("Data\Textures\Snake_skin.jpg")	; грузим текстуру змеи

HideEntity Snake_main_body
HideEntity Snake_main_tail

Global Snake_Health=100		; жизни
Global Apple_Count=0			; количество собранных яблок

Global Snake_delay#=1.5		; общее кол-во задержки для цепи (body_time# которое должно пройти)
Global Snake_spawn#=0		; змея должна увеличиться?
Global Snake_speed#=0.1		; скорость передвижения

STATE$="<#4f4>CTAPT !</#>"

Snake_MAX=50		; макс. размер змеи
Snake_Size=5			; установка начального размера
Dim Snake_Massiv#(Snake_MAX,4)		; 2Д массив для цепочки змеи (Snake_MAX - это хвост, 1 - это голова)

; создание змеи

For i%=1 To Snake_Size
	Snake.Snake_Type=New Snake_Type
	
	Snake\body=CopyMesh(Snake_main_body)
	EntityTexture Snake\body,Snake_body_tex
	
	Snake_Massiv(i%,1)=Handle(Snake)
	Snake_Massiv(i%,2)=-i%
	Snake_Massiv(i%,3)=0
	Snake_Massiv(i%,4)=0
	
	Snake\body_time#=0
Next

Snake=First Snake_Type	; настройка головы
HideEntity Snake\body		; прячем мусор
Snake\body=CopyMesh(Snake_main_head)
EntityTexture Snake\body,Snake_body_tex

Snake=Last Snake_Type	; настройка хвоста
HideEntity Snake\body		; прячем мусор
Snake\body=CopyMesh(Snake_main_tail)
EntityTexture Snake\body,Snake_body_tex

; Земля

Global Terrain=LoadTerrain("Data\Textures\Heightmap.bmp")
MoveEntity Terrain,-10,0,-10
ScaleEntity Terrain,0.5,15,0.5

Grass=LoadTexture("Data\Textures\Ground.jpg") 
ScaleTexture Grass, 75, 75
EntityTexture Terrain,Grass,0,0

; яблоки

Global Apple_tex_r=LoadTexture("Data\Textures\Red.jpg")	
Global Apple_tex_g=LoadTexture("Data\Textures\Green.jpg")
Global Apple_tex_y=LoadTexture("Data\Textures\Yellow.jpg")

Global Apple_body=LoadMesh("Data\Models\Apple.3ds")
AppleX#=Rnd(0,105)
AppleY#=Rnd(30,40)		; текущая позиция яблока по Y
AppleZ#=Rnd(0,105)
AppleTY#=TerrainY(Terrain,AppleX#,AppleY#,AppleZ#)+0.3 ; точка Y яблока над Землёй
PositionEntity Apple_body,AppleX#,AppleY#,AppleZ#
TexNum%=Rand(1,3)
Select TexNum	; установка разной текстуры на яблоко
	Case 1: EntityTexture Apple_body,Apple_tex_r
	Case 2: EntityTexture Apple_body,Apple_tex_g
	Case 3: EntityTexture Apple_body,Apple_tex_y
End Select
Apple_temp_count=0	; временное количество яблок (в коде: при 7 обнуляется, создаётся камень)

; трава

BG_Init(Terrain)
BG_SetLOD(100, 1)

grassLayer=BG_LoadGrass("Data\Textures\Grass.png")
BG_SetDensity(grassLayer, 200)
BG_SetScale(grassLayer, 4, 2)

Stone_tex=LoadTexture("Data\Textures\Rock.jpg")
Stone_model=LoadMesh("Data\Models\Stone.3ds")

; камни

For i%=1 To 20
	Stone.Stone_Type=New Stone_Type
	Stone\body=CopyMesh(Stone_model)
	Stone\x#=Rnd(0,105)
	Stone\y#=Rnd(60,80)
	Stone\z#=Rnd(0,105)
	Stone\ty#=TerrainY(Terrain,Stone\x#,Stone\y#,Stone\z#)+0.3
	PositionEntity Stone\body,Stone\x#,Stone\y#,Stone\z#
	EntityTexture Stone\body,Stone_tex
	TurnEntity Stone\body,Rand(0,360),Rand(0,360),Rand(0,360)
Next

Music=LoadSound("Data\Music.mp3")
SoundVolume Music,1
LoopSound Music
MusicSndCh=PlaySound(Music)

HitSnd=LoadSound("Data\Hit.mp3")
DeadSnd=LoadSound("Data\Ahhhh.mp3")
EatSnd=LoadSound("Data\Eat.mp3")

Repeat
If (Snake_Health>0) And (Apple_Count<45) Then		; если не конец игры
	Temp.Snake_Type=Object.Snake_Type(Snake_Massiv(1,1))	; обращаемся к голове
	
	If KeyDown(203) Then TurnEntity Temp\body,0,5,0	; клавиша влево
	If KeyDown(205) Then TurnEntity Temp\body,0,-5,0	; клавиша вправо
	
	MoveEntity Temp\body,Snake_speed#,0,0
	Snake_Massiv(1,2)=EntityX#(Temp\body)
	Snake_Massiv(1,3)=EntityY#(Temp\body)
	Snake_Massiv(1,4)=EntityZ#(Temp\body)
	
	For i%=1 To Snake_Size
	
		Temp.Snake_Type=Object.Snake_Type(Snake_Massiv(i%,1))
		
		Snake_Massiv(i%,3)=TerrainY(Terrain,Snake_Massiv(i%,2),Snake_Massiv(i%,3),Snake_Massiv(i%,4))
		
		Temp\body_time#=Temp\body_time#+0.1
		If Temp\body_time#>Snake_delay# Then
			STATE$=""
			Temp\body_time#=0
			Snake_Massiv((Snake_Size+1)-i%,2)=Snake_Massiv(Snake_Size-i%,2)
			Snake_Massiv((Snake_Size+1)-i%,4)=Snake_Massiv(Snake_Size-i%,4)
		End If
		
		PositionEntity Temp\Body,Snake_Massiv(i%,2), Snake_Massiv(i%,3),Snake_Massiv(i%,4)
		
		If i>1 Then
			TempPrev.Snake_Type=Object.Snake_Type(Snake_Massiv(i%-1,1))
			PointEntity Temp\Body,TempPrev\Body
		EndIf
	Next
	
	Temp.Snake_Type=Object.Snake_Type(Snake_Massiv(1,1))
	
	PositionEntity Camera,EntityX#(Temp\body),EntityY#(Temp\body),EntityZ#(Temp\body)
	RotateEntity Camera,EntityPitch#(Camera),EntityYaw#(Temp\body)-90,EntityRoll#(Camera)		; - фиксированная камера
	MoveEntity Camera,0,5,-10
	
	;PositionEntity Camera,EntityX#(Temp\body),EntityY#(Temp\body)+Camera_scale#,EntityZ#(Temp\body)-Camera_scale#*0.5
	;PointEntity Camera,Apple_body
	
	BG_Update(Temp\body)
	
	For Stone.Stone_Type=Each Stone_Type
		If Stone\y#<Stone\ty# Then
			If EntityDistance(Temp\body,Stone\body)<6 Then
				STATE$="<#f44>O, HET !</#>"
				PlaySound(HitSnd)
				
				Stone\x#=Rnd(0,105)
				Stone\y#=Rnd(60,80)
				Stone\z#=Rnd(0,105)
				Stone\ty#=TerrainY(Terrain,Stone\x#,Stone\y#,Stone\z#)+0.3
				
				Stone.Stone_Type=New Stone_Type
				Stone\body=CopyMesh(Stone_model)
				Stone\x#=Rnd(0,105)
				Stone\y#=Rnd(60,80)
				Stone\z#=Rnd(0,105)
				Stone\ty#=TerrainY(Terrain,Stone\x#,Stone\y#,Stone\z#)+0.3
				PositionEntity Stone\body,Stone\x#,Stone\y#,Stone\z#
				EntityTexture Stone\body,Stone_tex
				TurnEntity Stone\body,Rand(0,360),Rand(0,360),Rand(0,360)
				Snake_Health=Snake_Health-10
			EndIf
		Else
			Stone\y#=Stone\y#-0.5
			If (EntityDistance(Temp\body,Stone\body)<6) And (STATE$<>"<#f44>O, HET !</#>") Then
				Snake_Health=0
				STATE$="<#f44>Y6UT !</#>"
				PlaySound(HitSnd)
			EndIf
		EndIf
		PositionEntity Stone\body,Stone\x#,Stone\y#,Stone\z#
		If EntityDistance(Apple_body,Stone\body)<6 Then
			AppleX#=Rnd(0,105)
			AppleY#=Rnd(30,40)
			AppleZ#=Rnd(0,105)
			AppleTY#=TerrainY(Terrain,AppleX#,AppleY#,AppleZ#)+0.3
		End If
		
		If Snake_Health<1 Then PlaySound(DeadSnd)
	Next
	
	If AppleY#>AppleTY# Then AppleY#=AppleY#-0.5
	
	If EntityDistance(Temp\body,Apple_body)<1.3 Then
		If Snake_Size<Snake_MAX Then
			PlaySound(EatSnd)
			STATE$="<#4f4>ECTb !</#>"
			Apple_Count=Apple_Count+1
			If Apple_Count=45 Then STATE$="<#4f4>YPA ! YPA !</#>"
			AppleX#=Rnd(0,105)
			AppleY#=Rnd(30,40)
			AppleZ#=Rnd(0,105)
			AppleTY#=TerrainY(Terrain,AppleX#,AppleY#,AppleZ#)+0.3
			TexNum%=Rand(1,3)
			Select TexNum
				Case 1: EntityTexture Apple_body,Apple_tex_r
				Case 2: EntityTexture Apple_body,Apple_tex_g
				Case 3: EntityTexture Apple_body,Apple_tex_y
			End Select
			
			Snake_speed#=Snake_speed#+0.01
			Camera_scale#=Camera_scale#-0.15
			Snake_spawn#=1
			
			Snake_delay#=1.5/(Snake_speed#*10)
			
			Apple_temp_count=Apple_temp_count+1
			If Apple_temp_count=7 Then
				Stone.Stone_Type=New Stone_Type
				Stone\body=CopyMesh(Stone_model)
				Stone\x#=Rnd(0,105)
				Stone\y#=Rnd(60,80)
				Stone\z#=Rnd(0,105)
				Stone\ty#=TerrainY(Terrain,Stone\x#,Stone\y#,Stone\z#)+0.3
				PositionEntity Stone\body,Stone\x#,Stone\y#,Stone\z#
				EntityTexture Stone\body,Stone_tex
				TurnEntity Stone\body,Rand(0,360),Rand(0,360),Rand(0,360)
				Apple_temp_count=0
			EndIf
		EndIf
	EndIf
	
	PositionEntity Apple_body,AppleX#,AppleY#,AppleZ#
	TurnEntity Apple_body,0,5,0
	
	If Temp\body_time#=0 And Snake_spawn#=1 Then
		Snake_spawn#=0
		Snake_Size=Snake_Size+1
		Snake.Snake_Type=New Snake_Type
		
		;HideEntity Snake\body
		Snake\body=CopyMesh(Snake_main_body)
		EntityTexture Snake\body,Snake_body_tex
		
		Snake_Massiv(Snake_Size,1)=Handle(Snake)
		Snake_Massiv(Snake_Size,2)=Snake_Massiv(Snake_Size-1,2)
		Snake_Massiv(Snake_Size,3)=Snake_Massiv(Snake_Size-1,3)
		Snake_Massiv(Snake_Size,4)=Snake_Massiv(Snake_Size-1,4)
		
		Snake\body_time#=0
		
		Snake=Last Snake_Type
		HideEntity Snake\body
		Snake\body=CopyMesh(Snake_main_tail)
		EntityTexture Snake\body,Snake_body_tex
		
		Snake=Before Snake
		HideEntity Snake\body
		Snake\body=CopyMesh(Snake_main_body)
		EntityTexture Snake\body,Snake_body_tex
	EndIf
EndIf

	Text3D(Font,-380,+260,"Health: " + Snake_Health + " %",0)
	Text3D(Font,-380,+220,"Apples: " + Apple_Count + " c.",0)
	Text3D(Font,-380,+180,"Speed: " + Int(Snake_speed*100) + " km/h",0)
	
	Text3D(Font,-50,+150,STATE$,0)
	
	RenderWorld
	
	Clear3D()
	
	Flip
	Delay 1
Until KeyHit(1)

End
;~IDEal Editor Parameters:
;~C#Blitz3D