What's the difference manipulating display object position? - apache-flex

I have 2 possibilities. It looks like these are the same (or I'm wrong). Which is better and why?
var quest1:DisplayObject = FrameCanvas.baseCanvas.addChild(app.questionmark1); //
quest1.x = posX; //
quest1.y = posY; //
or
app.questionmark1.x = posX;
app.questionmark1.y = posY;

In the first example quest1 is a reference to app.questionmark1 which you are adding to FrameCanvas.baseCanvas and then updating its x and y.
In the second example you are directly setting the x and y on app.questionmark1.
Both work to update app.questionmark1's x and y properties, but in the second example app.questionmark1 may not be on the stage unless you added it somewhere else in the code.
The second example is better because there's really not a reason to store a reference to app.questionmark1 as quest1 as you already can access it by app.questionmark1.

Related

Godot saving variable path from one .gd to another .gd

I have in a global gdscript, and inside i have
var number1 = 0
var number2 = 0,
which normally could be accessed by any gdscript by global.number1 and global.number2.
Then i have a different script with a Dictionary inside that holds some values.
How can i make it work like this(see following):
var dict = {0: {path = "global.number1"}, {1: {path = "global.number2"}}
and then, instead of using several if-statements if i want to expand the number of objects in the dictionary, i can do this:
dict[n].path += 1
I dont really know what are you actually asking, but maybe you forgot to set the path to global in the second script?
Anyway you should clarify what's the question.

How to tell if an object has been touch by the player in gml code

Hey am going to give an example of what am trying to do imagine that i have 5 circle sprites and in my gml code i want to do something like this if cirlce_1 was touch then you can touch circle_2 and if circle_2 was touch then you can touch cirlce_3. Please who can help me with this, willing to give a reward via paypal.
Touch events in Game Maker are treated as mouse events. If you want the circles to only allow the player to touch them in order, you can assign each one to have a number and make them all the same object. Take a look at this:
Script to create circles
counter = 0;
lastball = 0;
for(i = 0; i < 10; i++){//Make that third part "i += 1" if using a version before Studio
c = instance_create(floor(random(room_width)), floor(random(room_height)), objCircle);
lastball++;
c.myNum = lastball;
c.radius = 16;//Or whatever radius you want
};
The for statement here automatically generates circles around the room, but if you want manual control, try this:
newCircle()
c = instance_create(argument0, argument1, objCircle);
c.myNum = lastball;
c.radius = 16;
lastball++;
This will create a new circle wherever you want and will automatically increment lastball as well every time it's called. For instance, you could say newCircle(16, 27);.
In the step code for objCircle
if(mouse_check_button_pressed(mb_left) && point_distance(x, y, mouse_x, mouse_y) < radius && counter == myNum){
counter++;//Or counter += 1 in versions before Studio
//Insert whatever circles do when clicked here
};
The circles can be made to do anything when clicked. Since they're all the same object, perhaps you could use a switch statement so each one does something different depending on its number.
Let me know if there's anything else I can help with.

Qt: Using QTransform object for rotate differs from setting setRotation() in QGraphicsItem

While setting a QGraphicsItem rotation, I get different results upon the transformation origin point while using setRotation() and using:
transform = QTransform()
transform.rotate(myAngle)
myItem.setTransform(transform)
In both portion of code, I set setTransformOriginPoint() to the same point.
Results are:
While using setRotation() method, the item is rotated upon its transformation origin point.
While using the QTransform object, the item is rotated upon item's origin, that is, point (0,0).
My code is more complex than that, but I think It applies the same. The QGraphicsItem is in fact a QGraphicsItemGroup and I can check the issue adding just one item, and in my rotation procedure change the setRotation() method for the QTransform object. The latter, ignores the setTransformOriginPoint().
I'm having this issue for a while, and I dig a lot of resources. I browse the Qt C++ code, and I can see that the setRotation() method modifies a field calles rotation (a real value) in the TransformData structure within the QGraphicsItem. The origin point is also a two field real value in such a structure called xOrigin and yOrigin respectively. The transformation is stored in the tranform field. All this information is used in a variable called: transformData.
So, I don't get why the transformation set in the transformData->transform field is ignoring the values transformData->xOrigin and transformData->yOrigin at the time of being applied.
The code I used to test that issue is the following relevant part (I have an rotate item that receives mouse inputs and applies rotation to the item itself):
# This method using QTransform object....
def mouseMoveEvent(self, event):
if self.pressed:
parent = self.parentItem()
parentPos = parent.boundingRect().center()
newPoint = event.scenePos()
iNumber = (newPoint.x()-parentPos.x())-((newPoint.y()-parentPos.y()))*1j
angle = cmath.phase(iNumber)+1.5*math.pi
self.appliedRotation = (360-math.degrees(angle))%360 - self.angleOffset
transform = QTransform()
transform.rotate(self.appliedRotation)
self.parentItem().setTransform(transform)
# ...Against this one using setRotation()
def mouseMoveEvent(self, event):
if self.pressed:
parent = self.parentItem()
parentPos = parent.boundingRect().center()
newPoint = event.scenePos()
iNumber = (newPoint.x()-parentPos.x())-((newPoint.y()-parentPos.y()))*1j
angle = cmath.phase(iNumber)+1.5*math.pi
self.appliedRotation = (360-math.degrees(angle))%360 - self.angleOffset
self.parentItem().setRotation(self.appliedRotation)
On both, previously the setTransformOriginPoint() is set, but it's not a relevant part to show the code, but just to know that it is done.
I'm getting frustrated to not find a solution to it. As it seems so straightforward, why setting a rotation transformation matrix does not use the transformation origin point that I have set and while using setRotation() method works fine? That question took me to the source code, but now is more confusing as rotation is keeping separated from the transformation applied...
I was solving the same problem. I found out that QGraphicsItem::setTransformOriginPoint() is accepted only for QGraphicsItem::setRotation(). It is ignored for QGraphicsItem::setTransform().
I use this code to reach the same behavior for QTransform():
transform = QtGui.QTransform()
centerX = item.boundingRect().width()/2
centerY = item.boundingRect().height()/2
transform.translate( centerX , centerY )
transform.rotate( -rotation )
transform.translate( -centerX , -centerY )
item.setTransform( transform )

Flex Charts: Can you use a minimum/maximum point from an IAxis for Cartesian Data Canvas to draw the entire width of the chart?

I have a chart with a DateTime axis as my horizontal and a Linear Axis for my vertical inside a Adobe Flex Line Chart. I want to use a Cartesian Data Canvas as a background element and draw custom set of background graphics mostly rectangles. When I have more than a single data point, the graphics work perfectly since they are supposed to span the width of the entire chart.
When I have only a single data point, however, I can't seem to get the rectangles to draw. Since I want my rectangles to span the entire width of the chart, I was thinking that I could get the x-coordinates from my axis, but this isn't working.
var canvasWidth:Number = chtCanvas.width;
var canvasHeight:Number = chtCanvas.height;
var minPt:Array;
var maxPt:Array;
var minPtDate:Date;
var maxPtDate:Date;
var minPtComplete:Point;
var maxPtComplete:Point;
// This works fine when there is more than 1 data point
minPt = chtCanvas.localToData(new Point(0, 0));
maxPt = chtCanvas.localToData(new Point(canvasWidth,canvasHeight));
//This does return a date object, but wont draw below
minPtDate = axisDate.minimum;
maxPtDate = axisDate.maximum;
//This returns NaN for the x
minPtComplete = chtCanvas.dataToLocal(minPtDate, axisSalary.minimum);
maxPtComplete = chtCanvas.dataToLocal(maxPtDate, axisSalary.maximum);
// Also tried this. Also returns NaN for the x value
//minPtComplete = chtCanvas.dataToLocal(axisDate.minimum, axisSalary.minumum);
//maxPtComplete = chtCanvas.dataToLocal(axisDate.maximum, axisSalary.maximum);
My actual drawing method is as follows:
// Tried this, works with points >2, does not draw with single data point
chtCanvas.drawRect(minPt[0], detail[i].MaxValue, maxPt[0], detail[i].MinValue);
//tried this, no effect with single point
//chtCanvas.drawRect(minPtDate, detail[i].MaxValue, maxPtDate, detail[i].MinValue);
// Tried this, no effect with single point
//chtCanvas.drawRect(minPtDate, minPt[1], maxPtDate, detail[i].MinValue);
// Tried this also
//chtCanvas.drawRect(minPtComplete.x, detail[i].MaxValue, maxPtComplete.x, detail[i].MinValue);
In this example, detail is an array collection of salary values and Im using the data value in the array to determine the vertical bounds of my rectangles.
I need to draw the rectangles the entire width of the chart (even when there is only a single data point). Thanks
Thanks to Heikki for his help. The following code works to use the axis values to draw on your Cartesian Data Canvas:
chtCanvas.drawRect(axisDate.minimum as Date, axisSalary.maximum, axisDate.maximum as Date, axisSalary.minimum);
Casting the values as Date really helped. The rest of the code used above is unecessary.
One thing to note, I was using a DateFormatter to format the date values from my data. What I didn't consider was that when using a DateTimeAxis, Flex will automatically add in extra dates to display on the axis. In my case, I was using a custom parse function to create MY points, but wasnt considering the points Flex was creating and also passing to my parse function (Therefore, they were not getting parsed correctly). Once I corrected this, the values laid out correctly in the case of multiple data points. I'm still having a bit of an issue with single data points and them not filling the chart entirely, but they are now drawing.
UPDATE:
Although there are signs of life, the minimum and maximum are still not drawing the entire width of the chart in some cases depending on the dataUnits and labelUnits combination.
UPDATE #2: SOLVED
Ok, so the axis does work as minimum/maximum values for the Cartesian Data Canvas but there is something important to remember. For a single point (and probably for multiple points as well, I just couldnt visually see the difference), when using a custom DateTimeAxis parse function such as what was in the Adobe Flex ASDoc tutorials:
private function axisDateParseFunction(item:String):Date
{
var inputDate:String = item;
inputDate = fmtDate.format(inputDate);
var newDate:Date = new Date();
if(inputDate)
{
var a:Array = inputDate.split('/');
newDate.fullYear = a[2];
newDate.month = a[0] - 1;
newDate.date = a[1];
newDate.hours = 0;
newDate.hoursUTC = 0;
newDate.minutes = 0;
newDate.minutesUTC = 0;
newDate.seconds = 0;
newDate.secondsUTC = 0;
newDate.milliseconds = 0;
newDate.millisecondsUTC = 0;
}
return newDate;
}
You MUST remember to set the UTC values as shown above also. Since the DateTimeAxis uses date AND time, when you create new Date objects, their time values also get set to the local system time. Remember to set those values to zero also or you will get points that dont exactly line up with your axis labels.

How do I create variable paths using e4X?

I need to know how I can parse a variable path in Flex 3 & e4X. For example, I have two XML strings where the name of one element is the only difference.
<NameOfRoot>
<NameOfChild1>
<data>1</data>
</NameOfChild1>
</NameOfRoot>
<NameOfRoot>
<NameOfChild2>
<data>2</data>
</NameOfChild2>
</NameOfRoot>
Currently I am accessing variables like this:
var data1:String = NameOfRoot.*::NameOfChild1.*::data;
var data2:String = NameOfRoot.*::NameOfChild2.*::data;
I would rather make this task more abstract so that if "NameOfChild3" is introduced I do not need to update the code. For example:
var data:String = NameOfRoot.*::{variable}.*::data;
Does anyone have insights into how this can be done?
Use the child property (LiveDocs example here):
var tagName:String = "NameOfChild1";
var data:String = NameOfRoot.child(tagName).data;
That's with no namespacing--not sure whether it's necessary in your case, but I assume you'd add some *::'s?
this also works:
var data:String = NameOfRoot..data;
but if you have more than 1 data node you'll have to sort some stuff out.
It looks like the ".*." operation will work. I wonder if this is the easiest way to handle this problem.
var data:String = NameOfRoot.*.*::data;

Resources