I have a larger project, but I can narrow my problem down to this example:
public function Main()
{
var myContainer:Sprite = new Sprite;
myContainer.graphics.beginFill(0xFFFFFF);
myContainer.graphics.lineStyle(1);
myContainer.graphics.drawRect(10, 10, 300, 300);
myContainer.graphics.endFill();
addChild(myContainer);
trace('Container coords: ' + myContainer.x + ' ' + myContainer.y);
trace('Instance coords: ' + getChildAt(numChildren - 1).x + ' ' + getChildAt(numChildren - 1).y);
var spr:Sprite = new Sprite;
spr.graphics.beginFill(0xFF0000);
spr.graphics.lineStyle(1);
spr.graphics.drawCircle(30, 30, 10);
spr.graphics.endFill();
myContainer.addChild(spr);
trace('Child coords: ' + spr.x + ' ' + spr.y);
trace('Child instance coords: ' + myContainer.getChildAt(myContainer.numChildren - 1).x + ' ' + myContainer.getChildAt(myContainer.numChildren - 1).y);
}
The output is this:
Container coords: 0 0
Instance coords: 0 0
Child coords: 0 0
Child instance coords: 0 0
Can someone explain how to get the actual coordinates of a child sprite within a sprite (either local or global, I know you can convert between the two)?
your myContainer not set x,y. only has been set graphics draw coordinates (10,10). spr versa.
see a following code. this code some different, but visual output same. Is set to 10 the parent's coordinates. draw coordinates set (0,0). so myContainer x,y is 10 and i think, you are slightly mistaken. getChildAt(numChildren-1) is myContainer. so this coordinats also same. myContainer not have any children. graphics is not a child concept. Additionally, child coordinates is relative from parent.
var myContainer:Sprite = new Sprite;
myContainer.x = 10;
myContainer.y = 10;
myContainer.graphics.beginFill(0xFFFFFF);
myContainer.graphics.lineStyle(1);
myContainer.graphics.drawRect(0, 0, 300, 300);
myContainer.graphics.endFill();
addChild(myContainer);
//myContainer.x = 10, myContainer.y=10
//getChildAt(numChildren - 1).x = 10, getChildAt(numChildren - 1).y = 10
your code as follows:
my code as follows:
try this!
var point:Point = new Point(spr.x, spr.y);
point = localToGlobal(point);
trace('Child coords: ' + point);
Related
I am using the markup extension that can be found at https://github.com/wallabyway/markupExt and have not changed the code within the extension except setting this.size to a bigger value to make the marker easier to find
the actual rendering of the points works fine I just can't seem to place them in a specific position on the model, they just appear floating off in the middle of empty space.
Code to generate the point
var dummyData = [];
dummyData.push({
icon: Math.round(Math.random() * 3),
x: 129597.054373,
y: -27184.841094,
z: 44514.362733
});
window.dispatchEvent(new CustomEvent('newData', { 'detail': dummyData }));
I have tried feeding it values taken straight from a selected items properties and have also tried feeding it values taken from the following code (I have tried with and without the nominalise step)
function onMouseClick(event) {
var screenPoint = {
x: event.clientX,
y: event.clientY
};
var n = normalizeCoords(screenPoint)
var hitTest = viewer.impl.hitTest(n.x, n.y, true);
if (hitTest) {
alert(hitTest.intersectPoint.x + ' ' + ' ' + hitTest.intersectPoint.y + ' ' + hitTest.intersectPoint.z)
}
}
function normalizeCoords(screenPoint) {
var viewport = viewer.navigation.getScreenViewport();
var n = {
x: (screenPoint.x - viewport.left) / viewport.width,
y: (screenPoint.y - viewport.top) / viewport.height
};
return n;
}
The point moves when i change the x y z values but never to where I want them and am not sure where I am going wrong
Rather than the code found in the other extensions that uses the viewport to offset the point I seem to have fixed it by adding viewer.model.getData().globalOffset to the hit test intersection values
i have one swf which looks like below image
OBJECTIVE:-want to rotate the red colored line swf along center as per given image
i have conditions like
x-axis,y axis,x=1,x=y,x=-y
my first two conditions are shown in the images.
for the next three conditions the images are
You can do this either with a matrix translation and rotation, or by finding the objects center, rotating the object, and then translating it back (which is basically the same thing as the matrix technique).
The matrix way:
var mat:Matrix = spr.transform.matrix;
var bounds:Rectangle = spr.getBounds( spr.parent );
mat.translate( -(bounds.left + bounds.width/2), -(bounds.top + bounds.height/2 ) );
mat.rotate( degree * Math.PI / 180 ); //rotate amount
mat.translate( bounds.left + bounds.width/2, bounds.top + bounds.height/2 );
spr.transform.matrix = mat;
Without matrix:
var bounds:Rectangle = spr.getBounds( spr.parent );
var center:Point = new Point( bounds.x + bounds.width/2, bounds.y + bounds.height/2 );
spr.rotation = degree; //rotate amount
bounds = spr.getBounds( spr.parent );
var newCenter:Point = new Point( bounds.x + bounds.width/2, bounds.y + bounds.height/2 );
spr.x += center.x - newCenter.x;
spr.y += center.y - newCenter.y;
I'm using FlashDevelop to test a menu-type system that I want to use for a game, and I'm having serious issues figuring out either the Width and Height or the ScaleX and ScaleY (I'm not really sure which set is causing the problems) of the Sprite subclasses. I've read many things that seem to be the solution to my problem, including resizing the sprite subclass after I add any children, but none seem to work. Right now, I have 3 separate Classes.
Main:
public class Main extends Sprite
{
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
var BF:BFi = new BFi;
this.addChild(BF);
this.width = 640;
this.height = 480;
trace(this + "Dimensions: " + width + ", " + height);
trace(this + "Coordinates: " + x + ", " + y);
}
}
BFi:
public class BFi extends Sprite
{
public function BFi()
{
var BFMenu:BFiMenu = new BFiMenu;
addChild(BFMenu);
trace(getChildAt(0));
this.x = this.y = 0;
this.width = 640;
this.height = 480;
BFMenu.x = this.y = 0;
BFMenu.width = 640;
BFMenu.height = 480;
trace(this + "Dimensions: " + width + ", " + height);
trace(this + "Coordinates: " + x + ", " + y);
}
}
and BFiMenu:
public class BFiMenu extends Sprite
{
[Embed(source = "../Assets/Button1.png")]private var Button1:Class;
public function BFiMenu()
{
var Bounds:Sprite = new Sprite;
Bounds.graphics.lineStyle(2, 0, 1);
Bounds.graphics.drawRect(0, 0, 640, 480);
addChild(Bounds);
var NewButton:ComplexButton = new ComplexButton(220, 405, 200, 50, Button1, "PLAY", "Block", 50, 0x000000, function Button1(e:MouseEvent):void { /*parent.removeChildAt(0);*/ } );
//var NewButton:ComplexButton = new ComplexButton(0, 0, 200, 50, Button1, "PLAY", "Block", 50, 0x000000, function Button1(e:MouseEvent):void { parent.removeChildAt(0); } );
addChild(NewButton);
this.width = 640;
this.height = 480;
trace(this + "Dimensions: " + width + ", " + height);
trace(this + "Coordinates: " + x + ", " + y);
trace(NewButton + "Dimensions: " + NewButton.width + ", " +NewButton.height);
trace(NewButton + "Coordinates: " + NewButton.x + ", " + NewButton.y);
}
}
the rectangle named "Bounds" has the height and width of what I want (640x480), but the button that I placed in, supposed to have a y-coord of about 450, instead has a y-value of nearly 800, and is clearly distorted, but still on screen, even though the height is only 480.
The "ComplexButton" Class that is called is my own button class, and I've tested that enough to know that it works fine. when I run this program, it Distorts everything and nothing is where I wanted it to be. Any help would be very appreciated.
Few notes:
Any time a display object is created, the initial x and y coordinates are defaulted to zero, so you don't need to initialize them to 0 yourself.
Changing the width and height of an empty display object will do nothing. If the display object has graphical content, then it will scale that content so that it matches the desired width and height, which would also change the scale factors.
If you are going to draw a shape in a Disp.Object to give it a width and height, you do not then need to set those values explicitly.
Try removing each of the 3 places where you explicitly set those values.
I am working on a breakout type game with dynamically-created squares. When a brick gets hit, I fire off a removeMC function that is supposed to turn it white and make it shrink down in size. However, sometimes the squares just turn white instead of tweening down. I have included the script for the removeMV function as well as the function that creates the squares. Arg1 is the square to be removed. I apologize for the bad naming conventions, but the fire got corrupted and had to be recovered with a decompiler.
This is the removeMC function
public function removeMC(arg1:flash.display.Sprite):*
{
this.score --;
this.uiBar.txtScore.text=this.score;
var loc1:*=new flash.geom.ColorTransform();
loc1.color = 0xffffFF;
arg1.transform.colorTransform = loc1;
TweenMax.to(arg1, 0.4, {colorTransform:{tint:0x0000ff, tintAmount:1}});
var loc2:*=this.ballMC.x - this.ballMC.x % 30;
var loc3:*=this.ballMC.y - this.ballMC.y % 30;
arg1.scaleY = arg1.scaleY * -1;
// trace("Ball x:" + this.ballMC.x + " ballY:" + this.ballMC.y + " block x:" + loc2 + " block y:" + loc3);
var loc4:*=new fl.transitions.Tween(arg1, "width", null, 30, 0, 0.5, true);
var loc5:*=new fl.transitions.Tween(arg1, "height", null, 30, 0, 0.5, true);
var loc6:*=new fl.transitions.Tween(arg1, "x", null, 0, loc2, 0.5, true);
var loc7:*=new fl.transitions.Tween(arg1, "y", null, 0, loc3, 0.5, true);
this.brickArray.splice(this.indexSearch(this.brickArray, arg1), 1);
arg1.x+=3000;//failsafe to remove the squares. doesn't work
arg1.y+=3000;
return;
}
This is the function that creates the squares. Arg 1 and arg2 are the width and height in squares
public function createImgNodeGrid(arg1:int=1, arg2:int=1, arg3:Number=0):void
{
var loc6:*=0;
var loc7:*=null;
var loc8:*=null;
var loc9:*=null;
var loc10:*=null;
var loc1:*=this._img.width / arg1;
var loc2:*=this._img.height / arg2;
var loc3:*=arg1 * arg2;
this._imgNodes = [];
var loc4:*=0;
var loc5:*=0;
while (loc5 < arg1)
{
loc6 = 0;
while (loc6 < arg2)
{
loc7 = new flash.geom.Rectangle(loc5 * loc1, loc6 * loc2, loc1, loc2);
loc8 = new flash.display.BitmapData(loc1, loc2, true);
loc8.copyPixels(this._img.bitmapData, loc7, this.zero);
loc9 = new flash.display.Bitmap(loc8);
loc9.x = loc5 * (loc1 + arg3);
loc9.y = loc6 * (loc2 + arg3);
var loc11:*;
this._imgNodes[loc11 = loc4++] = loc9;
loc10 = new flash.display.Sprite();
loc10.mouseChildren = false;
this.brickArray.push(loc10);
loc10.addChild(loc9);
this._tiledImg.addChild(loc10);
++loc6;
}
++loc5;
}
return;
}
I may miss the mark here as its quite hard to read that lot, however, this is my suggestion for your removeMc function. I noticed you have TweenMax, so I would utilise that as opposed to the flash tweener class.
public function removeMC(arg1:flash.display.Sprite):*
{
this.score --;
this.uiBar.txtScore.text=this.score;
var loc1:*=new flash.geom.ColorTransform();
loc1.color = 0xffffFF;
arg1.transform.colorTransform = loc1;
var loc2:*=this.ballMC.x - this.ballMC.x % 30;
var loc3:*=this.ballMC.y - this.ballMC.y % 30;
TweenMax.to(arg1, 0.4, {scaleY:0, scaleX:0, x:loc2, y:loc3, colorTransform:{tint:0x0000ff, tintAmount:1}, onComplete:tweenComplete(arg1)});
// trace("Ball x:" + this.ballMC.x + " ballY:" + this.ballMC.y + " block x:" + loc2 + " block y:" + loc3);
this.brickArray.splice(this.indexSearch(this.brickArray, arg1), 1);
return;
}
private function tweenComplete(square:Sprite):void
{
this.removeChild(square);
}
That should result in the square shrinking to 0 size and becoming white at the same time. Then once it completes it will remove the child completely.
I've read a number of similar questions to this on here, but unfortunately none of them seem to give the exact answer I'm after, or they might but the maths is beyond me!
I'm creating a game where you have a cannon at the left edge of the screen. I want to be able to fire a cannonball from the cannon in an arc so that it intersects where the mouse pointer is on the screen.
I've seen a few examples that move a projectile in an arc from point a to point b, but what I need is for the cannonball to first move along the axis of the cannon itself, it's no good if the ball leaves the end of the cannon at a different angle to which the cannon is pointing.
The only force acting on the ball will be gravity and it's starting velocity.
Also to complicate matters, I need the cannons angle to change according to how far away the mouse pointer is from the end of the cannon, so if the pointer is far away than the cannon will point upwards say at an angle of 45 degrees, but if the pointer is very close to the end of the cannon then the cannon will point directly at the pointer, this I've more or less already got working by just getting the distance between them and then dividing it by a number and subtracting it from the rotation value of the cannon, but it's a bit of a rough way of doing it.
EDIT
Using the code below I've managed to the line in the screen shot below. But as you can see it's not the trajectory I need, I need something more like the red line I've put in.
And here's how I've implemented the code (probably wrongly)
public class GameTurretLine2
{
var rt:Object = null;
var lineMc:MovieClip = new MovieClip();
var myTurret:GameMainGun = null;
var pta:Point = new Point(0,0);
var ptb:Point = new Point(0,0);
var ptc:Point = new Point(0,0);
var ptd:Point = new Point(0,0);
public function GameTurretLine2(rt2,turret)
{
rt = rt2;
myTurret = turret;
lineMc.graphics.lineStyle(2, 0x55aa00);
mainLoop();
rt.rt.GameLayers.turretLineMc.addChild(lineMc);
}
function mainLoop()
{
lineMc.graphics.clear();
//get points
var turretEnd:Object = myTurret.rt.Useful.localToGlobalXY(myTurret.mC.turret.firePoint);
var turretStart:Object = myTurret.rt.Useful.localToGlobalXY(myTurret.mC.turret);
var mousePos:Point = new Point(myTurret.rt.rt.mouseX,myTurret.rt.rt.mouseY);
var inbetween:Point = new Point(0,0);
//start
pta.x = turretStart.newX;
pta.y = turretStart.newY;
//mouse end
ptd.x = mousePos.x;
ptd.y = mousePos.y;
// The cannon's angle:
// make the cannon's angle some inverse factor
// of the distance between the mouse and cannon tip
var dist:Number = myTurret.rt.Useful.getDistance(turretEnd.newX, turretEnd.newY, mousePos.x, mousePos.y);
var cAng:Number = dist * (180/Math.PI);
var ptbc:Point = new Point((ptd.x - pta.x) *.5,0);
ptbc.y = Math.tan(cAng) * ptbc.x;
//ptb = new Point(ptbc.x - ptbc.x * .15, ptbc.y);
ptb = new Point(turretEnd.newX, turretEnd.newY);
ptc = new Point(ptbc.x + ptbc.x * .5, ptbc.y);
// create the Bezier:
var bz:BezierSegment = new BezierSegment(pta,ptb,ptc,ptd);
trace(bz);
// define the distance between points that you want to draw
// has to be between 0 and 1.
var stepVal:Number = .1;
var curPt:Point = pta;
//draw circles
lineMc.graphics.drawCircle(pta.x, pta.y, 4);
lineMc.graphics.drawCircle(ptb.x, ptb.y, 4);
lineMc.graphics.drawCircle(ptc.x, ptc.y, 4);
lineMc.graphics.drawCircle(ptd.x, ptd.y, 4);
lineMc.graphics.lineStyle(2, 0x0000ff);
//step along the curve to draw it
for(var t:Number = 0;t < 1;t+=stepVal){
lineMc.graphics.moveTo(curPt.x, curPt.y);
curPt = bz.getValue(t);
trace("curPt = " + curPt.x + "," + curPt.y);
lineMc.graphics.lineTo(curPt.x, curPt.y);
}
trace("pta = " + pta.x + "," + pta.y);
trace("ptb = " + ptb.x + "," + ptb.y);
trace("ptc = " + ptc.x + "," + ptc.y);
trace("ptd = " + ptd.x + "," + ptd.y);
}
}
Also for some strange reason, the line created by the code flips, from how it is in the screen shot to an indented code (y flipped) just by moving the mouse a tiny amount, so as you move the mouse the line jumps everywhere.
One method is to create a Bezier curve.
This sounds like a workable solution because you essentially want the curve to always fit under some triangle. If this triangle defines the control points for a Bezier curve, you can make that match pretty closely the arc of a cannonball under gravity (it's not a perfect representation of gravity). One side-effect of this method is that the (inversed) height can define the force of the cannonball.
You can use the fl.motion.BezierSegment to create a curve and step along it. Paste this code into an FLA:
import fl.motion.BezierSegment;
var mySprite:Sprite = new Sprite();
addChild(mySprite);
mySprite.graphics.lineStyle(2, 0x55aa00);
// End point of the cannon:
var pta:Point = new Point(0, 100);
mySprite.graphics.drawCircle(pta.x, pta.y, 4);
trace("pta = " + pta.x + "," + pta.y);
// mouse point
// var ptd:Point = new Point(mouseX, mouseY);
// for testing:
var ptd:Point = new Point(200,100);
mySprite.graphics.drawCircle(ptd.x, ptd.y, 4);
trace("ptd = " + ptd.x + "," + ptd.y);
// The cannon's angle:
// make the cannon's angle some inverse factor
// of the distance between the mouse and cannon tip
// var dx:Number = ptd.x-pta.x;
// var dy:Number = ptd.y-pta.y;
// var dist:Number = Math.sqrt(dx * dx + dy * dy);
var cAng:Number = 30 * /(180/Math.PI);
// point the cannon in the correct direction here, however you are intending to do that.
// triangulate the cannon pt and mouse pt assuming the cannon's angle for both:
// *** NOTE: for simplicity, this assumes a straight line on the x-plane. ***
var ptbc:Point = new Point((ptd.x - pta.x) *.5,0);
ptbc.y = Math.tan(cAng) * ptbc.x;
trace("ptbc = " + ptbc.x + "," + ptbc.y);
// to adjust the curve:
var ptb:Point = new Point(ptbc.x - ptbc.x * .15, ptbc.y);
var ptc:Point = new Point(ptbc.x + ptbc.x * .5, ptbc.y);
mySprite.graphics.drawCircle(ptb.x, ptb.y, 4);
mySprite.graphics.drawCircle(ptc.x, ptc.y, 4);
// create the Bezier:
var bz:BezierSegment = new BezierSegment(pta,ptb,ptc,ptd);
trace(bz);
// define the distance between points that you want to draw
// has to be between 0 and 1.
var stepVal:Number = .1;
var curPt:Point = pta;
mySprite.graphics.lineStyle(2, 0x0000ff);
//step along the curve to draw it
for(var t:Number = 0;t < 1;t+=stepVal){
mySprite.graphics.moveTo(curPt.x, curPt.y);
curPt = bz.getValue(t);
trace("curPt = " + curPt.x + "," + curPt.y);
mySprite.graphics.lineTo(curPt.x, curPt.y);
}
mySprite.x = stage.stageWidth/2-mySprite.width/2;
mySprite.y = stage.stageHeight/2-mySprite.height/2;
As is, this code is not attached directly to the mouse, so you will have to use your own MouseEvent and AdjustCannonEvent to run this code. (Also, make sure to see the note in the code.)