Zmiana położenia Objektów
Ostatnio potrzebowałem losowego rozmieszczania obiektów, w pionie lub poziomie. Postanowiłem napisać klasę która będzie uniwersalna i będę mógł ją wykorzystywać wielokrotnie. Padło pytanie jakie wymogi musi spełniać:
- Najlepiej jak nie będę musiał tworzyć instancji klasy.
- Powinienem mieć możliwość wybrania rozmieszczania pionowo lub poziomo.
- Obiekty nie powinny na siebie nachodzić oraz powinny być od siebie oddalone w odpowiedniej odległości.
- Obiekty nie będą miały tych samych wymiarów więc dla każdego z nich wysokość i szerokość będzie różna.
- Granica rozmieszczenia, by obiekty nie wychodziły poza ekran.
- Losowe lub nie rozmieszczanie obiektów.
Mam wymogi jakie ma spełniać klasa więc zaczynam pisać
public class Mieszaj {
domyślna odległość między obiektami ustawiłem na 10
private static var odstep:Number = 10;
domyślna granica rozmieszczania ustawiłem na 3000
private static var granica:Number = 3000;
domyślnie losuje elementy, ale nie muszę
private static var losowe:String = "tak";
inicjuje wysokość i szerokość elementów
private static var wysokoscElementu:Number = 0;
private static var szerokoscElementu:Number = 0;
By nie pomylić się przy wywoływaniu i ograniczyć pomyłki pion i poziom są osobno wywoływane.
Mieszanie poziome i pionowe praktycznie niczym się nie będzie różnić dlatego opiszę tylko pierwsze z nich.
public static function poziomo (obiekty:Array, obj:Object = null):Array {
Sprawdzam czy jest obiekt z danymi
if (obj != null) {
Jeżeli jest, szukam w nim interesujących mnie danych.
if (obj.odstep) {
odstep = obj.odstep;
}
if (obj.granica && Number(obj.granica) !=0) {
granica = obj.granica;
}
if (obj.losowe) {
losowe = obj.losowe;
}
}
Potrzebna będzie tablica w której przetrzymywać będę indeksy obiektów.
var nowa:Array;
if (losowe == "tak") {
Jeżeli mają to być losowe liczby używam klasy specjalnie stworzonej do tego celu.
nowa = TablicaRandom.random(obiekty.length);
} else {
Gdy nie losujemy, tablica będzie zawierać indeksy w rosnącej kolejności.
nowa = tablicaBezLosowania(obiekty.length);
}
Inicjuje zmienną w której będę przetrzymywać poprzedni index. Mógłbym oczywiście za każdym razem brać wartość z tablicy, ale dla jasności kodu ją inicjuje.
var poprzedni:Number;
Nowa zmienna w której będę przechowywał wartość y obiektów ze sceny. Zmienna przyda się do ustawienia obiektu który będzie przekraczać granice.
var yy:Number = 0;
Tyle ustawień, teraz zaczynamy zabawę
Lecimy po tablicy obiektów
for (var i = 0; i < obiekty.length; i++) {
Jeżeli jest to pierwszy element to:
if (i==0) {
ustawiamy x
obiekty[nowa[i]].x = 0;
i y na 0
obiekty[nowa[i]].y = 0;
Jeżeli to kolejny obiekt to:
} else {
Położenie x zależy od położenie oraz szerokości poprzedniego elementu
obiekty[nowa[i]].x = obiekty[poprzedni].x + obiekty[poprzedni].width + odstep;
natomiast y jest równe zmiennej yy
obiekty[nowa[i]].y = yy;
}
Jezeli x + szerokość obiektu przekroczą naszą granicę
if ((obiekty[nowa[i]].x + obiekty[nowa[i]].width) > granica) {
To ustawiamy jego x na 0
obiekty[nowa[i]].x = 0;
oraz przesuwamy względem osi Y o wysokość największego elementu z poprzedniego rzędzie oraz dodajemy do tego odstęp
yy = yy + wysokoscElementu + odstep;
obiekty[nowa[i]].y = yy;
zerujemy wysokość dla następnego rzędu
wysokoscElementu = 0;
}
i szukamy w nowym rzędzie najwyższego elementu
if (wysokoscElementu < obiekty[nowa[i]].height) {
Jeżeli taki znajdziemy to zapisujemy jego wysokość
wysokoscElementu = obiekty[nowa[i]].height;
}
oraz zapamiętujemy nasz obiekt jako poprzedni dla następnej pętli
poprzedni = nowa[i];
}
zwracamy tablicę.
return nowa;
I to tyle. Trochę pisania i mam klasę która pomoże mi na pewno wiele razy
Przykład:

