Creating Mouse Event Handlers For Canvas Shapes - javascript

I'm coding a tile based game in javascript using canvas and was wondering how I could create a simple event handler for when the mouse enters the dimensions of a tile.
I've used jquery's http://api.jquery.com/mousemove/ in the past but for a very simple application but can't seem to wrap my head around how I'll do it in this case (quickly).
Hmm..
I started writing this post without a clue of how to do it, but I just tried using the jquery mousemove like I started above. I have a working version, but it seems 'slow' and very clunky. It's doesn't seem smooth or accurate.
I put all mode code into a js fiddle to share easily:
http://jsfiddle.net/Robodude/6bS6r/1/
so what's happening is:
1) jquery's mousemove event handler fires
2) Sends the mouse object info to the GameBoard
3) Sends the mouse object info to the Map
4) Loops through all the tiles and sends each one the mouse object
5) the individual tile then determines if the mouse coords are within its boundaries. (and does something - in this case, I just change the tiles properties to white)
but here are the sections I'm most concerned about.
$("#canvas").mousemove(function (e) {
mouse.X = e.pageX;
mouse.Y = e.pageY;
game.MouseMove(mouse);
Draw();
});
function GameBoard() {
this.Map = new Map();
this.Units = new Units();
this.MouseMove = function (Mouse) {
this.Map.MouseMove(Mouse);
};
}
function Map() {
this.LevelData = Level_1(); // array
this.Level = [];
this.BuildLevel = function () {
var t = new Tile();
for (var i = 0; i < this.LevelData.length; i++) {
this.Level.push([]);
for (var a = 0; a < this.LevelData[i].length; a++) {
var terrain;
if (this.LevelData[i][a] == "w") {
terrain = new Water({ X: a * t.Width, Y: i * t.Height });
}
else if (this.LevelData[i][a] == "g") {
terrain = new Grass({ X: a * t.Width, Y: i * t.Height });
}
this.Level[i].push(terrain);
}
}
};
this.Draw = function () {
for (var i = 0; i < this.Level.length; i++) {
for (var a = 0; a < this.Level[i].length; a++) {
this.Level[i][a].Draw();
}
}
};
this.MouseMove = function (Mouse) {
for (var i = 0; i < this.Level.length; i++) {
for (var a = 0; a < this.Level[i].length; a++) {
this.Level[i][a].MouseMove(Mouse);
}
}
};
this.BuildLevel();
}
function Tile(obj) {
//defaults
var X = 0;
var Y = 0;
var Height = 40;
var Width = 40;
var Image = "Placeholder.png";
var Red = 0;
var Green = 0;
var Blue = 0;
var Opacity = 1;
// ...
this.Draw = function () {
ctx.fillStyle = "rgba(" + this.Red + "," + this.Green + "," + this.Blue + "," + this.Opacity + ")";
ctx.fillRect(this.X, this.Y, this.Width, this.Height);
};
this.MouseMove = function (Mouse) {
if ((Mouse.X >= this.X) && (Mouse.X <= this.Xmax) && (Mouse.Y >= this.Y) && (Mouse.Y <= this.Ymax)) {
this.Red = 255;
this.Green = 255;
this.Blue = 255;
}
};
}

If you have a grid of tiles, then given a mouse position, you can retrieve the X and Y index of the tile by dividing the X mouse position by the width of a tile and Y position with the height and flooring both.
That would make Map's MouseMove:
this.MouseMove = function (Mouse) {
var t = new Tile();
var tileX = Math.floor(mouse.X / t.Width);
var tileY = Math.floor(mouse.Y / t.Height);
this.Level[tileY][tileX].MouseMove(Mouse);
};
Edit: You asked for some general suggestions. Here you go:
It's more common to use initial uppercase letters for only classes in JavaScript.
Mouse is a simple structure; I don't think it needs to have its own class. Perhaps use object literals. (like {x: 1, y: 2})
You may want to use JavaScript's prototype objects, rather than using this.method = function() { ... } for every method. This may increase performance, since it only has to create the functions once, and not whenever a new object of that class is made.

Related

Enemy detection and turret animation/control in a JavaScript p5.js game

I'm making a tower defense game using JavaScript and p5.js library. My enemy follows a path and their location is always stored in a list. I have a base and a gun, the gun rotates around the base(as 1 unit) and is supposed to point towards the nearest enemy. I have a function that will allow me to make the gun point towards the enemy pointEnemy however, I'm not able to get the correct condition to make it point towards the nearest enemy in it's range. I need the correct argument for enemyx & enemyy. I'm currently spawning 100 enemies and they keep moving, their location is stored in globalenemy1position. Any help is appreciated, thank you.
Required Code
Some important variables
var numberOfEnemy1 = 100
let classenemy1 = new Enemy1(numberOfEnemy1);
var globalenemy1position = [];
var isFireTowerPressed = false;
var FireTowerPos = []; // Position of all FireTowers => [x,y]
var FireTowerRange = 300;
var FireTowerAngle = 0;
My Enemy Class
class Enemy1
{
constructor(number_of_enemies)
{
this.number_of_enemies = number_of_enemies;
this.enemy_position = [];
this.enemy1speed = 4;
}
enemy1_spawn()
{
let randomx = random(-300, -100);
for(var i=0; i<this.number_of_enemies; i++)
{
var positionx = randomx;
var positiony = 100;
this.enemy_position.push([positionx + (-i*50), positiony]);
globalenemy1position.push([positionx + (-i*50), positiony]);
image(enemy1, this.enemy_position[i][0], this.enemy_position[i][1]);
}
}
enemy1_move()
{
for(var i = 0; i < this.enemy_position.length; i++)
{
image(enemy1, this.enemy_position[i][0], this.enemy_position[i][1]);
if (this.enemy_position[i][0] >= 200 && this.enemy_position[i][1] <= 450 && this.enemy_position[i][0] < 599)
{
this.enemy_position[i][1] += this.enemy1speed;
globalenemy1position[i][1] += this.enemy1speed;
}
else if (this.enemy_position[i][1] >= 100 && this.enemy_position[i][0] >= 600)
{
this.enemy_position[i][1] -= this.enemy1speed;
globalenemy1position[i][1] -= this.enemy1speed;
}
else if (this.enemy_position[i][0] >= 750)
{
this.enemy_position[i][0] = 750;
lives --;
this.enemy_position.shift();
globalenemy1position.shift();
}
else
{
this.enemy_position[i][0] += this.enemy1speed;
globalenemy1position[i][0] += this.enemy1speed;
}
}
}
}
Draw Function - Redraws Every Frame
function draw()
{
background(60, 238, 161);
[...]
classenemy1.enemy1_move();
rect(750, 70, 50, 100);
ShowLives();
if (isFireTowerPressed == true)
{
image(firetowerbaseImg, mouseX - 28, mouseY - 28);
noFill();
stroke(0,0,0);
strokeWeight(1);
circle(mouseX, mouseY, 300);
}
for (var i = 0; i < FireTowerPos.length; i++)
{
image(firetowerbaseImg, FireTowerPos[i][0], FireTowerPos[i][1]);
if (globalenemy1position.length >= 1)
{
var gunx = FireTowerPos[i][0] +28;
var guny = FireTowerPos[i][1]+25;
var gunrange = FireTowerPos[i][3];
for (j=0; j<globalenemy1position.length; j++)
{
// Need help with this statement here
pointEnemy(globalenemy1position[j][0], globalenemy1position[j][1], gunx, guny, FireTowerPos[i][2], FireTowerPos[i][3]);
}
}
else
{
image(firetowerturretImg, FireTowerPos[i][0], FireTowerPos[i][1]-20);
}
}
}
Function to make the gun point towards Enemy - I need the proper value for enemyx & enemyy
function pointEnemy(enemyx, enemyy, gunx, guny, gunangle, gunrange)
{
const isWithinRange = dist(enemyx, enemyy, gunx, guny) < gunrange;
if(isWithinRange)
{
gunangle = atan2(enemyy - guny, enemyx - gunx) + radians(90);
}
push();
translate(gunx, guny);
// rect(-25, -20, 50, 40) // Draw the gun base
// ellipse(0, 0, gun.range*2) // display the gun range
rotate(gunangle);
image(firetowerturretImg, -28, -45); // Set the offset of the gun sprite and draw the gun
pop();
}
Here is a picture to help visualise the problem
As you can see, currently I'm just iterating through all the enemies and giving their location, so it's basically pointing to every enemy nearby.
Updates
1
I tried the approach given by #user3386109 , but wasn't able to implement it, also if possible I want the turret/gun to point towards the enemy till it leaves the range and not always point towards the closest enemy. It should start off with the closest and then keep pointing towards it till it leaves or the enemy dies(position removed from the list), whichever comes first. The function should then restart again and continue the process.
This process is the complete aiming for the tower. Add this to draw and it searches for enemies.
for (var i = 0; i < FireTowerPos.length; i++)
{
// image(firetowerbaseImg, FireTowerPos[i][0], FireTowerPos[i][1]);
// pointEnemy(mouseX, mouseY, FireTowerPos[i][0] +28, FireTowerPos[i][1]+25, FireTowerPos[i][2], FireTowerPos[i][3]);
image(firetowerbaseImg, FireTowerPos[i][0], FireTowerPos[i][1]);
var enemiesInRange = [];
let firetowerx = FireTowerPos[i][0];
let firetowery = FireTowerPos[i][1];
for (var j = 0; j < globalenemy1position.length; j++)
{
var checkDist = dist(globalenemy1position[j][0], globalenemy1position[j][1], firetowerx, firetowery);
let thisenemyx = globalenemy1position[j][0];
let thisenemyy = globalenemy1position[j][1];
if (checkDist < FireTowerRange)
{
enemiesInRange.push([thisenemyx, thisenemyy]);
pointEnemy(enemiesInRange[0][0], enemiesInRange[0][1], FireTowerPos[i][0] +28, FireTowerPos[i][1]+25, FireTowerPos[i][2], FireTowerPos[i][3]);
}
else
{
enemiesInRange.shift();
}
}
}

Detect a mouse click on an overlapping grid of boxes - JavaScript Canvas

I am currently trying to detect a mouse click on two grids of boxes simultaneously. One grid is easy, and I've just been using:
var gridPosX = Math.floor(mouseClickX/BoxWidth);
var gridPosY = Math.floor(mouseClickY/BoxHeight);
Now I also want to detect a mouse click on a secondary grid of boxes, located at the corners of the first grid of boxes. This could be achieved in a similar way to the first grid. The problem comes in because I want to detect a click on either the first grid, or the second one, at the same time. What is the best way to differentiate a click on the first grid verses a click on the second grid? I've tried to remove the Math.floor and used the greater than and less than operators (> <) to see if the click was closer to one grid spot than the other, but I've had no luck with that so far.
This is an image example of the grid. The black being the main one, the red being the second one
var WIDTH = 1280, HEIGHT = 1280;
var canvas, context;
var grid = [];
var grid2 = [];
var gridWidth = 10, gridHeight = 10;
var boxWidth = WIDTH/gridWidth, boxHeight = HEIGHT/gridHeight;
function main(){
canvas = document.createElement("canvas");
canvas.width = WIDTH;
canvas.height = HEIGHT;
context = canvas.getContext("2d");
document.body.appendChild(canvas);
canvas.onmousedown = function(e){
if(e.which == 1){
var gridPosX = Math.floor(e.offsetX/boxWidth);
var gridPosY = Math.floor(e.offsetY/boxHeight);
grid[gridPosX][gridPosY] = 0;
}
}
init();
setInterval(draw, 30);
}
function init(){
for(var x = 0; x < gridWidth; x++){
grid[x] = [];
grid2[x] = [];
for(var y = 0; y < gridHeight; y++){
grid[x][y] = 1;
grid2[x][y] = 1;
}
}
}
function draw(){
for(var x = 0; x < gridWidth; x++){
for(var y = 0; y < gridHeight; y++){
if(grid[x][y] == 1){
context.fillStyle = 'gray';
context.fillRect(x*boxWidth, y*boxHeight, boxWidth, boxHeight);
context.strokeRect(x*boxWidth, y*boxHeight, boxWidth, boxHeight);
}
}
}
for(var x = 0; x < gridWidth; x++){
for(var y = 0; y < gridHeight; y++){
if(grid2[x][y] == 1){
context.fillStyle = 'red';
context.fillRect((x*boxWidth)+(boxWidth)-(boxWidth/4), (y*boxHeight)+(boxHeight)-(boxHeight/4), boxWidth/2, boxHeight/2);
context.strokeRect((x*boxWidth)+(boxWidth)-(boxWidth/4), (y*boxHeight)+(boxHeight)-(boxHeight/4), boxWidth/2, boxHeight/2);
}
}
}
}
main();
Since the red grids show on top of the gray ones, I think you can first decide whether a mouse event is on a red grid or not. If not, then it must be on gray grids.
Based on the calculations below to check if a red grid is clicked:
var xRedIndex = Math.floor((e.offsetX - 3 / 4 * boxWidth) / (boxWidth / 2));
var yRedIndex = Math.floor((e.offsetY - 3 / 4 * boxHeight) / (boxHeight / 2));
if (xRedIndex % 2 === 0 && yRedIndex % 2 === 0) {
console.log("red");
console.log("Red grid x: " + (xRedIndex / 2));
console.log("Red grid y: " + (yRedIndex / 2));
} else {
console.log("gray");
var gridPosX = Math.floor(e.offsetX / boxWidth);
var gridPosY = Math.floor(e.offsetY / boxHeight);
grid[gridPosX][gridPosY] = 0;
}
Basically, you first subtract the initial gray area in the first column/row from the offsetX/Y, then see if the rest of the offsetX/Y contains an odd or even number of boxSize/2 (side length of red grid). An even number means the click is on red grids, otherwise it falls on the uncovered gray area.
Working fiddle: https://jsfiddle.net/mwxzgth6/1/

Is there a way to automatically generate a pseudo image map?

Hitbox Overlay IIFE Code
//CSS Hitbox Solution 08-26-2015
//StackOverflow - https://stackoverflow.com/questions/32233084/show-an-element-without-hitbox-does-not-take-mouse-touch-input
//Detect MouseOver https://stackoverflow.com/questions/1273566/how-do-i-check-if-the-mouse-is-over-an-element-in-jquery
//Source: https://stackoverflow.com/questions/3942776/using-jquery-to-find-an-element-at-a-particular-position
//https://css-tricks.com/snippets/jquery/get-x-y-mouse-coordinates/
(function($) {
$.mlp = {
x: 0,
y: 0
}; // Mouse Last Position
function documentHandler() {
var $current = this === document ? $(this) : $(this).contents();
$current.mousemove(function(e) {
jQuery.mlp = {
x: e.pageX,
y: e.pageY
};
});
$current.find("iframe").load(documentHandler);
}
$(documentHandler);
$.fn.ismouseover = function(overThis) {
var result = false;
this.eq(0).each(function() {
var $current = $(this).is("iframe") ? $(this).contents().find("body") : $(this);
var offset = $current.offset();
result = offset.left <= $.mlp.x && offset.left + $current.outerWidth() > $.mlp.x && offset.top <= $.mlp.y && offset.top + $current.outerHeight() > $.mlp.y;
});
return result;
};
})(jQuery);
$('.notification-box').on("click", function() {
$("button").each(function(i) {
var iteratedButton = $('button:eq(' + i + ')');
var buttonID = iteratedButton.attr("id");
if (iteratedButton.ismouseover()) {
iteratedButton.toggleClass(buttonID);
}
});
});
Example 01: Overlay Example for context
Example 02: Concept for auto generating content - Derived from this stackoverflow question.
There is a way by which one can have multiple objects underneath an overlay that masks them. Then, there is a way to have the pointer interact with the elements underneath said overlay if the user clicks at the predetermined point. My question is, may someone please write the code that would, marry the concept of the <map> tag with the IIFE that detects if the point of reference the user clicked is that image and then, act as though it was clicked.
If that did not make sense, simply, I am looking for a process that deviates away from manually setting up coordinates for <area> or having to use tool (which are profound) such as http://www.image-maps.com/. Rather, we would let the pointer do all the work.
We have the following high utility + highly compatible methods: .offset(), .position(), elementFromPoint() and the ability to put elements behind a mask utilizing basic CSS.
So we could combine the IIFE Overlay hitbox method above + ???? = Profit (good bye mapping coordinates via <map>).
I just do not know what the ???? is. I do know that whatever the solution is, I would prefer that it works in all browsers (including IE 5).
Lastly, the process should be fairly automatic in design, setup and implementation.
Whoever creates it, please dub it autoMapperJs (as it would not be limited to images).
Update:
A core feature component of the ???? has been realized as noted by #Alex in the comments. CreateJs notices when the pointer is hovered over a non-transparent area of a image. That is powerful and should be standard in the tool created. It also seems to utilize .mousemove() and z-index. Please keep commenting, as collectively, I feel a solution can be found.
Here's a start. Put images into an array of layers and placements on canvas then run through them on mouse over for hit. Also put over images in layers array to draw that image when hit.
var can = document.getElementById('image-map');
var W = can.width;
var H = can.height;
var ctx = can.getContext('2d');
var layers = [];
var mouse = {x:0,y:0};
can.addEventListener('mousemove', function(evt) {
mouse = getMousePos(can, evt);
drawCanvas();
}, false);
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left,
y: evt.clientY - rect.top
};
}
main();
function main() {
initLayers();
drawCanvas();
}
function drawCanvas() {
ctx.clearRect(0, 0, W, H);
var hit = -1;
for (var i =layers.length; i--;) {
var c = layers[i];
if(maskHit(c.img, c.x, c.y)) {
hit = i;
break;
}
}
for (var i =0; i < layers.length; i++) {
var c = layers[i];
var img = hit === i ? c.hov : c.img;
ctx.drawImage(img, c.x, c.y);
}
ctx.drawImage(circ(10,"rgba(255,200,0,.75)"), mouse.x-10/2,mouse.y-10/2);
}
// UTILITY TO DRAW SAMPLE IMAGES
function circ(size, color) {
var can = document.createElement('canvas');
can.width = can.height = size;
var to_rad = Math.PI / 180;
var ctx = can.getContext('2d');
ctx.beginPath();
ctx.moveTo(size, size / 2);
ctx.arc(size / 2, size / 2, size / 2, 0, 360 * to_rad);
ctx.fillStyle = color;
ctx.fill();
return can;
}
function initLayers() {
var s = 75; // size
// PUT YOUR IMAGES IN A LAYERS ARRAY WITH X,Y COORDS FOR CANVAS
// PLACEMENT. X AND Y ARE TOP LEFT CORNDER OF IMAGE. STORE HOVER
// IMAGE FOR MOUSE HIT.
layers = [{
img: circ(s, "#090"),
hov: circ(s, "#C0C"),
x: 123,
y: 12
}, {
img: circ(s, "#F00"),
hov: circ(s, "#C0C"),
x: 63,
y: 12
}, {
img: circ(s, "#00F"),
hov: circ(s, "#C0C"),
x: 3,
y: 12
}];
}
var maskCan = document.createElement("canvas");
maskCan.width=maskCan.height=1;
var maskCtx = maskCan.getContext('2d');
function maskHit(img, x, y) {
// get relative coords to image upper left corner
x = mouse.x - x;
y = mouse.y - y;
if (x < 0 || y < 0 || x > img.width || y > img.height) return false;
//return 1; // square hit, no alpha check
// ALPHA CHECK - draw one pixel, get and check alpha.
// sx sy sw sh dx dy dw dh
maskCtx.clearRect(0,0,1,1);
maskCtx.drawImage(img, x, y, 1, 1, 0, 0, 1, 1);
var imageData = maskCtx.getImageData(0,0,1,1);
//console.log(imageData.data[3])
return imageData.data[3] === 255;
}
#image-map {
border: 1px solid #ACE;
}
<canvas id="image-map" width="200" height="100"></canvas>

identify an object on canvas by a click event

Into this simple code I use an eventListener which doesn't look to work at all. The canvas display an image and the given hitpaint() function is supposed determines whether a click occurs. I cant understand why the eventListener behaves like that. Any insight would be helpful.
mycanv.addEventListener("click", function(e) {
var output = document.getElementByID("output");
ctx.fillStyle = 'blue';
//ctx.clearRect(0,0,100,20);
if (hitpaint) {
//ctx.fillText("hit",100,20);
output.innerHTML = "hit";
} else {
//ctx.fillText("miss",100,20);
output.innerHTML = "miss";
}
}, false);
The hitpaint() function is defined as:
function hitpaint(mouse_event) {
var bounding_box = mycanv.getBoundingClientRect();
var mousex = (mouse_event.clientX - bounding_box.left) *
(mycanv.width / bounding_box.width);
var mousey = (mouse_event.clientY - bounding_box.top) *
(mycanv.height / bounding_box.height);
var pixels = ctx.getImageData(mousex, mousey, 1, 1);
for (var i = 3; i < pixels.data.length; i += 4) {
// If we find a non-zero alpha we can just stop and return
// "true" - the click was on a part of the canvas that's
// got colour on it.
if (pixels.data[i] !== 0) return true;
}
// The function will only get here if none of the pixels matched in
return false;
}
Finally, the main loop which display the picture in random location into the canvas:
function start() {
// main game function, called on page load
setInterval(function() {
ctx.clearRect(cat_x, cat_y, 100, 100);
cat_x = Math.random() * mycanv.width - 20;
cat_y = Math.random() * mycanv.height - 20;
draw_katy(cat_x, cat_y);
}, 1000);
}
There are a some issues here:
As Grundy points out in the comment, the hitpaint is never called; right now it checks for it's existence and will always return true
The mouse coordinates risk ending up as fractional values which is no-go with getImageData
Scaling the mouse coordinates is usually not necessary. Canvas should preferably have a fixed size without an additional CSS size
Add boundary check for x/y to make sure they are inside canvas bitmap
I would suggest this rewrite:
mycanv.addEventListener("click", function(e) {
var output = document.getElementByID("output");
ctx.fillStyle = 'blue';
//ctx.clearRect(0,0,100,20);
if (hitpaint(e)) { // here, call hitpaint()
//ctx.fillText("hit",100,20);
output.innerHTML = "hit";
} else {
//ctx.fillText("miss",100,20);
output.innerHTML = "miss";
}
}, false);
Then in hitpaint:
function hitpaint(mouse_event) {
var bounding_box = mycanv.getBoundingClientRect();
var x = ((mouse_event.clientX - bounding_box.left) *
(mycanv.width / bounding_box.width))|0; // |0 cuts off any fraction
var y = ((mouse_event.clientY - bounding_box.top) *
(mycanv.height / bounding_box.height))|0;
if (x >= 0 && x < mycanv.width && y >= 0 && y < mycanv.height) {
// as we only have one pixel, we can address alpha channel directly
return ctx.getImageData(x, y, 1, 1).data[3] !== 0;
}
else return false; // x/y out of range
}

CreateJS - updating children coordinates with parent

I'd like to change the coordinates of 2 children containers within a parent container. Originally, I was looping through the children of the parent container and changing their x,y individually... but then it made more sense to just change the parent container's x,y...
The issue with that is... I need to get the individual altered coordinates of each child... But changing the parent container's coordinates doesn't seem to change the children's coordinates in relation to the stage...
The question is... how can I get the changing x,y of the children when I alter their parent's x,y?
Thanks
So if I'm moving the container of children around as such:
function NPCMove() {
if (pointA) {
if (ContainerOfAnimals.x < 400) {
ContainerOfAnimals.x +=2;
}
else {
pointA = false;
pointB = true;
}
}
else if (pointB) {
if (ContainerOfAnimals.x > 100) {
ContainerOfAnimals.x-=2;
}
else {
pointB = false;
pointA = true;
}
}
}
I can check the distance of the player to each child in the Parent Container as such using localToGlobal? (NPC_Array contains Parent Containers)
for (var i = 0; i < NPC_Array.length; i++) {
//get children containers of each big Container
for (var j = 0; j < NPC_Array[i].children.length; j++) {
//need child.x's global location now...
var pt = NPC_Array[i].localToGlobal(NPC_Array[i].children[j].x, NPC_Array[i].children[j].y);
var distX = Math.abs(players_Array[0].x - pt.x);
var distY = Math.abs(players_Array[0].y - pt.y);
if (distX < 50 && distY < 50) {
//Player is near child...
You would do a localToGlobal:
var stage = new createjs.Stage("test");
var p = new createjs.Container();
p.x = 200;
p.y = 200;
var c1 = new createjs.Shape();
c1.graphics.beginFill("#FF0000");
c1.graphics.drawRect(0, 0, 100, 100);
c1.graphics.endFill();
var c2 = new createjs.Shape();
c2.graphics.beginFill("#00FF00");
c2.graphics.drawRect(0, 0, 100, 100);
c2.graphics.endFill();
c2.x = 100;
p.addChild(c1);
p.addChild(c2);
stage.addChild(p);
stage.update();
var pt = p.localToGlobal(c2.x, c2.y);
alert("Stage x of c2: " + pt.x);
See it in action

Categories