why class can call the no static function? - cocos2d-x

bool GameOverLayer::init()
{
if (CCLayerColor::initWithColor(ccc4(255, 255, 255, 255))) {
return true;
}
else
{
return false;
}
}
the function initWithColor isnot static function , why i can called it with cclayercolor?
define initWithColor function as below code :
bool CCLayerColor::initWithColor(const ccColor4B& color)
{
CCSize s = CCDirector::sharedDirector()->getWinSize();
this->initWithColor(color, s.width, s.height);
return true;
}

GameOverLayer is inherited from CCLayerColor and initWithColor function is public and non-static so in code you can use this statement:
CCLayerColor::initWithColor(ccc4(255,255,255,255));
that means call inherited function from selected parent.
if you don't like this type of calling you can use:
this->initWithColor(ccc4(255,255,255,255));
if you like to know more about this type of programming read more about inheritance and multiple inheritance. you can start in here and here

Related

Is it possible to make use of a value returned from a method called by a delegate?

While experimenting with a basic coding stuff, I wondered, if a value returned by a method called by a delegate, could be used or captured. In other words, where will the return value will go ?
For example :
class Main extends Sprite
{
public var mc:MyMc;
function Main()
{
mc.addEventListener( "myClick" , myClick);
}
function myClick(e:Event):String //returning a string
{
return "What happens to this return value ???"
}
}
class MyMc extends MovieClip
{
function MyMc()
{
addEventListener( MouseEvent.CLICK , onClick);
}
function onClick(e:Event):String //returning a string
{
dispatchEvent(new Event("myClick"));
}
}
As I know it's not possible to do, but, there are at least some ways to implement the logic similar to what you've told about.
For example, you may call a method of a dispatcher, from a listener method:
class Main extends Sprite
{
public var mc:MyMc;
function Main()
{
mc.addEventListener("myClick" , myClick);
}
function myClick(e:Event):void
{
mc.specialMethod("some string");
}
}
class MyMc extends MovieClip
{
function MyMc()
{
addEventListener(MouseEvent.CLICK , onClick);
}
function onClick(e:Event):void
{
dispatchEvent(new Event("myClick"));
}
public function specialMethod(param:String):void
{
// Do something to the param
}
}
Also, you may think about dispatching an event from the Main class, and listen to it in the MyMc class, or pass a callback, which returns a string, from Main to the MyMc.
It's according to you and your needs to return something from the listener function because normally it must return nothing :
... This function must accept an Event object as its only parameter and must return nothing, ...
but you can of course get the returned value(s), take a look on this little example :
var light_on:Boolean = false;
btn_light_on.addEventListener(MouseEvent.CLICK, btn_on_onPress);
btn_light_off.addEventListener(MouseEvent.CLICK, btn_off_onPress);
function btn_on_onPress(e:MouseEvent): Boolean {
light_on = true;
if(e.target === btn_light_off){
light_on = false;
}
return light_on;
}
function btn_off_onPress(e:MouseEvent): void {
trace('The light is', btn_on_onPress(e) ? 'on' : 'off');
}
Hope that can help.

Overriding function from another class

I am defining this function in one of my classes:
public function onUse():void {};
Then in another of my classes (let's call it "class2"), I create a object of this class, and then want to override this function with another one. After some Google-Fu, I have found this, and used it...
button.onUse {
variable = value;
}
...but it executes instantly, and not when onUse() is called - which seems to be an empty function, always.
I didn't find anything more than that - I tried a few things myself, like specifying a function inside class2 and using button.onUse = function();, but it always throws errors.
Can anyone tell me whether what I am trying to do is actually possible, and if it is, how can I do it?
You can only override functions when you are extending the class:
public class A {
public function foo():void {
doStuff();
}
}
public class B extends A {
override public function foo():void {
doOtherStuff();
}
}
var n:A = new A();
n.foo(); // => calls doStuff();
var o:B = new B();
o.foo(); // => calls doOtherStuff();
Hence, assigning a different function to a class method of an instance is not possible at runtime.
You can, however, let your original class contain a field of type Function, and then simply assign a different closure to it.
public class A {
public var foo:Function;
}
var n:A = new A();
n.foo = function ():void {
doStuff();
};
n.foo(); // => calls doStuff();
var o:A = new A();
o.foo = function ():void {
doOtherStuff();
}
o.foo(); // => calls doOtherStuff();
check the syntax of
button.onUse {
variable = value;
}
a function would be defined as
public function onUse():void {};
and overwritten with
override public function onUse():void {
}
in a different class
the way you're trying to do it, does not constitute overriding a function.
What I've done in similar circumstances is create a onClickFunction function in the class
public var onClickFunction:Function = null;
and then in the CLICK event listener function add
if(onClickFunction != null){
onClickFunction();
}
then you can assign your on-click functionality by doing something like this
button.onClickFunction = function():void{
variable = value;
// dostuff
}
this is not the best way of doing it, but probably the easiest way of implementing the functionality. And ideally you'd use inheritance the way the spacepirate suggested.

How to override the transform.matrix setter

I have a class which extends the Sprite object in as3. I need to be able to override the transform.matrix setter in this class but haven't been successful in doing so.
I've tried many things, along with creating my own separate class which extends the Transform class and then overrides its set matrix function, and set my transform = new CustomTransform(). Sadly this didn't work.
In code this is what i tried:
public class MyClass extends Sprite
{
public function MyClass()
{
super(); transform = new MyTransform(this);
}
}
class MyTransform extends Transform
{
public function MyTransform(dp:DisplayObject)
{
super();
}
override public function set matrix(value:Matrix)
{
super.matrix = value;
customcode();
}
}
All help is greatly appreciated!
This seems to work:
public class MyClass extends Sprite
{
public function MyClass()
{
super();
transform = new MyTransform(this,super.transform);
// i'm drawing a rect just to see the results of scaling
graphics.beginFill(0xff0000);
graphics.drawRect(0,0,100,100);
graphics.endFill();
}
override public function get transform():Transform {
var tmp:Transform;
if(super.transform is MyTransform) {
tmp = super.transform;
} else {
tmp = new MyTransform(this,super.transform);
}
return tmp;
}
override public function set transform(value:Transform):void {
var tmp:Transform;
if(value is MyTransform) {
tmp = value;
} else {
tmp = new MyTransform(this,value);
}
super.transform = tmp;
}
}
public class MyTransform extends Transform
{
public function MyTransform(dp:DisplayObject,transf:Transform = null)
{
super(dp);
if(transf) {
for(var prop:String in transf) {
this[prop] = transf[prop];
}
}
}
override public function set matrix(value:Matrix):void
{
super.matrix = value;
// customcode();
}
}
Use:
var sp:MyClass = new MyClass();
var mat:Matrix = sp.transform.matrix;
mat.scale(3,3);
trace(sp.transform);
sp.transform.matrix = mat;
addChild(sp);
The problem is that, even if you create and assign your tranform to be of type MyTransform, the getter returns a regular Transform object. There's something weird about how transform objects work in Flash (this is also true for SoundTransform, for instance). There's some kind of cache mechanism implemented in a rather lame way that forces you to reassign the instance if you want to commit your changes.
I mean this pattern:
var t:Transform = mc.transform;
// do something with t
mc.transform = t;
So I think this is related to why your code doesn't work as expected.
To get around this, I'm checking both in the setter and the getter if the trasnform object passed is of type MyTransform. If it is, I use it as is. If it's not, I create a MyTransform object and copy all of the properties from the original Transform. It'd be nice if the Transform class had a clone method, but it doesn't, so I implemented this simple copy mechanism. Not sure if this doesn't mess up with some internal state in Transform (could be the case). I haven't tested it apart from applying a scale, once. You might want to do it, as there could be other side effects I'm not considering. Also, this is probably not the most performant. But I can't think of another way to have your matrix setter called.
Edit
Using a static/global dispatcher is not a good idea except you really need it to be global. Implementing IEventDispatcher, since you can't directly extend EventDispatcher, is what you want.
The code needed for that is a bit verbose, but it's a no-brainer anyway. All you need is having an internal instance of event dispatcher and implement the methods of the interface. In said methods, you forward the parameteres to the actual dispatcher.
public class MyTransform extends Transform implements IEventDispatcher
{
private var _dispatcher:EventDispatcher;
public function MyTransform(dp:DisplayObject,transf:Transform = null)
{
super(dp);
_dispatcher = new EventDispatcher(this);
if(transf) {
for(var prop:String in transf) {
this[prop] = transf[prop];
}
}
}
override public function set matrix(value:Matrix):void
{
super.matrix = value;
// customcode();
}
public function dispatchEvent(event:Event):Boolean {
return _dispatcher.dispatchEvent(event);
}
public function addEventListener(type:String,listener:Function,useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void {
_dispatcher.addEventListener(type,listener,useCapture,priority,useWeakReference);
}
public function removeEventListener(type:String,listener:Function,useCapture:Boolean = false):void {
_dispatcher.removeEventListener(type,listener,useCapture);
}
public function hasEventListener(type:String):Boolean {
return _dispatcher.hasEventListener(type);
}
public function willTrigger(type:String):Boolean {
return _dispatcher.willTrigger(type);
}
}

How to call "this" from an anonymous method?(flex, as)

This is my code:
public function setPaneContent(names : Array, parent : AbstractPane) : void {
//....
okButton.addEventListener(MouseEvent.CLICK, function okMouseClickHandler(e : Event) : void {
parent.addNewPane(valuesPane, parent);
PopUpManager.removePopUp(/*need to put "this"*/);
});
//.....
}
When i call PopUpManager.removePopUp(/*need to put "this"*/);, i need to make a reference at the object that contains this method(this).
So my question is: "Is it possible to make a reference at 'this' keyword within an anonymous method?"
store this to some variable: _this = this in the constructor, use _this. (it works in javascript)
You don't have to, you can call another function
public function setPaneContent(names : Array, parent : AbstractPane) : void
{
okButton.addEventListener(MouseEvent.CLICK,
function okMouseClickHandler(e : Event) :void
{
parent.addNewPane(valuesPane, parent);
// call the remove function where you can reference "this"
remove();
});
//.....
}
private function remove():void
{
PopUpManager.removePopUp(this);
}

ActionScript Custom Class With Return Type?

i just know this is a dumb question, so excuse me in advance.
i want to essentially classify a simple function in it's own .as file. the function compares integers. but i don't know how to call the class and receive a boolean return.
here's my class
package
{
public class CompareInts
{
public function CompareInts(small:int, big:int)
{
compare(small, big);
}
private function compare(small:int, big:int):Boolean
{
if (small < big)
return true;
else
return false;
}
}
}
so now i'd like to write something like this:
if (CompareInts(1, 5) == true). or output 'true' by writing trace(CompareInts(1, 5));
You have 2 options:
1) Make your compare function public and static.
static public function compare(small:int,big:int):Boolean {
{
if (small < big)
return true;
else
return false;
}
}
And call it:
CompareInts.compare(1,5);
2) You don't actually need a class. You can just use a function. As long as there's only one public definition per AS file, you'll be fine (by that I mean that at the "top" level you can have a public class, an interface, a public function, a public var or a public namespace. It won't work if you try to have more than one.
package {
public function compare(small:int,big:int):Boolean {
{
if (small < big)
return true;
else
return false;
}
}
Or, you could inline this into a single line and ditch the class / function entirely (parens are not neccesary, I just added them for clarity):
var compare:Boolean = (small < big);
You are creating a Class and then function that are members of that Class so for calling them you have to instanciate the Class and then call the function of the instance created.
Also CompareInts is the constructor of the class it can't return anything
the working code corresponding to your class will be:
package {
public class CompareInts {
public function CompareInts(){}
public function compare(small:int, big:int):Boolean {
if (small < big)
return true;
else
return false;
}
}
}
new CompareInts().compare(1, 2);
But this a litle bit overkill so what you can do is create a static function into your class and then call it directly without the needed to instanciate the class.
package {
public class Compare {
public static function compareInts(small:int, big:int):Boolean {
if (small < big)
return true;
else
return false;
}
}
}
Compare.compareInts(1, 2)
If you don't want to group more functions into a Class you can always declare a single function into a Package:
package {
public function compareInts(small:int, big:int):Boolean {
if (small < big)
return true;
else
return false;
}
}
An AS3 constructor can never have a return value. If you want to keep this method in a class, then have the constructor just call an init() function and have init() return values.
Hope that helps clear up the "why?" that might be swirling in your head.