I am developing a tree game and having dots to add branches on the tree, I want to enhance it for e.g. when one dot get a click then it display other dots within a particular radius around it.
From the description you've given, I think you are looking for Distance Formula.
Sqrt((y2-y1)^2 + (x2-x1)^2)
For example:
You have a radius defined and an array of dots:
var radius:int = 20;
var myDots = new Array ({'x':0, 'y': 0}, {'x': 5, 'y': 5}, {'x': 10, 'y': 5}, {'x': 10, 'y': 5}, {'x': 10, 'y': 10});
The dot being clicked is (5,5) and suppose you have a determined radius r=20.
Now, to get all the dots withing the radius r, by iterating in the dots:
function getDotsWithinRadius(x,y){
for(var i= 0; i<myDots.length;i++){
var x2 = myDots[i].x;
var y2 = myDots[i].y;
var val = Math.sqrt(Math.pow(y2-y,2) + Math.pow(x2-x, 2));
if(val <=radious){
/*The dot is with the radius of the give location.
This is the place where you tell the current dot to show up or
something like that.
*/
}
}
}
I haven't tested the code but I really hope this gives you an understanding.
Related
I'm trying to determine if a point is inside a polygon using TurfJS.
But I'm getting unexpected results.
In first place, I tested this simple code and works well.
The intersection is true because the point pt0 is one the points in the polygon.
var pt0 = turf.point([1, 1]);
var poly0 = turf.polygon([
[
[-1, -1],
[-1, 1],
[1, 1],
[-1, -1]
]
]);
var inter0 = turf.intersect(poly0,pt0); // TRUE
var inside0 = turf.inside(pt0,poly0); // FALSE
The next code is very similar, but the intersection returns undefined, while the tested point also belongs to the polygon.
var polygon1 = turf.polygon([
[-56.14700317382812,-33.179944977396694],
[-56.14502906799316,-33.16895330313461],
[-56.13266944885254,-33.174557074027],
[-56.14700317382812,-33.179944977396694]
]);
var point1 = turf.point([-56.13266944885254,-33.174557074027]);
var inter1 = turf.intersect(polygon1,point1); // UNDEFINED
var inside1 = turf.inside(point1,polygon1); // FALSE
Here is a JSFiddle.
how to get the graphics points and change the values of its x&y at runtime?
for example:
var moveToX:Array = [50, 200];
var moveToY:Array = [0, 0];
var lineToX:Array = [100, 0, 50, 250, 150, 200];
var lineToY:Array = [100, 100, 0, 100, 100, 0];
var _points:Array = [];
var linesIndex:int = 0;
var myShape:Shape = new Shape();
myShape.graphics.lineStyle(3, 0x000000, .2);
myShape.graphics.beginFill(0x666666, .1);
for (var i:uint = 0; i< moveToX.length; i++)
{
var _point:Point = new Point(moveToX[i], moveToY[i]);
_points.push(_point);
}
for (var p:uint = 0; p< _points.length; p++)
{
myShape.graphics.moveTo(_points[p].x, _points[p].y);
myShape.graphics.lineTo(lineToX[linesIndex], lineToY[linesIndex]);
myShape.graphics.lineTo(lineToX[linesIndex+1], lineToY[linesIndex+1]);
myShape.graphics.lineTo(lineToX[linesIndex+2], lineToY[linesIndex+2]);
linesIndex +=3;
}
myShape.x = 0;
myShape.y = 0;
addChild(myShape);
Now I want to change the points values and update the shape at runtime, but what I am looking for is NOT to clear and redraw it again.. I am trying to apply the changes directly to the same shape because it has a lot of points and lines as the update will be every 20 milliseconds..
So can you help please? Thnaks.
You can't just simply move graphic geometry and see it moves on the screen.
There is no magic and when you want to see graphic in different position on the screen you need to redraw it. When you move MovieClip by changing x or y properties the whole its graphics is redrawing still.
If you want to translate all points by the same value the best way to do this is just change position properties of your Shape object.
i created three arrays and each of them has their own sets of questions in it. is it possible to shuffle that three arrays everytime the game starts? so that the user will have to answer different sets of question everytime he clicks for a new game.
See for example:
Randomize or shuffle an array
as3 random array - randomize array - actionscript 3
The second one has a nice cheeky little use of Array.sort():
var arr:Array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
function randomize (a:*, b:*):int
{
return (Math.random() > .5) ? 1 : -1;
}
trace(arr.sort(randomize));
To shuffle the 3 arrays you could create 3 other arrays that will serve to hold the shuffled values.
var arr1:Array = [1, 2, 3, 4, 5];
var sorted1:Array = new Array(arr1.length);
var arr2:Array = [1, 2, 3, 4, 5];
var sorted2:Array = new Array(arr2.length);
var arr3:Array = [1, 2, 3, 4, 5];
var sorted3:Array = new Array(arr3.length);
randomPos:Number = 0;
you could then create a function that takes the value from one array and place it into a new shuffled array.
function shuffleArray(x, y){
for(var i:int = 0; i < y.length; i++){
randomPos = int(Math.random() * x.length);
y[i] = x.splice(randomPos, 1)[0];
}
}
Then you would call the suffleArray function on each set of arrays:
shuffleArray(arr1, sorted1);
shuffleArray(arr2, sorted2);
shuffleArray(arr3, sorted3);
I hope this helps.
I want to create volume knob using HTML5 and CreateJS. It is almost done. you can see this on following url
http://www.urbantruanthosting.co.uk/radiosimulator/testpage.html
but it is moving on every event of js. And I want to rotate on mouse's pressmove event on both side and currently it's moving clockwise, how can I rotate it in reverse. Please give me suggestion.
Thanks in advance.
and I have used following code.
var bmp = new createjs.Bitmap(image).set({
scaleX: 1,
scaleY: 1,
regX: w / 2,
regY: h / 2,
cursor: "pointer",
x: 305,
y: -90,
rotation: -55
});
bmp.regX = bmp.image.width / 2;
bmp.regY = bmp.image.height / 2;
var movieClip = new createjs.Container();
movieClip.addChild(bmp);
imageContainer.addChild(movieClip);
/*add events to enavle the knob to moveclockwise START*/
bmp.addEventListener("pressmove", function (evt) {
TweenMax.to(bmp, 5, { rotation: 270, repeat: -1, ease: Linear.easeNone });
if (headerCnt == 0) {
audioElement.play();
screen.src = 'images/header_5.jpg';
headerCnt = 5;
screenImage.set({
image: screen
});
}
stage.update();
});
This is where trigonometry comes in handy. Check out the following fiddle. Using the Math.atan2 function, we can calculate the angle of the mouse pointer relative to the center of the dial. Then, we convert radians to degrees and set the rotation of the dial.
dial.addEventListener("pressmove", function(e){
console.log(e);
//Calc Angle
var adj = e.stageX - dialHolder.x;
var opp = e.stageY - dialHolder.y;
var angle = Math.atan2(opp, adj);
angle = angle / (Math.PI / 180);
dial.rotation = angle;
});
Note: The regX and regY points might be slightly off which is why the dial wobbles a bit.
HTML5 canvas: I'm looking for a way to draw a single stroke around a combined path.
For example if I have two overlapping circles I don't want to have two overlapping circle strokes, but one single stroke around the combined region of both circles..
Any chance for that?
It can be done by using globalCompositeOperation. There are various ways you can draw the shapes them selves but here is one approach that results in this (for the two rectangle circles in the demo):
Step 1: setup the normal canvas
Step 2: setup an off-screen canvas
Update Not sure how I could miss the obvious, but you can of course just stroke the circles first, then punch a whole with composite mode and a fill - much faster (I guess I had images on my mind when I came up with the offset redraw).
The reason for off-screen canvas is if you have something in the background already on the main canvas. This will be deleted otherwise where we punch the hole. If nothing is there there is no problem drawing this to a single canvas - updated code:
/// some regions
var rect = [ [20, 20, 200, 200], [100, 100, 200,200] ],
/// ox = off-screen context
ox.strokeStyle = '#fff';
ox.lineWidth = 3 * 2; /// x2 as half will be gone when we punch hole
/// stroke outlines
for(; r = rect[i]; i++) {
o = r[2] * 0.5;
ox.beginPath();
ox.arc(r[0] + o, r[1] + o, o, 0, 2 * Math.PI);
ox.stroke();
}
/// punch hole with composite mode and fill
ox.globalCompositeOperation = 'destination-out';
for(i = 0; r = rect[i]; i++) {
o = r[2] * 0.5;
ox.beginPath();
ox.arc(r[0] + o, r[1] + o, o, 0, 2 * Math.PI);
ox.fill();
}
/// draw result to main canvas
/// ctx = main context, ocanvas = off-screen canvas
ctx.drawImage(ocanvas, 0, 0);
(Animated) online demo using this optimized version
I'll leave the old code as it can be used for images that can't be stroked -
Now draw the shapes filled to the off-screen canvas. Draw in the color you want the outline to be in.
/// some regions
var rect = [ [20, 20, 200, 200], [100, 100, 200,200] ],
/// ox = off-screen canvas
ox.fillStyle = '#fff';
/// draw the array with circes
for(; r = rect[i]; i++) {
var o = r[2] * 0.5;
ox.beginPath(); //use this here - arcs are currently buggy
ox.arc(r[0] + o, r[1] + o, o, 0, 2 * Math.PI);
ox.fill(); //.. and here
}
Now draw the cached image of the shapes back to main canvas. the shapes must be drawn with a slight offset in each direction - this step will create the outline:
/// ctx = main context, ocanvas = off-screen canvas
ctx.drawImage(ocanvas, -1, -1);
ctx.drawImage(ocanvas, 1, -1);
ctx.drawImage(ocanvas, 1, -1);
ctx.drawImage(ocanvas, 1, 1);
ctx.drawImage(ocanvas, -1, 1);
ctx.drawImage(ocanvas, 1, 1);
ctx.drawImage(ocanvas, -1, -1);
ctx.drawImage(ocanvas, -1, 1);
And finally we punch a "hole" in the filled shape to make it transparent with an outline using globalCompositeOperation + a final draw in 0 offset position :
ctx.globalCompositeOperation = 'destination-out';
ctx.drawImage(ocanvas, 0, 0);
ONLINE DEMO
To make the border thicker just increase the offset when you draw back the shapes to main canvas.
That's my current solution. Doesn't need a second canvas and is easier to achieve. It still uses the Ken's idea to use globalCompositeOperation:
context.lineWidth = 2;
context.stroke();
var prev = context.globalCompositeOperation;
context.globalCompositeOperation = "destination-out";
context.fill();
context.globalCompositeOperation = prev;