【问题标题】:How to check if user clicked on smaller object before larger object?如何检查用户是否在较大对象之前点击了较小的对象?
【发布时间】:2015-04-14 03:21:10
【问题描述】:

大家好,我目前正在开发一款游戏,目标是让用户点击舞台上的对象。但是在用户点击较小的对象之前,用户必须先点击最大的对象。我想让它如果用户先点击一个较小的对象而不是较大的对象,那么游戏就会结束。我想我可以为舞台上的每个对象设置布尔值,但我的 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。

这是与我的主要 ENTER_FRAME 侦听器相关联的 if 语句:

    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 为真,表示它已被点击,而 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();
             }
         }

    }

【问题讨论】:

  • 抱歉,我认为我可以接受这两个答案。它声明检查您是否接受或它作为解决方案的一部分有所帮助。我重新检查了你的谢谢 LDMS
  • 不用担心,只要确保没有您认为有问题的地方

标签: actionscript-3 if-statement boolean flash-cs6 boolean-logic


【解决方案1】:

可能无法正常工作,因为您的最终else if 语句将永远无法到达(因为您之前正在处理b2 == true,然后将绕过所有其他其他语句)。再加上你在之前处理它时将 b2 设置为 false,所以在它得到你的最终语句时它总是为 false。

在检查其他内容之前,您需要移动最后的 else if。见代码 cmets:

    //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();
        }
    }
}

【讨论】:

  • 嘿@LDMS 感谢您的回复。由于某种原因,if 语句仍然被调用:/。我打算实现您写出的第二种方法,但它不会考虑到用户必须始终先单击较大的框,即 box_1 在用户单击任何其他较小的框之前。
  • 当然可以。只要您的数组在顶部按从大到小的顺序排列
  • 非常感谢您的详细回答。我刚刚接受了你的回答。我收到的只有一个错误“无法访问空对象引用的属性或方法”。我相信这与没有可用的盒子有关。我将它设置为已经将盒子添加到舞台的位置,更具体地说是另一个名为“mainScreen”的电影剪辑,然后从那个屏幕我只是引用这些盒子,因为我的代码显示“box_1,等等......”有什么我应该做不同的事情来避免这个错误?再次感谢
  • 等等,也许它毕竟与那个无关。我相信这与我如何设置阵列有关。我正在使用 Flash 开发,所以我在“扩展电影剪辑”的地方添加: private var aBoxesArray:Array;然后在我的构造函数中,我像这样启动它: aBoxesArray = [box_1, box_2, box_3, box_4];这是正确的做法吗?
  • 这是一种完全可以接受的方式,是的,只要所有这些框都存在于那时。如果您通过代码创建盒子,那么最好在循环中进行。如果添加了 pastebin 链接或更新了问题以包含您的整个班级,我可以更好地评论它
【解决方案2】:
//Store your clips in an array
var myClips:Array = [mc1,mc2,mc3,mc4];

//get the clip sizes and store it to an array.
var sizes:Array = new Array();
for (var i:uint = 0; i < myClips.length; i++) {
    sizes.push(myClips[i].width);
}

//apply Numeric array sort. 
sizes.sort(Array.NUMERIC);
function onClickAction(e:MouseEvent):void { 
    //Check wheather the array is empty or not.
    if (sizes.length != 0) {
        //Check wheather the clicked object bigger or not.
        if (e.target.width == sizes[sizes.length - 1]) {
            trace("Bigger");
            e.target.alpha = .5;
            sizes.splice(sizes.length-1,1);         
        } else {
            trace("Smaller");
        }
    }
}

【讨论】:

  • 非常感谢您的评论。我现在要尝试实施它,看看是否一切正常,回来告诉你进展如何,谢谢@Benny
  • 嘿,Benny,我似乎遇到的唯一问题是当我添加这个 '.width;'到'aSizesArray.push(aBoxesArray[i].width);'我收到此错误无法访问空对象引用的属性或方法。
  • 我在上面上传了一张图片,展示了我如何在 Flash Develop 中使用你的方法
猜你喜欢
  • 1970-01-01
  • 2016-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 1970-01-01
  • 2018-03-12
相关资源
最近更新 更多