AS3 : accessing variable value - actionscript

I have on stage 3 buttons every button should play a sound ... i'm trying to
make the class code dynamic .But i'm stuck with a problem please see the code .
i need help ! fla link & class link
i want to get the String inside the variable not only the name .
package
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class CustumClass extends MovieClip
{
private var R1:String ="im a string inside R1";
private var R2:String ="im a string inside R2";
private var R3:String = "im a string inside R3";
private var btns:Array;
private var link:String;
public function CustumClass()
{
// constructor code
btns = new Array(r1,r2,r3); //___ buttons on stage
onLoop();
}
private function onLoop():void
{
for (var i:int = 0; i<btns.length; i++)
{
btns[i].addEventListener(MouseEvent.CLICK,handleBtn);
}
}
private function handleBtn(e:MouseEvent):void
{
// ____ i want to get the string inside variable
link = e.target.name.toUpperCase();
trace (link);
}
}
}

Instead of storing your buttons in an Array
private var btns:Array;
use a Dictionary
private var buttons:Dictionary = new Dictionary();
Then add each reference to a button along with the String that you want to associate with it
// constructor code
buttons[r1] = "text for r1";
buttons[r2] = "text for r2";
buttons[r3] = "text for r3";
onLoop();
You can iterate over the keys.
private function onLoop():void
{
for (var button:Object in buttons)
{
button.addEventListener(MouseEvent.CLICK,handleBtn);
// if above fails, try something like
IEventListener(button).addEventListener(MouseEvent.CLICK,handleBtn);
}
}
You can retrieve a value with a key
private function handleBtn(e:MouseEvent):void
{
trace (buttons[e.currentTarget]);
}

Related

Constructor with not initialized final class variables

I have this class:
class Entry {
final String id;
final List<ListEntry> listEntries;
Entry({this.listEntries}):
id = Uuid().v4();
Entry.withId({this.id, this.listEntries});
}
// create new class instance
var e = Entry();
Now when I call any method on e.listEntries I will get a NPE because it is not initialized. Is there a way to have it default to an empty list in case the constructor argument is not provided?
You can use a Factory constructor:
class Entry {
final String id;
final List<String> listEntries;
factory Entry({List<String> listEntries}) {
return Entry._(listEntries ?? []);
}
Entry._(this.listEntries):
id = Uuid().v4();
Entry.withId({this.id, this.listEntries});
}
You can initialize the field in the initializer list instead of using this.ListEntries (an initializing formal).
class Entry {
final String id;
final List<ListEntry> listEntries;
Entry({List<ListEntry> listEntries})
: this.withId(id: Uuid().v4(), listEntries: listEntries);
Entry.withId({this.id, this.listEntries})
: listEntries = listEntries ?? [];
}
// create new class instance
var e = Entry();
Here I reuse the Entry.withId constructor so I only have to write things once.

1067: Implicit Coercion of a value

So I'm currently trying to run my collision test on my two sprites, and I'm getting the following error:
C:\\Code\\Game\Game.as, Line 54, Column 34 1067: Implicit coercion of a value of type mvc:PlayerModel to an unrelated type assets.Scripts:SpriteAnimation.
Which is pointing to the following line of code:
handleSpriteToSpriteCollision(_player, _boss);
The function is as follows:
private function handleSpriteToSpriteCollision(sprite1:SpriteAnimation, sprite2:SpriteAnimation):void
{
var toSprite2 : VectorModel = new
VectorModel(0,0,0,0, sprite2.x - sprite1.x, sprite2.y - sprite1.y);
var bitmapData1:BitmapData = new BitmapData(sprite1.width, sprite1.height);
while(testBitmapCollision(sprite1.spriteFrameBitmapData, sprite1.topLeftX, sprite1.topLeftY, sprite2.spriteFrameBitmapData, sprite2.topLeftX, sprite2.topLeftY))
{
sprite2.x -= toSprite2.dx;
sprite2.y -= toSprite2.dy;
}
}
Both sprites display just fine, but as soon as I make the function call it all comes crumbling down. At this point I just need some fresh eyes to take a look at the code to see what's going wrong.
Edit: Here is the PlayerModel.as
package mvc
{
import flash.events.Event;
import flash.events.EventDispatcher;
import assets.Scripts.SpriteAnimation;
public class PlayerModel extends EventDispatcher
{
private var _previousX:Number = 0;
private var _previousY:Number = 0;
private var _xPos:Number = 0;
private var _yPos:Number = 0;
public var vx:Number = 0;
public var vy:Number = 0;
private var _height:uint = 30;
private var _width:uint;
private var _color:uint;
public function PlayerModel():void
{
}
public function update():void
{
xPos += vx;
yPos += vy;
}
public function get height():uint
{
return _height;
}
public function get color():uint
{
return _color;
}
public function get xPos():Number
{
return _xPos;
}
public function set xPos(value:Number):void
{
_xPos = value;
dispatchEvent(new Event(Event.CHANGE));
}
public function get yPos():Number
{
return _yPos;
}
public function set yPos(value:Number):void
{
_yPos = value;
dispatchEvent(new Event(Event.CHANGE));
}
public function set setX(value:Number):void
{
_previousX = value - vx;
xPos = value;
}
public function set setY(value:Number):void
{
_previousY = value - vy;
yPos = value;
}
}
}
The first thing i would check is the class of your boss and player objects inherit your SpriteAnimation class:
class PlayerModel extends SpriteAnimation
{ ...
Seems as though your handleSpriteToSpriteCollision function is looking for two SpriteAnimations and at least the PlayerModel being passed isn't one
Sprite inherits EventDispatcher so as long as your SpriteAnimation inherits Sprite as well, you shouldn't lose any functionality

DataBinding is not working properly in custom list itemrenderer

I am developing iPad application using Flex/Air.
I have problem with data binding in custom list item renderer.
I have list with a collection of Classes as data provider.
Each class have a static property enabled. I display each class using an item renderer, where my item renderer is enabled when the Class property is enabled.
The classes look like that:
public class MyClass
{
public static const var name:String = "My Class";
private static var enabled:Boolean = false;
[Bindable]
public static function get enabled():Boolean
{
return enabled;
}
public static function set enabled(value:Boolean):Boolean
{
enabled = value;
}
}
Then I have the list:
<list dataProvider={new ArrayCollection([MyClass])} itemRenderer="CustomItemRenderer"/>
And the CustomItemRenderer looks like that:
<s:ItemRenderer autoDrawBackground="false" enabled={data.enabled}>
<s:label text={data.name}/>
<s:/ItemRenderer>
So when I change the enabeled property of MyClass, the list is not updated.
The item renderer is still disabeled.
MyClass.enabeled = true;
Do you have any idea what the problem can be?
Thank you in advance!
Ivan
Try this (I edited the code without IDE, it should be correct thought):
// to dispatch a custom event your class needs to extends the EventDispatcher Class.
public class MyClass extends EventDispatcher
{
public static const var name:String = "My Class";
private static var _enabled:Boolean = false;
// getter & setter with dispatchEvent could not be static...
// instead the getter/setter for enabled, will change the static _enabled value.
[Bindable(event="enabledChange")]
public function get enabled():Boolean
{
return _enabled;
}
public function set enabled(value:Boolean):void
{
_enabled = value;
dispatchEvent(new Event("enabledChange"));
}
}

Dynamic class method invocation in Dart

Like the question at Dynamic class method invocation in PHP I want to do this in Dart.
var = "name";
page.${var} = value;
page.save();
Is that possible?
There are several things you can achieve with Mirrors.
Here's an example how to set values of classes and how to call methods dynamically:
import 'dart:mirrors';
class Page {
var name;
method() {
print('called!');
}
}
void main() {
var page = new Page();
var im = reflect(page);
// Set values.
im.setField("name", "some value").then((temp) => print(page.name));
// Call methods.
im.invoke("method", []);
}
In case you wonder, im is an InstanceMirror, which basically reflects the page instance.
There is also another question: Is there a way to dynamically call a method or set an instance variable in a class in Dart?
You can use Dart Mirror API to do such thing. Mirror API is not fully implemented now but here's how it could work :
import 'dart:mirrors';
class Page {
String name;
}
main() {
final page = new Page();
var value = "value";
InstanceMirror im = reflect(page);
im.setField("name", value).then((_){
print(page.name); // display "value"
});
}
You can use Serializable
For example:
import 'package:serializable/serializable.dart';
#serializable
class Page extends _$PageSerializable {
String name;
}
main() {
final page = new Page();
var attribute = "name";
var value = "value";
page["name"] = value;
page[attribute] = value;
print("page.name: ${page['name']}");
}

Can I instantiate a class from a Runtime Shared Library through an interface?

In my Runtime Shred Library SWF I have a class named BackButton that extends MovieClip and interfaces IGameButton:
package com.game.button
{
import com.interfaces.IGameButton;
import flash.text.TextField;
public class BackButton extends MovieClip implements IGameButton
{
public var labelTxt:TextField;
public function BackButton()
{
super();
}
public function get label():String
{
return labelTxt.text;
}
public function set label(value:String):void
{
labelTxt.text = value;
}
}
}
When I load the RSL into my main SWF by doing the following:
var backButtonClassName:String = "com.game.button.BackButton";
var BackButtonClass:Class = getDefinitionByName(backButtonClassName) as Class;
var backButton:IGameButton = new BackButtonClass();
I get the following error at runtime:
Type Coercion failed: cannot convert com.game.button::BackButton#bb12af1 to com.interfaces.IGameButton.
What am I doing wrong?
Your getDefinition call needs to reference the ApplicationDomain which must be set in your loader context:
public function loadHandler(e:Event) : void {
var loaderInfo:LoaderInfo = e.target as LoaderInfo;
var BackButtonClass : Class = loaderInfo.applicationDomain.getDefinition( "com.game.button.BackButton" );
}
var loader : Loader = new Loader();
var context : LoaderContext = new LoaderContext();
context.applicationDomain = ApplicationDomain.currentDomain;
loader.load( new URLRequest("backbutton.swf"), context );

Resources