Flash and JAWS Accessibility - actionscript-3

Currently I am trying to use JAWS screen reader to make a .swf I have created easier to those who need this sort of software.
I so far have been able to set the name and tab-indexes for two movie-clips.
I was wondering if anyone knew how to get the screen reader to read the names or descriptions of these movie-clips?
import flash.accessibility.AccessibilityProperties;
stop();
setupJAWS();
/////////////////////---JAWS---//////////////////////////////////////
function enable( mc:* ) {
trace("Enabled");
var _accessClip = mc;
_accessClip.accessibilityProperties.silent = false;
_accessClip.tabEnabled = true;
}
function disable( mc:* ) {
var _accessClip = mc;
_accessClip.accessibilityProperties.silent = true;
_accessClip.tabEnabled = false;
}
function setupJAWS(){
trace("SETTING UP");
this.Text58.accessibilityProperties = new AccessibilityProperties();
this.Text58.accessibilityProperties.name = "TEXT1";
this.Text58.tabIndex = 2;
enable(this.Text58);
this.Text59.accessibilityProperties = new AccessibilityProperties();
this.Text59.accessibilityProperties.name = "TEXT2";
this.Text59.tabIndex = 3;
enable(this.Text59);
Accessibility.updateProperties();
stage.focus=Text58;
}
If you don't know that answer to this could you please up vote the question as I really need this answered, Thanks in advance. :)

Related

AS3 Collision Detection Arrays

I've been trying to figure out an easier way to code this for a simple RPG I have been working on, it works perfectly if the item that is unable to pass through is added individually. When I've tried to work with arrays, it throws off a bunch of evil errors. Granted I am new to AS3 but I have tried to find a solution to this, with no luck.
if(heroMC.hitTestObject(block1)) {
hitObj = true;
heroMC.x = gX;
heroMC.y = gY;
} else if(heroMC.hitTestObject(bridgeBlock2)) {
hitObj = true;
heroMC.x = gX;
heroMC.y = gY;
} if(heroMC.hitTestObject(bridgeBlock3)) {
hitObj = true;
heroMC.x = gX;
heroMC.y = gY;
} else {
hitObj = false;
gX = heroMC.x;
gY = heroMC.y;
}
I then add every individual entry, to my list. If heroMC does intersect the object, then it changes the value of hitObj to true. If nothing is colliding, the hitObj will return as false. What solutions could I use to make this easier and cleaner.
Thanks in advance guys.
Insert your blocks MovieClips into an array
var blocksArray: Arry = new Array(block1, bridgeBlock2, bridgeBlock3);
Add Enter frame handler event for catch the changes
this.addEventListener(Event.ENTER_FRAME, onEnterFramehandler);
function onEnterFramehandler(e: Event): void {
//initially set it to false
hitObj = false;
for (var i: uint = 0; i < blocksArray.length; i++) {
//If hit the object set it to true;
if (heroMC.hitTestobject(blocksArray[i])) {
hitObj = true;
//set the position of the heroMc if true
heroMC.x = gX;
heroMC.y = gY;
break;
}
}
//get the position of the heroMc if false
gX = heroMC.x;
gY = heroMC.y;
}

Customizing Clothes on Character in Game User Personalization

I could use help with customization in Flash games! I am pretty new to AS3 and have a game I am building where the user can dress the character based on a few options and a color picker, then move on to a race. I cannot get the clothes that are chosen to stay, and the ones excluded leave, without all of them staying or leaving. I've tried variables, if/else conditions and switch statements, but nothing is working. I have a feeling it's a condition, but I don't know how to write it and can't find anyone in a similar boat.
I have been scouring my books (Flash CS6 Missing Manual and ActionScript 3.0 Cookbook), and I've gotten very close, but nothing works. I really could use a lot of help with this, it's a final project and the stress might be hiding the answer, but I surely don't have it.
Not sure if I did this right, I've never used this site before. Thank you in advance!
UPDATE
Here is a link to where the .swf file is currently uploaded for your input.
http://yellownotebook.weebly.com/other-work.html
Please ignore the DONE button at the beginning, I am working on that still. I need the clothes to be invisible on the start up, and the remaining unselected clothes after that to be discarded? Invisible? I still don't understand which way is best for this situation. I started reading something about Display Lists?
I'm also not sure what part of the code would be most helpful, so here it is.
var mcdress2 = mcdress2
var mcpants = mcpants
var mcshirt = mcshirt
var mctop = mctop
var clothes = mctop + mcpants + mcshirt + mcdress2
var fairy = clothes + mcwings + mcfay
mcfay.visible = false;
mctop.visible = false;
mcshirt.visible = false;
mcpants.visible = false;
mcdress2.visible = false;
mcwings.visible = false;
cpClothes.visible = false;
import fl.events.ColorPickerEvent;
fairybg.btnplay.addEventListener(MouseEvent.CLICK,clickPlayListener);
btndone.addEventListener(MouseEvent.CLICK,clickDoneListener);
fairybg.gotoAndStop("Game Start");
function clickPlayListener(evt:MouseEvent):void
{
fairybg.gotoAndStop("Background Start")
mcfay.visible = true;
mctop.visible = true;
mcshirt.visible = true;
mcpants.visible = true;
mcdress2.visible = true;
mcwings.visible = true;
cpClothes.visible = true;
}
//fairy.scaleY = fairy.scaleX
function clickDoneListener(evt:MouseEvent):void
{
fairybg.gotoAndStop("Background Fly")
fairybg.gotoAndStop("Background Fly")
//fairy.width = 1/2
//fairy.height = 1/2;
//if it was this way, she would be bare when she flies, needs "if" condition?
//mctop.visible = false;
//mcshirt.visible = false;
//mcpants.visible = false;
//mcdress2.visible = false;
cpClothes.visible = false;
btndone.visible = false;
}
//fairy.scaleY = fairy.scaleX
mcdress2.gotoAndStop(1);
mcdress2.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownListener);
function mouseDownListener (event:MouseEvent):void
{
mcdress2.gotoAndStop("Dress End");
mctop.gotoAndStop("Top Start");
mcpants.gotoAndStop("Pants Start");
mcshirt.gotoAndStop("Shirt Start");
}
mcshirt.gotoAndStop(1);
mcshirt.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownListener2);
function mouseDownListener2 (event:MouseEvent):void
{
mcshirt.gotoAndStop("Shirt End");
mcdress2.gotoAndStop("Dress Start");
mctop.gotoAndStop("Top Start");
}
mcpants.gotoAndStop(1);
mcpants.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownListener3);
function mouseDownListener3 (event:MouseEvent):void
{
mcpants.gotoAndStop("Pants End");
mcdress2.gotoAndStop("Dress Start");
}
mctop.gotoAndStop(1);
mctop.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownListener4);
function mouseDownListener4 (event:MouseEvent):void
{
mctop.gotoAndStop("Top End");
mcshirt.gotoAndStop("Shirt Start");
mcdress2.gotoAndStop("Dress Start");
}
//use color picker to change clothing color (all items same color)
cpClothes.addEventListener(ColorPickerEvent.CHANGE,changeColorPicker);
function changeColorPicker(evt:ColorPickerEvent):void
{
var myColorTransform = new ColorTransform ();
myColorTransform.color = evt.color;
mcdress2.transform.colorTransform = myColorTransform;
mctop.transform.colorTransform = myColorTransform;
mcshirt.transform.colorTransform = myColorTransform;
mcpants.transform.colorTransform = myColorTransform;
//trace ("color changed")
//trace (evt.color)
//trace (mcdress.color)
//opaqueBackground = evt.color;
}
cpClothes.colors =
[0xF7977A,0xFFF79A,0x6ECFF6,0xF49AC2];
switch (clothes) {
case "Dress End" :
mcshirt.visible = false;
mctop.visible = false;
mcpants.visible = false;
break;
case "Top End" :
mcshirt.visible = false;
mcdress2.visible = false;
mcpants.visible = false;
break;
case "Shirt End" :
mctop.visible = false;
mcdress2.visible = false;
mcpants.visible = false;
break;
default :
//mcdress2.gotoAndStop("Dress Start")
//mctop.gotoAndStop("Top Start")
//mcshirt.gotoAndStop("Shirt Start")
//mcpants.gotoAndStop("Pants Start")
mcdress2.visible = true;
mctop.visible = true;
mcshirt.visible = true;
mcpants.visible = true;
}
/*if (clickDoneListener==true) {
fairy.width = .5
fairy.height = .5;
}*/
//trace ("it works!")
//var _mcpants:mcpants;
//function newmcpants(e:MouseEvent):void
//{
//if (_mcpants)
// return
//_mcpants = new mcpants();
//_mcpants.x = 263.35;
//_mcpants.y = 270.40;
//addChild(_mcpants);
//}
//function deletemcpants(e:MouseEvent):void;
//{
//if (_mcpants && contains(_mcpants))
//removeChild(_mcpants);
//_mcpants = null;
//displayText("Deleted mcpants successfully!");
//}
As you can see, I have a lot of code commented out, I have been trying everything I can find for it to work. I also am trying to scale her down 50% after the DONE button is clicked and the game is started, but I have not figured out a way for that one either. Thank you so so much for any help!
You must add information to your system about which clothes have been selected. You are right that it is about conditionals but your conditional will need the information to base the selection on. I think there are 3 alternatives:
Manage a collection of the clothes that are put on
Make clothes objects that have a property, cloth.weared = true or false
Have slots for your clothes: upperbody, lowerbody etc. and assign the selected clothes there: upperbody = somecloth;
I made 1. as a bare bones example for you. Hopefully you can understand it! May not be the most elegant solution but does work, is quite simple and I think the logic is quite close to what you already have: http://jsfiddle.net/n37qx/
var selected = [];
var SHIRT = "shirt";
var DRESS = "dress";
var TROUSERS = "trousers";
var all = [SHIRT, DRESS, TROUSERS];
//logic
function putOn(cloth) {
if (arraycontains(selected, cloth)) {
return;
}
//replace check
if (cloth === SHIRT) {
removeIfContains(selected, DRESS);
} else if (cloth === DRESS) {
removeIfContains(selected, SHIRT);
removeIfContains(selected, TROUSERS);
}
selected.push(cloth);
}
function hideNotSelected() {
for (var i=0; i < all.length; i++) {
var cloth = all[i];
if (arraycontains(selected, cloth)) {
log("wearing - not hiding: " + cloth)
} else {
log("hide: " + cloth);
}
}
}
//test flow - code instead of UI actions
log("1. Put on shirt + trousers, dress should get hidden:");
putOn(SHIRT)
putOn(TROUSERS);
hideNotSelected();
log("---");
log("2. Put on dress - trousers and shirt should get hidden:");
putOn(DRESS);
hideNotSelected();
//utilities
...
That is Javascript. Actionscript is basically Javascript (ECMAScript) with extensions. You have nice array helpers there already so don't need the ones I added to the bottom there. http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/collections/ArrayList.html

Feathers (Starling-based Adobe AIR library) List control doesn't work the second time it's instantiated

I'm having a problem with a Feathers List control. It works the first time I enter the screen that contains the list, but the second time I enter that screen in the same app execution, the scrolling list doesn't scroll at all plus texts don't appear. No error appears in the console.
I've tried lots of stuff, but I still have the same problem: It only works the first time it's instantiated. If I exit the screen and come back, it doesn't work at all!
When exiting the screen it's disposed and when coming back to that screen it's a new instance of List. Why does it work only the first time?
Also, I tried not using a custom ItemRenderer at all, so only the images appear, no text, and still the same happens. The list doesn't respond to scroll events the SECOND time is instantiated. So it's not a problem with the ItemRenderer.
Ok, here's some code:
typeList = new List();
typeList.x = Settings.appResolution[0] - Settings.menuTypeColumnWidth;
typeList.y = Settings.topBarHeight;
typeList.width = Settings.menuTypeColumnWidth;
typeList.height = Settings.appResolution[1] - Settings.topBarHeight;
typeList.dataProvider = new ListCollection(listContents);
typeList.itemRendererProperties['labelField'] = 'text';
typeList.itemRendererProperties['accessoryLabelField'] = 'articles';
typeList.itemRendererProperties['iconSourceField'] = 'thumbnail';
var listLayout:VerticalLayout = new VerticalLayout();
listLayout.gap = Settings.menuTypeItemGap;
typeList.layout = listLayout;
typeList.addEventListener(Event.CHANGE, onListChange);
typeList.itemRendererType = MenuTypeItemRenderer;
As you can see it's nothing out of the ordinary.
Thanks for your help.
Are you sure that the ListCollection used by the list is still available when the 2nd instantiation is performed?
_list.dataProvider = new ListCollection(items);
Here's a sample of code I've used. See if it offers any clues. I call the clearList function before the class is removed from the stage.
private function onAddedToStage(e:starling.events.Event):void {
removeEventListener(starling.events.Event.ADDED_TO_STAGE, onAddedToStage);
addEventListener(starling.events.Event.REMOVED_FROM_STAGE, onRemovedFromStage);
//only do this if a list does not already exist.
if(!_list){
items = new <ListItem>[];
for(var i:int = 0; i < 20; i++) {
items.push(new ListItem("Item text"));
}
_list = new List();
_list.itemRendererFactory = function():IListItemRenderer {
renderer = new ListItemRenderer();
// pass your skins in here
renderer.defaultSkin = new Image(AssetManager.getAtlas().getTexture("listItemClear_normal"));
renderer.defaultSelectedSkin = new Image(AssetManager.getAtlas().getTexture("listItemClear_selected"));
return renderer;
};
vl = new VerticalLayout();
vl.hasVariableItemDimensions = false;
_list.layout = vl;
_list.scrollerProperties.snapScrollPositionsToPixels = true;
_list.scrollerProperties.verticalScrollPolicy = Scroller.SCROLL_POLICY_AUTO;
_list.scrollerProperties.horizontalScrollPolicy = Scroller.SCROLL_POLICY_OFF;
_list.scrollerProperties.scrollBarDisplayMode = Scroller.SCROLL_BAR_DISPLAY_MODE_FLOAT;
//need to use a factory as we are not using a theme
_list.scrollerProperties.verticalScrollBarFactory = myScrollBarFactoryFunction;
_list.isSelectable = false;
_list.scrollerProperties.hasElasticEdges = true;
_list.itemRendererProperties.height = 60r;
_list.addEventListener(starling.events.Event.CHANGE, list_changeHandler);
_list.width = 320;
_list.height = StartUp._stageHeight;
addChild(_list);
_list.dataProvider = new ListCollection(items);
}
}
public function myScrollBarFactoryFunction():IScrollBar {
scrollBar = new SimpleScrollBar();
scrollBar.direction = SimpleScrollBar.DIRECTION_VERTICAL;
scrollBar.thumbProperties.defaultSkin = new Scale3Image(new Scale3Textures(AssetManager.getAtlas().getTexture("vertical-scroll-bar-thumb-skin"), 5, 14, Scale3Textures.DIRECTION_VERTICAL));
scrollBar.thumbProperties.width = 4;
scrollBar.thumbProperties.minHeight = 20;
scrollBar.width = 4;
return scrollBar;
}
public function clearList():void {
if (_list) {
scrollBar = null;
renderer = null;
vl = null;
removeChild(_list);
_list = null;
items.length = 0;
items = null;
}
}

Something like cookies in Flash/ActionScript

i need to implement something like a cookie in a flash file....and i dont have a clue about ActionScript.
Basically it is a video with a mute/unmute button. If i mute the video and refresh the browser it is not muted again.So i need to persist the mute status somehow.
Here is my complete ActionScript File:
import flash.net.SharedObject;
var a:Boolean = false;
var cookie:SharedObject = sharedobject.getLocal("muted");
if (cookie.data.muted == true) {
SoundMixer.soundTransform = new SoundTransform(0);
Object(root).ton_btn.gotoAndStop(2);
}
ton_btn.addEventListener(MouseEvent.MOUSE_OVER, fl_MouseOverHandler);
function fl_MouseOverHandler(event:MouseEvent):void
{
Object(root).ton_btn.buttonMode = true;
Object(root).ton_btn.useHandCursor = true;
}
ton_btn.addEventListener(MouseEvent.CLICK, fl_MouseClickHandler);
function fl_MouseClickHandler(event:MouseEvent):void
{
if (! a)
{
var muteStatus:Boolean = true;
cookie.data.muted = muteStatus;
SoundMixer.soundTransform = new SoundTransform(0);
Object(root).ton_btn.gotoAndStop(2);
trace(a);
}
else
{
var muteStatus:Boolean = false;
cookie.data.muted = muteStatus;
SoundMixer.soundTransform = new SoundTransform(1);
Object(root).ton_btn.gotoAndStop(1);
trace(a);
}
a = ! a;
}
This is not working, now my mute button is flickering....it seems, that the if clause is constantly executing.
Thanks for any tip, hint or link in advance. ;)
Regards
Nils
Edit:
So stupid...it was just a typo.
var cookie:SharedObject = sharedobject.getLocal("muted");
must be:
var cookie:SharedObject = SharedObject.getLocal("muted");
Now it is working.
I recommend following opensource that is popular ActionScript3.0 Cookie Frameworks. In general, two kinds of cookies in with the framework is known. Please see under open source. Solve your problem more quickly, you may give. Number 1 is a only Sourcode and Tutorial, Number 2 is a full of Frameworks.
Read and Write and Edit using a SharedObject
Actionscript3 Cookie Util

Flex mobile - increase list scrolling performance

Imagine a tablet app that displays two content areas side by side. They completely fill the display, so are 100% in height and 50% in width.
Lets assume we add a list to one container. Naturally this list will consume half the space of the whole display.
Now to my problem, is it possible that high framerate scrolling is kind of impossible with lists of this size? I've got the most basic AS3 ItemRenderer and still can't get anything higher than 30fps during scrolling. Now the odd part, if I add stuff the other container, lets say another list or other components, the list scrolling performance drops to the low 20s.
So nowhere near the 40+ fps you see Adobe advertising in their MAX shows.
I'm testing on a iPad2 and 3 and even with static values, scrolling isn't really good. Now if I enable streaming values so that the ItemRenderer's set data method is called, the framerate drops another 2 to 3 frames.
My (almost) complete renderer looks like this, but even if I strip it to just display a single textfield, disable the stuff going on in the set data and also set only the size of the single textfield in the layoutContents, performance is as described, about 30 if the list is displayed alone, low 20s if other stuff is displayed as well.
//FCStyleableTextField is just a StyleableTextField with an additional ID
private var _textFields:Vector.<FCStyleableTextField>;
private var _oldValues:Dictionary;
private var _sym:Symbol;
public function GridRenderer() {
super();
_textFields = new Vector.<FCStyleableTextField>();
_oldValues = new Dictionary();
}
override protected function createChildren():void {
var _symLabel:FCStyleableTextField = new FCStyleableTextField();
_symLabel.editable = false;
_symLabel.selectable = false;
_symLabel.multiline = false;
_symLabel.id="sym";
_symLabel.setStyle("fontSize", fontSize);
_symLabel.textColor = 0xc0c0c0;
_textFields.push(_symLabel);
addChild(_symLabel);
var fidLen:int = fids.length;
for (var i:int = 0; i<fidLen; i++) {
var _fid_lbl:FCStyleableTextField = new FCStyleableTextField();
_fid_lbl.selectable = false;
_fid_lbl.editable = false;
_fid_lbl.multiline = false;
_fid_lbl.id = String(fids[i]);
_fid_lbl.textColor = 0xc0c0c0;
_fid_lbl.setStyle("textAlign", "right");
_fid_lbl.setStyle("fontSize", fontSize);
_fid_lbl.text = " ";
_textFields.push(_fid_lbl);
addChild(_fid_lbl);
if(i>visibleColumns) {
_fid_lbl.includeInLayout = false;
_fid_lbl.visible = false;
}
}
}
override public function set data(value:Object):void {
if(!value) return;
if(data) {
// check if the value's symbolName is different than the current
// data's symbolName, if so, the itemRenderer has been
// recycled, thus we need to reset the old fid values
if((value as Symbol).symbolName != (data as Symbol).symbolName)
_oldValues = new Dictionary();
}
super.data = value;
_sym = data as Symbol;
try {
var textLen:int = _textFields.length;
for (var i:int = 0; i<textLen;i++) {
var lbl:FCStyleableTextField = _textFields[i];
if(lbl.id == "sym") {
lbl.text = _sym.symbolName;
lbl.truncateToFit();
} else {
if(lbl.id == _sym.fidList.fidMap[lbl.id].fidId && lbl.text != _sym.fidList.fidMap[lbl.id].fieldValue) {
var time:int = new Date().time;
var timerName:String = _sym.symbolName+","+lbl.id+","+grid;
globalTimer.addTimer(timerName, time, "reset", lbl, null, null);
var _oldVal:* = _oldValues[lbl.id];
var _newVal:* = _sym.fidList.fidMap[lbl.id].fieldValue;
// basic color formatting
if(Number(_newVal) > Number(_oldVal))
lbl.textColor = 0x40c040;
else if(Number(_newVal) < Number(_oldVal))
lbl.textColor = 0xf05050;
// add + to change and changePercent fids if value is positive
if(lbl.id == "56") {
if(_newVal >0)
lbl.text = "+" + _newVal;
else
lbl.text = String(_newVal);
} else if(lbl.id == "11") {
if(_newVal >0)
lbl.text = "+" + _newVal;
else
lbl.text = String(_newVal);
} else
lbl.text = String(_newVal);
if(!_sym.fidList.fidMap[lbl.id].fieldValue)
lbl.text =" ";
_oldValues[lbl.id] = _newVal;
}
}
lbl.truncateToFit();
}
} catch (e:Error) { /* nothing to do here -> try/catch required due to async symbolassembly */ }
}
override protected function layoutContents(unscaledWidth:Number, unscaledHeight:Number):void {
var viewWidth:Number = unscaledWidth - paddingLeft - paddingRight;
var viewHeight:Number = unscaledHeight - paddingTop - paddingBottom;
var _previousLabel:FCStyleableTextField;
var textLen:int = _textFields.length;
for(var i:int =0; i<textLen;i++) {
var lbl:FCStyleableTextField = _textFields[i];
graphics.beginFill(0x808080, .3);
lbl.height = viewHeight;
lbl.y = paddingTop;
if(lbl.id=="sym") {
lbl.width = 95;
} else if (lbl.id == "35000") {
lbl.width = 24;
} else {
lbl.width = optimalColWidth;
}
_previousLabel ? lbl.x = (_previousLabel.x + _previousLabel.width): lbl.x = paddingLeft;
graphics.drawRect(lbl.x+lbl.width, 1, 1, unscaledHeight-1);
lbl.commitStyles();
_previousLabel = lbl;
graphics.endFill();
}
}
Still, I'm pretty sure that it is not the item renderer that causes the slowdown, cause as I said, it costs 2, maybe 3 frames compared to a renderer that displays just a single textfield.
I rather think that Flex somehow can't handle the amount of vectors being displayed at once, is something like that possible? And is there any way to boost performance?
I already disabled live streaming values as soon as the user scrolls the list, so that flex basically just has to scroll bitmaps (since LabelItemRenderer automatically enables cacheasbitmap), but that gained maybe 4 frames.
What are your guys tricks to make scrolling a little smoother?
Figured out that using setElementSize() and setElementPosition() instead of using width/height and x/y makes quite a difference. Gained 3fps in initial scrolling performance and 8fps once every item has been rendered.
So I'm pretty close to 30fps now, still not close to what you can do with a native app, but I figure that's as good as it gets with Flex and such a massive renderer.
Also disabled live updates so that the renderer doesn't need to be cached as a bitmap again when updates come in.