Reputation: 2102
Iv looked around online for a solution to this issue but iv been unable to solve it.
I want to extend the sprite class to make my own interactive circle. Everything works but setting the X,Y, Width and height of the custom class does not work:
class CircleDraw extends Sprite
{
public function new(x:Int,y:Int,width:Int,height:Int)
{
super();
this.x = x;
this.y = y;
this.width = width;
this.height = height;
drawCircle();
}
private function drawCircle()
{
this.graphics.beginFill(0xffffff);
this.graphics.drawCircle(this.x,this.y, this.width);
this.graphics.endFill();
}
}
The approach above does not work as expected, setting x,y and width via the constructor results in literally nothing appearing. Yet if i set them manually, either within the class
this.graphics.drawCircle(200,200, 30);
Or prior to addChild:
circle = new CircleDraw(10,10,100,200);
circle.x=100;
circle.y=100;
it then appears on screen. also after adding it like so once the values have been added manually within the class rather than this.x etc:
circle = new CircleDraw(10,10,100,200);
addChild(circle);
So my question is this, how do i extend a class (Sprite) and allow the constructor to modify its parents default variables and keep the values?
Just to provide all the code as requested:
This does not work:
circle = new CircleDraw(10,10,100,200);
addChild(circle);
when Circle draw is like this:
class CircleDraw extends Sprite
{
public function new(x:Int,y:Int,width:Int,height:Int)
{
super();
this.x = x;
this.y = y;
this.width = width;
this.height = height;
drawCircle();
}
private function drawCircle()
{
this.graphics.beginFill(0xffffff);
this.graphics.drawCircle(this.x, this.y, this.width);
this.graphics.endFill();
}
}
It does work if i modify the method:
private function drawCircle()
{
this.graphics.beginFill(0xffffff);
this.graphics.drawCircle(200, 200, 30);
this.graphics.endFill();
}
Or if during the instancing of the object i set the X and Y variables as mentioned before the edit.
Upvotes: 1
Views: 176
Reputation: 96
Be aware, that you are kind of dealing with 2 coordinate spaces. The one were the Sprite will be added and the graphics object of that Sprite. If you set this.x
and this.width
you are actually setting properties of this Sprite. So in regards of positing you are moving the Sprite itself in that case. The Sprite "graphics" property has it's own coordinate space.
For example if you pass x=100
in your CircleDraw constructor function you are first moving the sprite itself by x=100
and then draw the circle with an x offset of 100. So if you would add the sprite directly to the Stage you would start drawing your circle actually at x=200
, because you effectively applied the position twice. It seems to me this is not what you actually are intending.
Also your CircleDraw instance (which is also a Sprite of course) is "empty" when you are constructing it. So calling this.width = width
in your constructor has no effect. this.width
will stay 0 because the Sprite has no contents at that point. So in the drawCircle method you are drawing a circle with a width
of 0.
Probably the better solution would be to simply pass the arguments of your constructor function to your drawCircle function, without setting any properties.
Upvotes: 2
Reputation: 1557
You are indeed setting the base class variables successfully, it's just that DisplayObject.width
has a rather specific (and perhaps not that obvious) behavior.
width:Float
Indicates the width of the display object, in pixels. The width is calculated based on the bounds of the content of the display object. When you set the width property, the
scaleX
property is adjusted accordingly, as shown in the following code:Except for TextField and Video objects, a display object with no content(such as an empty sprite) has a width of 0, even if you try to set
width
to a different value.
—OpenFL API: DisplayObject: width
In this sense, OpenFL follows the ActionScript 3.0 API.
Upvotes: 3
Reputation: 982
From the (partial) code you posted, it looks it should work.
In other words, setting parent's variables like that should work.
I doubt there are some other code you didn't post gets in the way. I suggest you print out the x, y values in the drawCircle call to debug.
I also doubt the circle is drawn off-screen so you can't see it. Because you first moved the sprite, to (x,y) and then draw a circle in (x,y) inside the sprite. So effectively the circle is at (2x,2y) in global space
EDIT:
this.graphics.drawCircle(200,200, 30);
You claim this worked. Should draw at (210,210) with radius 30
circle = new CircleDraw(10,10,100,200);
circle.x=100;
circle.y=100;
You claim this worked. Should draw at (200,200) with radius 100
circle = new CircleDraw(10,10,100,200);
addChild(circle);
You claim this didn't work. Should draw at (20,20) with radius 100
From the above three version, you are actually drawing at different places with different sizes. So I still suspect that "didn't work" may due to the fact that you are drawing at some places not in sight.
So I still suggest you print out the value of x, y, width inside the private drawCircle function to see what's happening
Upvotes: 2
Reputation: 4888
From what I can surmise, it looks like you're trying to override a constructor (new) that takes no arguments.
I'm not entirely sure, but that might not get you what you want. What I think you're actually doing is just creating a method "new" on the extended class, and then within it, feeding the parent nothing (super()). So the parent will not have the constructor arguments. It would be interesting to do look at that object in a debugger and look at the instance properties vs. the parent ones.
There's probably a way around that, but I think you might want to look at doing this via composition instead of inheritance. For example, in "new", create a new instance of a sprite, and manipulate the properties of that.
class MySprite
{
public var sprite : Sprite;
public function new ( ) {
sprite = new Sprite ();
}
}
You would then perform your operations on that sprite instance. Essentially, you are just wrapping a sprite in your own class. Decorator, more or less.
I found some reference to the topic here (it's been a while since I did any Flash programming), it shows addChild and removeChild implementations, etc.
http://old.haxe.org/forum/thread/685
Upvotes: 2