this._parent.reorderChild is not a function when adding LayerColor to a Node - cocos2d-iphone

here is the cocos2d Javascript function
spawnGrid: function(x,y) {
var newGrid = cc.instantiate(this.gridPrefab).getComponent('Grid');
this.gameArea.addChild(newGrid.node);
newGrid.init(x,y,10);
var width = 75;
var height = 75;
var backgroundLayer = new cc.LayerColor(cc.Color.RED,width,height);
this.gameArea.addChild(backgroundLayer);
backgroundLayer.setPosition(cc.p(width * 0.5, height * 0.5));
}
when this line execute
this.gameArea.addChild(backgroundLayer);
the console show this error
Uncaught TypeError: this._parent.reorderChild is not a function
any idea?

This might be late but for future reference,
I encountered the same error while trying to draw a simple line over an empty node (960 x 460). After 30 min of frustration, I found out that there is this internal _sgNode that apparently does the trick. It may not be the best solution since it's an internal object and may change...
So in your case the temporary work around would be to access the original node using
this.gameArea._sgNode.addChild(backgroundLayer)
I hope this helps

Related

Programmatically aligning a created TButton right next to an adjacent TComponent in an FMX Frame

Referring to the picture, I would like to align a dynamically created TButton at runtime right next to a BindNavigator.
TButton *Add_But;
Add_But = new TButton(this);
Add_But->Visible = true;
Add_But->Text = "Add";
//Add_But->Position->X = 300;
//Add_But->Position->Y = 350;
Add_But->Parent=Form1->BindNavigator1;
Form1->Frame1->AddObject(Form1->StringGridBindSourceDB1);
Form1->Frame1->AddObject(Form1->BindNavigator1);
Form1->Frame1->AddObject(Add_But);
Add_But->Align=Fmx::Types::TAlignLayout::Right;
If I execute the above code, the Add_But button would align next to BindNavigator enclosed portion of the area between the last three buttons starting from the refresh button. Positioning Add_But using X,Y is not the ideal solution as I would like the Add_But to space out by certain margin padding just by using the Align property.
How to programmatically construct a TBounds margin object to resolve the issue?
Not Optimum solution using Two FlowLayout ,Believe TGridPanelLayout is much better choice , quite difficult to code correctly at runtime on cell position placement as the Main Frame is Just An Empty container refresh to hold Any child item based on selection
TFlowLayout *tlayout=new TFlowLayout(this);
tlayout->AddObject(Form1->StringGridBindSourceDB1);
TFlowLayout *tlayout1=new TFlowLayout(this);
// approximate the size of the TGrid
tlayout1->Width=600;
tlayout1->AddObject(Form1->BindNavigator1);
Add_But->Margins->Left = 10;
tlayout1->AddObject(Add_But);
tlayout->AddObject(tlayout1);
Form1->Frame1->AddObject(tlayout);
I have not written any apps in FMX but I saw no reason why you could not simply drop a TPanel on your FMX form then drop a TBindNavigator onto the TPanel unless there is a reason it can't be done this way, just trying to help.
This code works fine in Builder 10.3 on FMX Form
TButton *b = new TButton(TPanel1);
b->Parent = TPanel1;
b->Visible = true;
b->Position->X = TBindNavigator1->Width + 25;
b->Position->Y = TPanel1->Height / 2 - b->Height / 2;
b->Width = b->Width * 2;
b->Text = "Runtime Button";
How it looks when you run the code

RaphaelJS subpath on transformed path

I'm having issues with creating a subpath on a path that has been transformed. It seems that the subpath is generated with the original position of the path in reference rather than the post transform location of the path. How do I get around this?
var paper = new Raphael("canvas");
var lineParams = {
fill: "#ff0",
gradient: "90-#526c7a-#64a0c1",
stroke: "#3b4449",
"stroke-width": 2
};
var line1 = paper.path("M 0 50 h 200").attr(lineParams);
line1.transform("T100,100");
if (line1 != null) {
var lineBBox = line1.getBBox()
var lineEnd = lineBBox.x2 - lineBBox.x;
var lineTipStart = lineEnd - 10;
var lineTipString = line1.getSubpath(lineTipStart, lineEnd);
var lineTip = paper.path(lineTipString);
lineTip.attr({
"stroke-width": 2,
stroke: '#FF0000'
});
}
http://jsfiddle.net/nzwthkmo/1/
Its not so much a case of getting around it, as realising what its doing, and deciding how you want to approach it.
The original path has a transform applied to it, the path is still exactly the same. So do you want the same thing (maybe your code will be expecting that), or do you want a new modified path with new baked coordinates with the transform in place.
So depending on what you will do in the future with it, you could either
a) Simply apply the same transform to the subpath...
var lineTip = paper.path(lineTipString).transform("T100,100");
or
b) create a new path where the coordinates are all permanently transformed...
var lineTip = paper.path( Raphael.transformPath(lineTipString, "T100,100") )
fiddle with both examples (one commented out).

Removing body (balls) from physics engine

I've been trying to remove elements (balls) that have been added to the Physics engine, but I can't find a way to do it.
This is the code I'm using to add the molecules to the Physics Engine:
var numBodies = 15;
function _addMolecules() {
for (var i = 0; i < numBodies; i++) {
var radius = 20;
var molecule = new Surface({
size: [radius * 2, radius * 2],
properties: {
borderRadius: radius + 'px',
backgroundColor: '#'+(0x1000000+(Math.random())*0xffffff).toString(16).substr(1,6)
}
});
molecule.body = new Circle({
radius: radius,
mass: 2
});
this.pe.addBody(molecule.body);
this.molecules.push(molecule);
this.moleculeBodies.push(molecule.body);
molecule.state = new Modifier({origin: [0.5, 0.5]});
//** This is where I'm applying the gravity to the balls and also where I'm checking the position of each ball
molecule.state.transformFrom(addBodyTransform.bind(molecule.body));
this._add(molecule.state).add(molecule);
}
}
and on the addBodyTransform function I'm adding the gravity to the balls and checking their position, and for any that are outside the top part of the viewport I want to remove it completely (I'm only using walls on the left, right and bottom edges of the viewport).
function addBodyTransform() {
var pos;
for (var i = 0; i < thisObj.moleculeBodies.length; i++) {
pos = thisObj.moleculeBodies[i].getPosition();
if(pos[1]<(-windowY/2)){
//I tried this but it doesn't work
thisObj.pe.removeBody(thisObj.moleculeBodies[i]);
thisObj.moleculeBodies[i].render = function(){ return null; };
}
}
thisObj.gravity.applyForce(this);
return this.getTransform();
}
It doesn't work. I tried a couple of other things, but no luck. Whereas changing the position of the balls on the function above worked fine:
thisObj.moleculeBodies[i].setPosition([0, 0]);
Does anybody have any idea how to remove a body (a circle in this case)?
P.S.: thisObj is the variable I'm assign the "this" object to in the constructor function and thisObj.pe is the instance of the PhysicsEngine(). Hope that makes sense.
After some investigation, using the unminified source code and trying out different things, I realised that there was something weird going on in the library.
Having a look at the repository, I found out that the function _getBoundAgent is being used before it is defined, which matched with the error I was getting (you can check it here: https://travis-ci.org/Famous/physics). So it looks like it is a bug in the Famo.us source-code. Hopefully it will be fixed in the next release.
For the time being, I had to create a hack, which is basically detaching all agents (as well as gravity) from the balls that go outside the viewport and setting their (fixed) position far outside the viewport (about -2000px in both directions).
I know it is not the best approach (a dirty one indeed), but if you have the same problem and want to use it until they release a fix for that, here is what I did:
function addBodyTransform() {
var pos = this.body.getPosition();
//Check if balls are inside viewport
if(pos[1]<(-(windowY/2)-100)){
if(!this.removed){
//flagging ball so the code below is executed only once
this.removed = true;
//Set position (x and y) of the ball 2000px outside the viewport
this.body.setPosition([(-(windowX/2)-2000), (-(windowY/2)-2000)]);
}
return this.body.getTransform();
}else{
//Add gravity only if inside viewport
thisObj.gravity.applyForce(this.body);
return this.body.getTransform();
}
}
and on the _addMolecules function, I'm adding a "molecule.removed = false":
function _addMolecules() {
for (var i = 0; i < numBodies; i++) {
...
molecule.state = new Modifier({origin: [0.5, 0.5]});
//Flagging molecule so I know which ones are removed
molecule.removed = false;
molecule.state.transformFrom(addBodyTransform.bind(molecule));
this._add(molecule.state).add(molecule);
}
}
Again, I know it is not the best approach and I will be keen in hearing from someone with a better solution. :)

RaphaelJS hide shape onmouseout

I've created 4 rects using for loop. If you hover on any of these rects a rect will be displayed alongside. But the problem is that newly displayed rect doesn't hide on mouse out. What is wrong with my code?
JS Fiddle
window.onload = function() {
var paper = Raphael(0, 0, 640, 540);
function aa(h1,h2){
var showbox = paper.rect(h1+300,h2,100,100);
}
function ab(){
showbox.hide();
}
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
(function(i, j) {
var boxes = paper.rect(0 + (j * 100), 0 + (i * 100), 100, 100).attr({
fill: '#303030',
stroke: 'white'
});
boxes.node.onmouseover = function() {
var h1 = boxes.getBBox().x;
var h2 = boxes.getBBox().y;
aa(h1,h2);
};
boxes.node.onmouseout = function() {
ab();
};
})(i, j);
}
}
You've got javascript scope problems (plus two other smaller problems, see below).
The variable showbox is defined within function aa. So your onmouseout function can't see it. Get Firebug or your browser's equivalent up and you'll see a stack of showbox is not defined errors.
Tip: When working with Raphael, I usually create an object or array that contains all my created objects, keyed for easy access and scoped above all my Raphael-related functions so all of them can access it (see jsfiddle example below).
How to access your Raphael objects is a piece of application design you need to decide on early on, else you'll need to do lots of refactoring further down the line (been there, it hurts!).
Here's an adapted version of your code that works:
jsfiddle
Edit: I added comments explaining each change.
It also fixes two other problems:
(In the jsfiddle code) No such attr as display: none; in Raphael, try .attr({opacity:0}) or .hide()...
...BUT... don't! Your mouseover event creates rectangles, your mouseout event... hides them...? You're going to have an ever-growing stack of invisible rectangles that could eventually crash someone's browser. Either show, then hide, or create, then remove - don't create then hide!
The mouseover / mouseout events themselves are actually fine! :-)

Creating reusable objects with Raphael

I'm stuck on a simple problem (I just started using the lib):
What is the most effective way to create sets of objects, replicate them and transform them?
Creating a bunch of circles around a center point:
var height = 150,
width = 150,
branchRadius = 20,
centerX = width / 2,
centerY = height / 2,
treeCrownCenterOffset = 10,
treeCrownRotationCenterX = centerX,
treeCrownRotationCenterY = centerY - treeCrownCenterOffset,
rotationCenter = [treeCrownRotationCenterX , treeCrownRotationCenterY],
paper = Raphael('logo', height , width ),
outerCircle = paper.circle(treeCrownRotationCenterX, treeCrownRotationCenterY, branchRadius).attr({fill:'#F00'}),
innerCircle = paper.circle(treeCrownRotationCenterX, treeCrownRotationCenterY, branchRadius - 4).attr({fill:'#000'}),
branch = paper.set([outerCircle, innerCircle]),
crown = paper.set(),
numCircles = 8, rotationStep = 360 / numCircles, i = 0;
for(; i < numCircles - 1 ; i++) {
//Cloning a branch and pushing it to the crown after transforming it
crown.push(branch.clone().transform('r' + ((i + 1) * rotationStep) + ',' + rotationCenter));
}
//Putting a second crown 200px right of the first crown
//Yes, I'm building a tree :-) No trunk at this point
crown.clone().transform('t200,0');​​​​​
If you like violin, here is the fiddle.
This is my naive code, thinking a set of cloned sets (the crown of cloned branches) will indeed be moved to position (200, 0), next to the first crown.
It doesn't work: looks like a cloned set of cloned elements cannot be moved:
crown.clone().transform('t200,0');​
Not much happens when this line is executed.
Seems like "cloning" is not doing what I expect, and that the transformations are not carried to the second (cloned) collection of objects.
The basic question is:
How does one go about creating reusable objects with Raphael?
Thanks.
You are cloning the set, but since your canvas is only 150px wide, translating it by 200 pixels is sending it off the reservation :)
When you do expand the size of the canvas, however, you will see that only one circle appears to have been cloned. This is not the case. The problem is not with the cloning but the transformation.
I find transformations to be a huge headache. The line "crown.clone().transform('t200,0');​" is applying that transformation to each object in the set, but I believe it is overriding the rotation. Even if it weren't, it would be applying the translation after the rotating, sending the circles scattering as if by centrifugal force.
I know you wanted to avoid looping through the cloned set, but this works:
var crown2 = crown.clone();
for (i = 0; i < crown2.length; i ++) {
crown2[i].transform('t200,0r' + (i * rotationStep) + ',' + rotationCenter);
​}​
Also, note that you didn't add the original branch to the set. You need this:
branch = paper.set([outerCircle, innerCircle]),
crown = paper.set(),
numCircles = 8, rotationStep = 360 / numCircles, i = 0;
//ADD ORIGINAL BRANCH TO SET
crown.push(branch);
Updated fiddle.