При разработке игры часто бывает нужно расположить объекты в виде сетки. Это может быть меню выбора уровня, меню с заработанными медальками, инвентарь или внутриигровой магазин.
Для начала нам понадобится сам объект, который мы будем расставлять по сетке. DefaultItem это обычный спрайт с текстовым полем, чтобы быть уверенным, что элементы расположены именно в таком порядке какой нам нужен.
Сетка предназначена для объектов с нулевой точкой регистрации и при отрисовке нашего спрайта нужно об этом помнить. Сам спрайт будет шириной и высотой в 72px.
Код DefaultItem.as
package {
import flash.display.*;
import flash.text.*;
import flash.geom.*;
public class DefaultItem extends Sprite {
private const COLOR:uint = 0x900000;
private const WIDTH:int = 72;
private const HEIGHT:int = 72;
public var label:TextField;
public function DefaultItem(labelText:String = "") {
graphics.beginFill(COLOR);
graphics.drawRect(-WIDTH * 0.5, -HEIGHT * 0.5, WIDTH, HEIGHT);
graphics.endFill();
label = new TextField();
label.autoSize = TextFieldAutoSize.CENTER;
label.defaultTextFormat = new TextFormat("Tahoma", 14, 0xFFFFFF);
label.text = labelText;
label.x = -label.width * 0.5;
label.y = -label.height * 0.5;
addChild(label);
}
}
}
Для самой сетки нам понадобятся набор параметров определяющий внешний вид отображения.
- GRID_WIDTH - количество элементов по горизонтали
- GRID_HEIGHT - количество элементов по вертикали
- GRID_POSITION_X - центр сетки по горизонтали
- GRID_POSITION_Y - центр сетки по вертикали
- SPACING - расстояние между элементами
- CELL_WIDTH - ширина ячейки
- CELL_HEIGHT - высота ячейки
Сам ролик будет размером 640x480 и сетка будет располагаться строго по центру.
Код Grid.as
package {
import flash.display.*;
import flash.events.*;
[SWF(width="640", height="480", backgroundColor="0x222222", frameRate="30")]
public class Grid extends Sprite {
private const GRID_POSITION_X:int = 320;
private const GRID_POSITION_Y:int = 240;
private const GRID_WIDTH:int = 6;
private const GRID_HEIGHT:int = 3;
private const CELL_WIDTH:int = 72;
private const CELL_HEIGHT:int = 72;
private const SPACING:int = 2;
public function Grid() {
var cellWidth:int = CELL_WIDTH + SPACING;
var cellHeight:int = CELL_HEIGHT + SPACING;
var ofsetX:Number = GRID_POSITION_X - (GRID_WIDTH * cellWidth) * 0.5;
var ofsetY:Number = GRID_POSITION_Y - (GRID_HEIGHT * cellHeight) * 0.5;
var inc:int = 1;
for (var i:int = 0; i < GRID_HEIGHT; i++) {
for (var j:int = 0; j < GRID_WIDTH; j++) {
var cx:Number = ofsetX + j * cellWidth;
var cy:Number = ofsetY + i * cellHeight;
cx = cx + cellWidth * 0.5;
cy = cy + cellHeight * 0.5;
var item:DefaultItem = new DefaultItem("Item "+inc);
item.x = cx; item.y = cy;
addChild(item);
inc++;
}
}
}
}
}
Так как у нас при построении сетки идет двойной цикл - в коде есть переменая inc, которая начинается с единицы и прибавляется на одну единицу при создании очередного элемента, помогая нам указывать какой именно по счету элемент был добавлен.
Теперь можно протестировать ролик и посмотреть результат:
Дополнение: у нас в сетке 6*3 = 18 элементов. Как быть если в сетке должно располагаться, к примеру, 15 элементов? Сделать это довольно просто. Нам нужна еще одна константа с максимальным количеством элементов:
private const TOTAL_ITEMS:int = 15;
После этого нужно добавить еще одну строчку в код, как раз перед добавлением элемента:
if (inc > TOTAL_ITEMS) continue;
Таким образом новые объекты уже не будут добавляться. Тестируем: