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

Доброго времени суток! Сорри за паузу, но времени в обрез...

сегодня создадим "квадратное" игровое поле, и заставим змею двигаться по квадратам...

Ну насегодня большой логики не будет... в основном рутинное программирование, поэтому приступим сразу к разборке сегодняшнего кода...

для начала добавим несколько полезных функций:
Function SnakePosition(id%,x#,y#,z#)
 For SnakeManager.snm = Each snm
  If id=SnakeManager\id% Then
   SnakeManager\x#=x#
   SnakeManager\y#=y#
   SnakeManager\z#=z#
   Exit
  EndIf
 Next
End Function

Function SnakeGetX(id%)
 For SnakeManager.snm = Each snm
  If id=SnakeManager\id% Then
   Return SnakeManager\x#
  EndIf
 Next
End Function

Function SnakeGetZ(id%)
 For SnakeManager.snm = Each snm
  If id=SnakeManager\id% Then
   Return SnakeManager\z#
  EndIf
 Next
End Function

Function SnakeGetY(id%)
 For SnakeManager.snm = Each snm
  If id=SnakeManager\id% Then
   Return SnakeManager\y#
  EndIf
 Next
End Function

Function SnakeGetAngleX#(id%)
 For SnakeManager.snm = Each snm
  If id=SnakeManager\id% Then
   Return SnakeManager\ax#
  EndIf
 Next
End Function

Function SnakeGetAngleY#(id%)
 For SnakeManager.snm = Each snm
  If id=SnakeManager\id% Then
   Return SnakeManager\ay#
  EndIf
 Next
End Function

Function SnakeGetAngleZ#(id%)
 For SnakeManager.snm = Each snm
  If id=SnakeManager\id% Then
   Return SnakeManager\az#
  EndIf
 Next
End Function
Функции просты но полезны, думаю объяснять их функционирование не стоит, а назначение: запрос угла, запрос позиции и установка позиции головы змеи...

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

создадим его для начала
For i=0 To 15
 For j=0 To 15
  t%=CreateSphere ()
  PositionEntity t%,i*10-5,0,j*10-5
  ScaleMesh t%,0.5,0.5,0.5
 Next
Next
эти два цикла разметят кусок мирового пространства на клетки... 15 на 15, размер каждой клетки будет 10 на 10 единиц...

-5 это корректировка (сдвиг) игрового поля, чтобы позиция 0,0 как раз была в центре первой клетки... оно нам пригодится для дальнейших рассчетов.


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

код управления будет следующим:
 speed#=0.7
 If Direction%=0 Then SnakeMove(a,0,0,speed#)
 If Direction%=2 Then SnakeMove(a,0,0,-speed#)
 If Direction%=1 Then SnakeMove(a,-speed#,0,0)
 If Direction%=3 Then SnakeMove(a,speed#,0,0)

 If KeyDown(200) Then 
  If (SnakeGetX(a) Mod 10)=0 
   Direction%=0
   If Int(SnakeGetAngleY(a))<>0
    SnakeSetAngle(a,0,0,0)
    SnakePosition (a,(Int(SnakeGetX(a))/10)*10,0,SnakeGetZ(a))
   EndIf
  EndIf
 EndIf

 If KeyDown(208) Then 
  If (SnakeGetX(a) Mod 10)=0 
   Direction%=2
   If Int(SnakeGetAngleY(a))<>180
    SnakeSetAngle(a,0,180,0)
    SnakePosition (a,(Int(SnakeGetX(a))/10)*10,0,SnakeGetZ(a))
   EndIf
  EndIf
 EndIf

 If KeyDown(203) Then 
  If (SnakeGetZ(a) Mod 10)=0 
   Direction%=1
   If Int(SnakeGetAngleY(a))<>90
    SnakeSetAngle(a,0,90,0)
    SnakePosition (a,SnakeGetX(a),0,(Int(SnakeGetZ(a))/10)*10)
   EndIf
  EndIf
 EndIf

 If KeyDown(205) Then 
  If (SnakeGetZ(a) Mod 10)=0 
   Direction%=3   
   If Int(SnakeGetAngleY(a))<>270
    SnakeSetAngle(a,0,270,0)
    SnakePosition (a,SnakeGetX(a),0,(Int(SnakeGetZ(a))/10)*10)
   EndIf
  EndIf
 EndIf
Этот код каждый может составить по своему усмотрению. мне понравился такой способ реализации.

значит так: вводим дополнительную переменную: Direction%, эта переменная будет отвечать за направление движения... у нас ведь всего 4-х стороннее движение (налево, направо, вверх, вниз), по диагонали нам ездить не надо... для быстрого понятия всего советую представить себе часы: "12" - направление вверх обозначим числом "0", "3" - направление вправо числом "1", "6" - направление вниз, числом "2", 9 - направление влево числом "3"...

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

далее обработку клавиш... теперь нам надо при нажатии клавиш только менять направления... о передвижении змеи заботится предыдущий блок условий... НО! просто так нам изменять направления нельзя, нам нужно еще изменить угол головы змеи и проверять находится ли змея на середине квадрата игрового поля...

"If (SnakeGetX(a) Mod 10)=0" проверяет находится-ли змея на середине квадрата! путем сравнения не пойдет, потому, что если шаг будет равен например 0.3 то попадание на ровное число 10 будет очень редким... поэтому здесь вычисляется остаток от деления на 10 (размер квадрата) если он равен нулю, то змея находится на позиции кратной 10, а такие позиции находятся ровно в центре квадратов (для этого мы и сдвигали игровое поле на -5)

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


вот, в принципе, и все на сегодня... теперь есть поле, по которому змея может ползать... и поворачивать можно только "по квадратам"..

рабочий код на этом шаге лежит в аттаче
__________________
Как минимум я помог многим (с)
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
LLI.T.A.L.K.E.R. (05.02.2010)