Движение
Долго смотрел на эти бонусы, летающие вверх вниз и чуть не загипнотизировался. Скукота. Надо бы еще что-нибудь сделать. Без чего там еще аркад не бывает? Я бы добавил в игру еще платформы, на которые игрок может запрыгнуть и проехать. Это неотъемлемая часть любой аркады. Стоп. Сначала давайте определимся с терминами. Объект ,который может двигаться вверх/вниз (ось у) я буду называть ЛИФТ, а объект , который двигается влево / вправо (ось х) - ПЛАТФОРМА. Ок, для начала я предлагаю создать платформу. Что нам для этого нужно. Надо указать ее начальное расположение, указать конечные точки пути и направление.
Я тут изобразил кусочек тайловой карты размером 6х4. А серенький квадрат с белой линией вверху- это платформа. Как вы видите, ее начальные координаты (2,2) и по моей задумке, она должна двигаться влево до (0,2) и вправо до (5,2), красные стрелочки. Или если сказать иначе, то на две клетки влево и на три клетки вправо, от своей начальной позиции. Если принять начальную позицию за ноль(смотрим на цифры снизу), то 2 тайла влево соответствуют <-2>, а 3 вправо - соответствуют <+3>. Мне кажется более удачным задавать перемещение именно так, в относительных координатах, нежели в координатах карты. Договорились? Ок, договорились. Кто не согласен - пишет свой код, кто согласен - читает дальше. Создадим новый тип TmovingX :
Type TmovingX
Field x:Int Field y:Int Field width:Int Field height:Int
Field speed:Int Field dirx:Int
Field mindir:Int Field maxdir:Int End type
Так , первые 4 поля нам знакомы, мы все про них знаем.
- Speed - ну это понятно, скорость. То есть на сколько пикселей двигать платформу при передвижении.
- Dirx - тут как в бонусах, направление движения: dirx = -1, это влево , а dirx = 1 это вправо.
- Mindir и maxdir - ну это и так понятно
Забыл добавить: платформа движется только по оси х, тогда y-координату вообще можем отбросить, учтем ее только при задании начальных координат для создания платформы. Кстати, вот так бы выглядела функция создания (Create) для платформы, которая на рисунке выше:
TmovingX.Create( 2 , 2 , -2 , 3 , -1)
Как вы наверное догадались, первые два параметра - тайловые координаты платформы на карте, затем - на сколько клеток она может перемещаться влево, следующий параметр - на сколько тайлов вправо, и последний параметр - начальное направление (влево). Вот сама функция :
Function Create(xt:Int , yt:Int , mn:Int , mx:Int, d:Int)
Local TMX:TmovingX = New TmovingX
TMX.x = xt * TILESIZE TMX.y = yt * TILESIZE
TMX.width = TILESIZE TMX.height = TILESIZE
TMX.speed = 1
TMX.dirx = d
TMX.mindir = (mn + xt) * TILESIZE TMX.maxdir = (mx + xt + 1) * TILESIZE
ListAddLast(MovingXList , TMX) End Function
Да , проницательные мои, вы сразу заметили ,что я еще не объявил список для хранения всех платформ. Устраняю упущение:
Global MovingXList:Tlist = CreateList() 'напишите это сверху, то есть до объявления типа
Ну теперь порядок.
Метод рисования платформы. Засуну все свои художественные замыслы куда-нибудь поглубже, и сделаю платформу все тем же прямоугольником, но теперь уже серого цвета и с белою полоской сверху.
Method Draw()
SetColor(128 , 128 , 128) ' установить серый цвет DrawRect(x , y , Width , Height) ' нарисовать платформу SetColor(255 , 255 , 255) ' установить белый цвет DrawLine(x , y , x + width - 1 , y) ' нарисовать линию сверху End Method
Ну, это было для вас не сложно, ведь правда? А вот и функция перемещения нашей платформы, на нее поглядите внимательнее:
Method Update()
If( mindir >= x Or maxdir <= (x + width) ) dirx = - dirx EndIf
x = x + speed * dirx
End method
Не находите ничего знакомого? Бааа, да это ж брат или точнее сестра Tbonus.Update() только там было перемещение вверх / вниз и внутри тайла, а здесь наша платформа перемещается на бОльшие расстояния и вправо/влево. Но код остался на 90% таким же. Только у поменялся на х. Разве не здорово? Лишь нет задержки анимации (AnimDelay), я решил , что здесь она ни к чему. Но вы можете добавить сюда и этот параметр.
Итак нам осталось создать где-нибудь нашу платформу и нарисовать ее на экране. Предлагаю сделать так:
TmovingX.Create(13 , 3 , - 2 , 5 , 1)
Рисуем как обычно, проходим по всему списку, перемещаем и отображаем каждую платформу.
For Local CurMovingX:TmovingX = EachIn MovingXList
CurMovingX.Update() CurMovingX.Draw() Next
Вы можете создать для этого отдельную функцию и назвать ее, например, Draw_All_Platforms(), а мне что-то неохота, и потому я опять пихну все в Tlevel.Render(), пусть рисуются в одном месте тайлы, бонусы и платформы. Зато главный цикл будет поменьше. Вот исходник:
SuperStrict
Global ScrWidth : Int = 640 Global ScrHeight : Int = 480
Global TileList:TList = CreateList() Global BonusList:TList = CreateList() Global MovingXList:TList = CreateList()
Const TILESIZE:Int = 32
Type TTile Field x:Int Field y:Int
Field xTile:Int Field yTile:Int Field Width:Byte Field Height:Byte
Field Walkable:Byte Function Create(sx:Int, sy:Int, WB:Byte) Local TT:TTile = New TTile TT.width = TiLESIZE TT.height = TiLESIZE TT.xTile = sx TT.yTile = sy TT.x = TT.xTile * TT.width TT.y = TT.yTile * TT.height TT.Walkable = WB
ListAddLast(TileList , TT) End Function
Method update() If walkable 'walkable SetColor(255 , 0 , 0) 'red Else 'NOT walkable SetColor(0 , 255 , 0) 'green End If End Method
Method Draw() DrawRect(x,y,Width,Height) End Method
End Type
Type TLevel Field Width : Byte Field Height : Byte
Field Map:Int[,] Function Create:TLevel(MyMap:Int[],map_width:Int,map_height:Int) Local TM : TLevel = New TLevel TM.Width = map_width TM.Height = map_height
TM.map = New Int [TM.Width, TM.Height] TM.load(myMap) Return TM End Function Method Load(arrMap:Int[]) For Local i:Int = 0 Until Height For Local j:Int = 0 Until Width Map[j , i] = arrMap[j + (i * Width)] If Map[j , i] TTile.Create(j , i , True) Else TTile.Create(j , i , False) End If Next Next End Method
Method Render() For Local CurTile:TTile = EachIn TileList CurTile.Update() CurTile.Draw() Next For Local CurBonus:TBonus = EachIn BonusList CurBonus.Update() CurBonus.Draw() Next For Local CurMovingX:TMovingX = EachIn MovingXList CurMovingX.Update() CurMovingX.Draw() Next End Method End Type
Type TBonus Field x:Int Field y:Int Field width:Int Field height:Int Field points:Int Field miny:Int Field maxy:Int Field diry:Int Field speed:Int Field AnimDelay:Int Function Create(sx:Int,sy:Int,pts:Int) Local TB : TBonus = New TBonus TB.Width = 6 TB.Height = 16 TB.x = sx * TiLESIZE + ((TiLESIZE - TB.width) / 2) 'center it TB.y = sy * TiLESIZE + ((TiLESIZE - TB.height) / 2) 'center it TB.points = pts TB.miny = TB.y - 4 TB.maxy = TB.y + TB.Height + 4 TB.diry = -1 TB.speed = 1 TB.AnimDelay = 5 ListAddLast(BonusList ,TB) End Function Method Update() If(Animdelay < 0)
If ( miny >= (y) Or maxy <= (y + height) ) diry = -diry End If y = y + speed * diry AnimDelay = 5
End If AnimDelay :- 1 End Method Method Draw() SetColor(255 , 255 , 0) DrawRect(x,y,Width,Height) End Method End Type
Type TMovingX Field x:Int Field y:Int Field width:Int Field height:Int Field mindir:Int Field maxdir:Int
Field dirx:Int Field speed:Int Function Create(xt:Int , yt:Int , mn:Int , mx:Int , d:Int) Local TMX:TMovingX = New TMovingX
TMX.x = xt * TILESIZE TMX.y = yt * TILESIZE
TMX.width = TILESIZE TMX.height = TILESIZE
TMX.speed = 1
TMX.dirx = d
TMX.mindir = (mn + xt) * TILESIZE TMX.maxdir = (mx + xt + 1) * TILESIZE
ListAddLast(MovingXList, TMX) End Function
Method Update() If( mindir >= x Or maxdir <= (x + width) ) dirx = - dirx EndIf x :+ speed * dirx End Method Method Draw() SetColor(128 , 128 , 128) ' gray DrawRect(x , y , Width , Height) SetColor(255 , 255 , 255) ' white line DrawLine(x , y , x + width - 1 , y) End Method
End Type
Global LevMap:Int[]=[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,.. 1,0,0,0,1,0,0,0,1,1,0,0,0,1,0,0,0,0,0,1,.. 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,.. 1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,.. 1,0,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,.. 1,0,0,0,0,0,1,1,0,0,1,1,1,1,1,1,1,1,1,1,.. 1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,.. 1,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,1,1,1,1,.. 1,0,0,0,0,0,0,0,0,1,1,0,0,0,1,0,0,0,0,1,.. 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
Global MyLevel : TLevel = New TLevel.Create(LevMap , 20 , 10)
Function Init_All_Bonuses() TBonus.Create(1 , 1 , 25) TBonus.Create(3 , 8 , 25) TBonus.Create(4 , 8 , 25) TBonus.Create(5 , 8 , 25) TBonus.Create(15 , 1 , 100) TBonus.Create(7 , 4 , 100) TBonus.Create(9 , 7 , 10) TBonus.Create(4 , 6 , 10) TBonus.Create(9 , 2 , 10) TBonus.Create(14 , 7 , 10) TBonus.Create(17 , 6 , 10) TBonus.Create(17 , 4 , 10) TBonus.Create(18 , 4 , 10) TBonus.Create(3 , 3 , 10) End Function
TMovingX.Create(13 , 3 , - 2 , 5 , 1)
'----------------------------- main loop ----------------------------- Graphics(ScrWidth, ScrHeight)
Init_All_Bonuses()
Repeat Cls
MyLevel.Render() Flip Until KeyDown(KEY_ESCAPE) Or AppTerminate()
End
Можете поэкспериментировать с размерами платформы, сделать ее уже, типа рейки, уменьшить ширину, задать другие координаты и т.д. Кстати, эксперименты с чужим (да и своим) кодом дают большее понимание того, что в нем происходит. А теперь ответственное задание. Сделайте лифт (TmovingY). Ну чтобы вверх/вниз ездил. Думаю того, что я рассказал, достаточно для этого. Дерзайте и всё у вас получится!
|