Action Script 3. Как запомнить координаты последнего объекта x
Я создаю флеш игру, в которой объекты падают с неба, и игрок должен уничтожить их, нажав на них. Но у меня есть проблема, иногда они порождают друг друга. Вот пример того, что я имею в виду:
Объекты должны появляться рядом друг с другом, но не друг с другом.
Вот мои постоянные переменные:
public static const GRAVITY:Number = 3;
public static const HIT_TOLERANCE:Number = 50;
//Powerup
public static const APPLE_END_Y:Number = 640;
public static const APPLE_SPAWN_CHANCE:Number = 0.02; //per frame per second
public static const APPLE_START_Y:Number = 110;
public static const APPLE_SPAWN_START_X:Number = 50;
public static const APPLE_SPAWN_END_X:Number = 500;
//Scoring
public static const PLAYER_START_SCORE:Number = 0;
public static const SCORE_PER_APPLE:Number = 10;
Вот часть кода, где создаются объекты:
private function update(evt:Event)
{
//Spawn new apples
if (Math.random() < randomChance)
{
//spawn x coordinates
var newPirmas = new Pirmas();
newPirmas.x = Math.random() * C.APPLE_SPAWN_END_X + C.APPLE_SPAWN_START_X;
var newAntras = new Antras();
newAntras.x = Math.random() * C.APPLE_SPAWN_END_X + C.APPLE_SPAWN_START_X;
var newTrecias = new Trecias();
newTrecias.x = Math.random() * C.APPLE_SPAWN_END_X + C.APPLE_SPAWN_START_X;
var newApple = new Apple();
newApple.x = Math.random() * C.APPLE_SPAWN_END_X + C.APPLE_SPAWN_START_X;
//spawn y coordinates
newPirmas.y = C.APPLE_START_Y;
newAntras.y = C.APPLE_START_Y;
newTrecias.y = C.APPLE_START_Y;
newApple.y = C.APPLE_START_Y;
newPirmas.addEventListener(MouseEvent.CLICK, onClick);
newAntras.addEventListener(MouseEvent.CLICK, onClick);
newTrecias.addEventListener(MouseEvent.CLICK, onClick);
newApple.addEventListener(MouseEvent.CLICK, onClick);
itemsToSpawn.push(newPirmas, newAntras, newTrecias, newApple);
}
}
Как кто-то сказал: As for making sure they don't overlap, you can keep a history of their spawn points, and change how you get their random X value. Just iterate through the array of previous X values, and make sure the new one isn't within (oldX + (width/2)).
Но я не могу сделать это успешно, не могли бы вы помочь мне сохранить историю их точек появления? Большое спасибо.
1 ответ
var t:Array = [];
t[0] = [APPLE_SPAWN_START_X, APPLE_SPAWN_END_X + APPLE_WIDTH/2];
t сохранит доступные интервалы, по которым вы можете создать новое яблоко. Во время начала нет яблока, и у t есть только один интервал, звезда X интервала - APPLE_SPAWN_START_X, конец X интервала - APPLE_SPAWN_END_X + APP_WIDTH/2.
где вы хотите сгенерировать новое яблоко, вы найдете свободный интервал в t, если мы найдем интервал как mInterval(интервал может быть помещен в яблоко, значит endX - starX >= APPLE_WIDTH), тогда мы могли бы сгенерировать ваше новое яблоко,
Нам просто нужно изменить строки в вашей функции обновления, как
newPirmas.x = Math.random() * C.APPLE_SPAWN_END_X + C.APPLE_SPAWN_START_X;
Вместо
newPirmas.x = mInterval[0] + Math.random()*APPLE_WIDTH;
Когда мы устанавливаем newPirmas.x, мы ломаем mInterval и генерируем два новых интервала, значениями являются [mInterval[0],newPirmas.x] и []newPirmas.x + APPLE_WIDTH, mInterval[0]], поэтому нам нужно удалите mInterval в t и поместите два новых интервала в t.
/**
*
* @return index of available interval in target array
*/
public static function findAvailInterval(target:Array, appleWidth:int):int {
if (target == null || target.length == 0) {
return -1;
}
var endX:int = 0;
var startX:int = 0;
var length:int = target.length;
for (var i:int = 0; i < length; i++) {
var temp:Array = target[i] as Array;
if (temp == null || temp.length < 2) {
return -1;
}
startX = temp[0];
endX = temp[1];
var intervalWidth:int = endX - startX;//the interval width
if (intervalWidth >= appleWidth) {//find an available one
return i;
}
}
return -1;
}
public static function breakInterval(target:Array, appleWidth:int, index:int):int {
var temp:Array = target[index];
var startX:int = temp[0];
var endX:int = temp[1];
var width:int = endX - startX;
var availableNewXRange:int = width - appleWidth;//the apple‘s max x, and the min x is startX
//random a position
var appleX:int = startX + availableNewXRange*Math.random();
var leftInterval:Array = [startX, appleX];//the left interval of apple
var rightInterval:Array = [appleX+appleWidth, endX];//the right interval of apple
//delete temp
target.splice(index, 1);
if (isAvailableInterval(leftInterval, appleWidth)) {
target.push(leftInterval);
}
if (isAvailableInterval(rightInterval, appleWidth)) {
target.push(rightInterval);
} else {
trace("vvv");
}
return appleX;
}
private static function isAvailableInterval(interval:Array, appleWidth:int):Boolean {
if (interval == null || interval.length < 2) {
return false;
}
return (interval[1] - interval[0]) >= appleWidth;
}
Поместите три функции в класс A
var target:Array = [[0, 1000]];
var appWidth:int = 80;
for (var i:int = 0; i < 4; i++) {
var index:int = A.findAvailInterval(target, appWidth);
if (index != -1) {
var interval:Array = target[index];
RR.breakInterval(target, appWidth, index);
trace(interval);
}
}