How do I use my own custom properties on a KineticJS Sprite? - html

I am using the KineticJS Sprite object in creation of a simple HTML5 2D canvas game. I need each sprite to have certain characteristics, such as 'shield', 'firepower', 'speed', etc. So I need to add my own custom properties to the Sprite object.
Ideally I want something like:
mySpriteObj.setCustom('shield',50) // set a custom property to 50
...and then later..
var shield = mySpriteObj.getCustom('shield') // returns 50
But there doesn't appear to be anything like that. I did try to use the attr property (getAttr and setAttr) with my own custom values but this did not work.
Is there an easy way to associate your own variables with a Sprite object?
thanks
Owen

Even though getAttr() and setAttr() are the best method to do it, as long as you are not trying to save the canvas using .toJSON() and then recreate the node, you can simply assign whatever custom values directly like this:
mySpriteObj.shield = someValue;
mySpriteObj.speed = someOtherValue;
var myObjSpeed = mySpriteObj.speed;
var myObjShield = mySpriteObj.shield;
Although, you might want to share your code using getAttr() and setAttr() and try to fix error in that.

To add a method to a Kinetic.Shape you can use the addMethods function see the docs
You can check the the Kinetic Source for examples on how to use this method.
Example:
Kinetic.Util.addMethods(Kinetic.Shape, {
getCustom: function() {
//getCustom attribute code here
},
getCustom2: function() {
//getCustom attribute code here
}
});
Notice you can add multiple functions by adding more properties (functions) in the object for the second parameter of the addMethod function.
And like Ani says, you should use the getAttr() and setAttr() functions to get and set the custom attributes.
http://kineticjs.com/docs/Kinetic.Shape.html#getAttr
http://kineticjs.com/docs/Kinetic.Shape.html#setAttr

Related

AS3-Flash CS6 How to make a code that applies to all objects

Right, I am trying to make a game and I would like a bit of code that whenever I place makes something applies to all objects. For example I have: A background, Lamp, Player and Text. I would like it so I don't have to make the Lamp, Background and Text a symbol but have one bit of code that refers to them whenever I type it, so I don't have to list them all individually.
If you are looking to affect a specific, known set of display objects, you could add them into an array when they get created, and then use that array as your collection of objects to do whatever you need to.
Code here is procedural, not OOP, but should give you the gist. If you paste this into an FLA file and create the three objects (instances names) you'll have a decent sample of what this approach may be able to help you work with.
This can become more advanced, creates asa its own AS3 class, and be made smarted to handle whatever visual display changes that might be needed. But you only need ot make it as complicated as suits your needs.
var myDisplayObjs_arr:Array = [];
function addObj(obj:DisplayObject):void{
myDisplayObjs_arr.push(obj);
}
function affectObjs(config:Object):void{
// config object that includes things like alpha, colorTransform, whatever
for (var i:int = 0; i<myDisplayObjs_arr.length; i++){
var dispObj:DisplayObject = myDisplayObjs_arr[i];
if (config.alpha) {
dispObj.alpha = config.alpha;
}
if (config.scaleX) {
dispObj.scaleX = config.scaleX;
}
}
}
addObj(lamp);
addObj(background);
addObj(header_txt);
// Call affectObjs(), passing it an object of some basic changes
affectObjs({alpha:.5, scaleX:2});

Flash AS3 Creating components on stage via Button

Sorry for my complicated questioning ;)
I've created several components on my stage (Slider, TextLabel, CheckBox, ...) with the addChild(...) method. Now, if the user needs one Slider component more (for another input), I want to give him a button "addButton" (already on stage) with an CLICK addEventListener. The function which is fired in the addEventListener should create a new Slider component on stage, e.g.
addButton.addEventListener(MouseEvent.CLICK,addSlider("slid1",20,160,250,0,250,30));
The problem is to pass the parameters to the function, i need to set the new Slider to several basic values, like position, width, minimum, maximum and so on....
Can this be achieved in this way?
thx,
edwin
There are several ways you can do this. The simplest way is to call your function inside a mouse event handler:
addButton.addEventListener(MouseEvent.CLICK, addSliderHandler);
function addSliderHandler(e:MouseEvent):void {
{
addSlider("slid1",20,160,250,0,250,30);
}
EDIT (to answer your comment question):
To position your new component according to existing components, you can keep a variable reference to the position in the script and pass this as a parameter. For instance, suppose you want the first generated slider to be at y:160, and every slider to be 40px more than this, change the script to this:
var sliderY:int = 160;
addButton.addEventListener(MouseEvent.CLICK, addSliderHandler);
function addSliderHandler(e:MouseEvent):void {
{
addSlider("slid1",20,sliderY,250,0,250,30);//Pass sliderY instead of literal number
sliderY += 40;//Add 40 to sliderY
}
Now, every time you use this function to create a button it will be positioned at y = sliderY, then it will add 40 to sliderY....so the first one generated will be at 160, the next at 200, the next at 240 etc.
Hope this helps!

Customshapes in Limejs

I want to know the custom shape creation in html5 using LimeJS.Could anyone tell me how to create a custom shape like comment in a game using LimeJS for html5.
for images
var gameMap = new lime.Sprite().setSize(400,300).setFill('images/bk.jpg').setPosition(0,0).setAnchorPoint(0,0);
for custom shapes we have to fill with different points
You essentially create a custom sprite, and render the UI appropriately, which could be a combination of elements. The shell needs to be:
test.board = function() {
goog.base(this);
}
goog.inherits(test.board, lime.Sprite);
Text input isn't direct; here is an article on text input: https://groups.google.com/forum/?fromgroups=#!topic/limejs/txaxgK3eXQg. You can use a label, and attach to the key press event. I don't know if this works for canvas rendering...

Add a property to a Button or other type of Objects

I always created additional property to MovieCLips using the syntax
myMC.myProperty
without any sort of declaration... But i can use this method only with MovieClips.. What about if i want to add a property to a button or any different type of object? I need to extend the class? Do you can me suggest how? Many thanks
You can add property to movieclips in runtime because MovieClip is dynamic class. If the class is not dynamic, you should extend it to create methods and properties.
Read about dynamic classes.
I tend to create custom classes for nearly everything.
I would extend the relevant class and set up a private var for your new property. You can then pass in the value to the constructor or add a getter/setter method to call externally.
private function _myProperty:int;
public function get myProperty():int
{
return _myProperty;
}
public function set myProperty(newVal:int):void
{
_myProperty = newVal;
}
Getter/setter methods add a few lines of code that may seem unnecessary but on big projects when you find a property is being set and you don't know why, you can put a break point in your set myProperty
Subclass is main solution.
Next works only with mx components (flex sdk 3).
Most components have data : Object property that you can freely use to store data.
Monkey patching sometimes is the only way to go. It allows you to add custom properties to flex sdk classes. I don't think you should use it in your case. But I used it to change core logic that is locked by private keyword in flex sdk.
Hope that helps.

as3 Access to undefined property?

Can someone help me to find out why I'm getting the error message "Access to undefined property: removeChild(goBack)" on the following snipped?
BTW, this is for flash CS4
function nameOfFunction() {
var goBack:backButton_mc = new backButton_mc();
goBack.x = 10;
goBack.y = 700;
goBack.back_text.text = myXML.*[buildingName].NAME;
goBack.name = "backBtn";
goBack.buttonMode = true;
addChild(goBack);
goBack.addEventListener(MouseEvent.CLICK, anotherFunction);
}
function anotherFunction(e:MouseEvent):void {
removeChild(goBack);
}
You are wrong with the scope. (surprise :-D)
The variable goBack is just defined inside of "nameOfFunction", when you try to access this from a another function like "anotherFunction" it will not exists anymore (even if it is on the display list)
There are different possibilities to solve this problem:
function anotherFunction(e:MouseEvent):void {
removeChild(e.currentTarget);
}
Or the best way would be: promote goBack as a class member of the class holding both functions. (Or if you don't use classes make goBack "global".)
Hippo is correct, but I feel it is important to explain a little more.
You created a local variable, i.e. var someVariable:DataType; within a function. This means that that variable will only be available to objects in the scope (inside) of the function (local to), and it will only last for the lifetime of the function. Soon as that function has ran the code is gone until ran again. It looks like you are probable programming directly inside the flash IDE on the time-line, which is fine, but, if you were using a document class, you could merely declare you variable in the Class scope just above the constructor function, and then set the value in the same function that your using now. This way, the reference to the variable doesn't exist within the function, it is merely set from within. This will allow that variable to be accessed from anywhere in the same class even if set to private.
This may help:
//Frame 1, Actions layer
//Slap goBack right onto the root / stage
var goBack:MovieClip;
/*
I noticed you had this data-typed differently,
i prefer to type to an interface, not an implementation.
Since your class is a movieclip in the library it extends
MovieClip and therefor IS A MovieClip, but ok either way.
*/
function nameOfFunction():void
{
goBack = new backButton_mc();
goBack.x = 10;
goBack.y = 700;
goBack.back_text.text = myXML.*[buildingName].NAME;
goBack.name = "backBtn";
goBack.buttonMode = true;
addChild(goBack);
goBack.addEventListener(MouseEvent.CLICK, anotherFunction);
}
function anotherFunction(e:MouseEvent):void
{
removeChild(goBack);
}
Scope is very important and after a while very easy to tackle. Stick with it, experiment, read up on conventions and standards that can help your development and get to loving the DocumentClass becuase even though it may be daunting to some at first, once you learn it and get used to it, it so hard to go back to programming in the flash IDE on the timeline, where I believe only display objects and audio have any place being.