Skip to main content
Inspiring
August 16, 2011
Question

Switching touch events from symbols/classes to the main stage?

  • August 16, 2011
  • 1 reply
  • 354 views

For previous threads:

http://forums.adobe.com/thread/864057

http://forums.adobe.com/thread/863566

http://forums.adobe.com/thread/864262

http://forums.adobe.com/thread/863597


Bug ID #2940816

I have an app that wasn't compiling correctly. I sent the bug to Adobe who responded with a workaround. However, I can't figure out how to make their stated workaround work in my code.

I have puzzle pieces on the stage. Each is assigned to a separate class. Inside the class I have touch events defining multiple touch events for each piece.

I have another spot on the stage where, when it is touched, a puzzle piece appears. These are also each linked to a separate class. Inside this class I also have touch events defining multiple touch events for each piece.

Though it works fine on my computer, it wasn't working on an iPad. Adobe said that I needed to switch the touch events so that they were assigned to the main stage instead of to each individual object.

However, the code they gave me didn't really make sense in context and I'm confused how to implement it.

This is the code in the class for each piece that is created when you touch the stage:

        public function GeoPiece(): void {
            if (PuzzleGlobals.currentLevel == "Name") {
                this.gotoAndStop("wholeName");
            }
            else if (PuzzleGlobals.currentLevel == "Abbrev") {
                this.gotoAndStop("abbrev");
            }
            else if (PuzzleGlobals.currentLevel == "Shape") {
                this.gotoAndStop("shape");
            }
            this.addEventListener(TouchEvent.TOUCH_MOVE, geoPieceBegin);
        }
       
        public function geoPieceBegin (e:TouchEvent): void {
            PuzzleGlobals.pieceActive = true;
            e.target.startTouchDrag(e.touchPointID, false);
            e.target.addEventListener(TouchEvent.TOUCH_END, geoPieceEnd);
            e.target.interactionBegin();
            MovieClip(this.parent.parent).nameDisplay.gotoAndStop(e.target.abbrev);
            PuzzleGlobals.currentPiece = e.target.abbrev;
        }
       
        public function geoPieceEnd (e:TouchEvent): void {
            PuzzleGlobals.pieceActive = false;
            if (currentObjOver.isLocked == true) {
                currentObjOver.gotoAndStop ("Lock");
            }
            else {
                currentObjOver.gotoAndStop ("Out");
            }
            MovieClip(this.parent.parent).nameDisplay.gotoAndStop(PuzzleGlobals.chosenPuzzle);
            e.target.stopTouchDrag(e.touchPointID);
            if (this.dropTarget.parent is GeoPuzzle) {
                if (GeoPuzzle(this.dropTarget.parent).abbrev == e.target.abbrev) {
                    PuzzleGlobals.statesCompletedUSA++;
                    GeoPuzzle(this.dropTarget.parent).isLocked = true;
                    GeoPuzzle(this.dropTarget.parent).gotoAndStop("Lock");
                    e.target.parent.removeChild(DisplayObject(e.target));
                }
                else {
                    //play BOOP sound indicated wrong drop;
                }
            }
            if (PuzzleGlobals.statesCompletedUSA == PuzzleGlobals.TOTAL_NUMBER_USA) {
                //play fireworks game
            }
            else {
                //do nothing
            }
            e.target.removeEventListener(TouchEvent.TOUCH_END, geoPieceEnd);
        }
       
        public function interactionBegin () {
            if (this.dropTarget != null && this.dropTarget.parent is GeoPuzzle) { //check to make sure it's over a puzzle piece
                currentObjOver = GeoPuzzle(this.dropTarget.parent);
                currentObjOver.gotoAndStop("Over");
            }
            if (lastObjOver != currentObjOver) {
                if (lastObjOver.isLocked == true) {
                    lastObjOver.gotoAndStop("Lock");
                }
                else {
                    lastObjOver.gotoAndStop("Out");
                }
                lastObjOver = currentObjOver;
            }
        }

This is the code in the class for each piece that's already on the stage:

        public function GeoPuzzle(): void {
            if (this.isLocked == true) {
                this.gotoAndStop ("Lock");
            }
            if (PuzzleGlobals.pieceActive == true) {
                this.addEventListener(TouchEvent.TOUCH_BEGIN, geoPuzzleBegin);
            }
        }
               
        public function geoPuzzleBegin (e:TouchEvent): void {
            e.target.addEventListener(TouchEvent.TOUCH_END, geoPuzzleEnd);
            e.target.gotoAndStop("Over");
            MovieClip(this.parent).nameDisplay.gotoAndStop(e.target.abbrev);
        }
       
        public function geoPuzzleEnd (e:TouchEvent): void {
            if (e.target.isLocked == false) {
                e.target.gotoAndStop("Off");
            }
            else if (e.target.isLocked == true) {
                e.target.gotoAndStop("Lock");
            }
            MovieClip(this.parent).nameDisplay.gotoAndStop(PuzzleGlobals.chosenPuzzle);
            e.target.removeEventListener(TouchEvent.TOUCH_END, geoPuzzleEnd);
        }

You can see that each piece (whether it's already locked on the stage or movable) reacts differently to different touch events. However, this is the code that Adobe gave me as a workaround:

this.stage.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchEvent);
this.stage.addEventListener(TouchEvent.TOUCH_MOVE, onTouchEvent);
this.stage.addEventListener(TouchEvent.TOUCH_END, onTouchEvent);

var beginCount:uint=0;
var moveCount:uint=0;
var endCount:uint=0;

function onTouchEvent(event:TouchEvent):void{
     switch (event.type){
          case TouchEvent.TOUCH_BEGIN:
                         trace("BEGIN")
                         beginCount++;
                         square.x = event.stageX;
                         square.y = event.stageY;
                         square.startTouchDrag(event.touchPointID, false);
                         break;
          case TouchEvent.TOUCH_MOVE:
                         trace("MOVE")
                         moveCount++;
                         break;
          case TouchEvent.TOUCH_END:
                         trace("END")
                         endCount++;
                         square.stopTouchDrag(event.touchPointID);
                         break;
     }
     trace("begin: "+beginCount+" move: "+moveCount+" end: "+endCount);
//     countText.text = "begin: "+beginCount+" move: "+moveCount+" end: "+endCount;
}

This doesn't make any sense to me because it seems that it would only work if touching the stage had to react in just a single way. I have multiple pieces that need to each react differently.

1. The pieces that are locked to the stage need to highlight when touched and display their name.

2. These pieces also need to keep themselves highlighted and their names displayed when the touch is dragged off of them instead of just removed.

3. Each piece needs to be created when touching the Puzzle Piece button the stage. As these pieces are dragged, they need to highlight the pieces underneath them and unhighlight them when they are dragged off. They also need to display their own names, and lock into place when they are dragged over the correct piece.

My questions are:

1. Why don't touch events work in the compiler?

2. How can I translate my current working code's touch events to all be directly linked to the stage instead of their objects?

Thanks so much!

Amber

This topic has been closed for replies.

1 reply

AmbariAuthor
Inspiring
August 29, 2011

I am going to copy and paste this answer into all of the forums I've asked this question in case some noob like me comes along and needs the answer.

I found the problem! After 3 months I finally figured out what was wrong and why my app was working in Device Central when exported as Flash 10.1 and not on my iPad when exported as AIR for iOS.

The problem is that in the Flash runtime, if a line of code returns a bug, the flash runtime says "Error, shmerror, try again next time." So I had one if, else statement that was executing when it wasn't supposed to be - only once, at the very beginning of the program. It was throwing an error. When I exported as Flash, flash didn't care, and still executed the code later when it was supposed to. But Apple won't let their programs crash. So instead of just trying that code again, Apple decided, after the first error was thrown, that it would then COMPLETELY IGNORE that line of code. So the error was in the line where the states would unhighlight themselves. Apple just shut down that line of code, that's why it wouldn't execute properly.

I ended up changing this line of code

if (lastObjOver != null && lastObjOver.isLocked == true)

which threw an error when the piece was FIRST dragged over the puzzle, to to this

if (lastObjOver.parent != null && lastObjOver.isLocked == true)

which wouldn't throw the error.

Problem solved!

If anyone else is having this problem, I suggest you do what I did. Change all your touch events to mouse events so you can run the program in the adc debugger. That's when I discovered the error being thrown.