Debugging a release only flash issue - actionscript-3

I've got an Adobe Flash 10 program that freezes in certain cases, however only when running under a release version of the flash player. With the debug version, the application works fine.
What are the best approaches to debugging such issues? I considered installing the release player on my computer and trying to set some kind of non-graphical method of output up (I guess there's some way to write a log file or similar?), however I see no way to have both the release and debug versions installed anyway :( .
EDIT: Ok I managed to replace my version of flash player with the release version, and no freeze...so what I know so far is:
Flash: Debug Release
Vista 32: works works
XP PRO 32: works* freeze
I gave them the debug players I had to test this
Hmm, seeming less and less like an error in my code and more like a bug in the player (10.0.45.2 in all cases)... At the very least id like to see the callstack at the point it freezes. Is there some way to do that without requiring them to install various bits and pieces, e.g. by letting flash write out a log.txt or something with a "trace" like function I can insert in the code in question?
EDIT2: I just gave the swf to another person with XP 32bit, same results :(
EDIT3:
Ok, through extensive use of flash.external.ExternalInterface.call("alert", "..."); I managed to find the exact line causing the problem (I also improved exception handling code so rather than freeze it told me there was an "unhandled" exception). The problem now is what on earth is flashes problem with this with the release player on some machines...
particles.push(p);
Which causes a TypeError #1034 on said platforms. Particles is a Vector.<Particle>, p is a Particle. I tested with getQualifiedClassName and got:
getQualifiedClassName(p) = ::Particle
getQualifiedClassName(particles) = __AS3__.vec::Vector.<::Particle>
Any ideas why this is a problem and what to do to make it work?
EDIT4:
Ok I seem to have solved this. The Particle class is just a simple internal class located after the package {...} in the action script file using it. I moved this into its own file (particle.as) and made it a proper public class in my package, and problem solved.
Maybe its a flash bug or maybe I missed the memo about not using internal classes in vectors or something, although if that's the case I would have expected something or other (either at compile time or with debug runtimes) to disallow it explicitly, e.g. some error on the "private var particles:Vector.<Particle>;" line. If I get a chance I guess I'll take a look at contacting the Adobe flash team concerning this or something.
Thanks for help giving debugging tips which I guess is more along the original questions lines :)

This is a long shot, but are the Particles the objects that you are clicking? If so then catching the event in the wrong phase of bubbling, and pushing event.target (assuming it to be a Particle) could cause that problem.
Whatever the problem, I have something that should help you debug. A class that creates a pseudo trace window in your SWF, much nicer than extinterfacing to javascript. I've forgotten who wrote it, but I feel like it's Senocular. I use it any time I need to get traces back from end users.
Just drop it in the default package for your project, call stage.addChild(new Output());, and then to trace call Output.trace("A message");
package {
import flash.display.Shape;
import flash.display.Sprite;
import flash.display.Stage;
import flash.display.GradientType;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Matrix;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.text.TextFieldAutoSize;
/**
* Creates a pseudo Output panel in a publish
* swf for displaying trace statements.
* For the output panel to capture trace
* statements, you must use Output.trace()
* and add an instance to the stage:
* stage.addChild(new Output());
*
*/
public class Output extends Sprite {
private var output_txt:TextField;
private var titleBar:Sprite;
private static var instance:Output;
private static var autoExpand:Boolean = false;
private static var maxLength:int = 1000;
public function Output(outputHeight:uint = 400){
if (instance && instance.parent){
instance.parent.removeChild(this);
}
instance = this;
addChild(newOutputField(outputHeight));
addChild(newTitleBar());
addEventListener(Event.ADDED, added);
addEventListener(Event.REMOVED, removed);
}
// public methods
public static function trace(str:*):void {
if (!instance) return;
instance.output_txt.appendText(str+"\n");
if (instance.output_txt.length > maxLength) {
instance.output_txt.text = instance.output_txt.text.slice(-maxLength);
}
instance.output_txt.scrollV = instance.output_txt.maxScrollV;
if (autoExpand && !instance.output_txt.visible) instance.toggleCollapse();
}
public static function clear():void {
if (!instance) return;
instance.output_txt.text = "";
}
private function newOutputField(outputHeight:uint):TextField {
output_txt = new TextField();
//output_txt.type = TextFieldType.INPUT;
output_txt.border = true;
output_txt.borderColor = 0;
output_txt.background = true;
output_txt.backgroundColor = 0xFFFFFF;
output_txt.height = outputHeight;
var format:TextFormat = output_txt.getTextFormat();
format.font = "_sans";
output_txt.setTextFormat(format);
output_txt.defaultTextFormat = format;
return output_txt;
}
private function newTitleBar():Sprite {
var barGraphics:Shape = new Shape();
barGraphics.name = "bar";
var colors:Array = new Array(0xE0E0F0, 0xB0C0D0, 0xE0E0F0);
var alphas:Array = new Array(1, 1, 1);
var ratios:Array = new Array(0, 50, 255);
var gradientMatrix:Matrix = new Matrix();
gradientMatrix.createGradientBox(18, 18, Math.PI/2, 0, 0);
barGraphics.graphics.lineStyle(0);
barGraphics.graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, gradientMatrix);
barGraphics.graphics.drawRect(0, 0, 18, 18);
var barLabel:TextField = new TextField();
barLabel.autoSize = TextFieldAutoSize.LEFT;
barLabel.selectable = false;
barLabel.text = "Output";
var format:TextFormat = barLabel.getTextFormat();
format.font = "_sans";
barLabel.setTextFormat(format);
titleBar = new Sprite();
titleBar.addChild(barGraphics);
titleBar.addChild(barLabel);
return titleBar;
}
// Event handlers
private function added(evt:Event):void {
stage.addEventListener(Event.RESIZE, fitToStage);
titleBar.addEventListener(MouseEvent.CLICK, toggleCollapse);
fitToStage();
toggleCollapse();
}
private function removed(evt:Event):void {
stage.removeEventListener(Event.RESIZE, fitToStage);
titleBar.removeEventListener(MouseEvent.CLICK, toggleCollapse);
}
private function toggleCollapse(evt:Event = null):void {
if (!instance) return;
output_txt.visible = !output_txt.visible;
fitToStage(evt);
}
private function fitToStage(evt:Event = null):void {
if (!stage) return;
output_txt.width = stage.stageWidth;
output_txt.y = stage.stageHeight - output_txt.height;
titleBar.y = (output_txt.visible) ? output_txt.y - titleBar.height : stage.stageHeight - titleBar.height;
titleBar.getChildByName("bar").width = stage.stageWidth;
}
}
}

Judging by when the freeze occurs, try to pinpoint some possibilities for what the offending code may be, and use De MonsterDebugger to check variables etc.
EDIT:
I'm pretty certain that the actual call stack is only available to you in the debug versions of the Flash Player / AIR. Still, it may be useful in the debug player to trace the stack from within the handler for the button to see if anything is out of place:
var err:Error = new Error(“An Error”);
trace(err.getStackTrace());
FYI the getStackTrace method is only available in the debug player, so there is no way to write it to a log.txt in production.

Related

TouchEvent.TOUCH_BEGIN, onTouchBegin Freezes after several Reloads

I am building an Adobe Air AS3 IOS and Android App, in which i have a movie clip in the center of the stage. When you start touching this movie clip, you can move it all around the stage.
This is how i'm doing so :
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
MC_M1.alpha = 1;
MC_M1.addEventListener(Event.ENTER_FRAME, ifHitAct);
MC_M1.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchBegin);
MC_M1.x = 0.516 * gameIntro.stageWidthToUse;
MC_M1.y = 0.75 * gameIntro.stageHeightToUse;
MC_M1.height = 0.2 * gameIntro.stageHeightToUse;
MC_M1.width = MC_M1.height / 1.4;
gameIntro.STAGE.stage.addChildAt(MC_M1,1);
function onTouchBegin(event:TouchEvent)
{
trace("TouchBegin");
if (touchMoveID != 0)
{
trace("It Did Not");
return;
}
touchMoveID = event.touchPointID;
gameIntro.STAGE.stage.addEventListener(TouchEvent.TOUCH_MOVE, onTouchMove);
gameIntro.STAGE.stage.addEventListener(TouchEvent.TOUCH_END, onTouchEnd);
}
function onTouchMove(event:TouchEvent)
{
if (event.touchPointID != touchMoveID)
{
return;
}
//trace("Moving")
MC_M1.x = event.stageX;
MC_M1.y = event.stageY;
}
function onTouchEnd(event:TouchEvent)
{
if (event.touchPointID != touchMoveID)
{
return;
}
//trace("Ending");
touchMoveID = 0;
gameIntro.STAGE.stage.removeEventListener(TouchEvent.TOUCH_MOVE, onTouchMove);
gameIntro.STAGE.stage.removeEventListener(TouchEvent.TOUCH_END, onTouchEnd);
}
When the player actually looses the game, what i am actually doing is the following :
MC_M1.removeEventListener(Event.ENTER_FRAME , ifHitAct);
MC_M1.removeEventListener(TouchEvent.TOUCH_BEGIN , onTouchBegin);
gameIntro.STAGE.stage.removeChild(MC_M1);
MC_M1.alpha = 0;
isDead = 1;
replayButToUse.x = 0.127 * gameIntro.stageWidthToUse;
replayButToUse.y = 0.91 * gameIntro.stageHeightToUse;
replayButToUse.addEventListener(MouseEvent.CLICK, gotoIntro);
This is all happening in a class called : introClassToUse.
So when the users looses, he will get a replay button, and when he clicks it, he will go back to the same class and reload everything, using the following code :
function gotoIntro(event:MouseEvent):void
{
replayButToUse.removeEventListener(MouseEvent.CLICK, gotoIntro);
replayButToUse.alpha = 0;
replayButToUse.removeEventListener(MouseEvent.CLICK, gotoIntro);
stop();
var reload:introClassToUse = new introClassToUse();
}
And so everything loads back up and the game restarts. My problem is, i'm facing a very weird behavior when i tend to replay the game more than 2-3 times. The MC_M1 just stops listening to any touch event, but keeps on listening to ENTER_FRAME events, in which i keep touching the MC_M1 but it seems to not respond to it. I even debugged it remotely from my iPhone, for the first couple of replays, i can see the trace("TouchBegin"); with it's outcome, it was showing me TouchBegin, but after a few replays, the touch events just froze. What am i missing?
Any help is really appreciated, i'm new in AS3, i need to learn so i could manage more
Edit 1 :
I have no code on any frame, i just have lots of AS Classes.
The fla file is linked to an AS Class called gameIntro. In this class, i have linked the following :
- STAGE is an object of type Stage.
- gameIntro.STAGE = stage
Later on, when the user clicks a play button, i call the class introClassToUse. This class has all the game functionalities. All the code present above is in introClassToUse. When the user looses and clicks the replay button, he will go to "goToIntro" function, im which i recall the introClassToUse.
It's all working fine, with several other timers implemented and all, the only problem is that after several replays, the MC_M1 just freezes over
I am removing the MC_M1 each time the user looses and re-add them when i call back the introClassToUse, because i tried to use the .visible property, it didn't work at all ( this is why i am using the gameIntro.STAGE.stage.removeChild(MC_M1)
I know the question is old but maybe someone is still wondering what is going on here (like me).
There are lot of problems in you code but I thing the root of your problem starts here:
function gotoIntro(event:MouseEvent):void{
//...
var reload:introClassToUse = new introClassToUse();
}
It is usually unwanted behavior if simply creating an instance does more than nothing to your program and you don't even need to assign it to variable in this case.
You mentioned this code is located in your introClassToUse class. This basically means that you are creating new instance of your game inside old one and this seem to be completely awry.
You should consider using only instance properties in your class definition and create new introClassToUse() in external classes;
You didn't include many important details about your code like
How the whole class structures look like - for example you can't place line like MC_M1.addEventListener(Event.ENTER_FRAME, ifHitAct);in the scope of your class so obviously you have this in some function and we don't know when and from where it is called.
Where and how your variables are declared, and assigned. It's hard to tell if your MC_M1 is property of an instance or a class, is it internal/public/private/...
Do you link library symbols to your classes or acquire it from stage.
There could be many things that could give you such result. Based on what you wrote I've reproduced behavior similar to what you've describe but using mouse event and a dummy loose condition. This ends the game each time you drop the mc partially outside right edge of the sage, show restart button and starts again if you click it (basically it's mostly your code). It works fine for about 10s and than suddely you can't move the mc anymore. The frame event is still tracing out but touch/mouse is not.
How can it be? I suspect that you could remove only listeners somewhere and have invisible mc stuck on the new one. And this could be easy overlooked, especially if you using static properties. Again we don't even know where is your movie clip coming from so we can only guess what is happening whit your code but I've tried to take the example simple this is how I did it. The problem may lay in some completely different place but you can guess for all scenarios.
Document class of the project - GameIntro.as
package
{
import flash.display.Sprite;
public class GameIntro extends Sprite
{
//Document class. this need to be compiled with strict mode off.
public function GameIntro() {
GameIntro.STAGE = stage;
GameIntro.stageWidthToUse = stage.stageWidth;
GameIntro.stageHeightToUse = stage.stageHeight;
var intro:IntroClassToUse = new IntroClassToUse();
stage.addChild(intro);
}
}
}
IntroClassToUse.as
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.utils.Timer;
/**
* You need to have library symbol linked to this class in .fla with two mcs -
* mcFromLibrarySymbol (dragable) and repButton (reapatButton)
*/
public class IntroClassToUse extends MovieClip
{
var t = 0; //timer ticks
var fc:uint = 0; //frames counter
var isDead = 0;
var mc;
static var repButton;
var logicContex:Timer = new Timer(30);
public function IntroClassToUse() {
trace("toUse", GameIntro.stageWidthToUse);
mc = mcFromLibrarySymbol;
if(!repButton) repButton = repButtonX;
logicContex.addEventListener(TimerEvent.TIMER, logicInterval);
logicContex.start();
init();
}
internal function init() {
trace("init");
mc.alpha = 1;
mc.addEventListener(Event.ENTER_FRAME, onFrame);
mc.addEventListener(MouseEvent.MOUSE_DOWN, onMDown);
mc.x = 0.516 * GameIntro.stageWidthToUse;
mc.y = 0.75 * GameIntro.stageHeightToUse;
mc.height = 0.2 * GameIntro.stageHeightToUse;
mc.width = mc.height / 1.4;
GameIntro.STAGE.stage.addChildAt(mc, 1);
}
internal function onLoose() {
trace("onLoose");
mc.removeEventListener(Event.ENTER_FRAME , onFrame);
mc.removeEventListener(MouseEvent.MOUSE_DOWN, onMDown);
GameIntro.STAGE.stage.removeChild(mc);
mc.alpha = 0;
isDead = 1;
repButton.x = 0.127 * GameIntro.stageWidthToUse;
repButton.y = 0.91 * GameIntro.stageHeightToUse;
repButton.addEventListener(MouseEvent.CLICK, onReplay);
repButton.alpha = 1;
}
internal function onReplay(e:MouseEvent):void {
trace("onReplay");
repButton.removeEventListener(MouseEvent.CLICK, onReplay);
repButton.alpha = 0;
stop();
new IntroClassToUse();
}
internal function onMDown(e:MouseEvent):void {
trace("mouseDow");
GameIntro.STAGE.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMMove);
GameIntro.STAGE.stage.addEventListener(MouseEvent.MOUSE_UP, onMUp);
}
internal function onMMove(e:MouseEvent):void {
mc.x = e.stageX;
mc.y = e.stageY;
}
//you loose the game if you release you mc with part of it over rigth stage edge.
internal function onMUp(e:MouseEvent):void {
trace("mouseUp");
GameIntro.STAGE.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMMove);
GameIntro.STAGE.stage.removeEventListener(MouseEvent.MOUSE_UP, onMUp);
trace("Stage:", GameIntro.STAGE.numChildren);
if (mc.x + mc.width > GameIntro.STAGE.stageWidth) onLoose();
}
internal function onFrame(e:Event):void {
trace("frames", fc++);
}
internal function logicInterval(e:TimerEvent):void {
if (t++ < 300 || !isDead) return;
init();
mc.alpha = 0;
mc.removeEventListener(MouseEvent.MOUSE_DOWN, onMDown);
isDead = 0;
}
}
}

Why might browseForOpen fail to display File Dialog yet claim it is open if recalled?

I am trying to open a file dialog with file.browseForOpen. Most of the time it works but on the very rare occasion (such as in meetings) the file browser simply does not appear and does not block (as a modal should).
If I press the button calling the code at this point then I get an error which states "there can only be one".
There are no sub-windows and I can't find to file dialog, even after minimizing the main window, yet the error insists that it is open. I wrote some code which disabled the button when the code above is called and then enables it on any of the events but when this error occurs the button is then permanently disabled.
There are another 10,000 lines of code, some which keep running even while the file browser is open. None of them seem related to the file browser so I moved the following code into a new project, to test, and could not replicate the bug.
var filter:FileFilter = new FileFilter("Image/Video", "*.jpg;*.png;*.mp4;");
var imagesFilter:FileFilter = new FileFilter("jpg/png", "*.jpg;*.png");
var docFilter:FileFilter = new FileFilter("mp4", "*.mp4;");
var filters:Array = [filter, imagesFilter, docFilter];
var fileBrowser:File = File.userDirectory;
fileBrowser.addEventListener(FileListEvent.SELECT_MULTIPLE, onFileSelected);
fileBrowser.addEventListener(Event.CANCEL, clean);
fileBrowser.addEventListener(IOErrorEvent.IO_ERROR, clean);
fileBrowser.browseForOpen("Select Slides", filters);
Does anyone know anything which could save me from a 'needle in a haystack' exhaustive search? Has anyone else ever experienced this same problem? I couldn't find any solutions when searching "File dialog opens but isn't visible" or more than 30 variations of that search including "File dialog doesn't open".
Lastly, is there a way to force the file dialog to close if I detect that the user is interacting with the main window whilst it should be blocked? Just as a bandage fix should the problem not be solved (breaks modal flow, I know, but modal flow is already broken at that point).
UPDATE:
After removing a class and replacing it with a less efficient urlMonitor the problem seems to have gone away.
If anyone can work out what went wrong then I will mark your answer as complete.
The class I removed seemed completely unrelated but I will show the code:
package reuse.Network
{
import flash.desktop.NativeApplication;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IOErrorEvent;
import flash.events.StatusEvent;
import flash.events.TimerEvent;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
import flash.utils.Timer;
import air.net.URLMonitor;
[Event(name="networkStatusChanged", type="reuse.Network.CheckInternetEvent")]
public class NetStatusMonitor extends EventDispatcher
{
private var url:String;
private var urlMonitor:URLMonitor;
public function NetStatusMonitor(url:String = 'http://www.adobe.com')
{
super();
this.url = url;
}
protected function onNetwork_ChangeHandler(event:Event):void
{
checkWebsite(url, dispatchStatus);
}
/**
* Checks a specific website for connectivity.
* #param uri URI of the website to check for a response from
* #param result Function which accepts a bool as a response.
* #param idleTimeout How many milliseconds to wait before timing out
*/
public function checkWebsite(uri:String, result:Function, idleTimeout:Number = NaN):void
{
var timeout:Timer;
var request:URLRequest = new URLRequest(uri);
if(!isNaN(idleTimeout))
{
request.idleTimeout = idleTimeout;
timeout = new Timer(request.idleTimeout + 1000, 1);
timeout.addEventListener(TimerEvent.TIMER_COMPLETE, failed);
timeout.start();
}
var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.TEXT;
loader.addEventListener(Event.COMPLETE, complete);
loader.addEventListener(IOErrorEvent.IO_ERROR, failed);
loader.load(request);
function complete():void
{
result(true);
cleanup();
}
function failed(e:*):void
{
result(false);
cleanup();
}
function cleanup():void
{
if(timeout)
{
timeout.stop();
timeout.removeEventListener(TimerEvent.TIMER_COMPLETE, failed);
timeout = null;
}
loader.close();
loader.removeEventListener(Event.COMPLETE, complete);
loader.removeEventListener(IOErrorEvent.IO_ERROR, failed);
loader = null;
}
}
public function start():void
{
checkWebsite(url, dispatchStatus, 5000);
if(!NativeApplication.nativeApplication.hasEventListener(Event.NETWORK_CHANGE))
NativeApplication.nativeApplication.addEventListener(Event.NETWORK_CHANGE, onNetwork_ChangeHandler);
if(urlMonitor == null)
{
var request:URLRequest = new URLRequest(url);
urlMonitor = new URLMonitor(request);
urlMonitor.pollInterval = 30;
}
if(!urlMonitor.hasEventListener(StatusEvent.STATUS))
urlMonitor.addEventListener(StatusEvent.STATUS, onNetStatus_ChangeHandler);
if(!urlMonitor.running)
urlMonitor.start();
}
public function stop():void
{
if(urlMonitor)
{
if(urlMonitor.running)
urlMonitor.stop();
if(urlMonitor.hasEventListener(StatusEvent.STATUS))
urlMonitor.removeEventListener(StatusEvent.STATUS, onNetStatus_ChangeHandler);
urlMonitor = null;
}
}
private function onNetStatus_ChangeHandler(event:StatusEvent):void
{
dispatchStatus(urlMonitor.available);
}
private function dispatchStatus(status:Boolean):void
{
dispatchEvent(new CheckInternetEvent(CheckInternetEvent.NETWORK_STATUS_CHANGED, status));
}
}
}
Anyone familiar with Raja Jaganathan might recognize this class from Adobe Air - Check for internet connection
I posted this as a bug to Adobe and the following note was added to it:
Alex Rekish
11:06:11 PM GMT+00:00 Apr 12, 2016
I have seen this problem and found workaround. You need remove
listeners, force cancel and null pervious file object that you you for
browseForOpen method.
previousBrowseFile.removeEventListener(Event.SELECT,
fileSelected); previousBrowseFile.removeEventListener(Event.CANCEL,
fileCancelled); previousBrowseFile.cancel(); previousBrowseFile= null;

Gettling starling to work with box2d and debugdraw with as3

This topic has been raised before, but not one of the examples I've found online seem to work for me! I am trying to get starling to work with box2d, and also for the box2d debugdraw.
I have tried a bunch of different methods, and my code is now a bit of a mess due to commenting out to try different mixes of the "solution". Does anyone know how to do all this properly? I would be greatly in dept if someone could explain it.
Here is the last attempt I tried:
In my Startup class:
package {
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
//import flash.events.Event;
import starling.core.Starling;
//import starling.display.Sprite;
import flash.events.Event;
[SWF(width="640", height="480", frameRate="60", backgroundColor="#000000")]
public class Startup extends Sprite {
public static var mStarling:Starling;
public static var debugSprite:Sprite;
public function Startup() {
//addChild ( new Stats() );
super();
//stage.align = StageAlign.TOP_LEFT;
//stage.scaleMode = StageScaleMode.NO_SCALE;
// create our Starling instance
mStarling = new Starling(Game, stage);
// set anti-aliasing (higher the better quality but slower performance)
mStarling.antiAliasing = 1;
mStarling.showStats = true;
// start it!
mStarling.start();
stage.stage3Ds[0].addEventListener(Event.CONTEXT3D_CREATE, onContextCreated);
}
private function onContextCreated(e:Event):void{
////debug mode
// debugSprite=new Sprite();
// //addChild(debugSprite);
// Starling.current.nativeOverlay.addChild(debugSprite);
//var debugSprite:Sprite=new Sprite();
addChild(debugSprite);
(mStarling.stage.getChildAt(0) as Game).DebugDraw(debugSprite)
}
I call the debugdraw like this:
debugDraw(Startup.debugSprite);
Here is a heavily commented out debugdraw:
private function debugDraw(debugSprite:flash.display.Sprite):void {
/*var worldDebugDraw:b2DebugDraw=new b2DebugDraw();
//var debugSprite:flash.display.Sprite = new flash.display.Sprite();
var debugSprite:Sprite = new Sprite();
addChild(debugSprite);
//mStarling.current.nativeOverlay.addChild(debugSprite);
//worldDebugDraw.SetSprite(debugSprite);
//debugDraw.SetSprite(Starling.current.nativeOverlay); //DOESN'T SEEM TO WORK
worldDebugDraw.SetDrawScale(worldScale);
worldDebugDraw.SetFlags(b2DebugDraw.e_shapeBit|b2DebugDraw.e_jointBit);
//worldDebugDraw.SetFillAlpha(0.0);
//worldDebugDraw.SetAlpha(0.0);
//visible
worldDebugDraw.SetFillAlpha(0.8); //for testing
worldDebugDraw.SetAlpha(1); //for testing
world.SetDebugDraw(worldDebugDraw);*/
var worldDebugDraw:b2DebugDraw = new b2DebugDraw();
worldDebugDraw.SetSprite(debugSprite);
world.SetDebugDraw(worldDebugDraw);
}
DebudDraw works with ONE classic Flash Sprite (you keep creating new ones for some reason). Only one b2DebugDraw should be created and set with that ONE Sprite.
Starling pretends to own the stage and all displaylist but it doesn't. Use simply your StartUp instance or even directly the stage itself without passing through Starling it will avoid some confusion.
The right way to do all this:
public var debugSprite:Sprite;//no static var
Starting what?
//don't start it!
mStarling.start();
You star something that cannot be started. At this point you are trying to create a valid Context3D so be patient. Remove that line.
Now in onContextCreated:
mStarling.start();//now you can start
debugSprite = new Sprite();//create your sprite
addChild(debugSprite);
var game:Game = mStarling.stage.getChildAt(0) as Game;//Game? somebody is following a tutorial ...
if(game)
{
game.setDebug(debugSprite);//this is a new public method to create in Game
}
In Game in method setDebug (with one parameter Sprite):
var worldDebugDraw:b2DebugDraw = new b2DebugDraw();
worldDebugDraw.SetSprite(myspriteparameter);
world.SetDebugDraw(worldDebugDraw);
That's it, don't create new Sprite, don't create new debugdraw, you are good to go that's all you need.

Red5 and AS3 - file "Mystream" is deleted (not recording)

This my first time using StackExchange so I apologize if I miss anything.
I am trying to create a AS3 Flash that will record a video using a webcam and RED5 media server; I am stuck (I am not a programmer, more of a computer handyman that does everything).
The example that comes with RED5 works fine (though is in AS2 and I could not, for some reason, make certain things I need to do work), but my code doesnt seem to record the stream as there is not file, the RED5 console only says:
[INFO] [NioProcessor-3] org.red5.server.adapter.ApplicationAdapter - File lecture.flv was deleted
here is the code so far. (updated 09/07/12)
import flash.display.Sprite;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.media.Camera;
import flash.events.MouseEvent;
import flash.media.Microphone;
import flash.events.*;
import flash.media.Video;
var _cam:Camera
var _mic:Microphone
// create basic netConnection object
var _nc:NetConnection = new NetConnection();
_nc.client = this
// connect to the local Red5 server
_nc.connect("rtmp://localhost/myapp");
_nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
//Add listeners for buttons
record_btn.addEventListener( MouseEvent.CLICK, recordvid );
stop_btn.addEventListener( MouseEvent.CLICK, stopvideo );
//submit_btn.addEventListener( MouseEvent.CLICK, onSubmit );
//Listeners
function netStatusHandler(event:NetStatusEvent):void{
trace("start netstatus handler");
if (event.info.code == "NetConnection.Connect.Success"){
attachCamera();
}
}
function attachCamera(e:Event = null):void {
trace("attach");
//Attach Camera to field
_cam=Camera.getCamera();
_mic=Microphone.getMicrophone()
vid.attachCamera(_cam);
}
function stopvideo(e:MouseEvent):void {
//_ns.close();
}
function recordvid(e:MouseEvent):void {
var _ns:NetStream = new NetStream(_nc);
trace("publish");
_ns.attachCamera(_cam);
_ns.attachAudio(_mic);
_ns.publish("lecture", "record");
}
You have to connect & wait for the successful status before publishing the stream.
For Example :
var nc:NetConnection = new NetConnection();
nc.connect("rtmp://fms.example.com/lectureseries");
nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
function netStatusHandler(event:NetStatusEvent):void{
if (event.info.code == "NetConnection.Connect.Success"){
var ns:NetStream = new NetStream(nc);
ns.publish("lecture", "record");
}
}
Have a look at the Netstream documentation to learn more.
I just found the answer thru extreme googleing, I needed to declare the Netstream variable outside the function; otherwise the "publish" video was "empty" as the garbage collector was destroying my variable at some point.
so outside a function I declare
var _ns:NetStream;
and inside the function I declare:
function recordvid(e:MouseEvent):void {
_ns = new NetStream(_nc);
_ns.attachCamera(_cam);
_ns.attachAudio(_mic);
_ns.publish("lecture", "record");
Awesomely enough, I found the answer right here in stackoverflow

How to detect Adobe Flash crash reason?

Edit02: The reason why the flash crash because the wrong distance cause the programm to divide something by 0 - well I found the error on my own, but my question still is, is there something like a crashreport that you can add / edit?
Edit: I found the bug in the script its located here
if(baseVerticies[vertX]-boneObj.x < 0){
distance = distance*-1;
}
at one point it generates the wrong distance, but this is not what the program causes to crash, I know how to solve the bug but it would still be interesting how to add functions to detect flash crash reasons
OLD:
Hey I am currently testing the CS6 Flash demo but one function always kills flash and I dont get any error messages, so my question is ... how can I hunt the bug down?
The only things I know: it crashes when I call a certain function (the one which I posted below) - it doesnt crash on the first call ... more like on the third or second
is there any way to add debugEvents or something als that would be usefull to track the error?
thx in advance =)
public function rotateBone(boneObj : Bone, point : Point){
//rotates the boneGrafik
boneObj.rotation = (point.x+boneObj.old_rotation)/2;
if(axis == "horizontal"){
var firstV : int = selected_bone*(squares+1)*2;
var lastV : int = selected_bone*(squares+1)*2 + squares*2;
var radius : Number = Math.sqrt((verticies[lastV]-verticies[firstV])*(verticies[lastV]-verticies[firstV])+
(verticies[lastV+1]-verticies[firstV+1])*(verticies[lastV+1]-verticies[firstV+1]));
//will be exectued for every single vertex
for(var s = 0; s<=squares; s++){
var vertX : int = selected_bone * (squares+1) * 2 + s*2;
var distance : Number = Math.sqrt((verticies[vertX]-boneObj.x)*(verticies[vertX]-boneObj.x)+
(verticies[vertX+1]-boneObj.y)*(verticies[vertX+1]-boneObj.y));
//calculates Vector
var rads:Number = boneObj.rotation / 180 * Math.PI;
var p:Point = new Point();
p.x=Math.cos(rads);
p.y=Math.sin(rads);
//baseMesh is used in order to check if the vertex pos is positiv / negative
if(baseVerticies[vertX]-boneObj.x < 0){
distance = distance*-1;
}
verticies[vertX] = boneObj.x + p.x * radius * (distance/radius);
verticies[vertX+1] = boneObj.y + p.y * radius * (distance/radius);
}
}else if (axis == "vertical"){
for(var r = 0; r<=rows; r++){
vertX = r * (squares+1) * 2 + selected_bone * 2;
}
}
updateMesh();
}
I'm not sure what you mean it crashes without exception. Are you testing in the browser? If so, then you could download and install the appropriate Flash debugger player from the list here: http://www.adobe.com/support/flashplayer/downloads.html
This should give you an error window whenever FlashPlayer crashes, which will contain debugging information. It will also write crashes and debugging data to a log file. There's more info on that here: http://helpx.adobe.com/flash-player/kb/configure-debugger-version-flash-player.html
Finally, if you want to catch and handle otherwise unhandled exceptions, you can do that in FP10.1 and later. Here are the Adobe docs about it: http://help.adobe.com/en_US/FlashPlatform/beta/reference/actionscript/3/flash/events/UncaughtErrorEvent.html, and here is the sample code from that page:
package
{
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.ErrorEvent;
import flash.events.UncaughtErrorEvent;
import flash.net.URLRequest;
public class LoaderUncaughtErrorEventExample extends Sprite
{
private var ldr:Loader;
public function LoaderUncaughtErrorEventExample()
{
ldr = new Loader();
ldr.load(new URLRequest("child.swf"));
ldr.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, uncaughtErrorHandler);
}
private function uncaughtErrorHandler(event:UncaughtErrorEvent):void
{
if (event.error is Error)
{
var error:Error = event.error as Error;
// do something with the error
}
else if (event.error is ErrorEvent)
{
var errorEvent:ErrorEvent = event.error as ErrorEvent;
// do something with the error
}
else
{
// a non-Error, non-ErrorEvent type was thrown and uncaught
}
}
}
}