Функция движения и удаления блоков, вызывается в кадре:

Код:
// UPDATE BLOCKS
private function update_blocks(): void {
// двигаем и удаляем блоки
var bl:uint = _blocks.length - 1;
var b:Block;
// двигаем и удаляем блоки
for (var i:int=bl;i>=0;i--){
b = _blocks[i];
b.x-=_hero.vx //вместо героя двигаем блоки со скоростью героя *-1
//удаляем блоки, которые оказались за пределами экрана, из массива и со cцены
if (b.x < -180) {
b.free(); // внутренняя чистка блока
_blocks.splice(i, 1);
i--;
//каждый раз при удалении блока проверяем количество оставшихся блоков
if (bl<14) {addWave()} // если блоков меньше 14 - создаём новую партию блоков
}
}
}
Партии (в коде я называю их волнами) блоков при создании записываются в массив
private var _waves:Vector.<Vector.<uint>>; //двухмерный вектор с числами
Это нужно для того, чтобы при необходимости создать заново уже удалённые блоки (т.е. вернуться к какому-нибудь чекпойнту).
За 1 раз создаётся 10 блоков - это и есть волна. Каждому из 10 блоков случайным образом (но с некоторыми ограничениями) присваивается определённый тип:

Код:
// Создание волны
private function addWave():void {
// максимальный тип блока (пока рассматриваем только типы 0 и 1. Чем дальше играть, тем больше будет типов)
var maxType:uint;
// проверяем номер волны
var waveNumber:uint = _waves.length; // в начале игры массив волн пуст
// в первых трёх волнах все блоки (т.е. первые 30 блоков) типа 0
if (waveNumber == 0) {
maxType = 0; // тип блока может быть только 0
//заполняем первые три ячейки массива волн векторами с 10 типами для присвоения создаваемым функцией addBlocks() блокам
for (var k:int = 0; k < 3; k++) {
_waves[_waves.length] = new <uint>[0,0,0,0,0,0,0,0,0,0];
addBlocks(_waves.length-1);
}
} else {
// проверка доступных типов по номеру волны
if (waveNumber >= 3) { maxType = 1 }; // с четвёртой волны появлется тип 1
// временный вектор для вычислений (потом приравняем его к вектору волн)
var tempVector:Vector.<uint> = new < uint > [0,0,0,0,0,0,0,0,0,0];
var tvl:uint = tempVector.length; // длина вектора
var testee:uint; // число-кандидат
var traps:uint = 0; // общее количество типов, отличных от 0 (ловушек)
var traps1:uint = 0; // количество единиц
trace('Проверяем каждый блок')
// перебор каждого блока
for (var j:int = 0; j < tvl; j++) {
trace('Блок '+j)
// выбираем случайное число в пределах доступного максимума типа
testee = MyMath.randomRange(0, maxType);
trace('Случайно выпало число '+testee+', проверяем, подойдёт ли оно')
// допустимое количество ловушек подряд зависит от выпавшего типа
var inarow:uint;
switch (testee) {
case 1: inarow=3; break; // блоков типа 1 может быть только 3 подряд
default: inarow = 0; break;
}
trace('Максимальное число ловушек типа '+testee+' - '+inarow)
// если выпал ноль, оставляем так, если нет - проверяем дальше
if (testee != 0) {
trace('Выпал не ноль, поэтому продолжаем проверку')
// если это первая или последняя ячейка, то ставим ноль
if ((j == 0) || (j == tvl - 1)) {
trace('Ячейка является первой или последней (вот доказательство: j='+j+'), поэтому ставим ноль')
testee = 0;
} else {
trace('Ячейка не является первой или последней (вот доказательство: j='+j+'), поэтому продолжаем')
// если ловушек меньше шести - проверяем дальше
if (traps < 6) {
trace('Ловушек ещё меньше 6 (их на самом деле '+traps+'), поэтому продолжаем')
// если блоков типа 1 меньше 6 - проверяем дальше
if (traps1 < 6) {
trace('Блоковтипа 1 меньше 6 (их на самом деле '+traps1+'), поэтому продолжаем')
// проверяем предыдущие клетки (если подряд уже стоит нужное количество - ставим 0)
// нет смысла проверять ячейки 0-2, т.к. 0 всегда пустая, а 1 и 2 никогда не будут третьей подряд
// начинаем проверять с ячейки 3, если максимум подряд 2, с 4, если 3 и т.д.
if (j > (1 + inarow)) {
trace('Индекс проверяемой ячейки ' + j + ', а максимально в ряд может быть ' + inarow + ', поэтому имеет смысл проверять текущую ячейку, т.к. перед ней стоит ' + j + ' ячеек, одна из которых точно нулевая (первая)')
traps++
traps1++
trace('Но пока не стал проверять предыдущие ячейки, а просто оставил всё как есть и прибавил счётчик ловушек - теперь их '+traps+', a блоков типа 1 - '+traps1)
// в противном случае не проверяем предыдущие ячейки
} else {
trace('Индекс проверяемой ячейки ' + j + ', а максимально в ряд может быть ' + inarow + ', поэтому нет смысла проверять текущую ячейку, т.к. перед ней стоит ' + j + ' ячеек, одна из которых точно нулевая (первая)')
traps++;
}
// если блоков с номером 1 уже 6 - ставим 0
} else {
trace('Блоков типа 1 уже '+traps1+', поэтому мы ставим ноль')
testee = 0;
}
// если ловушек уже 6 - ставим ноль
} else {
trace('Ловушек всего уже '+traps+', поэтому мы ставим ноль')
testee = 0;
}
}
} else {
trace('Так как выпал ноль, мы просто оставили всё, как есть')
}
trace('В итоге, после всех проверок проверяемое число testee='+testee)
// присваиваем ячейке тестового вектора получившееся значение
tempVector[j] = testee;
trace('Ячейке временного вектора tempVector[j] присвоено полученное значение, теперь tempVector[j]=' + tempVector[j])
trace('Весь временный вектор на данном этапе выглядит вот так: tempVector='+tempVector)
}
// после того, как присвоили значения всем ячейкам, приравниваем очередную волну из массива волн к расчётному вектору
_waves[_waves.length] = tempVector;
addBlocks(_waves.length - 1); // добавляем 10 блоков, передав ссылку на нужный вектор, который будет картой типов для создаваемой волны
}
// проверяем список волн и типы блоков в них
for (var i:int = 0; i < _waves.length; i++) { trace('wave ' + i + ': ' + _waves[i]) };
// при создании объектов героя ставим всегда наверх
setChildIndex(DisplayObject(_hero), numChildren-1);
}
Таким образом, в вектор с волнами мы добавили волну (вектор с числами), которую будем использовать как карту типов при создании блоков:

Код:
// Создание блоков по указанному массиву вектора волн
/**
*
* @param wl номер волны для присвоения типа
*/
private function addBlocks(wl:uint):void {
// точка отсчёта для создаваемой волны: либо 0 (если первая), либо x последнего блока
var sx:int = (_blocks.length>0)?(_blocks[_blocks.length-1].x):(0);
// помещаем в массив блоков 10 экземпляров блоков
for (var b:uint = 0; b < 10; b++) {
// суём в массив новый блок, смещая его по x относительно предыдущего, а по оси y просто ставим на уровень земли
// присваиваем создаваемому блоку тип из массива волн
_blocks.push(addChild(new Block(sx+BlockW*(b+1), GL,_waves[wl][b])));
};
}
Буду признателен за советы по оптимизации системы генерации блоков и их типов.
Про использование пула понял, пока читаю про него и пытаюсь понять, как им пользоваться.