Issue with removing eventlistener in actionscript - android

I'm not new to flash, but I'm a bit of a noob with actionscript, trying to build an app in flash pro (or rather, animate cc) which will (hopefully) teach the users music theory (how to read music, etc.). What I want is to have different lessons on separate frames, with separate "screens" which the user can swipe through. I'm using multiple copies of the swipe code which adobe provides in their swipe gallery template.
On frame 5, I use the following:
stop()
Multitouch.inputMode = MultitouchInputMode.GESTURE;
var currentGalleryItem:Number = 1;
var totalGalleryItems:Number = 10;
stage.addEventListener (TransformGestureEvent.GESTURE_SWIPE, fl_SwipeToGoToNextPreviousFrameB);
function fl_SwipeToGoToNextPreviousFrameB(event:TransformGestureEvent):void
{
if(event.offsetX == 1)
{
if(currentGalleryItem > 1){
currentGalleryItem--;
slideRight();
}
}
else if(event.offsetX == -1)
{
if(currentGalleryItem < totalGalleryItems){
currentGalleryItem++;
slideLeft();
}
}
}
var slideCounter:Number = 0;
function slideLeft(){
lsn112.addEventListener("enterFrame", moveGalleryLeft);
}
function slideRight(){
lsn112.addEventListener("enterFrame", moveGalleryRight);
}
function moveGalleryLeft(evt:Event){
lsn112.x -= 128;
slideCounter++;
if(slideCounter == 10){
lsn112.removeEventListener("enterFrame", moveGalleryLeft);
slideCounter = 0;
}
}
function moveGalleryRight(evt:Event){
lsn112.x += 128;
slideCounter++;
if(slideCounter == 10){
lsn112.removeEventListener("enterFrame", moveGalleryRight);
slideCounter = 0;
}
}
Home112.addEventListener(MouseEvent.CLICK, fl_ClickToGoToAndStopAtFrame_22);
function fl_ClickToGoToAndStopAtFrame_22(event:MouseEvent):void
{
gotoAndStop(2);
}
stop()
Frame 6 is almost identical, just with different names for variables, functions, etc.:
stop()
Multitouch.inputMode = MultitouchInputMode.GESTURE;
var currentGalleryItemA:Number = 1;
var totalGalleryItemsA:Number = 11;
stage.addEventListener (TransformGestureEvent.GESTURE_SWIPE, fl_SwipeToGoToNextPreviousFrameA);
function fl_SwipeToGoToNextPreviousFrameA(event:TransformGestureEvent):void
{
if(event.offsetX == 1)
{
if(currentGalleryItemA > 1){
currentGalleryItemA--;
slideRightA();
}
}
else if(event.offsetX == -1)
{
if(currentGalleryItemA < totalGalleryItemsA){
currentGalleryItemA++;
slideLeftA();
}
}
}
var slideCounterA:Number = 0;
function slideLeftA(){
lsn113.addEventListener("enterFrame", moveGalleryLeftA);
}
function slideRightA(){
lsn113.addEventListener("enterFrame", moveGalleryRightA);
}
function moveGalleryLeftA(evt:Event){
lsn113.x -= 128;
slideCounterA++;
if(slideCounterA == 10){
lsn113.removeEventListener("enterFrame", moveGalleryLeftA);
slideCounterA = 0;
}
}
function moveGalleryRightA(evt:Event){
lsn113.x += 128;
slideCounterA++;
if(slideCounterA == 10){
lsn113.removeEventListener("enterFrame", moveGalleryRightA);
slideCounterA = 0;
}
}
Home113.addEventListener(MouseEvent.CLICK, fl_ClickToGoToAndStopAtFrame_23);
function fl_ClickToGoToAndStopAtFrame_23(event:MouseEvent):void
{
gotoAndStop(2);
}
stop()
There is also a button as part of the movieclip "lsn112" which is being swiped. Don't know if this is relevant or not, but the code is:
stop();
fwdtest.addEventListener(MouseEvent.CLICK, GoRootNext112);
function GoRootNext112(event:MouseEvent):void
{
MovieClip(root).nextFrame();
}
It works fine to a point, but I think an eventlistener is not being removed properly. When the user swipes through the gallery, it works as expected. They can then move onto the next gallery, which also works as expected. No errors so far. However, if they then go back to the menu, and then back to the gallery, I get an error code 1009:
TypeError: Error #1009: Cannot access a property or method of a null
object reference. at
MusicTheorySwipe_fla::MainTimeline/slideRightA()[MusicTheorySwipe_fla.MainTimeline::frame6:32]
at
MusicTheorySwipe_fla::MainTimeline/fl_SwipeToGoToNextPreviousFrameA()[MusicTheorySwipe_fla.MainTimeline::frame6:16]
at runtime::ContentPlayer/simulationSendGestureEvent() at
runtime::SimulatedContentPlayer/clientSocketDataHandler()
What confuses me is that I am using frame 5 at this point, yet I get an error referencing frame 6. It appears to me that flash is attempting to send a gesture to the eventlistener in frame 6, even though I'm on frame 5, which I'm guessing is down to an eventlistener not being removed. However, being new to code, I don't know when to remove the eventlistener without breaking the code.
Here's a link to a zip containing the relevant .fla, .swf and .xml files.
http://speedy.sh/5JP7c/MusicTheorySwipe.zip
As this is the method I would like to use over many, many frames, I would really appreciate your time and help in resolving this.
EDIT
Ok, I've simplified the code as best I can, to try and eliminate any suspects.
Frame 5:
Multitouch.inputMode = MultitouchInputMode.GESTURE;
stage.addEventListener(TransformGestureEvent.GESTURE_SWIPE , onSwipeA);
var currentGalleryItemA:Number = 1;
var totalGalleryItemsA:Number = 5;
function onSwipeA (e:TransformGestureEvent):void{
//User swiped towards right
if (e.offsetX == 1) {
if(currentGalleryItemA > 1){
currentGalleryItemA--;
lsn113.x += 1280;
}
}
//User swiped towards left
if (e.offsetX == -1) {
if(currentGalleryItemA < totalGalleryItemsA){
currentGalleryItemA++;
lsn113.x -= 1280;
if(currentGalleryItemA == totalGalleryItemsA){
nextFrame()
}
}
}
}
stop();
Frame 6:
stage.removeEventListener(TransformGestureEvent.GESTURE_SWIPE , onSwipeA);
Multitouch.inputMode = MultitouchInputMode.GESTURE;
stage.addEventListener(TransformGestureEvent.GESTURE_SWIPE , onSwipeB);
var currentGalleryItemB:Number = 1;
var totalGalleryItemsB:Number = 11;
function onSwipeB (e:TransformGestureEvent):void{
//User swiped towards right
if (e.offsetX == 1) {
if(currentGalleryItemB > 1){
currentGalleryItemB--;
lsn112.x += 1280;
}
}
//User swiped towards left
if (e.offsetX == -1) {
if(currentGalleryItemB < totalGalleryItemsB){
currentGalleryItemB++;
lsn112.x -= 1280;
}
if(currentGalleryItemB == totalGalleryItemsB){
nextFrame()
}
}
}
stop();
And that's all the actionscript there is now, yet it's still not working. Any ideas?

On frame 2 when you switch to frame 6 check if stage has the event listener fl_SwipeToGoToNextPreviousFrameA() and if so remove it. That should fix your error.

You need to remove the listener at couple of frames.
Write these lines on frame2 after all of your code
stage.removeEventListener (TransformGestureEvent.GESTURE_SWIPE, fl_SwipeToGoToNextPreviousFrameA);
stage.removeEventListener (TransformGestureEvent.GESTURE_SWIPE, fl_SwipeToGoToNextPreviousFrameB);
Write this line on frame5 before you define listener
stage.removeEventListener (TransformGestureEvent.GESTURE_SWIPE, fl_SwipeToGoToNextPreviousFrameA);
Write this line on frame6 before you define listener
stage.removeEventListener (TransformGestureEvent.GESTURE_SWIPE, fl_SwipeToGoToNextPreviousFrameB);
and remove both from any other frame you can jump from frame5 and frame6.

Related

Unity Raycast results different on two devices

I use the following codes to detect which UI element is the player pointing. It works well in Unity Editor, on one of my Android phone, but failed on a second Android phone.
public static T RaycastOnFirstPointed<T>(EventSystem eventSystem, GraphicRaycaster raycaster)
{
if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer)
{
if (Input.touches == null || Input.touches.Length == 0) return default;
}
var m_PointerEventData = new PointerEventData(eventSystem);
m_PointerEventData.position = Input.mousePosition;
var results = new List<RaycastResult>();
raycaster.Raycast(m_PointerEventData, results); // On the 2nd phone the results.length is 0
foreach (RaycastResult result in results)
{
var component = result.gameObject.GetComponent<T>();
if (component != null)
{
return component;
}
}
return default;
}
This method is called within a IEndDragHandler.OnEndDrag method. I tried to debug it on the 2nd Android phone, and saw the results.length is 0 after Raycast was executed.(it should be > 0 since I ended my drag on several overlapped UI elements, and it is > 0 on the 1st phone, not sure why the 2nd phone is different)
I don't have any clue where should I go from here to find the problem. Please show me some directions, thank you!
More info:
Phone 1: MI 8 Lite, OS: MIUI 10.3
Phone 2: MI 9, OS: MIUI 10.2.35
============Update===========
Reason found:
When IEndDragHandler.OnEndDrag is triggered, the Input.mousePosition has different value on the two devices. 1st Phone has the touch position from the last frame, while the 2nd phone seems clears that value, and it has a very large wrong value. I'm working on how to solve this in a proper way. Any suggestions are welcomed.
Problem solved. As I updated in the question, this problem is caused by wrong Input.mousePosition value on different devices. So I updated the RaycastOnFirstPointed method as follows:
public static T RaycastOnFirstPointed<T>(EventSystem eventSystem, GraphicRaycaster raycaster, PointerEventData eventData = null)
{
if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer)
{
if (Input.touches == null || Input.touches.Length == 0) return default;
}
var m_PointerEventData = new PointerEventData(eventSystem);
if (eventData == null)
{
m_PointerEventData.position = Input.mousePosition;
}
else
{
m_PointerEventData.position = eventData.position;
}
var results = new List<RaycastResult>();
raycaster.Raycast(m_PointerEventData, results);
foreach (RaycastResult result in results)
{
var component = result.gameObject.GetComponent<T>();
if (component != null)
{
return component;
}
}
return default;
}
When call this method within OnEndDrag, pass in the PointerEventData that unity provides and use its position.

Detect scrollTop() when hovered (handheld device)

I am using jQuery's scrollTop() for a fixed menu:
function fixed_menu(){
if( $('window').width() < 770 )
{
var menu = $('.col-left.sidebar');
var offset = menu.offset();
var trigger = offset.top;
$(document).scroll(function(e){
if($('body').scrollTop() >= trigger){
menu.addClass('fixed');
} else if ($('body').scrollTop() < trigger){
menu.removeClass('fixed');
}
});
}
}
fixed_menu();
When I am testing on my own phone (android device, Moto G 2nd gen), the if statement still works while scrolling.
When I am testing on an iPad mini, the if statement only initiates when the hover is done.
How can I make this function work on certain iOS devices, while the hover is still ongoing?
The scrollTop() function is problematic in different browser. You can try with $('html, body').scrollTop() and $(window).scroll()
function fixed_menu(){
if( $('window').width() < 770 ){
var menu = $('.col-left.sidebar');
var offset = menu.offset();
var trigger = offset.top;
$(window).scroll(function(e){
if($('html, body').scrollTop() >= trigger){
menu.addClass('fixed');
} else if ($('html, body').scrollTop() < trigger){
menu.removeClass('fixed');
}
});
}
}
fixed_menu();

Get touch Location and tap on monogame

I'm writing a game in monogame for Android for my school project but I can't get touch location to do one simple tap action, I search but I can't find anything useful to do that. My game is a pipe puzzle game that I want when player touch a pipe it rotate but as I say I can't do this. this is my code for keyboard input.
KeyboardState newState = Keyboard.GetState();
if (oldState.IsKeyUp(Keys.Space) && newState.IsKeyDown(Keys.Space))
{
angle1 += (float)Math.PI / 2.0f;
}
oldState = newState;
You'll want to add a check for the following:
TouchCollection touchCollection = TouchPanel.GetState();
if (touchCollection.Count > 0)
{
//Only Fire Select Once it's been released
if (touchCollection[0].State == TouchLocationState.Moved || touchCollection[0].State == TouchLocationState.Pressed)
{
Console.WriteLine(touchCollection[0].Position);
{
}
You can then do what ever you want with the Position variable.

PresetReverb doesn't work at all why?

im a testing my audiorecording application for android
im launching an application to be audio recording in real time with audio effects as below
it was applied to equalizer, bass boost, presetreverb API which developer.android provides
in the result, as for equalizer and bass boost effects they seem to work well, but presetreverb effect.. i don't know why because there was no error in Logcat..
presetreverb don't work at all, i'd like to see it though it even work bad..
so im begging you SOF experts' help
Q: could you find out its cause through my source code?
protected void onResume() {
super.onResume();
if (this.mainSwitch.isChecked()) {
this.audioForwarder.start();
}
this.visualizer.setEnabled(true);
boolean flag = this.eqSwitch.isChecked();
ViewGroup localViewGroup = this.eqSettings;
int i;
int j;
PresetReverb localPresetReverb;
localPresetReverb = this.reverb;
if (flag)
i = 0; // .setVisibility(0) -> View.VISIBLE
else
i = 8; // .setVisibility(8) -> View.GONE
localViewGroup.setVisibility(i); // .setVisibility(0) -> View.VISIBLE
this.equalizer.setEnabled(flag);
this.bassBoost.setEnabled(this.bassSwitch.isChecked());
j = this.reverbSpinner.getSelectedItemPosition();
if (j > 0) {
i = 8;
for (boolean flag1 = true;; flag1 = false) {
localPresetReverb.setEnabled(flag1);
if (this.reverb != null) {
this.reverb.setPreset((short) j);
}
Log.v("PresetReverb", this.reverb + "effect");
}
}
}
im trying on and on expecting your help
any idea appreciated and big helps for me
:)

exiting app when press back , and mixing up scenes when back to previous scene

I'm creating an android app using AS3 Flash CS5.5 , is just a simple photo gallery to photos that were uploaded to a web page , I have to Scenes:
Scene 1 is a welcomeing scnen with button leads to scene 2
Scene 2 is the gallery scene..
i'm using this code , and it is working well , but when I press BACK key at the device , first it exits from the app , and when I open the app again it send me to scene 2 is mixed up with scene 2 O.o .. so it's like it came back to scene 1 but it keeps the contents of scene 2 above the contents of scene 1 ..
so what can I do to stop exiting the app when pressing BACK key at the device ??
and what should I do to stop the problem of the BACK key , and write the correct code that send me back to the first scene ...
and thaaaanks a lot :))
var pictureArray:Array = new Array;
Multitouch.inputMode = MultitouchInputMode.GESTURE;
stage.addEventListener (TransformGestureEvent.GESTURE_SWIPE, fl_SwipeToGoToNextPreviousFrame);
var loader1 = new Loader();
loader1.load(new URLRequest("MYURL"));
pictureArray.push(loader1);
var loader2 = new Loader();
loader2.load(new URLRequest("MYURL"));
pictureArray.push(loader2);
addChild(pictureArray[0]);
pictureArray[0].x = 0; pictureArray[0].y = 0;
var n:int = 0;
function fl_SwipeToGoToNextPreviousFrame(event:TransformGestureEvent):void
{
if(event.offsetX == 1)
{
removeChild(pictureArray[n]);
n = n+1;
if (n>pictureArray.length - 1)
n=0;
addChild(pictureArray[n]);
pictureArray[n].x = 0; pictureArray[n].y = 0;
}
else if(event.offsetX == -1)
{
removeChild(pictureArray[n]);
n = n-1;
if (n<0)
n=pictureArray.length - 1;
addChild(pictureArray[n]);
pictureArray[n].x = 0; pictureArray[n].y = 0;
}
}
NativeApplication.nativeApplication.addEventListener(KeyboardEvent.KEY_DOWN, CheckKeypress, false, 0, true)
function CheckKeypress(event:KeyboardEvent):void
{
switch (event.keyCode)
{
case Keyboard.BACK:
gotoAndPlay(1, "Scene 1");
break;
}
}
function android_backUp(e:KeyboardEvent)
{
switch (e.keyCode)
{
case Keyboard.BACK :
e.preventDefault();
// YOUR CODE
break;
}
}

Categories

Resources