Как проверить, щелкнул ли пользователь меньший объект перед большим объектом?

Привет всем, сейчас я работаю над игрой, и цель состоит в том, чтобы пользователь нажимал на объекты на сцене. Но пользователь должен сначала щелкнуть самые большие объекты, прежде чем пользователь щелкнет по меньшим объектам. Я хотел сделать так, чтобы если пользователь сначала нажимал на меньший объект, а не на больший, то игра заканчивалась. Я думал, что могу настроить это с помощью логических значений для каждого объекта на сцене, но мои операторы if не сокращают его здесь, как я это настроил:

Вот мои объекты и логические значения, которые я использую:

//Add box references
    public var box_1:MovieClip;
    public var box_2:MovieClip;
    public var box_3:MovieClip;
    public var box_4:MovieClip;

    //Booleans
    private var b1:Boolean;
    private var b2:Boolean;
    private var b3:Boolean;
    private var b4:Boolean;

теперь я устанавливаю для всех логических значений значение false, и если пользователь нажимает на один из объектов, я устанавливаю для логического значения значение true.

Вот мои операторы if, привязанные к моему основному слушателю ENTER_FRAME:

    private function level_1():void 
    {

        if (b1)
        {
            mainScreen.box_1.gotoAndPlay("B1GONE");
            b1 = false;
        }else
        if (b2)
        {
            mainScreen.box_2.gotoAndPlay("B2GONE");
            b2 = false;
        }else
        if (b3)
        {
            mainScreen.box_3.gotoAndPlay("B3GONE");
            b3 = false;
        }else
        if (b2 && !b1)
        {
            endGameCondition();
        }

    }

По этому заявлению:

if (b2 && !b1)
        {
            endGameCondition();
        }

Я пытался заявить, что если box_2 имеет значение true, что означает, что на него нажали, а на box_1 еще не нажали, что является более крупным объектом, то игра окончена из-за того, что пользователь сначала не нажал на самый большой объект. Я настроил его так, чтобы box_1 был самым большим объектом, а остальные были на следующий размер меньше.

Может ли кто-нибудь понять, почему это работает неправильно или есть лучший способ сделать это?

**** ОБНОВИТЬ КАК УСТАНОВЛЕН МОЙ ОСНОВНОЙ КЛАСС СЕЙЧАС **************

Где я добавляю все свои видеоклипы и переменные:

public class boxTapEngine extends MovieClip 
{

    //Screens
    private var mainScreen:mcMainScreen;



    //Add box references
    public var box_1:MovieClip;
    public var box_2:MovieClip;
    public var box_3:MovieClip;
    public var box_4:MovieClip;


    private var aBoxesArray:Array;

в моей функции конструктора:

         aBoxesArray = [box_1, box_2, box_3, box_4];

        //AddMainScreen
        mainScreen = new mcMainScreen();
        mainScreen.x = (stage.stageWidth / 2);
        mainScreen.y = (stage.stageHeight / 2);
        stage.addChild(mainScreen);

        //Initiate numbers
        nLevel = 1;

        for each(var box:MovieClip in aBoxesArray)
        {
            box.addEventListener(MouseEvent.CLICK, boxClick);
        }

наконец, в функции boxClick:

private function boxClick(e:MouseEvent):void 
    {

         var box:MovieClip = e.currentTarget as MovieClip; //get a reference to one that was just clicked
         box.mouseEnabled = false; //we'll use this as a flag to know if it's been clicked yet
         box.gotoAndPlay("BGONE");


          //check to see if previous boxes have been clicked.
         //this will iterate through all the boxes in order
         for (var i:int = 0; i < aBoxesArray.length; i++)
         {
             if(aBoxesArray[i] == box) return; //if we've reached the currently clicked box, all is good, no need to keep checking so let's exit this loop and function
             if (!aBoxesArray[i].mouseEnabled)
             { //one of the previous boxes hasn't been clicked yet
                 endGameCondition();
             }
         }

    }

person Nathan    schedule 14.04.2015    source источник
comment
Извините, думал, что могу принять оба ответа. В нем говорится, чтобы проверить, принимаете ли вы или это помогло как часть решения. Я перепроверил ваше спасибо LDMS   -  person Nathan    schedule 16.04.2015
comment
Не беспокойтесь, просто убедитесь, что вы не чувствуете, что что-то не так.   -  person BadFeelingAboutThis    schedule 16.04.2015


Ответы (2)


Вероятно, это не работает, потому что ваш окончательный оператор else if никогда не будет достигнут (потому что вы обрабатываете b2 == true ранее, что затем обходит все остальные операторы else). Плюс вы устанавливаете b2 в false, когда вы обрабатываете его ранее, поэтому он всегда будет ложным к тому времени, когда он получит ваше окончательное утверждение.

Вам нужно переместить этот финал еще, если, прежде чем вы проверите другие вещи. См. комментарии к коду:

    //Do this first, and not as a else if
    if (b2 && !b1){
        endGameCondition();
        return; //no need to check checking things if it's game over
    }

    //now you can do the rest
    if (b1)
    {
        mainScreen.box_1.gotoAndPlay("B1GONE");
        b1 = false;
    }else
    if (b2)
    {
        mainScreen.box_2.gotoAndPlay("B2GONE");
        b2 = false;
    }else
    if (b3)
    {
        mainScreen.box_3.gotoAndPlay("B3GONE");
        b3 = false;
    }

Кроме того, вам не нужен обработчик ввода кадра, вы можете просто проверить все по щелчку. Что-то вроде этого будет работать:

var boxes:Array = [box_1,box_2,box_3,box_4]; //make sure this is in order of what needs to be clicked first

//if you wanted to actually sort them dynamically based off total size (regardless of what order you've stuffed them in the array), you could add in something like this, which will order them from biggest to smallest:
boxes.sort(function(a,b){
    //compare which item has a greater total area (width * height)
    if(a.width * a.height > b.width * b.height) return -1; //A is bigger, so put a before b in the array
    if(a.width * a.height < b.width * b.height) return 1; //put b before a in the array
    return 0; //return 0 if they are the same
});




for each(var box:MovieClip in boxes){
    box.addEventListener(MouseEvent.CLICK, boxClick,false,0,true);
}

function boxClick(e:Event):void {
    var box:MovieClip = e.currentTarget as MovieClip; //get a reference to one that was just clicked

    box.mouseEnabled = false; //we'll use this as a flag to know if it's been clicked yet
    box.gotoAndPlay("BGONE");

    //or you could just do this to get rid of the box:
    if(box.parent) box.parent.removeChild(box);

    //check to see if previous boxes have been clicked.
    //this will iterate through all the boxes in order
    for(var i:int=0;i<boxes.length;i++){
        if(boxes[i] == box) return; //if we've reached the currently clicked box, all is good, no need to keep checking so let's exit this loop and function
        if(!boxes[i].mouseEnabled){ //one of the previous boxes hasn't been clicked yet
            endGameCondition();
        }
    }
}
person BadFeelingAboutThis    schedule 14.04.2015
comment
Привет, @LDMS, спасибо за ответ. По какой-то причине оператор if все еще вызывается :/. Я собирался реализовать второй метод, который вы написали, но он не принял во внимание, что пользователь всегда должен сначала щелкнуть по большему полю, то есть по полю_1, прежде чем пользователь нажмет на любые другие меньшие поля. - person Nathan; 14.04.2015
comment
Конечно, это так. Пока ваш массив вверху находится в порядке от наибольшего к наименьшему - person BadFeelingAboutThis; 14.04.2015
comment
Большое спасибо за подробный ответ. Я только что принял твой ответ. Есть только одна ошибка, которую я получаю Не могу получить доступ к свойству или методу нулевой ссылки на объект. Я думаю, что это связано с отсутствием коробок. Я настроил его так, чтобы поля уже были добавлены на сцену, а точнее другой клип с именем mainScreen, затем с этого экрана я просто ссылаюсь на поля, поскольку мой код показывает box_1 и т. д. Есть ли что-то, что я должен делать по-другому? избежать этой ошибки? Спасибо еще раз - person Nathan; 16.04.2015
comment
Подождите, может быть, это не имеет никакого отношения к этому в конце концов. Я считаю, что это связано с тем, как я настроил массив. Я использую flash development, поэтому там, где он расширяет мувиклип, я добавляю: private var aBoxesArray:Array; Затем в моей функции-конструкторе я инициирую ее следующим образом: aBoxesArray = [box_1, box_2, box_3, box_4]; Это правильный способ сделать это? - person Nathan; 16.04.2015
comment
Да, это вполне приемлемый способ, пока все эти ящики существуют на тот момент. Если вы создаете блоки с помощью кода, было бы еще лучше просто сделать это в цикле. Если бы вы добавили ссылку pastebin или обновили вопрос, включив в него весь ваш класс, я мог бы лучше его прокомментировать. - person BadFeelingAboutThis; 16.04.2015
comment
Хорошо, только что обновил вопрос. Внизу я добавил, как у меня настроены все мои видеоклипы и переменные, а также как я реализовал ваш код, спасибо за это! - person Nathan; 16.04.2015
comment
Как вы создаете экземпляры ящиков? Вы используете временную шкалу FlasPro? - person BadFeelingAboutThis; 16.04.2015
comment
Да. У меня есть поля, размещенные на временной шкале моего видеоклипа mainScreen в первом кадре. Вот где я дал им имена их экземпляров box_1 и т. д. - person Nathan; 16.04.2015
comment
Подождите, я, наконец, понял это, я забыл, что мне нужно было ссылаться на него, например mainScreen.box_1. Еще раз спасибо за вашу помощь! - person Nathan; 16.04.2015
comment
О, хорошо, тогда просто добавьте к ним префикс mainScreen. например. mainScreen.box_1 . ваш mainScreen var должен быть общедоступным, я думаю, иначе вы можете получить ошибку о том, что он конфликтует с вашим именем экземпляра FlashPro - person BadFeelingAboutThis; 16.04.2015
comment
Да, я только что понял это, ха-ха. Я идиот, я делал это раньше, но я получил сообщение об ошибке, потому что инициировал массив, а затем добавил главный экран на сцену, когда я должен был сделать обратное, спасибо, LDMS, ваш лучший человек. - person Nathan; 16.04.2015
comment
Рад, что у вас все получилось! Удачи с остальной частью вашего приложения - person BadFeelingAboutThis; 16.04.2015

person    schedule
comment
Круто! Большое спасибо за этот комментарий. Я попытаюсь реализовать это прямо сейчас и посмотрю, все ли получится, я вернусь и дам вам знать, как все идет, спасибо @Benny - person Nathan; 14.04.2015
comment
Эй, Бенни, кажется, единственная проблема, с которой я столкнулся, это когда я добавляю этот '.width;' в ' aSizesArray.push(aBoxesArray[i].width);' Я получаю эту ошибку. Не удается получить доступ к свойству или методу нулевой ссылки на объект. - person Nathan; 14.04.2015
comment
Я загрузил картинку выше, показывающую, как я использую ваш метод с Flash Develop. - person Nathan; 14.04.2015